@concavejs/docstore-bun-sqlite 0.0.1-alpha.11 → 0.0.1-alpha.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/index.js +1062 -489
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -14,7 +14,6 @@ var __export = (target, all) => {
|
|
|
14
14
|
});
|
|
15
15
|
};
|
|
16
16
|
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
17
|
-
var __require = import.meta.require;
|
|
18
17
|
|
|
19
18
|
// ../../node_modules/convex/dist/esm/values/base64.js
|
|
20
19
|
function getLens(b64) {
|
|
@@ -802,6 +801,237 @@ var init_values = __esm(() => {
|
|
|
802
801
|
init_errors();
|
|
803
802
|
});
|
|
804
803
|
|
|
804
|
+
// ../core/dist/id-codec/base32.js
|
|
805
|
+
function base32Encode(data) {
|
|
806
|
+
if (data.length === 0)
|
|
807
|
+
return "";
|
|
808
|
+
let result = "";
|
|
809
|
+
let buffer = 0;
|
|
810
|
+
let bitsLeft = 0;
|
|
811
|
+
for (const byte of data) {
|
|
812
|
+
buffer = buffer << 8 | byte;
|
|
813
|
+
bitsLeft += 8;
|
|
814
|
+
while (bitsLeft >= 5) {
|
|
815
|
+
bitsLeft -= 5;
|
|
816
|
+
const index = buffer >> bitsLeft & 31;
|
|
817
|
+
result += ALPHABET[index];
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
if (bitsLeft > 0) {
|
|
821
|
+
const index = buffer << 5 - bitsLeft & 31;
|
|
822
|
+
result += ALPHABET[index];
|
|
823
|
+
}
|
|
824
|
+
return result;
|
|
825
|
+
}
|
|
826
|
+
function base32Decode(str) {
|
|
827
|
+
if (str.length === 0)
|
|
828
|
+
return new Uint8Array(0);
|
|
829
|
+
const outputLength = Math.floor(str.length * 5 / 8);
|
|
830
|
+
const result = new Uint8Array(outputLength);
|
|
831
|
+
let buffer = 0;
|
|
832
|
+
let bitsLeft = 0;
|
|
833
|
+
let outputIndex = 0;
|
|
834
|
+
for (const char of str) {
|
|
835
|
+
const value = ALPHABET_MAP.get(char);
|
|
836
|
+
if (value === undefined) {
|
|
837
|
+
throw new Error(`Invalid base32 character: ${char}`);
|
|
838
|
+
}
|
|
839
|
+
buffer = buffer << 5 | value;
|
|
840
|
+
bitsLeft += 5;
|
|
841
|
+
if (bitsLeft >= 8) {
|
|
842
|
+
bitsLeft -= 8;
|
|
843
|
+
result[outputIndex++] = buffer >> bitsLeft & 255;
|
|
844
|
+
}
|
|
845
|
+
}
|
|
846
|
+
return result;
|
|
847
|
+
}
|
|
848
|
+
function isValidBase32(str) {
|
|
849
|
+
for (const char of str) {
|
|
850
|
+
if (!ALPHABET_MAP.has(char)) {
|
|
851
|
+
return false;
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
return true;
|
|
855
|
+
}
|
|
856
|
+
var ALPHABET = "0123456789abcdefghjkmnpqrstvwxyz", ALPHABET_MAP;
|
|
857
|
+
var init_base32 = __esm(() => {
|
|
858
|
+
ALPHABET_MAP = new Map;
|
|
859
|
+
for (let i2 = 0;i2 < ALPHABET.length; i2++) {
|
|
860
|
+
ALPHABET_MAP.set(ALPHABET[i2], i2);
|
|
861
|
+
ALPHABET_MAP.set(ALPHABET[i2].toUpperCase(), i2);
|
|
862
|
+
}
|
|
863
|
+
ALPHABET_MAP.set("i", 1);
|
|
864
|
+
ALPHABET_MAP.set("I", 1);
|
|
865
|
+
ALPHABET_MAP.set("l", 1);
|
|
866
|
+
ALPHABET_MAP.set("L", 1);
|
|
867
|
+
ALPHABET_MAP.set("o", 0);
|
|
868
|
+
ALPHABET_MAP.set("O", 0);
|
|
869
|
+
});
|
|
870
|
+
|
|
871
|
+
// ../core/dist/id-codec/vint.js
|
|
872
|
+
function vintEncode(value) {
|
|
873
|
+
if (value < 0) {
|
|
874
|
+
throw new Error("VInt cannot encode negative numbers");
|
|
875
|
+
}
|
|
876
|
+
if (value > 4294967295) {
|
|
877
|
+
throw new Error("VInt cannot encode values larger than 2^32-1");
|
|
878
|
+
}
|
|
879
|
+
value = value >>> 0;
|
|
880
|
+
if (value < 128) {
|
|
881
|
+
return new Uint8Array([value]);
|
|
882
|
+
}
|
|
883
|
+
if (value < 16512) {
|
|
884
|
+
const adjusted2 = value - 128;
|
|
885
|
+
return new Uint8Array([128 | adjusted2 >> 8 & 63, adjusted2 & 255]);
|
|
886
|
+
}
|
|
887
|
+
if (value < 2113664) {
|
|
888
|
+
const adjusted2 = value - 16512;
|
|
889
|
+
return new Uint8Array([192 | adjusted2 >> 16 & 31, adjusted2 >> 8 & 255, adjusted2 & 255]);
|
|
890
|
+
}
|
|
891
|
+
if (value < 270549120) {
|
|
892
|
+
const adjusted2 = value - 2113664;
|
|
893
|
+
return new Uint8Array([
|
|
894
|
+
224 | adjusted2 >> 24 & 15,
|
|
895
|
+
adjusted2 >> 16 & 255,
|
|
896
|
+
adjusted2 >> 8 & 255,
|
|
897
|
+
adjusted2 & 255
|
|
898
|
+
]);
|
|
899
|
+
}
|
|
900
|
+
const adjusted = value - 270549120;
|
|
901
|
+
return new Uint8Array([
|
|
902
|
+
240 | adjusted >> 32 & 7,
|
|
903
|
+
adjusted >> 24 & 255,
|
|
904
|
+
adjusted >> 16 & 255,
|
|
905
|
+
adjusted >> 8 & 255,
|
|
906
|
+
adjusted & 255
|
|
907
|
+
]);
|
|
908
|
+
}
|
|
909
|
+
function vintDecode(data, offset = 0) {
|
|
910
|
+
if (offset >= data.length) {
|
|
911
|
+
throw new Error("VInt decode: unexpected end of data");
|
|
912
|
+
}
|
|
913
|
+
const first = data[offset];
|
|
914
|
+
if ((first & 128) === 0) {
|
|
915
|
+
return { value: first, bytesRead: 1 };
|
|
916
|
+
}
|
|
917
|
+
if ((first & 192) === 128) {
|
|
918
|
+
if (offset + 1 >= data.length) {
|
|
919
|
+
throw new Error("VInt decode: truncated 2-byte encoding");
|
|
920
|
+
}
|
|
921
|
+
const value = 128 + ((first & 63) << 8 | data[offset + 1]);
|
|
922
|
+
return { value, bytesRead: 2 };
|
|
923
|
+
}
|
|
924
|
+
if ((first & 224) === 192) {
|
|
925
|
+
if (offset + 2 >= data.length) {
|
|
926
|
+
throw new Error("VInt decode: truncated 3-byte encoding");
|
|
927
|
+
}
|
|
928
|
+
const value = 16512 + ((first & 31) << 16 | data[offset + 1] << 8 | data[offset + 2]);
|
|
929
|
+
return { value, bytesRead: 3 };
|
|
930
|
+
}
|
|
931
|
+
if ((first & 240) === 224) {
|
|
932
|
+
if (offset + 3 >= data.length) {
|
|
933
|
+
throw new Error("VInt decode: truncated 4-byte encoding");
|
|
934
|
+
}
|
|
935
|
+
const value = 2113664 + ((first & 15) << 24 | data[offset + 1] << 16 | data[offset + 2] << 8 | data[offset + 3]);
|
|
936
|
+
return { value: value >>> 0, bytesRead: 4 };
|
|
937
|
+
}
|
|
938
|
+
if ((first & 248) === 240) {
|
|
939
|
+
if (offset + 4 >= data.length) {
|
|
940
|
+
throw new Error("VInt decode: truncated 5-byte encoding");
|
|
941
|
+
}
|
|
942
|
+
const high = first & 7;
|
|
943
|
+
const low = (data[offset + 1] << 24 | data[offset + 2] << 16 | data[offset + 3] << 8 | data[offset + 4]) >>> 0;
|
|
944
|
+
const value = 270549120 + high * 4294967296 + low;
|
|
945
|
+
return { value: value >>> 0, bytesRead: 5 };
|
|
946
|
+
}
|
|
947
|
+
throw new Error("VInt decode: invalid prefix");
|
|
948
|
+
}
|
|
949
|
+
|
|
950
|
+
// ../core/dist/id-codec/fletcher16.js
|
|
951
|
+
function fletcher16(data) {
|
|
952
|
+
let sum1 = 0;
|
|
953
|
+
let sum2 = 0;
|
|
954
|
+
for (const byte of data) {
|
|
955
|
+
sum1 = (sum1 + byte) % 255;
|
|
956
|
+
sum2 = (sum2 + sum1) % 255;
|
|
957
|
+
}
|
|
958
|
+
return new Uint8Array([sum1, sum2]);
|
|
959
|
+
}
|
|
960
|
+
function verifyFletcher16(data, checksum) {
|
|
961
|
+
if (checksum.length !== 2)
|
|
962
|
+
return false;
|
|
963
|
+
const computed = fletcher16(data);
|
|
964
|
+
return computed[0] === checksum[0] && computed[1] === checksum[1];
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
// ../core/dist/utils/crypto.js
|
|
968
|
+
var weakRandomState;
|
|
969
|
+
var init_crypto = __esm(() => {
|
|
970
|
+
weakRandomState = (Date.now() ^ 2654435769) >>> 0;
|
|
971
|
+
});
|
|
972
|
+
|
|
973
|
+
// ../core/dist/id-codec/document-id.js
|
|
974
|
+
function encodeDocumentId(tableNumber, internalId) {
|
|
975
|
+
if (internalId.length !== INTERNAL_ID_LENGTH) {
|
|
976
|
+
throw new Error(`Internal ID must be exactly ${INTERNAL_ID_LENGTH} bytes, got ${internalId.length}`);
|
|
977
|
+
}
|
|
978
|
+
if (tableNumber < 1 || tableNumber > 4294967295) {
|
|
979
|
+
throw new Error(`Table number must be between 1 and 2^32-1, got ${tableNumber}`);
|
|
980
|
+
}
|
|
981
|
+
const tableBytes = vintEncode(tableNumber);
|
|
982
|
+
const payload = new Uint8Array(tableBytes.length + INTERNAL_ID_LENGTH);
|
|
983
|
+
payload.set(tableBytes, 0);
|
|
984
|
+
payload.set(internalId, tableBytes.length);
|
|
985
|
+
const checksum = fletcher16(payload);
|
|
986
|
+
const final = new Uint8Array(payload.length + 2);
|
|
987
|
+
final.set(payload, 0);
|
|
988
|
+
final.set(checksum, payload.length);
|
|
989
|
+
return base32Encode(final);
|
|
990
|
+
}
|
|
991
|
+
function decodeDocumentId(encoded) {
|
|
992
|
+
if (encoded.length < MIN_ENCODED_LENGTH || encoded.length > MAX_ENCODED_LENGTH) {
|
|
993
|
+
throw new Error(`Invalid document ID length: ${encoded.length} (expected ${MIN_ENCODED_LENGTH}-${MAX_ENCODED_LENGTH})`);
|
|
994
|
+
}
|
|
995
|
+
if (!isValidBase32(encoded)) {
|
|
996
|
+
throw new Error("Invalid document ID: contains invalid base32 characters");
|
|
997
|
+
}
|
|
998
|
+
const bytes = base32Decode(encoded);
|
|
999
|
+
if (bytes.length < 19) {
|
|
1000
|
+
throw new Error(`Invalid document ID: decoded to ${bytes.length} bytes (minimum 19)`);
|
|
1001
|
+
}
|
|
1002
|
+
const checksum = bytes.slice(bytes.length - 2);
|
|
1003
|
+
const payload = bytes.slice(0, bytes.length - 2);
|
|
1004
|
+
if (!verifyFletcher16(payload, checksum)) {
|
|
1005
|
+
throw new Error("Invalid document ID: checksum verification failed");
|
|
1006
|
+
}
|
|
1007
|
+
const { value: tableNumber, bytesRead } = vintDecode(payload, 0);
|
|
1008
|
+
const internalId = payload.slice(bytesRead, bytesRead + INTERNAL_ID_LENGTH);
|
|
1009
|
+
if (internalId.length !== INTERNAL_ID_LENGTH) {
|
|
1010
|
+
throw new Error(`Invalid document ID: internal ID is ${internalId.length} bytes (expected ${INTERNAL_ID_LENGTH})`);
|
|
1011
|
+
}
|
|
1012
|
+
return { tableNumber, internalId };
|
|
1013
|
+
}
|
|
1014
|
+
function isValidDocumentId(encoded) {
|
|
1015
|
+
try {
|
|
1016
|
+
decodeDocumentId(encoded);
|
|
1017
|
+
return true;
|
|
1018
|
+
} catch {
|
|
1019
|
+
return false;
|
|
1020
|
+
}
|
|
1021
|
+
}
|
|
1022
|
+
function internalIdToHex(internalId) {
|
|
1023
|
+
let hex = "";
|
|
1024
|
+
for (let i2 = 0;i2 < internalId.length; i2++) {
|
|
1025
|
+
hex += internalId[i2].toString(16).padStart(2, "0");
|
|
1026
|
+
}
|
|
1027
|
+
return hex;
|
|
1028
|
+
}
|
|
1029
|
+
var INTERNAL_ID_LENGTH = 16, MIN_ENCODED_LENGTH = 31, MAX_ENCODED_LENGTH = 37;
|
|
1030
|
+
var init_document_id = __esm(() => {
|
|
1031
|
+
init_base32();
|
|
1032
|
+
init_crypto();
|
|
1033
|
+
});
|
|
1034
|
+
|
|
805
1035
|
// ../core/dist/utils/utils.js
|
|
806
1036
|
function hexToArrayBuffer(hex) {
|
|
807
1037
|
if (hex === "") {
|
|
@@ -840,9 +1070,15 @@ function deserializeDeveloperId(developerId) {
|
|
|
840
1070
|
return null;
|
|
841
1071
|
}
|
|
842
1072
|
var DOC_ID_SEPARATOR = ":", LEGACY_DOC_ID_SEPARATOR = ";";
|
|
1073
|
+
var init_utils = __esm(() => {
|
|
1074
|
+
init_document_id();
|
|
1075
|
+
});
|
|
843
1076
|
|
|
844
1077
|
// ../core/dist/tables/interface.js
|
|
845
1078
|
function getFullTableName(tableName, componentPath) {
|
|
1079
|
+
if (isSystemTable(tableName)) {
|
|
1080
|
+
return tableName;
|
|
1081
|
+
}
|
|
846
1082
|
if (!componentPath || componentPath === "") {
|
|
847
1083
|
return tableName;
|
|
848
1084
|
}
|
|
@@ -859,23 +1095,28 @@ function parseFullTableName(fullName) {
|
|
|
859
1095
|
};
|
|
860
1096
|
}
|
|
861
1097
|
function isSystemTable(tableName) {
|
|
862
|
-
return
|
|
1098
|
+
return Object.hasOwn(SYSTEM_TABLE_NUMBERS, tableName);
|
|
863
1099
|
}
|
|
864
|
-
var SYSTEM_TABLE_NUMBERS, FIRST_USER_TABLE_NUMBER =
|
|
1100
|
+
var SYSTEM_TABLE_NUMBERS, FIRST_USER_TABLE_NUMBER = 10001;
|
|
865
1101
|
var init_interface = __esm(() => {
|
|
866
1102
|
SYSTEM_TABLE_NUMBERS = {
|
|
867
1103
|
_tables: 1,
|
|
868
1104
|
_scheduled_functions: 2,
|
|
869
1105
|
_storage: 3,
|
|
870
|
-
_crons: 4
|
|
1106
|
+
_crons: 4,
|
|
1107
|
+
_indexes: 5,
|
|
1108
|
+
_schemas: 6,
|
|
1109
|
+
_components: 7,
|
|
1110
|
+
_component_definitions: 8,
|
|
1111
|
+
_schema_validation_progress: 9
|
|
871
1112
|
};
|
|
872
1113
|
});
|
|
873
1114
|
|
|
874
1115
|
// ../core/dist/kernel/context-storage.js
|
|
875
|
-
function
|
|
1116
|
+
function resolveFromModuleResolver(resolveModule) {
|
|
876
1117
|
for (const specifier of ["node:async_hooks", "async_hooks"]) {
|
|
877
1118
|
try {
|
|
878
|
-
const mod =
|
|
1119
|
+
const mod = resolveModule(specifier);
|
|
879
1120
|
if (mod?.AsyncLocalStorage) {
|
|
880
1121
|
return mod.AsyncLocalStorage;
|
|
881
1122
|
}
|
|
@@ -918,16 +1159,16 @@ var resolveAsyncLocalStorage = () => {
|
|
|
918
1159
|
if (globalCtor) {
|
|
919
1160
|
return globalCtor;
|
|
920
1161
|
}
|
|
921
|
-
const
|
|
922
|
-
if (
|
|
923
|
-
const ctor =
|
|
1162
|
+
const getBuiltinModule = globalThis?.process?.getBuiltinModule;
|
|
1163
|
+
if (typeof getBuiltinModule === "function") {
|
|
1164
|
+
const ctor = resolveFromModuleResolver((specifier) => getBuiltinModule(specifier));
|
|
924
1165
|
if (ctor) {
|
|
925
1166
|
return ctor;
|
|
926
1167
|
}
|
|
927
1168
|
}
|
|
928
1169
|
const globalRequire = globalThis?.require;
|
|
929
1170
|
if (typeof globalRequire === "function") {
|
|
930
|
-
return
|
|
1171
|
+
return resolveFromModuleResolver(globalRequire);
|
|
931
1172
|
}
|
|
932
1173
|
return;
|
|
933
1174
|
}, AsyncLocalStorageCtor;
|
|
@@ -2212,7 +2453,7 @@ async function listSystemFunctions(options = {}) {
|
|
|
2212
2453
|
}
|
|
2213
2454
|
for (const route of httpRoutes) {
|
|
2214
2455
|
const method = route.route.method;
|
|
2215
|
-
const routePath = route.route.path;
|
|
2456
|
+
const routePath = mountHttpRoutePath(route.route.path, owningComponent);
|
|
2216
2457
|
results.push({
|
|
2217
2458
|
name: `${method} ${routePath}`,
|
|
2218
2459
|
module: listing.path,
|
|
@@ -2274,6 +2515,16 @@ async function loadAndAnalyzeModule(listing, componentPath) {
|
|
|
2274
2515
|
function makeCacheKey(componentPath, modulePath) {
|
|
2275
2516
|
return `${componentPath ?? ""}::${modulePath}`;
|
|
2276
2517
|
}
|
|
2518
|
+
function mountHttpRoutePath(routePath, componentPath) {
|
|
2519
|
+
if (!componentPath) {
|
|
2520
|
+
return routePath;
|
|
2521
|
+
}
|
|
2522
|
+
const prefix = `/${componentPath}`;
|
|
2523
|
+
if (routePath === "/") {
|
|
2524
|
+
return prefix;
|
|
2525
|
+
}
|
|
2526
|
+
return `${prefix}${routePath}`;
|
|
2527
|
+
}
|
|
2277
2528
|
function buildFallbackSourcePath(modulePath) {
|
|
2278
2529
|
const trimmed = modulePath.replace(/\\/g, "/").replace(/^\//, "");
|
|
2279
2530
|
const withConvex = trimmed.startsWith("convex/") ? trimmed : `convex/${trimmed}`;
|
|
@@ -3960,6 +4211,7 @@ var init_remote = __esm(() => {
|
|
|
3960
4211
|
// ../../node_modules/jose/dist/webapi/index.js
|
|
3961
4212
|
var init_webapi = __esm(() => {
|
|
3962
4213
|
init_verify4();
|
|
4214
|
+
init_local();
|
|
3963
4215
|
init_remote();
|
|
3964
4216
|
init_errors2();
|
|
3965
4217
|
});
|
|
@@ -4164,7 +4416,7 @@ function getRemoteJwks(jwksUrl, config) {
|
|
|
4164
4416
|
if (cached) {
|
|
4165
4417
|
JWKS_CACHE.delete(jwksUrl);
|
|
4166
4418
|
}
|
|
4167
|
-
const jwks = createRemoteJWKSet(new URL(jwksUrl));
|
|
4419
|
+
const jwks = jwksUrl.startsWith("data:") ? createLocalJWKSet(parseDataUriJson(jwksUrl)) : createRemoteJWKSet(new URL(jwksUrl));
|
|
4168
4420
|
const configuredTtl = config?.jwksCacheTtlMs;
|
|
4169
4421
|
const ttlMs = resolveJwksCacheTtlMs(configuredTtl);
|
|
4170
4422
|
JWKS_CACHE.set(jwksUrl, {
|
|
@@ -4173,6 +4425,24 @@ function getRemoteJwks(jwksUrl, config) {
|
|
|
4173
4425
|
});
|
|
4174
4426
|
return jwks;
|
|
4175
4427
|
}
|
|
4428
|
+
function parseDataUriJson(dataUri) {
|
|
4429
|
+
const match = /^data:([^;,]+)?(?:;charset=[^;,]+)?(;base64)?,(.*)$/i.exec(dataUri);
|
|
4430
|
+
if (!match) {
|
|
4431
|
+
throw new JWTValidationError("INVALID_TOKEN", "Invalid JWKS data URI");
|
|
4432
|
+
}
|
|
4433
|
+
const [, , isBase64, payload] = match;
|
|
4434
|
+
const jsonText = isBase64 ? decodeBase642(payload) : decodeURIComponent(payload);
|
|
4435
|
+
return JSON.parse(jsonText);
|
|
4436
|
+
}
|
|
4437
|
+
function decodeBase642(value) {
|
|
4438
|
+
if (typeof Buffer !== "undefined") {
|
|
4439
|
+
return Buffer.from(value, "base64").toString("utf8");
|
|
4440
|
+
}
|
|
4441
|
+
if (typeof atob === "function") {
|
|
4442
|
+
return new TextDecoder().decode(Uint8Array.from(atob(value), (char) => char.charCodeAt(0)));
|
|
4443
|
+
}
|
|
4444
|
+
throw new JWTValidationError("INVALID_TOKEN", "Base64 decoding is unavailable");
|
|
4445
|
+
}
|
|
4176
4446
|
function resolveJwksCacheTtlMs(configuredTtl) {
|
|
4177
4447
|
if (configuredTtl === undefined) {
|
|
4178
4448
|
return DEFAULT_JWKS_CACHE_TTL_MS;
|
|
@@ -4207,6 +4477,7 @@ async function verifyJwt(token, config) {
|
|
|
4207
4477
|
const options = {
|
|
4208
4478
|
issuer: effectiveConfig.issuer,
|
|
4209
4479
|
audience: effectiveConfig.audience,
|
|
4480
|
+
algorithms: effectiveConfig.algorithms,
|
|
4210
4481
|
clockTolerance: effectiveConfig.clockTolerance ?? DEFAULT_CLOCK_TOLERANCE_SECONDS
|
|
4211
4482
|
};
|
|
4212
4483
|
let payload;
|
|
@@ -4764,47 +5035,231 @@ var init_auth = __esm(() => {
|
|
|
4764
5035
|
init_auth_config_service();
|
|
4765
5036
|
});
|
|
4766
5037
|
|
|
4767
|
-
// ../core/dist/
|
|
4768
|
-
|
|
4769
|
-
|
|
4770
|
-
|
|
4771
|
-
|
|
4772
|
-
|
|
4773
|
-
|
|
4774
|
-
|
|
4775
|
-
|
|
4776
|
-
|
|
4777
|
-
|
|
4778
|
-
|
|
5038
|
+
// ../core/dist/components/manifest.js
|
|
5039
|
+
var COMPONENT_MANIFEST_SYMBOL;
|
|
5040
|
+
var init_manifest = __esm(() => {
|
|
5041
|
+
COMPONENT_MANIFEST_SYMBOL = Symbol.for("concave.componentManifest");
|
|
5042
|
+
});
|
|
5043
|
+
|
|
5044
|
+
// ../core/dist/id-codec/index.js
|
|
5045
|
+
var init_id_codec = __esm(() => {
|
|
5046
|
+
init_base32();
|
|
5047
|
+
init_document_id();
|
|
5048
|
+
});
|
|
5049
|
+
|
|
5050
|
+
// ../core/dist/system/system-tables.js
|
|
5051
|
+
function getSystemTableDefinition(name) {
|
|
5052
|
+
return SYSTEM_TABLE_DEFINITIONS.find((definition) => definition.name === name) ?? null;
|
|
5053
|
+
}
|
|
5054
|
+
function isPublicSystemTable(name) {
|
|
5055
|
+
return getSystemTableDefinition(name)?.visibility === "public";
|
|
5056
|
+
}
|
|
5057
|
+
function createTableInfo(name, tableNumber, componentPath = "", options = {}) {
|
|
5058
|
+
const fullName = getFullTableName(name, componentPath);
|
|
5059
|
+
return {
|
|
5060
|
+
tableNumber,
|
|
5061
|
+
name,
|
|
5062
|
+
componentPath: isSystemTableName(name) ? "" : componentPath,
|
|
5063
|
+
fullName,
|
|
5064
|
+
isSystem: options.isSystem ?? isSystemTableName(name),
|
|
5065
|
+
visibility: options.visibility ?? (isPublicSystemTable(name) ? "public" : "private"),
|
|
5066
|
+
state: "active",
|
|
5067
|
+
createdAt: options.createdAt ?? Date.now()
|
|
5068
|
+
};
|
|
5069
|
+
}
|
|
5070
|
+
function getReservedSystemTables() {
|
|
5071
|
+
return SYSTEM_TABLE_DEFINITIONS.map((definition) => createTableInfo(definition.name, SYSTEM_TABLE_NUMBERS[definition.name], "", {
|
|
5072
|
+
isSystem: true,
|
|
5073
|
+
visibility: definition.visibility
|
|
5074
|
+
}));
|
|
5075
|
+
}
|
|
5076
|
+
function tableInfoFromStoredDocument(value) {
|
|
5077
|
+
if (!value) {
|
|
5078
|
+
return null;
|
|
5079
|
+
}
|
|
5080
|
+
const name = typeof value.name === "string" ? value.name : null;
|
|
5081
|
+
const tableNumber = typeof value.tableNumber === "number" ? value.tableNumber : null;
|
|
5082
|
+
if (!name || !tableNumber) {
|
|
5083
|
+
return null;
|
|
5084
|
+
}
|
|
5085
|
+
const componentPath = typeof value.componentPath === "string" ? value.componentPath : "";
|
|
5086
|
+
const fullName = typeof value.fullName === "string" ? value.fullName : getFullTableName(name, componentPath);
|
|
5087
|
+
return {
|
|
5088
|
+
tableNumber,
|
|
5089
|
+
name,
|
|
5090
|
+
componentPath,
|
|
5091
|
+
fullName,
|
|
5092
|
+
isSystem: value.isSystem === true,
|
|
5093
|
+
visibility: value.visibility === "private" ? "private" : "public",
|
|
5094
|
+
state: "active",
|
|
5095
|
+
createdAt: typeof value.createdAt === "number" ? value.createdAt : Date.now()
|
|
5096
|
+
};
|
|
5097
|
+
}
|
|
5098
|
+
function nextUserTableNumber(tables) {
|
|
5099
|
+
let next = FIRST_USER_TABLE_NUMBER;
|
|
5100
|
+
for (const table of tables) {
|
|
5101
|
+
if (table.tableNumber >= next) {
|
|
5102
|
+
next = table.tableNumber + 1;
|
|
5103
|
+
}
|
|
5104
|
+
}
|
|
5105
|
+
return next;
|
|
5106
|
+
}
|
|
5107
|
+
function createSystemMetadata(partial) {
|
|
5108
|
+
const now = partial?.updatedAt ?? Date.now();
|
|
5109
|
+
return {
|
|
5110
|
+
version: 1,
|
|
5111
|
+
bootstrapped: true,
|
|
5112
|
+
tableIdStrategy: "registry_u32",
|
|
5113
|
+
developerIdCodec: "convex_base32",
|
|
5114
|
+
nextUserTableNumber: partial?.nextUserTableNumber ?? FIRST_USER_TABLE_NUMBER,
|
|
5115
|
+
registryVersion: partial?.registryVersion ?? now,
|
|
5116
|
+
runtimeMetadataVersion: partial?.runtimeMetadataVersion,
|
|
5117
|
+
bootstrappedAt: partial?.bootstrappedAt ?? now,
|
|
5118
|
+
updatedAt: now
|
|
5119
|
+
};
|
|
5120
|
+
}
|
|
5121
|
+
async function readSystemMetadata(docstore) {
|
|
5122
|
+
const metadata = await docstore.getGlobal(SYSTEM_METADATA_GLOBAL_KEY);
|
|
5123
|
+
if (!metadata || metadata.bootstrapped !== true || metadata.version !== 1) {
|
|
5124
|
+
return null;
|
|
5125
|
+
}
|
|
5126
|
+
return createSystemMetadata({
|
|
5127
|
+
nextUserTableNumber: metadata.nextUserTableNumber,
|
|
5128
|
+
registryVersion: metadata.registryVersion ?? metadata.updatedAt,
|
|
5129
|
+
runtimeMetadataVersion: metadata.runtimeMetadataVersion,
|
|
5130
|
+
bootstrappedAt: metadata.bootstrappedAt,
|
|
5131
|
+
updatedAt: metadata.updatedAt
|
|
5132
|
+
});
|
|
5133
|
+
}
|
|
5134
|
+
function createTableNumberReservationKey(tableNumber) {
|
|
5135
|
+
return `${TABLE_NUMBER_RESERVATION_GLOBAL_PREFIX}${tableNumber}`;
|
|
5136
|
+
}
|
|
5137
|
+
async function ensureSystemTablesBootstrapped(docstore) {
|
|
5138
|
+
const existingMetadata = await readSystemMetadata(docstore);
|
|
5139
|
+
if (existingMetadata?.version === 1 && existingMetadata.bootstrapped) {
|
|
5140
|
+
return;
|
|
5141
|
+
}
|
|
5142
|
+
const now = Date.now();
|
|
5143
|
+
const tableInfos = getReservedSystemTables();
|
|
5144
|
+
const existingEntries = await docstore.scan(stringToHex("_tables"));
|
|
5145
|
+
const existingByName = new Map;
|
|
5146
|
+
for (const entry of existingEntries) {
|
|
5147
|
+
const info = tableInfoFromStoredDocument(entry.value.value);
|
|
5148
|
+
if (info) {
|
|
5149
|
+
existingByName.set(info.fullName, info);
|
|
5150
|
+
}
|
|
5151
|
+
}
|
|
5152
|
+
const docs = [];
|
|
5153
|
+
const oracle = docstore.timestampOracle;
|
|
5154
|
+
const allocateTimestamp = oracle?.allocateTimestamp?.bind(oracle) ?? (() => BigInt(Date.now()));
|
|
5155
|
+
for (const table of tableInfos) {
|
|
5156
|
+
const existing = existingByName.get(table.fullName);
|
|
5157
|
+
const createdAt = existing?.createdAt ?? now;
|
|
5158
|
+
docs.push(createTableMetadataEntry(table, allocateTimestamp(), createdAt));
|
|
5159
|
+
}
|
|
5160
|
+
if (docs.length > 0) {
|
|
5161
|
+
await docstore.write(docs, new Set, "Overwrite");
|
|
5162
|
+
}
|
|
5163
|
+
const metadata = createSystemMetadata({
|
|
5164
|
+
nextUserTableNumber: nextUserTableNumber([...tableInfos, ...existingByName.values()]),
|
|
5165
|
+
registryVersion: now,
|
|
5166
|
+
bootstrappedAt: existingMetadata?.bootstrappedAt ?? now,
|
|
5167
|
+
updatedAt: now
|
|
5168
|
+
});
|
|
5169
|
+
await docstore.writeGlobal(SYSTEM_METADATA_GLOBAL_KEY, metadata);
|
|
5170
|
+
}
|
|
5171
|
+
function createTableMetadataEntryForUserTable(table, timestamp2) {
|
|
5172
|
+
return createTableMetadataEntry(table, timestamp2, table.createdAt);
|
|
5173
|
+
}
|
|
5174
|
+
function createTableMetadataEntry(table, timestamp2, createdAt) {
|
|
5175
|
+
const docId = createTableMetadataDocumentId(table.fullName);
|
|
5176
|
+
const developerId = encodeDocumentId(SYSTEM_TABLE_NUMBERS._tables, stableMetadataInternalIdBytes(table.fullName));
|
|
5177
|
+
const storedTable = {
|
|
5178
|
+
_id: developerId,
|
|
5179
|
+
_creationTime: Number(timestamp2),
|
|
5180
|
+
name: table.name,
|
|
5181
|
+
componentPath: table.componentPath,
|
|
5182
|
+
fullName: table.fullName,
|
|
5183
|
+
tableNumber: table.tableNumber,
|
|
5184
|
+
isSystem: table.isSystem,
|
|
5185
|
+
visibility: table.visibility,
|
|
5186
|
+
state: table.state,
|
|
5187
|
+
createdAt
|
|
5188
|
+
};
|
|
5189
|
+
return {
|
|
5190
|
+
ts: timestamp2,
|
|
5191
|
+
id: docId,
|
|
5192
|
+
value: {
|
|
5193
|
+
id: docId,
|
|
5194
|
+
value: storedTable
|
|
5195
|
+
},
|
|
5196
|
+
prev_ts: null
|
|
5197
|
+
};
|
|
5198
|
+
}
|
|
5199
|
+
function createTableMetadataDocumentId(fullTableName) {
|
|
5200
|
+
const internalIdBytes = stableMetadataInternalIdBytes(fullTableName);
|
|
5201
|
+
return {
|
|
5202
|
+
table: stringToHex("_tables"),
|
|
5203
|
+
internalId: internalIdToHex(internalIdBytes),
|
|
5204
|
+
tableNumber: SYSTEM_TABLE_NUMBERS._tables
|
|
5205
|
+
};
|
|
5206
|
+
}
|
|
5207
|
+
function stableMetadataInternalIdBytes(fullTableName) {
|
|
5208
|
+
const bytes = new Uint8Array(16);
|
|
5209
|
+
const input = new TextEncoder().encode(`table:${fullTableName}`);
|
|
5210
|
+
for (let i2 = 0;i2 < input.length; i2 += 1) {
|
|
5211
|
+
const target = i2 % 16;
|
|
5212
|
+
bytes[target] = bytes[target] * 33 + input[i2] & 255;
|
|
5213
|
+
}
|
|
5214
|
+
return bytes;
|
|
5215
|
+
}
|
|
5216
|
+
function isSystemTableName(name) {
|
|
5217
|
+
return Object.hasOwn(SYSTEM_TABLE_NUMBERS, name);
|
|
5218
|
+
}
|
|
5219
|
+
var SYSTEM_METADATA_GLOBAL_KEY = "concave:system_metadata:v1", TABLE_NUMBER_RESERVATION_GLOBAL_PREFIX = "concave:table_number:", SYSTEM_TABLE_DEFINITIONS;
|
|
5220
|
+
var init_system_tables = __esm(() => {
|
|
5221
|
+
init_manifest();
|
|
5222
|
+
init_id_codec();
|
|
5223
|
+
init_interface();
|
|
5224
|
+
init_utils();
|
|
5225
|
+
init_module_loader();
|
|
5226
|
+
SYSTEM_TABLE_DEFINITIONS = [
|
|
5227
|
+
{ name: "_tables", visibility: "public" },
|
|
5228
|
+
{ name: "_scheduled_functions", visibility: "public" },
|
|
5229
|
+
{ name: "_storage", visibility: "public" },
|
|
5230
|
+
{ name: "_crons", visibility: "public" },
|
|
5231
|
+
{ name: "_indexes", visibility: "private" },
|
|
5232
|
+
{ name: "_schemas", visibility: "private" },
|
|
5233
|
+
{ name: "_components", visibility: "private" },
|
|
5234
|
+
{ name: "_component_definitions", visibility: "private" },
|
|
5235
|
+
{ name: "_schema_validation_progress", visibility: "private" }
|
|
5236
|
+
];
|
|
5237
|
+
});
|
|
5238
|
+
|
|
5239
|
+
// ../core/dist/system/internal.js
|
|
5240
|
+
function requireSystemCapability(capability) {
|
|
5241
|
+
const principal2 = getPrincipal();
|
|
5242
|
+
if (!principal2) {
|
|
5243
|
+
throw new Error("System functions require authentication context");
|
|
5244
|
+
}
|
|
5245
|
+
requireAuthorization(principal2, { kind: "management_operation", capability });
|
|
5246
|
+
}
|
|
5247
|
+
function createSystemFunctions(deps) {
|
|
5248
|
+
const { query, mutation } = deps;
|
|
5249
|
+
return {
|
|
5250
|
+
systemListComponents: query({
|
|
4779
5251
|
args: {},
|
|
4780
|
-
handler: async (
|
|
5252
|
+
handler: async (ctx) => {
|
|
4781
5253
|
requireSystemCapability("components:read");
|
|
4782
|
-
const
|
|
4783
|
-
const
|
|
4784
|
-
|
|
4785
|
-
|
|
4786
|
-
|
|
4787
|
-
componentPaths.add(module.componentPath);
|
|
4788
|
-
}
|
|
4789
|
-
}
|
|
4790
|
-
const components = [];
|
|
4791
|
-
for (const path of componentPaths) {
|
|
4792
|
-
const componentModules = modules.filter((m) => path === "" ? !m.componentPath || m.componentPath === "" : m.componentPath === path);
|
|
4793
|
-
const functions = await listSystemFunctions({ componentPath: path || undefined });
|
|
4794
|
-
components.push({
|
|
4795
|
-
path: path || "(root)",
|
|
4796
|
-
isRoot: path === "",
|
|
4797
|
-
moduleCount: componentModules.length,
|
|
5254
|
+
const components = await loadComponentRows(ctx);
|
|
5255
|
+
const withFunctionCounts = await Promise.all(components.map(async (component) => {
|
|
5256
|
+
const functions = await listSystemFunctions({ componentPath: component.componentPath || undefined });
|
|
5257
|
+
return {
|
|
5258
|
+
...component,
|
|
4798
5259
|
functionCount: functions.length
|
|
4799
|
-
}
|
|
4800
|
-
}
|
|
4801
|
-
return
|
|
4802
|
-
if (a.isRoot)
|
|
4803
|
-
return -1;
|
|
4804
|
-
if (b.isRoot)
|
|
4805
|
-
return 1;
|
|
4806
|
-
return a.path.localeCompare(b.path);
|
|
4807
|
-
});
|
|
5260
|
+
};
|
|
5261
|
+
}));
|
|
5262
|
+
return sortComponentRows(withFunctionCounts);
|
|
4808
5263
|
}
|
|
4809
5264
|
}),
|
|
4810
5265
|
systemListTables: query({
|
|
@@ -4813,25 +5268,40 @@ function createSystemFunctions(deps) {
|
|
|
4813
5268
|
requireSystemCapability("tables:read");
|
|
4814
5269
|
const targetComponent = componentPath ?? "";
|
|
4815
5270
|
const schema2 = await loadSchemaDefinition(targetComponent);
|
|
4816
|
-
|
|
5271
|
+
const schemaTables = new Map;
|
|
4817
5272
|
if (schema2?.tables) {
|
|
4818
|
-
|
|
4819
|
-
|
|
4820
|
-
try {
|
|
4821
|
-
const systemTables = await ctx.db.system.query("_tables").collect();
|
|
4822
|
-
tableEntries = systemTables.map((table) => ({
|
|
4823
|
-
name: table.name,
|
|
4824
|
-
exported: {
|
|
4825
|
-
indexes: table.indexes || [],
|
|
4826
|
-
searchIndexes: table.searchIndexes || [],
|
|
4827
|
-
vectorIndexes: table.vectorIndexes || [],
|
|
4828
|
-
documentType: null
|
|
4829
|
-
}
|
|
4830
|
-
}));
|
|
4831
|
-
} catch {
|
|
4832
|
-
tableEntries = [];
|
|
5273
|
+
for (const table of extractTablesFromSchema(schema2)) {
|
|
5274
|
+
schemaTables.set(table.name, table);
|
|
4833
5275
|
}
|
|
4834
5276
|
}
|
|
5277
|
+
const discoveredTables = new Map;
|
|
5278
|
+
for (const name of schemaTables.keys()) {
|
|
5279
|
+
discoveredTables.set(name, {
|
|
5280
|
+
name,
|
|
5281
|
+
isSystem: isSystemTable(name),
|
|
5282
|
+
visibility: getDefaultSystemTableVisibility(name)
|
|
5283
|
+
});
|
|
5284
|
+
}
|
|
5285
|
+
try {
|
|
5286
|
+
const systemTables = await ctx.db.system.query("_tables").collect();
|
|
5287
|
+
discoveredTables.clear();
|
|
5288
|
+
for (const table of systemTables.filter((entry) => (entry.componentPath ?? "") === targetComponent)) {
|
|
5289
|
+
discoveredTables.set(table.name, {
|
|
5290
|
+
name: table.name,
|
|
5291
|
+
isSystem: table.isSystem === true || isSystemTable(table.name),
|
|
5292
|
+
visibility: table.visibility === "private" ? "private" : "public"
|
|
5293
|
+
});
|
|
5294
|
+
}
|
|
5295
|
+
} catch {}
|
|
5296
|
+
const tableEntries = Array.from(discoveredTables.values()).map((metadata) => ({
|
|
5297
|
+
...metadata,
|
|
5298
|
+
exported: schemaTables.get(metadata.name)?.exported ?? {
|
|
5299
|
+
indexes: [],
|
|
5300
|
+
searchIndexes: [],
|
|
5301
|
+
vectorIndexes: [],
|
|
5302
|
+
documentType: null
|
|
5303
|
+
}
|
|
5304
|
+
}));
|
|
4835
5305
|
const tableInfo = await Promise.all(tableEntries.map(async (table) => {
|
|
4836
5306
|
const fullName = getFullTableName(table.name, targetComponent);
|
|
4837
5307
|
const documentCount = await countDocuments(ctx, fullName);
|
|
@@ -4842,6 +5312,8 @@ function createSystemFunctions(deps) {
|
|
|
4842
5312
|
name: table.name,
|
|
4843
5313
|
fullName,
|
|
4844
5314
|
componentPath: targetComponent || undefined,
|
|
5315
|
+
isSystem: table.isSystem,
|
|
5316
|
+
visibility: table.visibility,
|
|
4845
5317
|
documentCount,
|
|
4846
5318
|
indexes: buildIndexList(exported?.indexes),
|
|
4847
5319
|
searchIndexes: searchIndexes.map((idx) => typeof idx === "string" ? idx : idx.indexDescriptor),
|
|
@@ -4875,7 +5347,7 @@ function createSystemFunctions(deps) {
|
|
|
4875
5347
|
}
|
|
4876
5348
|
try {
|
|
4877
5349
|
const fullName = getFullTableName(tableName, targetComponent);
|
|
4878
|
-
const sampleDoc = await ctx
|
|
5350
|
+
const sampleDoc = await getTableQuery(ctx, fullName).first();
|
|
4879
5351
|
const fields = sampleDoc ? Object.keys(sampleDoc).map((key) => ({
|
|
4880
5352
|
name: key,
|
|
4881
5353
|
type: typeof sampleDoc[key],
|
|
@@ -4910,7 +5382,7 @@ function createSystemFunctions(deps) {
|
|
|
4910
5382
|
handler: async (ctx, args) => {
|
|
4911
5383
|
requireSystemCapability("documents:read");
|
|
4912
5384
|
const fullName = getFullTableName(args.tableName, args.componentPath ?? "");
|
|
4913
|
-
let query2 = ctx
|
|
5385
|
+
let query2 = getTableQuery(ctx, fullName);
|
|
4914
5386
|
if (args.orderBy && args.orderBy !== "_creationTime") {
|
|
4915
5387
|
const allDocs2 = await query2.collect();
|
|
4916
5388
|
const sorted = allDocs2.sort((a, b) => {
|
|
@@ -4961,7 +5433,7 @@ function createSystemFunctions(deps) {
|
|
|
4961
5433
|
handler: async (ctx, args) => {
|
|
4962
5434
|
requireSystemCapability("documents:write");
|
|
4963
5435
|
const fullName = getFullTableName(args.tableName, args.componentPath ?? "");
|
|
4964
|
-
const docs = await ctx
|
|
5436
|
+
const docs = await getTableQuery(ctx, fullName).collect();
|
|
4965
5437
|
for (const doc of docs) {
|
|
4966
5438
|
await ctx.db.delete(doc._id);
|
|
4967
5439
|
}
|
|
@@ -5257,6 +5729,83 @@ function resolveFunctionReference(functionPath, componentPath) {
|
|
|
5257
5729
|
}
|
|
5258
5730
|
return functionPath;
|
|
5259
5731
|
}
|
|
5732
|
+
async function loadComponentRows(ctx) {
|
|
5733
|
+
try {
|
|
5734
|
+
const rows = await ctx.db.system.query("_components").collect();
|
|
5735
|
+
if (rows.length > 0) {
|
|
5736
|
+
return rows.map((row) => normalizeStoredComponentRow(row));
|
|
5737
|
+
}
|
|
5738
|
+
} catch {}
|
|
5739
|
+
const modules = await listRegisteredModules();
|
|
5740
|
+
const moduleCountByComponent = new Map;
|
|
5741
|
+
const hasHttpByComponent = new Map;
|
|
5742
|
+
const componentPaths = new Set([""]);
|
|
5743
|
+
for (const module of modules) {
|
|
5744
|
+
const componentPath = module.componentPath ?? "";
|
|
5745
|
+
componentPaths.add(componentPath);
|
|
5746
|
+
moduleCountByComponent.set(componentPath, (moduleCountByComponent.get(componentPath) ?? 0) + 1);
|
|
5747
|
+
if (module.path === "http") {
|
|
5748
|
+
hasHttpByComponent.set(componentPath, true);
|
|
5749
|
+
}
|
|
5750
|
+
}
|
|
5751
|
+
return Array.from(componentPaths).map((componentPath) => ({
|
|
5752
|
+
componentPath,
|
|
5753
|
+
path: componentPath || "(root)",
|
|
5754
|
+
isRoot: componentPath === "",
|
|
5755
|
+
parentPath: componentPath === "" ? null : componentPath.includes("/") ? componentPath.split("/").slice(0, -1).join("/") : "",
|
|
5756
|
+
depth: componentPath === "" ? 0 : componentPath.split("/").length,
|
|
5757
|
+
moduleCount: moduleCountByComponent.get(componentPath) ?? 0,
|
|
5758
|
+
childCount: 0,
|
|
5759
|
+
functionCount: 0,
|
|
5760
|
+
sourceType: "local",
|
|
5761
|
+
hasHttp: hasHttpByComponent.get(componentPath) === true
|
|
5762
|
+
}));
|
|
5763
|
+
}
|
|
5764
|
+
function normalizeStoredComponentRow(row) {
|
|
5765
|
+
const componentPath = typeof row.componentPath === "string" ? row.componentPath : "";
|
|
5766
|
+
return {
|
|
5767
|
+
componentPath,
|
|
5768
|
+
path: typeof row.displayPath === "string" ? row.displayPath : typeof row.path === "string" && row.path.length > 0 ? row.path : componentPath || "(root)",
|
|
5769
|
+
isRoot: row.isRoot === true || componentPath === "",
|
|
5770
|
+
parentPath: row.parentPath === null ? null : typeof row.parentPath === "string" ? row.parentPath : componentPath === "" ? null : "",
|
|
5771
|
+
depth: typeof row.depth === "number" ? row.depth : componentPath === "" ? 0 : componentPath.split("/").length,
|
|
5772
|
+
moduleCount: typeof row.moduleCount === "number" ? row.moduleCount : 0,
|
|
5773
|
+
childCount: typeof row.childCount === "number" ? row.childCount : 0,
|
|
5774
|
+
functionCount: 0,
|
|
5775
|
+
sourceType: row.sourceType === "npm" ? "npm" : row.sourceType === "local" ? "local" : undefined,
|
|
5776
|
+
sourcePath: typeof row.sourcePath === "string" ? row.sourcePath : undefined,
|
|
5777
|
+
packageName: typeof row.packageName === "string" ? row.packageName : undefined,
|
|
5778
|
+
packageVersion: typeof row.packageVersion === "string" ? row.packageVersion : undefined,
|
|
5779
|
+
hasHttp: row.hasHttp === true
|
|
5780
|
+
};
|
|
5781
|
+
}
|
|
5782
|
+
function sortComponentRows(rows) {
|
|
5783
|
+
const childrenByParent = new Map;
|
|
5784
|
+
for (const row of rows) {
|
|
5785
|
+
const parentKey = row.parentPath ?? null;
|
|
5786
|
+
const siblings = childrenByParent.get(parentKey) ?? [];
|
|
5787
|
+
siblings.push(row);
|
|
5788
|
+
childrenByParent.set(parentKey, siblings);
|
|
5789
|
+
}
|
|
5790
|
+
for (const siblings of childrenByParent.values()) {
|
|
5791
|
+
siblings.sort((a, b) => {
|
|
5792
|
+
if (a.isRoot)
|
|
5793
|
+
return -1;
|
|
5794
|
+
if (b.isRoot)
|
|
5795
|
+
return 1;
|
|
5796
|
+
return a.componentPath.localeCompare(b.componentPath);
|
|
5797
|
+
});
|
|
5798
|
+
}
|
|
5799
|
+
const ordered = [];
|
|
5800
|
+
const visit = (parentPath) => {
|
|
5801
|
+
for (const row of childrenByParent.get(parentPath) ?? []) {
|
|
5802
|
+
ordered.push(row);
|
|
5803
|
+
visit(row.componentPath);
|
|
5804
|
+
}
|
|
5805
|
+
};
|
|
5806
|
+
visit(null);
|
|
5807
|
+
return ordered;
|
|
5808
|
+
}
|
|
5260
5809
|
async function loadSchemaDefinition(componentPath) {
|
|
5261
5810
|
try {
|
|
5262
5811
|
const module = await loadConvexModule("schema", {
|
|
@@ -5290,13 +5839,26 @@ function extractTableMetadata(schema2, tableName) {
|
|
|
5290
5839
|
}
|
|
5291
5840
|
async function countDocuments(ctx, tableName) {
|
|
5292
5841
|
try {
|
|
5293
|
-
const documents = await ctx
|
|
5842
|
+
const documents = await getTableQuery(ctx, tableName).collect();
|
|
5294
5843
|
return documents.length;
|
|
5295
5844
|
} catch (error) {
|
|
5296
5845
|
console.warn(`Failed to count documents for table ${tableName}:`, error);
|
|
5297
5846
|
return 0;
|
|
5298
5847
|
}
|
|
5299
5848
|
}
|
|
5849
|
+
function getTableQuery(ctx, fullTableName) {
|
|
5850
|
+
const { tableName } = parseFullTableName(fullTableName);
|
|
5851
|
+
if (isSystemTable(tableName)) {
|
|
5852
|
+
return ctx.db.system.query(tableName);
|
|
5853
|
+
}
|
|
5854
|
+
return ctx.db.query(fullTableName);
|
|
5855
|
+
}
|
|
5856
|
+
function getDefaultSystemTableVisibility(tableName) {
|
|
5857
|
+
if (!isSystemTable(tableName)) {
|
|
5858
|
+
return "public";
|
|
5859
|
+
}
|
|
5860
|
+
return isPublicSystemTable(tableName) ? "public" : "private";
|
|
5861
|
+
}
|
|
5300
5862
|
function buildIndexList(indexes) {
|
|
5301
5863
|
const base = ["by_id", "by_creation_time"];
|
|
5302
5864
|
if (!indexes || indexes.length === 0) {
|
|
@@ -5398,6 +5960,7 @@ var init_internal = __esm(() => {
|
|
|
5398
5960
|
init_interface();
|
|
5399
5961
|
init_execution_log();
|
|
5400
5962
|
init_auth();
|
|
5963
|
+
init_system_tables();
|
|
5401
5964
|
});
|
|
5402
5965
|
|
|
5403
5966
|
// ../core/dist/system/system-functions-module.js
|
|
@@ -5555,8 +6118,9 @@ class ModuleRegistry {
|
|
|
5555
6118
|
const normalized = normalizeModuleListing(listing);
|
|
5556
6119
|
if (!normalized)
|
|
5557
6120
|
continue;
|
|
5558
|
-
|
|
5559
|
-
|
|
6121
|
+
const resultKey = `${normalized.componentPath ?? scope ?? ""}:${normalized.path}`;
|
|
6122
|
+
if (!results.has(resultKey)) {
|
|
6123
|
+
results.set(resultKey, {
|
|
5560
6124
|
...normalized,
|
|
5561
6125
|
scope: scope || undefined,
|
|
5562
6126
|
componentPath: normalized.componentPath ?? (scope || undefined)
|
|
@@ -5875,8 +6439,10 @@ var init_module_loader = __esm(() => {
|
|
|
5875
6439
|
class SchemaValidator {
|
|
5876
6440
|
schemaCache = new Map;
|
|
5877
6441
|
componentPath;
|
|
5878
|
-
|
|
6442
|
+
tableRegistry;
|
|
6443
|
+
constructor(componentPath, tableRegistry) {
|
|
5879
6444
|
this.componentPath = componentPath;
|
|
6445
|
+
this.tableRegistry = tableRegistry;
|
|
5880
6446
|
}
|
|
5881
6447
|
async loadTableSchema(tableName) {
|
|
5882
6448
|
if (this.schemaCache.has(tableName)) {
|
|
@@ -5919,8 +6485,11 @@ class SchemaValidator {
|
|
|
5919
6485
|
return;
|
|
5920
6486
|
}
|
|
5921
6487
|
try {
|
|
6488
|
+
const tableNumberToName = this.tableRegistry ? new Map((await this.tableRegistry.listTables()).map((table) => [table.tableNumber, table.fullName])) : undefined;
|
|
5922
6489
|
validateValidator(tableSchema, omit(document, ["_id", "_creationTime"]), "", {
|
|
5923
|
-
componentPath: this.componentPath ?? ""
|
|
6490
|
+
componentPath: this.componentPath ?? "",
|
|
6491
|
+
tableRegistry: this.tableRegistry,
|
|
6492
|
+
tableNumberToName
|
|
5924
6493
|
});
|
|
5925
6494
|
} catch (error) {
|
|
5926
6495
|
throw new ValidatorError(`Failed to insert or update a document in table "${tableName}" because it does not match the schema: ${error.message}`);
|
|
@@ -6018,6 +6587,16 @@ Path: ${formatPath(path)}
|
|
|
6018
6587
|
Value: ${formatValue(value)}
|
|
6019
6588
|
Validator: v.id("${validator2.tableName}")`);
|
|
6020
6589
|
}
|
|
6590
|
+
if (isValidDocumentId(value)) {
|
|
6591
|
+
const tableName2 = tableNameFromConvexId(value, options);
|
|
6592
|
+
if (!tableName2 || !isMatchingValidatorTable(tableName2, validator2.tableName, options.componentPath)) {
|
|
6593
|
+
throw new Error(`Value does not match validator.
|
|
6594
|
+
Path: ${formatPath(path)}
|
|
6595
|
+
Value: ${formatValue(value)}
|
|
6596
|
+
Validator: v.id("${validator2.tableName}")`);
|
|
6597
|
+
}
|
|
6598
|
+
return;
|
|
6599
|
+
}
|
|
6021
6600
|
const tableName = tableNameFromId(value);
|
|
6022
6601
|
if (!tableName || !isMatchingValidatorTable(tableName, validator2.tableName, options.componentPath)) {
|
|
6023
6602
|
throw new Error(`Value does not match validator.
|
|
@@ -6079,289 +6658,72 @@ Validator: v.object({...})`);
|
|
|
6079
6658
|
}
|
|
6080
6659
|
} else {
|
|
6081
6660
|
const fieldPath = path ? `${path}.${k}` : `.${k}`;
|
|
6082
|
-
validateValidator(fieldType, value[k], fieldPath, options);
|
|
6083
|
-
}
|
|
6084
|
-
}
|
|
6085
|
-
for (const k of Object.keys(value)) {
|
|
6086
|
-
if (validator2.value[k] === undefined) {
|
|
6087
|
-
throw new Error(`Object contains extra field \`${k}\` that is not in the validator.
|
|
6088
|
-
|
|
6089
|
-
Object: ${JSON.stringify(value)}
|
|
6090
|
-
Validator: v.object({...})`);
|
|
6091
|
-
}
|
|
6092
|
-
}
|
|
6093
|
-
return;
|
|
6094
|
-
}
|
|
6095
|
-
}
|
|
6096
|
-
}
|
|
6097
|
-
function tableNameFromId(id) {
|
|
6098
|
-
const parts = deserializeDeveloperId(id);
|
|
6099
|
-
if (!parts) {
|
|
6100
|
-
return null;
|
|
6101
|
-
}
|
|
6102
|
-
return hexToString(parts.table);
|
|
6103
|
-
}
|
|
6104
|
-
function isMatchingValidatorTable(idTableName, validatorTableName, componentPath) {
|
|
6105
|
-
if (idTableName === validatorTableName) {
|
|
6106
|
-
return true;
|
|
6107
|
-
}
|
|
6108
|
-
const { tableName: validatorBareName } = parseFullTableName(validatorTableName);
|
|
6109
|
-
const { tableName: idBareName } = parseFullTableName(idTableName);
|
|
6110
|
-
if (componentPath !== undefined) {
|
|
6111
|
-
const expectedFullName = getFullTableName(validatorBareName, componentPath);
|
|
6112
|
-
return idTableName === expectedFullName;
|
|
6113
|
-
}
|
|
6114
|
-
return idBareName === validatorBareName;
|
|
6115
|
-
}
|
|
6116
|
-
function isSimpleObject2(value) {
|
|
6117
|
-
const isObject2 = typeof value === "object";
|
|
6118
|
-
const prototype = Object.getPrototypeOf(value);
|
|
6119
|
-
const isSimple = prototype === null || prototype === Object.prototype || prototype?.constructor?.name === "Object";
|
|
6120
|
-
return isObject2 && isSimple;
|
|
6121
|
-
}
|
|
6122
|
-
var ValidatorError;
|
|
6123
|
-
var init_validator2 = __esm(() => {
|
|
6124
|
-
init_interface();
|
|
6125
|
-
init_module_loader();
|
|
6126
|
-
ValidatorError = class ValidatorError extends Error {
|
|
6127
|
-
path;
|
|
6128
|
-
constructor(message2, path = "") {
|
|
6129
|
-
super(message2);
|
|
6130
|
-
this.path = path;
|
|
6131
|
-
this.name = "ValidatorError";
|
|
6132
|
-
}
|
|
6133
|
-
};
|
|
6134
|
-
});
|
|
6135
|
-
|
|
6136
|
-
// ../core/dist/id-codec/base32.js
|
|
6137
|
-
function base32Encode(data) {
|
|
6138
|
-
if (data.length === 0)
|
|
6139
|
-
return "";
|
|
6140
|
-
let result = "";
|
|
6141
|
-
let buffer = 0;
|
|
6142
|
-
let bitsLeft = 0;
|
|
6143
|
-
for (const byte of data) {
|
|
6144
|
-
buffer = buffer << 8 | byte;
|
|
6145
|
-
bitsLeft += 8;
|
|
6146
|
-
while (bitsLeft >= 5) {
|
|
6147
|
-
bitsLeft -= 5;
|
|
6148
|
-
const index = buffer >> bitsLeft & 31;
|
|
6149
|
-
result += ALPHABET[index];
|
|
6150
|
-
}
|
|
6151
|
-
}
|
|
6152
|
-
if (bitsLeft > 0) {
|
|
6153
|
-
const index = buffer << 5 - bitsLeft & 31;
|
|
6154
|
-
result += ALPHABET[index];
|
|
6155
|
-
}
|
|
6156
|
-
return result;
|
|
6157
|
-
}
|
|
6158
|
-
function base32Decode(str) {
|
|
6159
|
-
if (str.length === 0)
|
|
6160
|
-
return new Uint8Array(0);
|
|
6161
|
-
const outputLength = Math.floor(str.length * 5 / 8);
|
|
6162
|
-
const result = new Uint8Array(outputLength);
|
|
6163
|
-
let buffer = 0;
|
|
6164
|
-
let bitsLeft = 0;
|
|
6165
|
-
let outputIndex = 0;
|
|
6166
|
-
for (const char of str) {
|
|
6167
|
-
const value = ALPHABET_MAP.get(char);
|
|
6168
|
-
if (value === undefined) {
|
|
6169
|
-
throw new Error(`Invalid base32 character: ${char}`);
|
|
6170
|
-
}
|
|
6171
|
-
buffer = buffer << 5 | value;
|
|
6172
|
-
bitsLeft += 5;
|
|
6173
|
-
if (bitsLeft >= 8) {
|
|
6174
|
-
bitsLeft -= 8;
|
|
6175
|
-
result[outputIndex++] = buffer >> bitsLeft & 255;
|
|
6176
|
-
}
|
|
6177
|
-
}
|
|
6178
|
-
return result;
|
|
6179
|
-
}
|
|
6180
|
-
function isValidBase32(str) {
|
|
6181
|
-
for (const char of str) {
|
|
6182
|
-
if (!ALPHABET_MAP.has(char)) {
|
|
6183
|
-
return false;
|
|
6184
|
-
}
|
|
6185
|
-
}
|
|
6186
|
-
return true;
|
|
6187
|
-
}
|
|
6188
|
-
var ALPHABET = "0123456789abcdefghjkmnpqrstvwxyz", ALPHABET_MAP;
|
|
6189
|
-
var init_base32 = __esm(() => {
|
|
6190
|
-
ALPHABET_MAP = new Map;
|
|
6191
|
-
for (let i2 = 0;i2 < ALPHABET.length; i2++) {
|
|
6192
|
-
ALPHABET_MAP.set(ALPHABET[i2], i2);
|
|
6193
|
-
ALPHABET_MAP.set(ALPHABET[i2].toUpperCase(), i2);
|
|
6194
|
-
}
|
|
6195
|
-
ALPHABET_MAP.set("i", 1);
|
|
6196
|
-
ALPHABET_MAP.set("I", 1);
|
|
6197
|
-
ALPHABET_MAP.set("l", 1);
|
|
6198
|
-
ALPHABET_MAP.set("L", 1);
|
|
6199
|
-
ALPHABET_MAP.set("o", 0);
|
|
6200
|
-
ALPHABET_MAP.set("O", 0);
|
|
6201
|
-
});
|
|
6202
|
-
|
|
6203
|
-
// ../core/dist/id-codec/vint.js
|
|
6204
|
-
function vintEncode(value) {
|
|
6205
|
-
if (value < 0) {
|
|
6206
|
-
throw new Error("VInt cannot encode negative numbers");
|
|
6207
|
-
}
|
|
6208
|
-
if (value > 4294967295) {
|
|
6209
|
-
throw new Error("VInt cannot encode values larger than 2^32-1");
|
|
6210
|
-
}
|
|
6211
|
-
value = value >>> 0;
|
|
6212
|
-
if (value < 128) {
|
|
6213
|
-
return new Uint8Array([value]);
|
|
6214
|
-
}
|
|
6215
|
-
if (value < 16512) {
|
|
6216
|
-
const adjusted2 = value - 128;
|
|
6217
|
-
return new Uint8Array([128 | adjusted2 >> 8 & 63, adjusted2 & 255]);
|
|
6218
|
-
}
|
|
6219
|
-
if (value < 2113664) {
|
|
6220
|
-
const adjusted2 = value - 16512;
|
|
6221
|
-
return new Uint8Array([192 | adjusted2 >> 16 & 31, adjusted2 >> 8 & 255, adjusted2 & 255]);
|
|
6222
|
-
}
|
|
6223
|
-
if (value < 270549120) {
|
|
6224
|
-
const adjusted2 = value - 2113664;
|
|
6225
|
-
return new Uint8Array([
|
|
6226
|
-
224 | adjusted2 >> 24 & 15,
|
|
6227
|
-
adjusted2 >> 16 & 255,
|
|
6228
|
-
adjusted2 >> 8 & 255,
|
|
6229
|
-
adjusted2 & 255
|
|
6230
|
-
]);
|
|
6231
|
-
}
|
|
6232
|
-
const adjusted = value - 270549120;
|
|
6233
|
-
return new Uint8Array([
|
|
6234
|
-
240 | adjusted >> 32 & 7,
|
|
6235
|
-
adjusted >> 24 & 255,
|
|
6236
|
-
adjusted >> 16 & 255,
|
|
6237
|
-
adjusted >> 8 & 255,
|
|
6238
|
-
adjusted & 255
|
|
6239
|
-
]);
|
|
6240
|
-
}
|
|
6241
|
-
function vintDecode(data, offset = 0) {
|
|
6242
|
-
if (offset >= data.length) {
|
|
6243
|
-
throw new Error("VInt decode: unexpected end of data");
|
|
6244
|
-
}
|
|
6245
|
-
const first = data[offset];
|
|
6246
|
-
if ((first & 128) === 0) {
|
|
6247
|
-
return { value: first, bytesRead: 1 };
|
|
6248
|
-
}
|
|
6249
|
-
if ((first & 192) === 128) {
|
|
6250
|
-
if (offset + 1 >= data.length) {
|
|
6251
|
-
throw new Error("VInt decode: truncated 2-byte encoding");
|
|
6252
|
-
}
|
|
6253
|
-
const value = 128 + ((first & 63) << 8 | data[offset + 1]);
|
|
6254
|
-
return { value, bytesRead: 2 };
|
|
6255
|
-
}
|
|
6256
|
-
if ((first & 224) === 192) {
|
|
6257
|
-
if (offset + 2 >= data.length) {
|
|
6258
|
-
throw new Error("VInt decode: truncated 3-byte encoding");
|
|
6259
|
-
}
|
|
6260
|
-
const value = 16512 + ((first & 31) << 16 | data[offset + 1] << 8 | data[offset + 2]);
|
|
6261
|
-
return { value, bytesRead: 3 };
|
|
6262
|
-
}
|
|
6263
|
-
if ((first & 240) === 224) {
|
|
6264
|
-
if (offset + 3 >= data.length) {
|
|
6265
|
-
throw new Error("VInt decode: truncated 4-byte encoding");
|
|
6266
|
-
}
|
|
6267
|
-
const value = 2113664 + ((first & 15) << 24 | data[offset + 1] << 16 | data[offset + 2] << 8 | data[offset + 3]);
|
|
6268
|
-
return { value: value >>> 0, bytesRead: 4 };
|
|
6269
|
-
}
|
|
6270
|
-
if ((first & 248) === 240) {
|
|
6271
|
-
if (offset + 4 >= data.length) {
|
|
6272
|
-
throw new Error("VInt decode: truncated 5-byte encoding");
|
|
6273
|
-
}
|
|
6274
|
-
const high = first & 7;
|
|
6275
|
-
const low = (data[offset + 1] << 24 | data[offset + 2] << 16 | data[offset + 3] << 8 | data[offset + 4]) >>> 0;
|
|
6276
|
-
const value = 270549120 + high * 4294967296 + low;
|
|
6277
|
-
return { value: value >>> 0, bytesRead: 5 };
|
|
6278
|
-
}
|
|
6279
|
-
throw new Error("VInt decode: invalid prefix");
|
|
6280
|
-
}
|
|
6281
|
-
|
|
6282
|
-
// ../core/dist/id-codec/fletcher16.js
|
|
6283
|
-
function fletcher16(data) {
|
|
6284
|
-
let sum1 = 0;
|
|
6285
|
-
let sum2 = 0;
|
|
6286
|
-
for (const byte of data) {
|
|
6287
|
-
sum1 = (sum1 + byte) % 255;
|
|
6288
|
-
sum2 = (sum2 + sum1) % 255;
|
|
6289
|
-
}
|
|
6290
|
-
return new Uint8Array([sum1, sum2]);
|
|
6291
|
-
}
|
|
6292
|
-
function verifyFletcher16(data, checksum) {
|
|
6293
|
-
if (checksum.length !== 2)
|
|
6294
|
-
return false;
|
|
6295
|
-
const computed = fletcher16(data);
|
|
6296
|
-
return computed[0] === checksum[0] && computed[1] === checksum[1];
|
|
6297
|
-
}
|
|
6298
|
-
|
|
6299
|
-
// ../core/dist/utils/crypto.js
|
|
6300
|
-
var weakRandomState;
|
|
6301
|
-
var init_crypto = __esm(() => {
|
|
6302
|
-
weakRandomState = (Date.now() ^ 2654435769) >>> 0;
|
|
6303
|
-
});
|
|
6304
|
-
|
|
6305
|
-
// ../core/dist/id-codec/document-id.js
|
|
6306
|
-
function encodeDocumentId(tableNumber, internalId) {
|
|
6307
|
-
if (internalId.length !== INTERNAL_ID_LENGTH) {
|
|
6308
|
-
throw new Error(`Internal ID must be exactly ${INTERNAL_ID_LENGTH} bytes, got ${internalId.length}`);
|
|
6309
|
-
}
|
|
6310
|
-
if (tableNumber < 1 || tableNumber > 4294967295) {
|
|
6311
|
-
throw new Error(`Table number must be between 1 and 2^32-1, got ${tableNumber}`);
|
|
6312
|
-
}
|
|
6313
|
-
const tableBytes = vintEncode(tableNumber);
|
|
6314
|
-
const payload = new Uint8Array(tableBytes.length + INTERNAL_ID_LENGTH);
|
|
6315
|
-
payload.set(tableBytes, 0);
|
|
6316
|
-
payload.set(internalId, tableBytes.length);
|
|
6317
|
-
const checksum = fletcher16(payload);
|
|
6318
|
-
const final = new Uint8Array(payload.length + 2);
|
|
6319
|
-
final.set(payload, 0);
|
|
6320
|
-
final.set(checksum, payload.length);
|
|
6321
|
-
return base32Encode(final);
|
|
6322
|
-
}
|
|
6323
|
-
function decodeDocumentId(encoded) {
|
|
6324
|
-
if (encoded.length < MIN_ENCODED_LENGTH || encoded.length > MAX_ENCODED_LENGTH) {
|
|
6325
|
-
throw new Error(`Invalid document ID length: ${encoded.length} (expected ${MIN_ENCODED_LENGTH}-${MAX_ENCODED_LENGTH})`);
|
|
6326
|
-
}
|
|
6327
|
-
if (!isValidBase32(encoded)) {
|
|
6328
|
-
throw new Error("Invalid document ID: contains invalid base32 characters");
|
|
6329
|
-
}
|
|
6330
|
-
const bytes = base32Decode(encoded);
|
|
6331
|
-
if (bytes.length < 19) {
|
|
6332
|
-
throw new Error(`Invalid document ID: decoded to ${bytes.length} bytes (minimum 19)`);
|
|
6333
|
-
}
|
|
6334
|
-
const checksum = bytes.slice(bytes.length - 2);
|
|
6335
|
-
const payload = bytes.slice(0, bytes.length - 2);
|
|
6336
|
-
if (!verifyFletcher16(payload, checksum)) {
|
|
6337
|
-
throw new Error("Invalid document ID: checksum verification failed");
|
|
6661
|
+
validateValidator(fieldType, value[k], fieldPath, options);
|
|
6662
|
+
}
|
|
6663
|
+
}
|
|
6664
|
+
for (const k of Object.keys(value)) {
|
|
6665
|
+
if (validator2.value[k] === undefined) {
|
|
6666
|
+
throw new Error(`Object contains extra field \`${k}\` that is not in the validator.
|
|
6667
|
+
|
|
6668
|
+
Object: ${JSON.stringify(value)}
|
|
6669
|
+
Validator: v.object({...})`);
|
|
6670
|
+
}
|
|
6671
|
+
}
|
|
6672
|
+
return;
|
|
6673
|
+
}
|
|
6338
6674
|
}
|
|
6339
|
-
|
|
6340
|
-
|
|
6341
|
-
|
|
6342
|
-
|
|
6675
|
+
}
|
|
6676
|
+
function tableNameFromId(id) {
|
|
6677
|
+
const parts = deserializeDeveloperId(id);
|
|
6678
|
+
if (!parts) {
|
|
6679
|
+
return null;
|
|
6343
6680
|
}
|
|
6344
|
-
return
|
|
6681
|
+
return hexToString(parts.table);
|
|
6345
6682
|
}
|
|
6346
|
-
function
|
|
6683
|
+
function tableNameFromConvexId(id, options) {
|
|
6347
6684
|
try {
|
|
6348
|
-
decodeDocumentId(
|
|
6349
|
-
|
|
6685
|
+
const decoded = decodeDocumentId(id);
|
|
6686
|
+
const fromMap = options.tableNumberToName?.get(decoded.tableNumber);
|
|
6687
|
+
if (fromMap) {
|
|
6688
|
+
return fromMap;
|
|
6689
|
+
}
|
|
6690
|
+
return null;
|
|
6350
6691
|
} catch {
|
|
6351
|
-
return
|
|
6692
|
+
return null;
|
|
6352
6693
|
}
|
|
6353
6694
|
}
|
|
6354
|
-
function
|
|
6355
|
-
|
|
6356
|
-
|
|
6357
|
-
hex += internalId[i2].toString(16).padStart(2, "0");
|
|
6695
|
+
function isMatchingValidatorTable(idTableName, validatorTableName, componentPath) {
|
|
6696
|
+
if (idTableName === validatorTableName) {
|
|
6697
|
+
return true;
|
|
6358
6698
|
}
|
|
6359
|
-
|
|
6699
|
+
const { tableName: validatorBareName } = parseFullTableName(validatorTableName);
|
|
6700
|
+
const { tableName: idBareName } = parseFullTableName(idTableName);
|
|
6701
|
+
if (componentPath !== undefined) {
|
|
6702
|
+
const expectedFullName = getFullTableName(validatorBareName, componentPath);
|
|
6703
|
+
return idTableName === expectedFullName;
|
|
6704
|
+
}
|
|
6705
|
+
return idBareName === validatorBareName;
|
|
6360
6706
|
}
|
|
6361
|
-
|
|
6362
|
-
|
|
6363
|
-
|
|
6364
|
-
|
|
6707
|
+
function isSimpleObject2(value) {
|
|
6708
|
+
const isObject2 = typeof value === "object";
|
|
6709
|
+
const prototype = Object.getPrototypeOf(value);
|
|
6710
|
+
const isSimple = prototype === null || prototype === Object.prototype || prototype?.constructor?.name === "Object";
|
|
6711
|
+
return isObject2 && isSimple;
|
|
6712
|
+
}
|
|
6713
|
+
var ValidatorError;
|
|
6714
|
+
var init_validator2 = __esm(() => {
|
|
6715
|
+
init_utils();
|
|
6716
|
+
init_interface();
|
|
6717
|
+
init_module_loader();
|
|
6718
|
+
init_id_codec();
|
|
6719
|
+
ValidatorError = class ValidatorError extends Error {
|
|
6720
|
+
path;
|
|
6721
|
+
constructor(message2, path = "") {
|
|
6722
|
+
super(message2);
|
|
6723
|
+
this.path = path;
|
|
6724
|
+
this.name = "ValidatorError";
|
|
6725
|
+
}
|
|
6726
|
+
};
|
|
6365
6727
|
});
|
|
6366
6728
|
|
|
6367
6729
|
// src/sqlite-docstore.ts
|
|
@@ -6372,7 +6734,10 @@ init_values();
|
|
|
6372
6734
|
|
|
6373
6735
|
// ../core/dist/docstore/interface.js
|
|
6374
6736
|
function documentIdKey(id) {
|
|
6375
|
-
const tableKey = id.table && id.table.length > 0 ? id.table : id.tableNumber !== undefined && Number.isInteger(id.tableNumber) && id.tableNumber > 0 ? `#${id.tableNumber}` :
|
|
6737
|
+
const tableKey = id.table && id.table.length > 0 ? id.table : id.tableNumber !== undefined && Number.isInteger(id.tableNumber) && id.tableNumber > 0 ? `#${id.tableNumber}` : null;
|
|
6738
|
+
if (!tableKey) {
|
|
6739
|
+
throw new Error("Invalid document ID: missing table and tableNumber");
|
|
6740
|
+
}
|
|
6376
6741
|
return `${tableKey}:${id.internalId}`;
|
|
6377
6742
|
}
|
|
6378
6743
|
var Order;
|
|
@@ -6579,6 +6944,7 @@ class TimestampOracle {
|
|
|
6579
6944
|
}
|
|
6580
6945
|
}
|
|
6581
6946
|
// ../core/dist/utils/keyspace.js
|
|
6947
|
+
init_utils();
|
|
6582
6948
|
var TABLE_PREFIX = "table";
|
|
6583
6949
|
var INDEX_PREFIX = "index";
|
|
6584
6950
|
function encodeComponent(component) {
|
|
@@ -6619,6 +6985,13 @@ function decodeIndexId(indexId) {
|
|
|
6619
6985
|
index: decoded.slice(separatorIndex + 1)
|
|
6620
6986
|
};
|
|
6621
6987
|
}
|
|
6988
|
+
|
|
6989
|
+
// ../core/dist/utils/index.js
|
|
6990
|
+
init_utils();
|
|
6991
|
+
|
|
6992
|
+
// ../core/dist/queryengine/indexing/index-manager.js
|
|
6993
|
+
init_utils();
|
|
6994
|
+
|
|
6622
6995
|
// ../core/dist/queryengine/indexing/index-key-codec.js
|
|
6623
6996
|
var TypeTag;
|
|
6624
6997
|
(function(TypeTag2) {
|
|
@@ -6668,8 +7041,9 @@ function encodeBigInt(n) {
|
|
|
6668
7041
|
return bytes;
|
|
6669
7042
|
}
|
|
6670
7043
|
function encodeString(s) {
|
|
6671
|
-
|
|
6672
|
-
|
|
7044
|
+
return encodeEscapedBytes(new TextEncoder().encode(s));
|
|
7045
|
+
}
|
|
7046
|
+
function encodeEscapedBytes(raw) {
|
|
6673
7047
|
let nullCount = 0;
|
|
6674
7048
|
for (const byte of raw) {
|
|
6675
7049
|
if (byte === 0)
|
|
@@ -6733,11 +7107,10 @@ function encodeValue(value) {
|
|
|
6733
7107
|
}
|
|
6734
7108
|
if (value instanceof ArrayBuffer || value instanceof Uint8Array) {
|
|
6735
7109
|
const bytes = value instanceof Uint8Array ? value : new Uint8Array(value);
|
|
6736
|
-
const
|
|
7110
|
+
const encoded = encodeEscapedBytes(bytes);
|
|
7111
|
+
const result = new Uint8Array(1 + encoded.length);
|
|
6737
7112
|
result[0] = TypeTag.Bytes;
|
|
6738
|
-
result.set(
|
|
6739
|
-
result[result.length - 2] = 0;
|
|
6740
|
-
result[result.length - 1] = 0;
|
|
7113
|
+
result.set(encoded, 1);
|
|
6741
7114
|
return result;
|
|
6742
7115
|
}
|
|
6743
7116
|
throw new Error(`Cannot encode value of type ${typeof value} in index key`);
|
|
@@ -6854,9 +7227,11 @@ class SchemaService {
|
|
|
6854
7227
|
tableCache = new Map;
|
|
6855
7228
|
schemaValidator;
|
|
6856
7229
|
componentPath;
|
|
6857
|
-
|
|
7230
|
+
tableRegistry;
|
|
7231
|
+
constructor(componentPath, tableRegistry) {
|
|
6858
7232
|
this.componentPath = componentPath;
|
|
6859
|
-
this.
|
|
7233
|
+
this.tableRegistry = tableRegistry;
|
|
7234
|
+
this.schemaValidator = new SchemaValidator(componentPath, tableRegistry);
|
|
6860
7235
|
}
|
|
6861
7236
|
async validate(tableName, document) {
|
|
6862
7237
|
try {
|
|
@@ -6981,6 +7356,10 @@ class SchemaService {
|
|
|
6981
7356
|
return this.cachedSchemaDefinition;
|
|
6982
7357
|
}
|
|
6983
7358
|
}
|
|
7359
|
+
|
|
7360
|
+
// ../core/dist/queryengine/index-query.js
|
|
7361
|
+
init_utils();
|
|
7362
|
+
|
|
6984
7363
|
// ../core/dist/observability/udf-trace.js
|
|
6985
7364
|
init_context_storage();
|
|
6986
7365
|
var TRACE_CONTEXT = new ContextStorage;
|
|
@@ -7224,11 +7603,10 @@ function evaluateFieldPath(fieldPath, document) {
|
|
|
7224
7603
|
}
|
|
7225
7604
|
return current;
|
|
7226
7605
|
}
|
|
7227
|
-
// ../core/dist/id-codec/index.js
|
|
7228
|
-
init_base32();
|
|
7229
|
-
init_document_id();
|
|
7230
7606
|
|
|
7231
7607
|
// ../core/dist/queryengine/developer-id.js
|
|
7608
|
+
init_utils();
|
|
7609
|
+
init_id_codec();
|
|
7232
7610
|
function parseDeveloperId(developerId) {
|
|
7233
7611
|
if (isValidDocumentId(developerId)) {
|
|
7234
7612
|
try {
|
|
@@ -7246,6 +7624,25 @@ function parseDeveloperId(developerId) {
|
|
|
7246
7624
|
}
|
|
7247
7625
|
return { table: parts.table, internalId: parts.internalId };
|
|
7248
7626
|
}
|
|
7627
|
+
async function parseDeveloperIdWithTableRegistry(developerId, tableRegistry) {
|
|
7628
|
+
if (isValidDocumentId(developerId)) {
|
|
7629
|
+
try {
|
|
7630
|
+
const decoded = decodeDocumentId(developerId);
|
|
7631
|
+
const tableInfo = await tableRegistry.getTableInfo(decoded.tableNumber);
|
|
7632
|
+
if (!tableInfo) {
|
|
7633
|
+
return null;
|
|
7634
|
+
}
|
|
7635
|
+
return {
|
|
7636
|
+
table: stringToHex(tableInfo.fullName),
|
|
7637
|
+
internalId: internalIdToHex(decoded.internalId),
|
|
7638
|
+
tableNumber: decoded.tableNumber
|
|
7639
|
+
};
|
|
7640
|
+
} catch {
|
|
7641
|
+
return null;
|
|
7642
|
+
}
|
|
7643
|
+
}
|
|
7644
|
+
return parseDeveloperId(developerId);
|
|
7645
|
+
}
|
|
7249
7646
|
function parseStorageId(storageId) {
|
|
7250
7647
|
const parsed = parseDeveloperId(storageId);
|
|
7251
7648
|
if (parsed) {
|
|
@@ -7262,12 +7659,21 @@ function parseStorageId(storageId) {
|
|
|
7262
7659
|
function isTablePlaceholder(table) {
|
|
7263
7660
|
return table.startsWith("#");
|
|
7264
7661
|
}
|
|
7662
|
+
|
|
7663
|
+
// ../core/dist/query/query-runtime.js
|
|
7664
|
+
init_utils();
|
|
7665
|
+
|
|
7265
7666
|
// ../core/dist/query/planner.js
|
|
7266
7667
|
init_interface();
|
|
7668
|
+
init_utils();
|
|
7669
|
+
|
|
7267
7670
|
// ../core/dist/query/actions.js
|
|
7671
|
+
init_utils();
|
|
7268
7672
|
init_interface();
|
|
7269
7673
|
|
|
7270
7674
|
// ../core/dist/queryengine/indexing/read-write-set.js
|
|
7675
|
+
init_utils();
|
|
7676
|
+
|
|
7271
7677
|
class RangeSet {
|
|
7272
7678
|
ranges = new Map;
|
|
7273
7679
|
addDocument(docId) {
|
|
@@ -7378,6 +7784,8 @@ function deserializeKeyRange(serialized) {
|
|
|
7378
7784
|
}
|
|
7379
7785
|
|
|
7380
7786
|
// ../core/dist/kernel/access-log.js
|
|
7787
|
+
init_utils();
|
|
7788
|
+
|
|
7381
7789
|
class AccessLog {
|
|
7382
7790
|
ranges = new RangeSet;
|
|
7383
7791
|
addDocument(docId) {
|
|
@@ -7402,104 +7810,9 @@ class AccessLog {
|
|
|
7402
7810
|
}
|
|
7403
7811
|
}
|
|
7404
7812
|
|
|
7405
|
-
// ../core/dist/
|
|
7813
|
+
// ../core/dist/kernel/kernel-context.js
|
|
7406
7814
|
init_interface();
|
|
7407
7815
|
|
|
7408
|
-
class MemoryTableRegistry {
|
|
7409
|
-
tablesByName = new Map;
|
|
7410
|
-
tablesByNumber = new Map;
|
|
7411
|
-
nextTableNumber = FIRST_USER_TABLE_NUMBER;
|
|
7412
|
-
constructor() {
|
|
7413
|
-
this.registerSystemTables();
|
|
7414
|
-
}
|
|
7415
|
-
registerSystemTables() {
|
|
7416
|
-
for (const [name, number] of Object.entries(SYSTEM_TABLE_NUMBERS)) {
|
|
7417
|
-
const info = {
|
|
7418
|
-
tableNumber: number,
|
|
7419
|
-
name,
|
|
7420
|
-
componentPath: "",
|
|
7421
|
-
fullName: name,
|
|
7422
|
-
isSystem: true,
|
|
7423
|
-
createdAt: Date.now()
|
|
7424
|
-
};
|
|
7425
|
-
this.tablesByName.set(name, info);
|
|
7426
|
-
this.tablesByNumber.set(number, info);
|
|
7427
|
-
}
|
|
7428
|
-
}
|
|
7429
|
-
async getOrAllocateTableNumber(tableName, componentPath = "") {
|
|
7430
|
-
const fullName = getFullTableName(tableName, componentPath);
|
|
7431
|
-
const existing = this.tablesByName.get(fullName);
|
|
7432
|
-
if (existing) {
|
|
7433
|
-
return existing.tableNumber;
|
|
7434
|
-
}
|
|
7435
|
-
if (isSystemTable(tableName) && componentPath === "") {
|
|
7436
|
-
const systemNumber = SYSTEM_TABLE_NUMBERS[tableName];
|
|
7437
|
-
if (systemNumber !== undefined) {
|
|
7438
|
-
return systemNumber;
|
|
7439
|
-
}
|
|
7440
|
-
}
|
|
7441
|
-
const tableNumber = this.nextTableNumber++;
|
|
7442
|
-
const info = {
|
|
7443
|
-
tableNumber,
|
|
7444
|
-
name: tableName,
|
|
7445
|
-
componentPath,
|
|
7446
|
-
fullName,
|
|
7447
|
-
isSystem: false,
|
|
7448
|
-
createdAt: Date.now()
|
|
7449
|
-
};
|
|
7450
|
-
this.tablesByName.set(fullName, info);
|
|
7451
|
-
this.tablesByNumber.set(tableNumber, info);
|
|
7452
|
-
return tableNumber;
|
|
7453
|
-
}
|
|
7454
|
-
async getTableInfo(tableNumber) {
|
|
7455
|
-
return this.tablesByNumber.get(tableNumber) ?? null;
|
|
7456
|
-
}
|
|
7457
|
-
async getTableInfoByName(tableName, componentPath = "") {
|
|
7458
|
-
const fullName = getFullTableName(tableName, componentPath);
|
|
7459
|
-
return this.tablesByName.get(fullName) ?? null;
|
|
7460
|
-
}
|
|
7461
|
-
async listTables(componentPath) {
|
|
7462
|
-
const tables = Array.from(this.tablesByNumber.values());
|
|
7463
|
-
if (componentPath === undefined) {
|
|
7464
|
-
return tables;
|
|
7465
|
-
}
|
|
7466
|
-
return tables.filter((t) => t.componentPath === componentPath);
|
|
7467
|
-
}
|
|
7468
|
-
async hasAccess(tableNumber, componentPath) {
|
|
7469
|
-
const info = await this.getTableInfo(tableNumber);
|
|
7470
|
-
if (!info) {
|
|
7471
|
-
return false;
|
|
7472
|
-
}
|
|
7473
|
-
if (info.isSystem) {
|
|
7474
|
-
return true;
|
|
7475
|
-
}
|
|
7476
|
-
return info.componentPath === componentPath;
|
|
7477
|
-
}
|
|
7478
|
-
getSystemTableNumber(systemTableName) {
|
|
7479
|
-
return SYSTEM_TABLE_NUMBERS[systemTableName];
|
|
7480
|
-
}
|
|
7481
|
-
reset() {
|
|
7482
|
-
this.tablesByName.clear();
|
|
7483
|
-
this.tablesByNumber.clear();
|
|
7484
|
-
this.nextTableNumber = FIRST_USER_TABLE_NUMBER;
|
|
7485
|
-
this.registerSystemTables();
|
|
7486
|
-
}
|
|
7487
|
-
getState() {
|
|
7488
|
-
return {
|
|
7489
|
-
tableCount: this.tablesByNumber.size,
|
|
7490
|
-
nextNumber: this.nextTableNumber
|
|
7491
|
-
};
|
|
7492
|
-
}
|
|
7493
|
-
}
|
|
7494
|
-
var globalRegistry = null;
|
|
7495
|
-
function getGlobalTableRegistry() {
|
|
7496
|
-
if (!globalRegistry) {
|
|
7497
|
-
globalRegistry = new MemoryTableRegistry;
|
|
7498
|
-
}
|
|
7499
|
-
return globalRegistry;
|
|
7500
|
-
}
|
|
7501
|
-
|
|
7502
|
-
// ../core/dist/kernel/kernel-context.js
|
|
7503
7816
|
class KernelContext {
|
|
7504
7817
|
authContext;
|
|
7505
7818
|
componentPath;
|
|
@@ -7516,11 +7829,14 @@ class KernelContext {
|
|
|
7516
7829
|
this.authContext = options.authContext;
|
|
7517
7830
|
this.componentPath = options.componentPath ?? "";
|
|
7518
7831
|
this.mutationTransaction = options.mutationTransaction;
|
|
7519
|
-
|
|
7520
|
-
|
|
7832
|
+
if (!options.tableRegistry) {
|
|
7833
|
+
throw new Error("KernelContext requires an explicit tableRegistry");
|
|
7834
|
+
}
|
|
7835
|
+
this.tableRegistry = options.tableRegistry;
|
|
7836
|
+
this.useConvexIdFormat = options.useConvexIdFormat ?? true;
|
|
7521
7837
|
}
|
|
7522
7838
|
async getTableNumber(tableName) {
|
|
7523
|
-
return this.tableRegistry.getOrAllocateTableNumber(tableName, this.componentPath);
|
|
7839
|
+
return this.tableRegistry.getOrAllocateTableNumber(tableName, isSystemTable(tableName) ? "" : this.componentPath);
|
|
7524
7840
|
}
|
|
7525
7841
|
nextSubrequestId(prefix, udfPath) {
|
|
7526
7842
|
return `${prefix}:${udfPath}:${Date.now()}:${Math.random()}:${this.subrequestCounter++}`;
|
|
@@ -7565,7 +7881,7 @@ class KernelContext {
|
|
|
7565
7881
|
this.writeLog.addDocument(docId);
|
|
7566
7882
|
}
|
|
7567
7883
|
recordLocalWrite(developerId, tableName, value, docId) {
|
|
7568
|
-
this.localWrites.set(developerId, { table: tableName, value });
|
|
7884
|
+
this.localWrites.set(developerId, { table: tableName, value, docId });
|
|
7569
7885
|
if (docId) {
|
|
7570
7886
|
this.recordDocumentWrite(docId);
|
|
7571
7887
|
return;
|
|
@@ -7607,7 +7923,13 @@ class KernelContext {
|
|
|
7607
7923
|
}
|
|
7608
7924
|
}
|
|
7609
7925
|
|
|
7926
|
+
// ../core/dist/kernel/udf-kernel.js
|
|
7927
|
+
init_id_codec();
|
|
7928
|
+
|
|
7610
7929
|
// ../core/dist/kernel/blob-store-gateway.js
|
|
7930
|
+
init_id_codec();
|
|
7931
|
+
init_utils();
|
|
7932
|
+
|
|
7611
7933
|
class BlobStoreGateway {
|
|
7612
7934
|
context;
|
|
7613
7935
|
docStore;
|
|
@@ -7656,7 +7978,7 @@ class BlobStoreGateway {
|
|
|
7656
7978
|
if (!this.storage) {
|
|
7657
7979
|
return null;
|
|
7658
7980
|
}
|
|
7659
|
-
const docId = parseStorageId(storageId);
|
|
7981
|
+
const docId = await parseDeveloperIdWithTableRegistry(storageId, this.context.tableRegistry) ?? parseStorageId(storageId);
|
|
7660
7982
|
if (!docId) {
|
|
7661
7983
|
console.debug(`[BlobStoreGateway] Failed to parse storage ID: ${storageId}`);
|
|
7662
7984
|
return null;
|
|
@@ -7677,7 +7999,7 @@ class BlobStoreGateway {
|
|
|
7677
7999
|
if (!this.storage) {
|
|
7678
8000
|
return null;
|
|
7679
8001
|
}
|
|
7680
|
-
const docId = parseStorageId(storageId);
|
|
8002
|
+
const docId = await parseDeveloperIdWithTableRegistry(storageId, this.context.tableRegistry) ?? parseStorageId(storageId);
|
|
7681
8003
|
if (!docId) {
|
|
7682
8004
|
return null;
|
|
7683
8005
|
}
|
|
@@ -7690,7 +8012,7 @@ class BlobStoreGateway {
|
|
|
7690
8012
|
}
|
|
7691
8013
|
async delete(storageId) {
|
|
7692
8014
|
const storage2 = this.requireStorage();
|
|
7693
|
-
const docId = parseStorageId(storageId);
|
|
8015
|
+
const docId = await parseDeveloperIdWithTableRegistry(storageId, this.context.tableRegistry) ?? parseStorageId(storageId);
|
|
7694
8016
|
if (!docId) {
|
|
7695
8017
|
return;
|
|
7696
8018
|
}
|
|
@@ -7715,13 +8037,17 @@ class BlobStoreGateway {
|
|
|
7715
8037
|
|
|
7716
8038
|
// ../core/dist/kernel/scheduler-gateway.js
|
|
7717
8039
|
init_values();
|
|
8040
|
+
init_id_codec();
|
|
8041
|
+
init_utils();
|
|
8042
|
+
|
|
7718
8043
|
// ../core/dist/kernel/syscalls/utils.js
|
|
7719
8044
|
init_values();
|
|
8045
|
+
init_utils();
|
|
7720
8046
|
async function resolveTableName(docId, tableRegistry) {
|
|
7721
8047
|
if (docId.tableNumber !== undefined) {
|
|
7722
8048
|
const info = await tableRegistry.getTableInfo(docId.tableNumber);
|
|
7723
8049
|
if (info) {
|
|
7724
|
-
return info.
|
|
8050
|
+
return info.fullName;
|
|
7725
8051
|
}
|
|
7726
8052
|
if (!isTablePlaceholder(docId.table)) {
|
|
7727
8053
|
return hexToString(docId.table);
|
|
@@ -7902,7 +8228,7 @@ class SchedulerGateway {
|
|
|
7902
8228
|
return developerId;
|
|
7903
8229
|
}
|
|
7904
8230
|
async cancel(id, state) {
|
|
7905
|
-
const docId =
|
|
8231
|
+
const docId = await parseDeveloperIdWithTableRegistry(id, this.context.tableRegistry);
|
|
7906
8232
|
if (!docId) {
|
|
7907
8233
|
throw new Error(`Scheduled job with id ${id} not found.`);
|
|
7908
8234
|
}
|
|
@@ -8027,6 +8353,8 @@ class ActionSyscalls {
|
|
|
8027
8353
|
|
|
8028
8354
|
// ../core/dist/kernel/syscalls/database-syscalls.js
|
|
8029
8355
|
init_values();
|
|
8356
|
+
init_id_codec();
|
|
8357
|
+
init_utils();
|
|
8030
8358
|
init_interface();
|
|
8031
8359
|
|
|
8032
8360
|
class DatabaseSyscalls {
|
|
@@ -8063,7 +8391,8 @@ class DatabaseSyscalls {
|
|
|
8063
8391
|
if (docId.tableNumber !== undefined) {
|
|
8064
8392
|
return { id: idString };
|
|
8065
8393
|
}
|
|
8066
|
-
|
|
8394
|
+
const expectedFullTableName = getFullTableName(tableName, isSystemTable(tableName) ? "" : this.context.componentPath);
|
|
8395
|
+
if (docId.table === stringToHex(expectedFullTableName)) {
|
|
8067
8396
|
return { id: idString };
|
|
8068
8397
|
}
|
|
8069
8398
|
return { id: null };
|
|
@@ -8122,29 +8451,28 @@ class DatabaseSyscalls {
|
|
|
8122
8451
|
return { _id: developerId };
|
|
8123
8452
|
}
|
|
8124
8453
|
async handleGet(args) {
|
|
8125
|
-
const { id } = args;
|
|
8454
|
+
const { id, table } = args;
|
|
8126
8455
|
if (typeof id !== "string") {
|
|
8127
8456
|
throw new Error("`id` argument for `get` must be a string.");
|
|
8128
8457
|
}
|
|
8129
|
-
const
|
|
8130
|
-
if (!
|
|
8458
|
+
const resolved = await this.resolveDocumentTarget(id, table, "get");
|
|
8459
|
+
if (!resolved) {
|
|
8131
8460
|
return null;
|
|
8132
8461
|
}
|
|
8133
|
-
this.context.recordDocumentRead(
|
|
8134
|
-
const doc = await this.queryRuntime.getVisibleDocumentById(id,
|
|
8462
|
+
this.context.recordDocumentRead(resolved.docId);
|
|
8463
|
+
const doc = await this.queryRuntime.getVisibleDocumentById(id, resolved.docId);
|
|
8135
8464
|
return doc ?? null;
|
|
8136
8465
|
}
|
|
8137
8466
|
async handleRemove(args) {
|
|
8138
|
-
const { id } = args;
|
|
8467
|
+
const { id, table } = args;
|
|
8139
8468
|
if (typeof id !== "string") {
|
|
8140
8469
|
throw new Error("`id` argument for `remove` must be a string.");
|
|
8141
8470
|
}
|
|
8142
|
-
const
|
|
8143
|
-
if (!
|
|
8471
|
+
const resolved = await this.resolveDocumentTarget(id, table, "remove", true);
|
|
8472
|
+
if (!resolved) {
|
|
8144
8473
|
throw new Error(`Document with id ${id} not found.`);
|
|
8145
8474
|
}
|
|
8146
|
-
const fullTableName
|
|
8147
|
-
const { tableName: bareTableName } = parseFullTableName(fullTableName);
|
|
8475
|
+
const { docId, fullTableName, bareTableName } = resolved;
|
|
8148
8476
|
const latest = await this.docStore.fetchLatestDocument(docId, this.context.snapshotTimestamp);
|
|
8149
8477
|
if (!latest) {
|
|
8150
8478
|
throw new Error(`Document with id ${id} not found.`);
|
|
@@ -8160,16 +8488,15 @@ class DatabaseSyscalls {
|
|
|
8160
8488
|
return {};
|
|
8161
8489
|
}
|
|
8162
8490
|
async handleShallowMerge(args) {
|
|
8163
|
-
const { id, value } = args;
|
|
8491
|
+
const { id, table, value } = args;
|
|
8164
8492
|
if (typeof id !== "string") {
|
|
8165
8493
|
throw new Error("`id` argument for `shallowMerge` must be a string.");
|
|
8166
8494
|
}
|
|
8167
|
-
const
|
|
8168
|
-
if (!
|
|
8495
|
+
const resolved = await this.resolveDocumentTarget(id, table, "patch", true);
|
|
8496
|
+
if (!resolved) {
|
|
8169
8497
|
throw new Error(`Document with id ${id} not found.`);
|
|
8170
8498
|
}
|
|
8171
|
-
const fullTableName
|
|
8172
|
-
const { tableName: bareTableName } = parseFullTableName(fullTableName);
|
|
8499
|
+
const { docId, fullTableName, bareTableName } = resolved;
|
|
8173
8500
|
if (value && typeof value === "object") {
|
|
8174
8501
|
if ("_id" in value) {
|
|
8175
8502
|
throw new Error("System field `_id` cannot be modified in a patch operation.");
|
|
@@ -8220,16 +8547,15 @@ class DatabaseSyscalls {
|
|
|
8220
8547
|
return {};
|
|
8221
8548
|
}
|
|
8222
8549
|
async handleReplace(args) {
|
|
8223
|
-
const { id, value } = args;
|
|
8550
|
+
const { id, table, value } = args;
|
|
8224
8551
|
if (typeof id !== "string") {
|
|
8225
8552
|
throw new Error("`id` argument for `replace` must be a string.");
|
|
8226
8553
|
}
|
|
8227
|
-
const
|
|
8228
|
-
if (!
|
|
8554
|
+
const resolved = await this.resolveDocumentTarget(id, table, "replace", true);
|
|
8555
|
+
if (!resolved) {
|
|
8229
8556
|
throw new Error(`Document with id ${id} not found.`);
|
|
8230
8557
|
}
|
|
8231
|
-
const fullTableName
|
|
8232
|
-
const { tableName: bareTableName } = parseFullTableName(fullTableName);
|
|
8558
|
+
const { docId, fullTableName, bareTableName } = resolved;
|
|
8233
8559
|
const replaceValue = jsonToConvex(value);
|
|
8234
8560
|
if (typeof replaceValue !== "object" || replaceValue === null || Array.isArray(replaceValue)) {
|
|
8235
8561
|
throw new Error("The replacement value for `replace` must be an object.");
|
|
@@ -8252,6 +8578,27 @@ class DatabaseSyscalls {
|
|
|
8252
8578
|
this.context.recordLocalWrite(id, fullTableName, newValue, canonicalDocId);
|
|
8253
8579
|
return {};
|
|
8254
8580
|
}
|
|
8581
|
+
async resolveDocumentTarget(id, table, operation, throwOnMismatch = false) {
|
|
8582
|
+
if (table !== undefined && typeof table !== "string") {
|
|
8583
|
+
throw new Error(`\`table\` argument for \`${operation}\` must be a string.`);
|
|
8584
|
+
}
|
|
8585
|
+
const docId = await parseDeveloperIdWithTableRegistry(id, this.context.tableRegistry);
|
|
8586
|
+
if (!docId) {
|
|
8587
|
+
return null;
|
|
8588
|
+
}
|
|
8589
|
+
const fullTableName = await resolveTableName(docId, this.context.tableRegistry);
|
|
8590
|
+
if (typeof table === "string") {
|
|
8591
|
+
const expectedFullTableName = getFullTableName(table, isSystemTable(table) ? "" : this.context.componentPath);
|
|
8592
|
+
if (fullTableName !== expectedFullTableName) {
|
|
8593
|
+
if (throwOnMismatch) {
|
|
8594
|
+
throw new Error(`Document with id ${id} does not belong to table ${table}.`);
|
|
8595
|
+
}
|
|
8596
|
+
return null;
|
|
8597
|
+
}
|
|
8598
|
+
}
|
|
8599
|
+
const { tableName: bareTableName } = parseFullTableName(fullTableName);
|
|
8600
|
+
return { docId, fullTableName, bareTableName };
|
|
8601
|
+
}
|
|
8255
8602
|
}
|
|
8256
8603
|
|
|
8257
8604
|
// ../core/dist/kernel/syscalls/identity-syscalls.js
|
|
@@ -8567,11 +8914,203 @@ class KernelSyscalls {
|
|
|
8567
8914
|
return this.jsRouter.dispatch(op, args);
|
|
8568
8915
|
}
|
|
8569
8916
|
}
|
|
8917
|
+
|
|
8918
|
+
// ../core/dist/tables/docstore-table-registry.js
|
|
8919
|
+
init_system_tables();
|
|
8920
|
+
init_utils();
|
|
8921
|
+
init_interface();
|
|
8922
|
+
|
|
8923
|
+
class DocStoreTableRegistry {
|
|
8924
|
+
docstore;
|
|
8925
|
+
tablesByNumber = new Map;
|
|
8926
|
+
tablesByName = new Map;
|
|
8927
|
+
loadPromise = null;
|
|
8928
|
+
cachedRegistryVersion = 0;
|
|
8929
|
+
constructor(docstore) {
|
|
8930
|
+
this.docstore = docstore;
|
|
8931
|
+
}
|
|
8932
|
+
async getOrAllocateTableNumber(tableName, componentPath = "") {
|
|
8933
|
+
await this.ensureLoaded();
|
|
8934
|
+
await this.ensureFresh();
|
|
8935
|
+
const normalizedComponent = isSystemTable(tableName) ? "" : componentPath;
|
|
8936
|
+
const fullName = getFullTableName(tableName, normalizedComponent);
|
|
8937
|
+
let existing = this.tablesByName.get(fullName);
|
|
8938
|
+
if (existing) {
|
|
8939
|
+
return existing.tableNumber;
|
|
8940
|
+
}
|
|
8941
|
+
await this.reloadTables();
|
|
8942
|
+
existing = this.tablesByName.get(fullName);
|
|
8943
|
+
if (existing) {
|
|
8944
|
+
return existing.tableNumber;
|
|
8945
|
+
}
|
|
8946
|
+
const oracle = this.docstore.timestampOracle;
|
|
8947
|
+
for (;; ) {
|
|
8948
|
+
const metadata = await readSystemMetadata(this.docstore) ?? createSystemMetadata({
|
|
8949
|
+
nextUserTableNumber: Math.max(FIRST_USER_TABLE_NUMBER, nextUserTableNumber(this.tablesByNumber.values()))
|
|
8950
|
+
});
|
|
8951
|
+
const candidate = Math.max(metadata.nextUserTableNumber, nextUserTableNumber(this.tablesByNumber.values()));
|
|
8952
|
+
const reserved = await this.docstore.writeGlobalIfAbsent(createTableNumberReservationKey(candidate), {
|
|
8953
|
+
fullName,
|
|
8954
|
+
reservedAt: Date.now()
|
|
8955
|
+
});
|
|
8956
|
+
if (!reserved) {
|
|
8957
|
+
await this.reloadTables();
|
|
8958
|
+
const raced = this.tablesByName.get(fullName);
|
|
8959
|
+
if (raced) {
|
|
8960
|
+
return raced.tableNumber;
|
|
8961
|
+
}
|
|
8962
|
+
continue;
|
|
8963
|
+
}
|
|
8964
|
+
const createdAt = Date.now();
|
|
8965
|
+
const info = createTableInfo(tableName, candidate, normalizedComponent, { createdAt, visibility: "public" });
|
|
8966
|
+
const timestamp2 = oracle?.allocateTimestamp?.() ?? BigInt(createdAt);
|
|
8967
|
+
const entry = createTableMetadataEntryForUserTable(info, timestamp2);
|
|
8968
|
+
try {
|
|
8969
|
+
await this.docstore.write([entry], new Set, "Error");
|
|
8970
|
+
} catch {
|
|
8971
|
+
await this.reloadTables();
|
|
8972
|
+
const raced = this.tablesByName.get(fullName);
|
|
8973
|
+
if (raced) {
|
|
8974
|
+
return raced.tableNumber;
|
|
8975
|
+
}
|
|
8976
|
+
throw new Error(`Failed to allocate table number for ${fullName}`);
|
|
8977
|
+
}
|
|
8978
|
+
const registryVersion = Number(timestamp2 > BigInt(Number.MAX_SAFE_INTEGER) ? BigInt(Date.now()) : timestamp2);
|
|
8979
|
+
await this.docstore.writeGlobal(SYSTEM_METADATA_GLOBAL_KEY, createSystemMetadata({
|
|
8980
|
+
nextUserTableNumber: candidate + 1,
|
|
8981
|
+
registryVersion,
|
|
8982
|
+
bootstrappedAt: metadata.bootstrappedAt,
|
|
8983
|
+
updatedAt: registryVersion
|
|
8984
|
+
}));
|
|
8985
|
+
this.cachedRegistryVersion = registryVersion;
|
|
8986
|
+
this.tablesByName.set(fullName, info);
|
|
8987
|
+
this.tablesByNumber.set(candidate, info);
|
|
8988
|
+
return candidate;
|
|
8989
|
+
}
|
|
8990
|
+
}
|
|
8991
|
+
async getTableInfo(tableNumber) {
|
|
8992
|
+
await this.ensureLoaded();
|
|
8993
|
+
await this.ensureFresh();
|
|
8994
|
+
const existing = this.tablesByNumber.get(tableNumber);
|
|
8995
|
+
if (existing) {
|
|
8996
|
+
return existing;
|
|
8997
|
+
}
|
|
8998
|
+
await this.reloadTables();
|
|
8999
|
+
return this.tablesByNumber.get(tableNumber) ?? null;
|
|
9000
|
+
}
|
|
9001
|
+
async getTableInfoByName(tableName, componentPath = "") {
|
|
9002
|
+
await this.ensureLoaded();
|
|
9003
|
+
await this.ensureFresh();
|
|
9004
|
+
const fullName = getFullTableName(tableName, isSystemTable(tableName) ? "" : componentPath);
|
|
9005
|
+
const existing = this.tablesByName.get(fullName);
|
|
9006
|
+
if (existing) {
|
|
9007
|
+
return existing;
|
|
9008
|
+
}
|
|
9009
|
+
await this.reloadTables();
|
|
9010
|
+
return this.tablesByName.get(fullName) ?? null;
|
|
9011
|
+
}
|
|
9012
|
+
async listTables(componentPath) {
|
|
9013
|
+
await this.ensureLoaded();
|
|
9014
|
+
await this.ensureFresh();
|
|
9015
|
+
const values = Array.from(this.tablesByNumber.values());
|
|
9016
|
+
if (componentPath === undefined) {
|
|
9017
|
+
return values.sort((a, b) => a.tableNumber - b.tableNumber);
|
|
9018
|
+
}
|
|
9019
|
+
return values.filter((table) => table.componentPath === componentPath).sort((a, b) => a.tableNumber - b.tableNumber);
|
|
9020
|
+
}
|
|
9021
|
+
async hasAccess(tableNumber, componentPath) {
|
|
9022
|
+
const info = await this.getTableInfo(tableNumber);
|
|
9023
|
+
if (!info) {
|
|
9024
|
+
return false;
|
|
9025
|
+
}
|
|
9026
|
+
if (info.isSystem) {
|
|
9027
|
+
return true;
|
|
9028
|
+
}
|
|
9029
|
+
return info.componentPath === componentPath;
|
|
9030
|
+
}
|
|
9031
|
+
getSystemTableNumber(systemTableName) {
|
|
9032
|
+
return SYSTEM_TABLE_NUMBERS[systemTableName];
|
|
9033
|
+
}
|
|
9034
|
+
async ensureLoaded() {
|
|
9035
|
+
if (!this.loadPromise) {
|
|
9036
|
+
this.loadPromise = this.loadTables();
|
|
9037
|
+
}
|
|
9038
|
+
await this.loadPromise;
|
|
9039
|
+
}
|
|
9040
|
+
async ensureFresh() {
|
|
9041
|
+
const metadata = await readSystemMetadata(this.docstore);
|
|
9042
|
+
if (!metadata) {
|
|
9043
|
+
if (this.cachedRegistryVersion !== 0 || this.tablesByName.size > 0 || this.tablesByNumber.size > 0) {
|
|
9044
|
+
await this.reloadTables();
|
|
9045
|
+
}
|
|
9046
|
+
return;
|
|
9047
|
+
}
|
|
9048
|
+
if (metadata.registryVersion > this.cachedRegistryVersion) {
|
|
9049
|
+
await this.reloadTables();
|
|
9050
|
+
}
|
|
9051
|
+
}
|
|
9052
|
+
async reloadTables() {
|
|
9053
|
+
this.loadPromise = this.loadTables();
|
|
9054
|
+
await this.loadPromise;
|
|
9055
|
+
}
|
|
9056
|
+
async loadTables() {
|
|
9057
|
+
await ensureSystemTablesBootstrapped(this.docstore);
|
|
9058
|
+
const docs = await this.docstore.scan(stringToHex("_tables"));
|
|
9059
|
+
this.tablesByName.clear();
|
|
9060
|
+
this.tablesByNumber.clear();
|
|
9061
|
+
for (const doc of docs) {
|
|
9062
|
+
const info = tableInfoFromStoredDocument(doc.value.value);
|
|
9063
|
+
if (!info) {
|
|
9064
|
+
continue;
|
|
9065
|
+
}
|
|
9066
|
+
this.tablesByName.set(info.fullName, info);
|
|
9067
|
+
this.tablesByNumber.set(info.tableNumber, info);
|
|
9068
|
+
}
|
|
9069
|
+
if (this.tablesByNumber.size === 0) {
|
|
9070
|
+
for (const [name, tableNumber] of Object.entries(SYSTEM_TABLE_NUMBERS)) {
|
|
9071
|
+
const info = createTableInfo(name, tableNumber, "", { isSystem: true });
|
|
9072
|
+
this.tablesByName.set(info.fullName, info);
|
|
9073
|
+
this.tablesByNumber.set(info.tableNumber, info);
|
|
9074
|
+
}
|
|
9075
|
+
}
|
|
9076
|
+
const metadata = await readSystemMetadata(this.docstore);
|
|
9077
|
+
if (!metadata) {
|
|
9078
|
+
const now = Date.now();
|
|
9079
|
+
this.cachedRegistryVersion = now;
|
|
9080
|
+
await this.docstore.writeGlobal(SYSTEM_METADATA_GLOBAL_KEY, createSystemMetadata({
|
|
9081
|
+
nextUserTableNumber: Math.max(FIRST_USER_TABLE_NUMBER, nextUserTableNumber(this.tablesByNumber.values())),
|
|
9082
|
+
registryVersion: now,
|
|
9083
|
+
bootstrappedAt: now,
|
|
9084
|
+
updatedAt: now
|
|
9085
|
+
}));
|
|
9086
|
+
} else {
|
|
9087
|
+
this.cachedRegistryVersion = metadata.registryVersion;
|
|
9088
|
+
}
|
|
9089
|
+
}
|
|
9090
|
+
}
|
|
9091
|
+
|
|
9092
|
+
// ../core/dist/tables/transactional-table-registry.js
|
|
9093
|
+
init_system_tables();
|
|
9094
|
+
init_utils();
|
|
9095
|
+
init_interface();
|
|
8570
9096
|
// ../core/dist/kernel/contexts.js
|
|
8571
9097
|
init_context_storage();
|
|
8572
|
-
var
|
|
8573
|
-
var
|
|
8574
|
-
var
|
|
9098
|
+
var SNAPSHOT_CONTEXT_SYMBOL = Symbol.for("@concavejs/core/snapshot-context");
|
|
9099
|
+
var TRANSACTION_CONTEXT_SYMBOL = Symbol.for("@concavejs/core/transaction-context");
|
|
9100
|
+
var ID_GENERATOR_CONTEXT_SYMBOL = Symbol.for("@concavejs/core/id-generator-context");
|
|
9101
|
+
var globalContexts = globalThis;
|
|
9102
|
+
var snapshotContext = globalContexts[SNAPSHOT_CONTEXT_SYMBOL] ?? new ContextStorage;
|
|
9103
|
+
var transactionContext = globalContexts[TRANSACTION_CONTEXT_SYMBOL] ?? new ContextStorage;
|
|
9104
|
+
var idGeneratorContext = globalContexts[ID_GENERATOR_CONTEXT_SYMBOL] ?? new ContextStorage;
|
|
9105
|
+
if (!globalContexts[SNAPSHOT_CONTEXT_SYMBOL]) {
|
|
9106
|
+
globalContexts[SNAPSHOT_CONTEXT_SYMBOL] = snapshotContext;
|
|
9107
|
+
}
|
|
9108
|
+
if (!globalContexts[TRANSACTION_CONTEXT_SYMBOL]) {
|
|
9109
|
+
globalContexts[TRANSACTION_CONTEXT_SYMBOL] = transactionContext;
|
|
9110
|
+
}
|
|
9111
|
+
if (!globalContexts[ID_GENERATOR_CONTEXT_SYMBOL]) {
|
|
9112
|
+
globalContexts[ID_GENERATOR_CONTEXT_SYMBOL] = idGeneratorContext;
|
|
9113
|
+
}
|
|
8575
9114
|
// ../core/dist/queryengine/convex-ops.js
|
|
8576
9115
|
var debug = () => {};
|
|
8577
9116
|
class CfConvex {
|
|
@@ -8624,6 +9163,8 @@ class BaseSqliteDocStore {
|
|
|
8624
9163
|
vectorIndexesByTable = new Map;
|
|
8625
9164
|
fts5Available = true;
|
|
8626
9165
|
statementCache = new Map;
|
|
9166
|
+
configuredSearchIndexes = [];
|
|
9167
|
+
configuredVectorIndexes = [];
|
|
8627
9168
|
constructor(adapter) {
|
|
8628
9169
|
this.adapter = adapter;
|
|
8629
9170
|
this.timestampOracle = new TimestampOracle;
|
|
@@ -8638,6 +9179,8 @@ class BaseSqliteDocStore {
|
|
|
8638
9179
|
return statement;
|
|
8639
9180
|
}
|
|
8640
9181
|
async setupSchema(options) {
|
|
9182
|
+
this.configuredSearchIndexes = [...options?.searchIndexes ?? []];
|
|
9183
|
+
this.configuredVectorIndexes = [...options?.vectorIndexes ?? []];
|
|
8641
9184
|
await this.adapter.exec(DOCUMENTS_TABLE_SCHEMA);
|
|
8642
9185
|
await this.adapter.exec(DOCUMENTS_BY_TABLE_INDEX);
|
|
8643
9186
|
await this.adapter.exec(INDEXES_TABLE_SCHEMA);
|
|
@@ -8645,6 +9188,24 @@ class BaseSqliteDocStore {
|
|
|
8645
9188
|
await this.setupSearchIndexes(options?.searchIndexes ?? []);
|
|
8646
9189
|
await this.setupVectorIndexes(options?.vectorIndexes ?? []);
|
|
8647
9190
|
}
|
|
9191
|
+
async resetForTesting() {
|
|
9192
|
+
const rows = await this.adapter.prepare("SELECT name FROM sqlite_master WHERE type = 'table' AND name NOT LIKE 'sqlite_%' AND sql IS NOT NULL").all();
|
|
9193
|
+
for (const row of rows) {
|
|
9194
|
+
const tableName = row?.name;
|
|
9195
|
+
if (typeof tableName !== "string" || tableName.length === 0) {
|
|
9196
|
+
continue;
|
|
9197
|
+
}
|
|
9198
|
+
await this.adapter.exec(`DROP TABLE IF EXISTS ${quoteSqlIdentifier(tableName)}`);
|
|
9199
|
+
}
|
|
9200
|
+
this.statementCache.clear();
|
|
9201
|
+
this.searchIndexesByTable.clear();
|
|
9202
|
+
this.vectorIndexesByTable.clear();
|
|
9203
|
+
this.fts5Available = true;
|
|
9204
|
+
await this.setupSchema({
|
|
9205
|
+
searchIndexes: this.configuredSearchIndexes,
|
|
9206
|
+
vectorIndexes: this.configuredVectorIndexes
|
|
9207
|
+
});
|
|
9208
|
+
}
|
|
8648
9209
|
async setupSearchIndexes(searchIndexes) {
|
|
8649
9210
|
try {
|
|
8650
9211
|
await this.adapter.exec(SEARCH_INDEXES_FTS_SCHEMA);
|
|
@@ -8860,6 +9421,15 @@ class BaseSqliteDocStore {
|
|
|
8860
9421
|
const stmt = this.getPreparedStatement("INSERT OR REPLACE INTO persistence_globals (key, json_value) VALUES (?, ?)");
|
|
8861
9422
|
await stmt.run(key, JSON.stringify(value));
|
|
8862
9423
|
}
|
|
9424
|
+
async writeGlobalIfAbsent(key, value) {
|
|
9425
|
+
const insertStmt = this.getPreparedStatement("INSERT OR IGNORE INTO persistence_globals (key, json_value) VALUES (?, ?)");
|
|
9426
|
+
const changesStmt = this.getPreparedStatement("SELECT changes() as changes");
|
|
9427
|
+
return this.adapter.transaction(async () => {
|
|
9428
|
+
await insertStmt.run(key, JSON.stringify(value));
|
|
9429
|
+
const row = await changesStmt.get();
|
|
9430
|
+
return Number(row?.changes ?? 0) > 0;
|
|
9431
|
+
});
|
|
9432
|
+
}
|
|
8863
9433
|
async previous_revisions(queries) {
|
|
8864
9434
|
const results = new Map;
|
|
8865
9435
|
const stmt = this.getPreparedStatement(`
|
|
@@ -9155,6 +9725,9 @@ class BaseSqliteDocStore {
|
|
|
9155
9725
|
return scored.slice(0, limit);
|
|
9156
9726
|
}
|
|
9157
9727
|
}
|
|
9728
|
+
function quoteSqlIdentifier(value) {
|
|
9729
|
+
return `"${value.replace(/"/g, '""')}"`;
|
|
9730
|
+
}
|
|
9158
9731
|
// ../docstore-sqlite-base/dist/transaction-runner.js
|
|
9159
9732
|
function createSerializedTransactionRunner(hooks) {
|
|
9160
9733
|
let queue = Promise.resolve();
|