@raideno/convex-kv 0.1.0

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/server.js ADDED
@@ -0,0 +1,2421 @@
1
+ var lookup = [];
2
+ var revLookup = [];
3
+ var Arr = Uint8Array;
4
+ var code = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
5
+ for (var i = 0, len = code.length; i < len; ++i) {
6
+ lookup[i] = code[i];
7
+ revLookup[code.charCodeAt(i)] = i;
8
+ }
9
+ revLookup["-".charCodeAt(0)] = 62;
10
+ revLookup["_".charCodeAt(0)] = 63;
11
+ function getLens(b64) {
12
+ var len = b64.length;
13
+ if (len % 4 > 0) {
14
+ throw new Error("Invalid string. Length must be a multiple of 4");
15
+ }
16
+ var validLen = b64.indexOf("=");
17
+ if (validLen === -1) validLen = len;
18
+ var placeHoldersLen = validLen === len ? 0 : 4 - validLen % 4;
19
+ return [validLen, placeHoldersLen];
20
+ }
21
+ function _byteLength(_b64, validLen, placeHoldersLen) {
22
+ return (validLen + placeHoldersLen) * 3 / 4 - placeHoldersLen;
23
+ }
24
+ function toByteArray(b64) {
25
+ var tmp;
26
+ var lens = getLens(b64);
27
+ var validLen = lens[0];
28
+ var placeHoldersLen = lens[1];
29
+ var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen));
30
+ var curByte = 0;
31
+ var len = placeHoldersLen > 0 ? validLen - 4 : validLen;
32
+ var i;
33
+ for (i = 0; i < len; i += 4) {
34
+ tmp = revLookup[b64.charCodeAt(i)] << 18 | revLookup[b64.charCodeAt(i + 1)] << 12 | revLookup[b64.charCodeAt(i + 2)] << 6 | revLookup[b64.charCodeAt(i + 3)];
35
+ arr[curByte++] = tmp >> 16 & 255;
36
+ arr[curByte++] = tmp >> 8 & 255;
37
+ arr[curByte++] = tmp & 255;
38
+ }
39
+ if (placeHoldersLen === 2) {
40
+ tmp = revLookup[b64.charCodeAt(i)] << 2 | revLookup[b64.charCodeAt(i + 1)] >> 4;
41
+ arr[curByte++] = tmp & 255;
42
+ }
43
+ if (placeHoldersLen === 1) {
44
+ tmp = revLookup[b64.charCodeAt(i)] << 10 | revLookup[b64.charCodeAt(i + 1)] << 4 | revLookup[b64.charCodeAt(i + 2)] >> 2;
45
+ arr[curByte++] = tmp >> 8 & 255;
46
+ arr[curByte++] = tmp & 255;
47
+ }
48
+ return arr;
49
+ }
50
+ function tripletToBase64(num) {
51
+ return lookup[num >> 18 & 63] + lookup[num >> 12 & 63] + lookup[num >> 6 & 63] + lookup[num & 63];
52
+ }
53
+ function encodeChunk(uint8, start, end) {
54
+ var tmp;
55
+ var output = [];
56
+ for (var i = start; i < end; i += 3) {
57
+ tmp = (uint8[i] << 16 & 16711680) + (uint8[i + 1] << 8 & 65280) + (uint8[i + 2] & 255);
58
+ output.push(tripletToBase64(tmp));
59
+ }
60
+ return output.join("");
61
+ }
62
+ function fromByteArray(uint8) {
63
+ var tmp;
64
+ var len = uint8.length;
65
+ var extraBytes = len % 3;
66
+ var parts = [];
67
+ var maxChunkLength = 16383;
68
+ for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {
69
+ parts.push(
70
+ encodeChunk(
71
+ uint8,
72
+ i,
73
+ i + maxChunkLength > len2 ? len2 : i + maxChunkLength
74
+ )
75
+ );
76
+ }
77
+ if (extraBytes === 1) {
78
+ tmp = uint8[len - 1];
79
+ parts.push(lookup[tmp >> 2] + lookup[tmp << 4 & 63] + "==");
80
+ } else if (extraBytes === 2) {
81
+ tmp = (uint8[len - 2] << 8) + uint8[len - 1];
82
+ parts.push(
83
+ lookup[tmp >> 10] + lookup[tmp >> 4 & 63] + lookup[tmp << 2 & 63] + "="
84
+ );
85
+ }
86
+ return parts.join("");
87
+ }
88
+ function parseArgs(args) {
89
+ if (args === void 0) {
90
+ return {};
91
+ }
92
+ if (!isSimpleObject(args)) {
93
+ throw new Error(
94
+ `The arguments to a Convex function must be an object. Received: ${args}`
95
+ );
96
+ }
97
+ return args;
98
+ }
99
+ function isSimpleObject(value) {
100
+ const isObject = typeof value === "object";
101
+ const prototype = Object.getPrototypeOf(value);
102
+ const isSimple = prototype === null || prototype === Object.prototype || // Objects generated from other contexts (e.g. across Node.js `vm` modules) will not satisfy the previous
103
+ // conditions but are still simple objects.
104
+ prototype?.constructor?.name === "Object";
105
+ return isObject && isSimple;
106
+ }
107
+ const LITTLE_ENDIAN = true;
108
+ const MIN_INT64 = BigInt("-9223372036854775808");
109
+ const MAX_INT64 = BigInt("9223372036854775807");
110
+ const ZERO = BigInt("0");
111
+ const EIGHT = BigInt("8");
112
+ const TWOFIFTYSIX = BigInt("256");
113
+ function isSpecial(n) {
114
+ return Number.isNaN(n) || !Number.isFinite(n) || Object.is(n, -0);
115
+ }
116
+ function slowBigIntToBase64(value) {
117
+ if (value < ZERO) {
118
+ value -= MIN_INT64 + MIN_INT64;
119
+ }
120
+ let hex = value.toString(16);
121
+ if (hex.length % 2 === 1) hex = "0" + hex;
122
+ const bytes = new Uint8Array(new ArrayBuffer(8));
123
+ let i = 0;
124
+ for (const hexByte of hex.match(/.{2}/g).reverse()) {
125
+ bytes.set([parseInt(hexByte, 16)], i++);
126
+ value >>= EIGHT;
127
+ }
128
+ return fromByteArray(bytes);
129
+ }
130
+ function slowBase64ToBigInt(encoded) {
131
+ const integerBytes = toByteArray(encoded);
132
+ if (integerBytes.byteLength !== 8) {
133
+ throw new Error(
134
+ `Received ${integerBytes.byteLength} bytes, expected 8 for $integer`
135
+ );
136
+ }
137
+ let value = ZERO;
138
+ let power = ZERO;
139
+ for (const byte of integerBytes) {
140
+ value += BigInt(byte) * TWOFIFTYSIX ** power;
141
+ power++;
142
+ }
143
+ if (value > MAX_INT64) {
144
+ value += MIN_INT64 + MIN_INT64;
145
+ }
146
+ return value;
147
+ }
148
+ function modernBigIntToBase64(value) {
149
+ if (value < MIN_INT64 || MAX_INT64 < value) {
150
+ throw new Error(
151
+ `BigInt ${value} does not fit into a 64-bit signed integer.`
152
+ );
153
+ }
154
+ const buffer = new ArrayBuffer(8);
155
+ new DataView(buffer).setBigInt64(0, value, true);
156
+ return fromByteArray(new Uint8Array(buffer));
157
+ }
158
+ function modernBase64ToBigInt(encoded) {
159
+ const integerBytes = toByteArray(encoded);
160
+ if (integerBytes.byteLength !== 8) {
161
+ throw new Error(
162
+ `Received ${integerBytes.byteLength} bytes, expected 8 for $integer`
163
+ );
164
+ }
165
+ const intBytesView = new DataView(integerBytes.buffer);
166
+ return intBytesView.getBigInt64(0, true);
167
+ }
168
+ const bigIntToBase64 = DataView.prototype.setBigInt64 ? modernBigIntToBase64 : slowBigIntToBase64;
169
+ const base64ToBigInt = DataView.prototype.getBigInt64 ? modernBase64ToBigInt : slowBase64ToBigInt;
170
+ const MAX_IDENTIFIER_LEN = 1024;
171
+ function validateObjectField(k) {
172
+ if (k.length > MAX_IDENTIFIER_LEN) {
173
+ throw new Error(
174
+ `Field name ${k} exceeds maximum field name length ${MAX_IDENTIFIER_LEN}.`
175
+ );
176
+ }
177
+ if (k.startsWith("$")) {
178
+ throw new Error(`Field name ${k} starts with a '$', which is reserved.`);
179
+ }
180
+ for (let i = 0; i < k.length; i += 1) {
181
+ const charCode = k.charCodeAt(i);
182
+ if (charCode < 32 || charCode >= 127) {
183
+ throw new Error(
184
+ `Field name ${k} has invalid character '${k[i]}': Field names can only contain non-control ASCII characters`
185
+ );
186
+ }
187
+ }
188
+ }
189
+ function jsonToConvex(value) {
190
+ if (value === null) {
191
+ return value;
192
+ }
193
+ if (typeof value === "boolean") {
194
+ return value;
195
+ }
196
+ if (typeof value === "number") {
197
+ return value;
198
+ }
199
+ if (typeof value === "string") {
200
+ return value;
201
+ }
202
+ if (Array.isArray(value)) {
203
+ return value.map((value2) => jsonToConvex(value2));
204
+ }
205
+ if (typeof value !== "object") {
206
+ throw new Error(`Unexpected type of ${value}`);
207
+ }
208
+ const entries = Object.entries(value);
209
+ if (entries.length === 1) {
210
+ const key = entries[0][0];
211
+ if (key === "$bytes") {
212
+ if (typeof value.$bytes !== "string") {
213
+ throw new Error(`Malformed $bytes field on ${value}`);
214
+ }
215
+ return toByteArray(value.$bytes).buffer;
216
+ }
217
+ if (key === "$integer") {
218
+ if (typeof value.$integer !== "string") {
219
+ throw new Error(`Malformed $integer field on ${value}`);
220
+ }
221
+ return base64ToBigInt(value.$integer);
222
+ }
223
+ if (key === "$float") {
224
+ if (typeof value.$float !== "string") {
225
+ throw new Error(`Malformed $float field on ${value}`);
226
+ }
227
+ const floatBytes = toByteArray(value.$float);
228
+ if (floatBytes.byteLength !== 8) {
229
+ throw new Error(
230
+ `Received ${floatBytes.byteLength} bytes, expected 8 for $float`
231
+ );
232
+ }
233
+ const floatBytesView = new DataView(floatBytes.buffer);
234
+ const float = floatBytesView.getFloat64(0, LITTLE_ENDIAN);
235
+ if (!isSpecial(float)) {
236
+ throw new Error(`Float ${float} should be encoded as a number`);
237
+ }
238
+ return float;
239
+ }
240
+ if (key === "$set") {
241
+ throw new Error(
242
+ `Received a Set which is no longer supported as a Convex type.`
243
+ );
244
+ }
245
+ if (key === "$map") {
246
+ throw new Error(
247
+ `Received a Map which is no longer supported as a Convex type.`
248
+ );
249
+ }
250
+ }
251
+ const out = {};
252
+ for (const [k, v2] of Object.entries(value)) {
253
+ validateObjectField(k);
254
+ out[k] = jsonToConvex(v2);
255
+ }
256
+ return out;
257
+ }
258
+ const MAX_VALUE_FOR_ERROR_LEN = 16384;
259
+ function stringifyValueForError(value) {
260
+ const str = JSON.stringify(value, (_key, value2) => {
261
+ if (value2 === void 0) {
262
+ return "undefined";
263
+ }
264
+ if (typeof value2 === "bigint") {
265
+ return `${value2.toString()}n`;
266
+ }
267
+ return value2;
268
+ });
269
+ if (str.length > MAX_VALUE_FOR_ERROR_LEN) {
270
+ const rest = "[...truncated]";
271
+ let truncateAt = MAX_VALUE_FOR_ERROR_LEN - rest.length;
272
+ const codePoint = str.codePointAt(truncateAt - 1);
273
+ if (codePoint !== void 0 && codePoint > 65535) {
274
+ truncateAt -= 1;
275
+ }
276
+ return str.substring(0, truncateAt) + rest;
277
+ }
278
+ return str;
279
+ }
280
+ function convexToJsonInternal(value, originalValue, context, includeTopLevelUndefined) {
281
+ if (value === void 0) {
282
+ const contextText = context && ` (present at path ${context} in original object ${stringifyValueForError(
283
+ originalValue
284
+ )})`;
285
+ throw new Error(
286
+ `undefined is not a valid Convex value${contextText}. To learn about Convex's supported types, see https://docs.convex.dev/using/types.`
287
+ );
288
+ }
289
+ if (value === null) {
290
+ return value;
291
+ }
292
+ if (typeof value === "bigint") {
293
+ if (value < MIN_INT64 || MAX_INT64 < value) {
294
+ throw new Error(
295
+ `BigInt ${value} does not fit into a 64-bit signed integer.`
296
+ );
297
+ }
298
+ return { $integer: bigIntToBase64(value) };
299
+ }
300
+ if (typeof value === "number") {
301
+ if (isSpecial(value)) {
302
+ const buffer = new ArrayBuffer(8);
303
+ new DataView(buffer).setFloat64(0, value, LITTLE_ENDIAN);
304
+ return { $float: fromByteArray(new Uint8Array(buffer)) };
305
+ } else {
306
+ return value;
307
+ }
308
+ }
309
+ if (typeof value === "boolean") {
310
+ return value;
311
+ }
312
+ if (typeof value === "string") {
313
+ return value;
314
+ }
315
+ if (value instanceof ArrayBuffer) {
316
+ return { $bytes: fromByteArray(new Uint8Array(value)) };
317
+ }
318
+ if (Array.isArray(value)) {
319
+ return value.map(
320
+ (value2, i) => convexToJsonInternal(value2, originalValue, context + `[${i}]`, false)
321
+ );
322
+ }
323
+ if (value instanceof Set) {
324
+ throw new Error(
325
+ errorMessageForUnsupportedType(context, "Set", [...value], originalValue)
326
+ );
327
+ }
328
+ if (value instanceof Map) {
329
+ throw new Error(
330
+ errorMessageForUnsupportedType(context, "Map", [...value], originalValue)
331
+ );
332
+ }
333
+ if (!isSimpleObject(value)) {
334
+ const theType = value?.constructor?.name;
335
+ const typeName = theType ? `${theType} ` : "";
336
+ throw new Error(
337
+ errorMessageForUnsupportedType(context, typeName, value, originalValue)
338
+ );
339
+ }
340
+ const out = {};
341
+ const entries = Object.entries(value);
342
+ entries.sort(([k1, _v1], [k2, _v2]) => k1 === k2 ? 0 : k1 < k2 ? -1 : 1);
343
+ for (const [k, v2] of entries) {
344
+ if (v2 !== void 0) {
345
+ validateObjectField(k);
346
+ out[k] = convexToJsonInternal(v2, originalValue, context + `.${k}`, false);
347
+ } else if (includeTopLevelUndefined) {
348
+ validateObjectField(k);
349
+ out[k] = convexOrUndefinedToJsonInternal(
350
+ v2,
351
+ originalValue,
352
+ context + `.${k}`
353
+ );
354
+ }
355
+ }
356
+ return out;
357
+ }
358
+ function errorMessageForUnsupportedType(context, typeName, value, originalValue) {
359
+ if (context) {
360
+ return `${typeName}${stringifyValueForError(
361
+ value
362
+ )} is not a supported Convex type (present at path ${context} in original object ${stringifyValueForError(
363
+ originalValue
364
+ )}). To learn about Convex's supported types, see https://docs.convex.dev/using/types.`;
365
+ } else {
366
+ return `${typeName}${stringifyValueForError(
367
+ value
368
+ )} is not a supported Convex type.`;
369
+ }
370
+ }
371
+ function convexOrUndefinedToJsonInternal(value, originalValue, context) {
372
+ if (value === void 0) {
373
+ return { $undefined: null };
374
+ } else {
375
+ if (originalValue === void 0) {
376
+ throw new Error(
377
+ `Programming error. Current value is ${stringifyValueForError(
378
+ value
379
+ )} but original value is undefined`
380
+ );
381
+ }
382
+ return convexToJsonInternal(value, originalValue, context, false);
383
+ }
384
+ }
385
+ function convexToJson(value) {
386
+ return convexToJsonInternal(value, value, "", false);
387
+ }
388
+ function convexOrUndefinedToJson(value) {
389
+ return convexOrUndefinedToJsonInternal(value, value, "");
390
+ }
391
+ function patchValueToJson(value) {
392
+ return convexToJsonInternal(value, value, "", true);
393
+ }
394
+ var __defProp$9 = Object.defineProperty;
395
+ var __defNormalProp$9 = (obj, key, value) => key in obj ? __defProp$9(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
396
+ var __publicField$9 = (obj, key, value) => __defNormalProp$9(obj, typeof key !== "symbol" ? key + "" : key, value);
397
+ class BaseValidator {
398
+ constructor({ isOptional }) {
399
+ __publicField$9(this, "type");
400
+ __publicField$9(this, "fieldPaths");
401
+ __publicField$9(this, "isOptional");
402
+ __publicField$9(this, "isConvexValidator");
403
+ this.isOptional = isOptional;
404
+ this.isConvexValidator = true;
405
+ }
406
+ }
407
+ class VId extends BaseValidator {
408
+ /**
409
+ * Usually you'd use `v.id(tableName)` instead.
410
+ */
411
+ constructor({
412
+ isOptional,
413
+ tableName
414
+ }) {
415
+ super({ isOptional });
416
+ __publicField$9(this, "tableName");
417
+ __publicField$9(this, "kind", "id");
418
+ if (typeof tableName !== "string") {
419
+ throw new Error("v.id(tableName) requires a string");
420
+ }
421
+ this.tableName = tableName;
422
+ }
423
+ /** @internal */
424
+ get json() {
425
+ return { type: "id", tableName: this.tableName };
426
+ }
427
+ /** @internal */
428
+ asOptional() {
429
+ return new VId({
430
+ isOptional: "optional",
431
+ tableName: this.tableName
432
+ });
433
+ }
434
+ }
435
+ class VFloat64 extends BaseValidator {
436
+ constructor() {
437
+ super(...arguments);
438
+ __publicField$9(this, "kind", "float64");
439
+ }
440
+ /** @internal */
441
+ get json() {
442
+ return { type: "number" };
443
+ }
444
+ /** @internal */
445
+ asOptional() {
446
+ return new VFloat64({
447
+ isOptional: "optional"
448
+ });
449
+ }
450
+ }
451
+ class VInt64 extends BaseValidator {
452
+ constructor() {
453
+ super(...arguments);
454
+ __publicField$9(this, "kind", "int64");
455
+ }
456
+ /** @internal */
457
+ get json() {
458
+ return { type: "bigint" };
459
+ }
460
+ /** @internal */
461
+ asOptional() {
462
+ return new VInt64({ isOptional: "optional" });
463
+ }
464
+ }
465
+ class VBoolean extends BaseValidator {
466
+ constructor() {
467
+ super(...arguments);
468
+ __publicField$9(this, "kind", "boolean");
469
+ }
470
+ /** @internal */
471
+ get json() {
472
+ return { type: this.kind };
473
+ }
474
+ /** @internal */
475
+ asOptional() {
476
+ return new VBoolean({
477
+ isOptional: "optional"
478
+ });
479
+ }
480
+ }
481
+ class VBytes extends BaseValidator {
482
+ constructor() {
483
+ super(...arguments);
484
+ __publicField$9(this, "kind", "bytes");
485
+ }
486
+ /** @internal */
487
+ get json() {
488
+ return { type: this.kind };
489
+ }
490
+ /** @internal */
491
+ asOptional() {
492
+ return new VBytes({ isOptional: "optional" });
493
+ }
494
+ }
495
+ class VString extends BaseValidator {
496
+ constructor() {
497
+ super(...arguments);
498
+ __publicField$9(this, "kind", "string");
499
+ }
500
+ /** @internal */
501
+ get json() {
502
+ return { type: this.kind };
503
+ }
504
+ /** @internal */
505
+ asOptional() {
506
+ return new VString({
507
+ isOptional: "optional"
508
+ });
509
+ }
510
+ }
511
+ class VNull extends BaseValidator {
512
+ constructor() {
513
+ super(...arguments);
514
+ __publicField$9(this, "kind", "null");
515
+ }
516
+ /** @internal */
517
+ get json() {
518
+ return { type: this.kind };
519
+ }
520
+ /** @internal */
521
+ asOptional() {
522
+ return new VNull({ isOptional: "optional" });
523
+ }
524
+ }
525
+ class VAny extends BaseValidator {
526
+ constructor() {
527
+ super(...arguments);
528
+ __publicField$9(this, "kind", "any");
529
+ }
530
+ /** @internal */
531
+ get json() {
532
+ return {
533
+ type: this.kind
534
+ };
535
+ }
536
+ /** @internal */
537
+ asOptional() {
538
+ return new VAny({
539
+ isOptional: "optional"
540
+ });
541
+ }
542
+ }
543
+ class VObject extends BaseValidator {
544
+ /**
545
+ * Usually you'd use `v.object({ ... })` instead.
546
+ */
547
+ constructor({
548
+ isOptional,
549
+ fields
550
+ }) {
551
+ super({ isOptional });
552
+ __publicField$9(this, "fields");
553
+ __publicField$9(this, "kind", "object");
554
+ globalThis.Object.values(fields).forEach((v2) => {
555
+ if (!v2.isConvexValidator) {
556
+ throw new Error("v.object() entries must be validators");
557
+ }
558
+ });
559
+ this.fields = fields;
560
+ }
561
+ /** @internal */
562
+ get json() {
563
+ return {
564
+ type: this.kind,
565
+ value: globalThis.Object.fromEntries(
566
+ globalThis.Object.entries(this.fields).map(([k, v2]) => [
567
+ k,
568
+ {
569
+ fieldType: v2.json,
570
+ optional: v2.isOptional === "optional" ? true : false
571
+ }
572
+ ])
573
+ )
574
+ };
575
+ }
576
+ /** @internal */
577
+ asOptional() {
578
+ return new VObject({
579
+ isOptional: "optional",
580
+ fields: this.fields
581
+ });
582
+ }
583
+ /**
584
+ * Create a new VObject with the specified fields omitted.
585
+ * @param fields The field names to omit from this VObject.
586
+ */
587
+ omit(...fields) {
588
+ const newFields = { ...this.fields };
589
+ for (const field of fields) {
590
+ delete newFields[field];
591
+ }
592
+ return new VObject({
593
+ isOptional: this.isOptional,
594
+ fields: newFields
595
+ });
596
+ }
597
+ /**
598
+ * Create a new VObject with only the specified fields.
599
+ * @param fields The field names to pick from this VObject.
600
+ */
601
+ pick(...fields) {
602
+ const newFields = {};
603
+ for (const field of fields) {
604
+ newFields[field] = this.fields[field];
605
+ }
606
+ return new VObject({
607
+ isOptional: this.isOptional,
608
+ fields: newFields
609
+ });
610
+ }
611
+ /**
612
+ * Create a new VObject with all fields marked as optional.
613
+ */
614
+ partial() {
615
+ const newFields = {};
616
+ for (const [key, validator] of globalThis.Object.entries(this.fields)) {
617
+ newFields[key] = validator.asOptional();
618
+ }
619
+ return new VObject({
620
+ isOptional: this.isOptional,
621
+ fields: newFields
622
+ });
623
+ }
624
+ /**
625
+ * Create a new VObject with additional fields merged in.
626
+ * @param fields An object with additional validators to merge into this VObject.
627
+ */
628
+ extend(fields) {
629
+ return new VObject({
630
+ isOptional: this.isOptional,
631
+ fields: { ...this.fields, ...fields }
632
+ });
633
+ }
634
+ }
635
+ class VLiteral extends BaseValidator {
636
+ /**
637
+ * Usually you'd use `v.literal(value)` instead.
638
+ */
639
+ constructor({ isOptional, value }) {
640
+ super({ isOptional });
641
+ __publicField$9(this, "value");
642
+ __publicField$9(this, "kind", "literal");
643
+ if (typeof value !== "string" && typeof value !== "boolean" && typeof value !== "number" && typeof value !== "bigint") {
644
+ throw new Error("v.literal(value) must be a string, number, or boolean");
645
+ }
646
+ this.value = value;
647
+ }
648
+ /** @internal */
649
+ get json() {
650
+ return {
651
+ type: this.kind,
652
+ value: convexToJson(this.value)
653
+ };
654
+ }
655
+ /** @internal */
656
+ asOptional() {
657
+ return new VLiteral({
658
+ isOptional: "optional",
659
+ value: this.value
660
+ });
661
+ }
662
+ }
663
+ class VArray extends BaseValidator {
664
+ /**
665
+ * Usually you'd use `v.array(element)` instead.
666
+ */
667
+ constructor({
668
+ isOptional,
669
+ element
670
+ }) {
671
+ super({ isOptional });
672
+ __publicField$9(this, "element");
673
+ __publicField$9(this, "kind", "array");
674
+ this.element = element;
675
+ }
676
+ /** @internal */
677
+ get json() {
678
+ return {
679
+ type: this.kind,
680
+ value: this.element.json
681
+ };
682
+ }
683
+ /** @internal */
684
+ asOptional() {
685
+ return new VArray({
686
+ isOptional: "optional",
687
+ element: this.element
688
+ });
689
+ }
690
+ }
691
+ class VRecord extends BaseValidator {
692
+ /**
693
+ * Usually you'd use `v.record(key, value)` instead.
694
+ */
695
+ constructor({
696
+ isOptional,
697
+ key,
698
+ value
699
+ }) {
700
+ super({ isOptional });
701
+ __publicField$9(this, "key");
702
+ __publicField$9(this, "value");
703
+ __publicField$9(this, "kind", "record");
704
+ if (key.isOptional === "optional") {
705
+ throw new Error("Record validator cannot have optional keys");
706
+ }
707
+ if (value.isOptional === "optional") {
708
+ throw new Error("Record validator cannot have optional values");
709
+ }
710
+ if (!key.isConvexValidator || !value.isConvexValidator) {
711
+ throw new Error("Key and value of v.record() but be validators");
712
+ }
713
+ this.key = key;
714
+ this.value = value;
715
+ }
716
+ /** @internal */
717
+ get json() {
718
+ return {
719
+ type: this.kind,
720
+ // This cast is needed because TypeScript thinks the key type is too wide
721
+ keys: this.key.json,
722
+ values: {
723
+ fieldType: this.value.json,
724
+ optional: false
725
+ }
726
+ };
727
+ }
728
+ /** @internal */
729
+ asOptional() {
730
+ return new VRecord({
731
+ isOptional: "optional",
732
+ key: this.key,
733
+ value: this.value
734
+ });
735
+ }
736
+ }
737
+ class VUnion extends BaseValidator {
738
+ /**
739
+ * Usually you'd use `v.union(...members)` instead.
740
+ */
741
+ constructor({ isOptional, members }) {
742
+ super({ isOptional });
743
+ __publicField$9(this, "members");
744
+ __publicField$9(this, "kind", "union");
745
+ members.forEach((member) => {
746
+ if (!member.isConvexValidator) {
747
+ throw new Error("All members of v.union() must be validators");
748
+ }
749
+ });
750
+ this.members = members;
751
+ }
752
+ /** @internal */
753
+ get json() {
754
+ return {
755
+ type: this.kind,
756
+ value: this.members.map((v2) => v2.json)
757
+ };
758
+ }
759
+ /** @internal */
760
+ asOptional() {
761
+ return new VUnion({
762
+ isOptional: "optional",
763
+ members: this.members
764
+ });
765
+ }
766
+ }
767
+ function isValidator(v2) {
768
+ return !!v2.isConvexValidator;
769
+ }
770
+ function asObjectValidator(obj) {
771
+ if (isValidator(obj)) {
772
+ return obj;
773
+ } else {
774
+ return v.object(obj);
775
+ }
776
+ }
777
+ const v = {
778
+ /**
779
+ * Validates that the value corresponds to an ID of a document in given table.
780
+ * @param tableName The name of the table.
781
+ */
782
+ id: (tableName) => {
783
+ return new VId({
784
+ isOptional: "required",
785
+ tableName
786
+ });
787
+ },
788
+ /**
789
+ * Validates that the value is of type Null.
790
+ */
791
+ null: () => {
792
+ return new VNull({ isOptional: "required" });
793
+ },
794
+ /**
795
+ * Validates that the value is of Convex type Float64 (Number in JS).
796
+ *
797
+ * Alias for `v.float64()`
798
+ */
799
+ number: () => {
800
+ return new VFloat64({ isOptional: "required" });
801
+ },
802
+ /**
803
+ * Validates that the value is of Convex type Float64 (Number in JS).
804
+ */
805
+ float64: () => {
806
+ return new VFloat64({ isOptional: "required" });
807
+ },
808
+ /**
809
+ * @deprecated Use `v.int64()` instead
810
+ */
811
+ bigint: () => {
812
+ return new VInt64({ isOptional: "required" });
813
+ },
814
+ /**
815
+ * Validates that the value is of Convex type Int64 (BigInt in JS).
816
+ */
817
+ int64: () => {
818
+ return new VInt64({ isOptional: "required" });
819
+ },
820
+ /**
821
+ * Validates that the value is of type Boolean.
822
+ */
823
+ boolean: () => {
824
+ return new VBoolean({ isOptional: "required" });
825
+ },
826
+ /**
827
+ * Validates that the value is of type String.
828
+ */
829
+ string: () => {
830
+ return new VString({ isOptional: "required" });
831
+ },
832
+ /**
833
+ * Validates that the value is of Convex type Bytes (constructed in JS via `ArrayBuffer`).
834
+ */
835
+ bytes: () => {
836
+ return new VBytes({ isOptional: "required" });
837
+ },
838
+ /**
839
+ * Validates that the value is equal to the given literal value.
840
+ * @param literal The literal value to compare against.
841
+ */
842
+ literal: (literal) => {
843
+ return new VLiteral({ isOptional: "required", value: literal });
844
+ },
845
+ /**
846
+ * Validates that the value is an Array of the given element type.
847
+ * @param element The validator for the elements of the array.
848
+ */
849
+ array: (element) => {
850
+ return new VArray({ isOptional: "required", element });
851
+ },
852
+ /**
853
+ * Validates that the value is an Object with the given properties.
854
+ * @param fields An object specifying the validator for each property.
855
+ */
856
+ object: (fields) => {
857
+ return new VObject({ isOptional: "required", fields });
858
+ },
859
+ /**
860
+ * Validates that the value is a Record with keys and values that match the given types.
861
+ * @param keys The validator for the keys of the record. This cannot contain string literals.
862
+ * @param values The validator for the values of the record.
863
+ */
864
+ record: (keys, values) => {
865
+ return new VRecord({
866
+ isOptional: "required",
867
+ key: keys,
868
+ value: values
869
+ });
870
+ },
871
+ /**
872
+ * Validates that the value matches one of the given validators.
873
+ * @param members The validators to match against.
874
+ */
875
+ union: (...members) => {
876
+ return new VUnion({
877
+ isOptional: "required",
878
+ members
879
+ });
880
+ },
881
+ /**
882
+ * Does not validate the value.
883
+ */
884
+ any: () => {
885
+ return new VAny({ isOptional: "required" });
886
+ },
887
+ /**
888
+ * Allows not specifying a value for a property in an Object.
889
+ * @param value The property value validator to make optional.
890
+ *
891
+ * ```typescript
892
+ * const objectWithOptionalFields = v.object({
893
+ * requiredField: v.string(),
894
+ * optionalField: v.optional(v.string()),
895
+ * });
896
+ * ```
897
+ */
898
+ optional: (value) => {
899
+ return value.asOptional();
900
+ },
901
+ /**
902
+ * Allows specifying a value or null.
903
+ */
904
+ nullable: (value) => {
905
+ return v.union(value, v.null());
906
+ }
907
+ };
908
+ var __defProp$8 = Object.defineProperty;
909
+ var __defNormalProp$8 = (obj, key, value) => key in obj ? __defProp$8(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
910
+ var __publicField$8 = (obj, key, value) => __defNormalProp$8(obj, typeof key !== "symbol" ? key + "" : key, value);
911
+ var _a, _b;
912
+ const IDENTIFYING_FIELD = Symbol.for("ConvexError");
913
+ class ConvexError extends (_b = Error, _a = IDENTIFYING_FIELD, _b) {
914
+ constructor(data) {
915
+ super(typeof data === "string" ? data : stringifyValueForError(data));
916
+ __publicField$8(this, "name", "ConvexError");
917
+ __publicField$8(this, "data");
918
+ __publicField$8(this, _a, true);
919
+ this.data = data;
920
+ }
921
+ }
922
+ const version = "1.29.3";
923
+ function performSyscall(op, arg) {
924
+ if (typeof Convex === "undefined" || Convex.syscall === void 0) {
925
+ throw new Error(
926
+ "The Convex database and auth objects are being used outside of a Convex backend. Did you mean to use `useQuery` or `useMutation` to call a Convex function?"
927
+ );
928
+ }
929
+ const resultStr = Convex.syscall(op, JSON.stringify(arg));
930
+ return JSON.parse(resultStr);
931
+ }
932
+ async function performAsyncSyscall(op, arg) {
933
+ if (typeof Convex === "undefined" || Convex.asyncSyscall === void 0) {
934
+ throw new Error(
935
+ "The Convex database and auth objects are being used outside of a Convex backend. Did you mean to use `useQuery` or `useMutation` to call a Convex function?"
936
+ );
937
+ }
938
+ let resultStr;
939
+ try {
940
+ resultStr = await Convex.asyncSyscall(op, JSON.stringify(arg));
941
+ } catch (e) {
942
+ if (e.data !== void 0) {
943
+ const rethrown = new ConvexError(e.message);
944
+ rethrown.data = jsonToConvex(e.data);
945
+ throw rethrown;
946
+ }
947
+ throw new Error(e.message);
948
+ }
949
+ return JSON.parse(resultStr);
950
+ }
951
+ const functionName = Symbol.for("functionName");
952
+ const toReferencePath = Symbol.for("toReferencePath");
953
+ function extractReferencePath(reference) {
954
+ return reference[toReferencePath] ?? null;
955
+ }
956
+ function isFunctionHandle(s) {
957
+ return s.startsWith("function://");
958
+ }
959
+ function getFunctionAddress(functionReference) {
960
+ let functionAddress;
961
+ if (typeof functionReference === "string") {
962
+ if (isFunctionHandle(functionReference)) {
963
+ functionAddress = { functionHandle: functionReference };
964
+ } else {
965
+ functionAddress = { name: functionReference };
966
+ }
967
+ } else if (functionReference[functionName]) {
968
+ functionAddress = { name: functionReference[functionName] };
969
+ } else {
970
+ const referencePath = extractReferencePath(functionReference);
971
+ if (!referencePath) {
972
+ throw new Error(`${functionReference} is not a functionReference`);
973
+ }
974
+ functionAddress = { reference: referencePath };
975
+ }
976
+ return functionAddress;
977
+ }
978
+ function validateArg(arg, idx, method, argName) {
979
+ if (arg === void 0) {
980
+ throw new TypeError(
981
+ `Must provide arg ${idx} \`${argName}\` to \`${method}\``
982
+ );
983
+ }
984
+ }
985
+ function validateArgIsNonNegativeInteger(arg, idx, method, argName) {
986
+ if (!Number.isInteger(arg) || arg < 0) {
987
+ throw new TypeError(
988
+ `Arg ${idx} \`${argName}\` to \`${method}\` must be a non-negative integer`
989
+ );
990
+ }
991
+ }
992
+ function setupAuth(requestId) {
993
+ return {
994
+ getUserIdentity: async () => {
995
+ return await performAsyncSyscall("1.0/getUserIdentity", {
996
+ requestId
997
+ });
998
+ }
999
+ };
1000
+ }
1001
+ var __defProp$7 = Object.defineProperty;
1002
+ var __defNormalProp$7 = (obj, key, value) => key in obj ? __defProp$7(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
1003
+ var __publicField$7 = (obj, key, value) => __defNormalProp$7(obj, typeof key !== "symbol" ? key + "" : key, value);
1004
+ class Expression {
1005
+ /**
1006
+ * @internal
1007
+ */
1008
+ constructor() {
1009
+ __publicField$7(this, "_isExpression");
1010
+ __publicField$7(this, "_value");
1011
+ }
1012
+ }
1013
+ var __defProp$6 = Object.defineProperty;
1014
+ var __defNormalProp$6 = (obj, key, value) => key in obj ? __defProp$6(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
1015
+ var __publicField$6 = (obj, key, value) => __defNormalProp$6(obj, key + "", value);
1016
+ class ExpressionImpl extends Expression {
1017
+ constructor(inner) {
1018
+ super();
1019
+ __publicField$6(this, "inner");
1020
+ this.inner = inner;
1021
+ }
1022
+ serialize() {
1023
+ return this.inner;
1024
+ }
1025
+ }
1026
+ function serializeExpression(expr) {
1027
+ if (expr instanceof ExpressionImpl) {
1028
+ return expr.serialize();
1029
+ } else {
1030
+ return { $literal: convexOrUndefinedToJson(expr) };
1031
+ }
1032
+ }
1033
+ const filterBuilderImpl = {
1034
+ // Comparisons /////////////////////////////////////////////////////////////
1035
+ eq(l, r) {
1036
+ return new ExpressionImpl({
1037
+ $eq: [serializeExpression(l), serializeExpression(r)]
1038
+ });
1039
+ },
1040
+ neq(l, r) {
1041
+ return new ExpressionImpl({
1042
+ $neq: [serializeExpression(l), serializeExpression(r)]
1043
+ });
1044
+ },
1045
+ lt(l, r) {
1046
+ return new ExpressionImpl({
1047
+ $lt: [serializeExpression(l), serializeExpression(r)]
1048
+ });
1049
+ },
1050
+ lte(l, r) {
1051
+ return new ExpressionImpl({
1052
+ $lte: [serializeExpression(l), serializeExpression(r)]
1053
+ });
1054
+ },
1055
+ gt(l, r) {
1056
+ return new ExpressionImpl({
1057
+ $gt: [serializeExpression(l), serializeExpression(r)]
1058
+ });
1059
+ },
1060
+ gte(l, r) {
1061
+ return new ExpressionImpl({
1062
+ $gte: [serializeExpression(l), serializeExpression(r)]
1063
+ });
1064
+ },
1065
+ // Arithmetic //////////////////////////////////////////////////////////////
1066
+ add(l, r) {
1067
+ return new ExpressionImpl({
1068
+ $add: [serializeExpression(l), serializeExpression(r)]
1069
+ });
1070
+ },
1071
+ sub(l, r) {
1072
+ return new ExpressionImpl({
1073
+ $sub: [serializeExpression(l), serializeExpression(r)]
1074
+ });
1075
+ },
1076
+ mul(l, r) {
1077
+ return new ExpressionImpl({
1078
+ $mul: [serializeExpression(l), serializeExpression(r)]
1079
+ });
1080
+ },
1081
+ div(l, r) {
1082
+ return new ExpressionImpl({
1083
+ $div: [serializeExpression(l), serializeExpression(r)]
1084
+ });
1085
+ },
1086
+ mod(l, r) {
1087
+ return new ExpressionImpl({
1088
+ $mod: [serializeExpression(l), serializeExpression(r)]
1089
+ });
1090
+ },
1091
+ neg(x) {
1092
+ return new ExpressionImpl({ $neg: serializeExpression(x) });
1093
+ },
1094
+ // Logic ///////////////////////////////////////////////////////////////////
1095
+ and(...exprs) {
1096
+ return new ExpressionImpl({ $and: exprs.map(serializeExpression) });
1097
+ },
1098
+ or(...exprs) {
1099
+ return new ExpressionImpl({ $or: exprs.map(serializeExpression) });
1100
+ },
1101
+ not(x) {
1102
+ return new ExpressionImpl({ $not: serializeExpression(x) });
1103
+ },
1104
+ // Other ///////////////////////////////////////////////////////////////////
1105
+ field(fieldPath) {
1106
+ return new ExpressionImpl({ $field: fieldPath });
1107
+ }
1108
+ };
1109
+ var __defProp$5 = Object.defineProperty;
1110
+ var __defNormalProp$5 = (obj, key, value) => key in obj ? __defProp$5(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
1111
+ var __publicField$5 = (obj, key, value) => __defNormalProp$5(obj, key + "", value);
1112
+ class IndexRange {
1113
+ /**
1114
+ * @internal
1115
+ */
1116
+ constructor() {
1117
+ __publicField$5(this, "_isIndexRange");
1118
+ }
1119
+ }
1120
+ var __defProp$4 = Object.defineProperty;
1121
+ var __defNormalProp$4 = (obj, key, value) => key in obj ? __defProp$4(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
1122
+ var __publicField$4 = (obj, key, value) => __defNormalProp$4(obj, typeof key !== "symbol" ? key + "" : key, value);
1123
+ class IndexRangeBuilderImpl extends IndexRange {
1124
+ constructor(rangeExpressions) {
1125
+ super();
1126
+ __publicField$4(this, "rangeExpressions");
1127
+ __publicField$4(this, "isConsumed");
1128
+ this.rangeExpressions = rangeExpressions;
1129
+ this.isConsumed = false;
1130
+ }
1131
+ static new() {
1132
+ return new IndexRangeBuilderImpl([]);
1133
+ }
1134
+ consume() {
1135
+ if (this.isConsumed) {
1136
+ throw new Error(
1137
+ "IndexRangeBuilder has already been used! Chain your method calls like `q => q.eq(...).eq(...)`. See https://docs.convex.dev/using/indexes"
1138
+ );
1139
+ }
1140
+ this.isConsumed = true;
1141
+ }
1142
+ eq(fieldName, value) {
1143
+ this.consume();
1144
+ return new IndexRangeBuilderImpl(
1145
+ this.rangeExpressions.concat({
1146
+ type: "Eq",
1147
+ fieldPath: fieldName,
1148
+ value: convexOrUndefinedToJson(value)
1149
+ })
1150
+ );
1151
+ }
1152
+ gt(fieldName, value) {
1153
+ this.consume();
1154
+ return new IndexRangeBuilderImpl(
1155
+ this.rangeExpressions.concat({
1156
+ type: "Gt",
1157
+ fieldPath: fieldName,
1158
+ value: convexOrUndefinedToJson(value)
1159
+ })
1160
+ );
1161
+ }
1162
+ gte(fieldName, value) {
1163
+ this.consume();
1164
+ return new IndexRangeBuilderImpl(
1165
+ this.rangeExpressions.concat({
1166
+ type: "Gte",
1167
+ fieldPath: fieldName,
1168
+ value: convexOrUndefinedToJson(value)
1169
+ })
1170
+ );
1171
+ }
1172
+ lt(fieldName, value) {
1173
+ this.consume();
1174
+ return new IndexRangeBuilderImpl(
1175
+ this.rangeExpressions.concat({
1176
+ type: "Lt",
1177
+ fieldPath: fieldName,
1178
+ value: convexOrUndefinedToJson(value)
1179
+ })
1180
+ );
1181
+ }
1182
+ lte(fieldName, value) {
1183
+ this.consume();
1184
+ return new IndexRangeBuilderImpl(
1185
+ this.rangeExpressions.concat({
1186
+ type: "Lte",
1187
+ fieldPath: fieldName,
1188
+ value: convexOrUndefinedToJson(value)
1189
+ })
1190
+ );
1191
+ }
1192
+ export() {
1193
+ this.consume();
1194
+ return this.rangeExpressions;
1195
+ }
1196
+ }
1197
+ var __defProp$3 = Object.defineProperty;
1198
+ var __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$3(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
1199
+ var __publicField$3 = (obj, key, value) => __defNormalProp$3(obj, key + "", value);
1200
+ class SearchFilter {
1201
+ /**
1202
+ * @internal
1203
+ */
1204
+ constructor() {
1205
+ __publicField$3(this, "_isSearchFilter");
1206
+ }
1207
+ }
1208
+ var __defProp$2 = Object.defineProperty;
1209
+ var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
1210
+ var __publicField$2 = (obj, key, value) => __defNormalProp$2(obj, typeof key !== "symbol" ? key + "" : key, value);
1211
+ class SearchFilterBuilderImpl extends SearchFilter {
1212
+ constructor(filters) {
1213
+ super();
1214
+ __publicField$2(this, "filters");
1215
+ __publicField$2(this, "isConsumed");
1216
+ this.filters = filters;
1217
+ this.isConsumed = false;
1218
+ }
1219
+ static new() {
1220
+ return new SearchFilterBuilderImpl([]);
1221
+ }
1222
+ consume() {
1223
+ if (this.isConsumed) {
1224
+ throw new Error(
1225
+ "SearchFilterBuilder has already been used! Chain your method calls like `q => q.search(...).eq(...)`."
1226
+ );
1227
+ }
1228
+ this.isConsumed = true;
1229
+ }
1230
+ search(fieldName, query) {
1231
+ validateArg(fieldName, 1, "search", "fieldName");
1232
+ validateArg(query, 2, "search", "query");
1233
+ this.consume();
1234
+ return new SearchFilterBuilderImpl(
1235
+ this.filters.concat({
1236
+ type: "Search",
1237
+ fieldPath: fieldName,
1238
+ value: query
1239
+ })
1240
+ );
1241
+ }
1242
+ eq(fieldName, value) {
1243
+ validateArg(fieldName, 1, "eq", "fieldName");
1244
+ if (arguments.length !== 2) {
1245
+ validateArg(value, 2, "search", "value");
1246
+ }
1247
+ this.consume();
1248
+ return new SearchFilterBuilderImpl(
1249
+ this.filters.concat({
1250
+ type: "Eq",
1251
+ fieldPath: fieldName,
1252
+ value: convexOrUndefinedToJson(value)
1253
+ })
1254
+ );
1255
+ }
1256
+ export() {
1257
+ this.consume();
1258
+ return this.filters;
1259
+ }
1260
+ }
1261
+ var __defProp$1 = Object.defineProperty;
1262
+ var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
1263
+ var __publicField$1 = (obj, key, value) => __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
1264
+ const MAX_QUERY_OPERATORS = 256;
1265
+ class QueryInitializerImpl {
1266
+ constructor(tableName) {
1267
+ __publicField$1(this, "tableName");
1268
+ this.tableName = tableName;
1269
+ }
1270
+ withIndex(indexName, indexRange) {
1271
+ validateArg(indexName, 1, "withIndex", "indexName");
1272
+ let rangeBuilder = IndexRangeBuilderImpl.new();
1273
+ if (indexRange !== void 0) {
1274
+ rangeBuilder = indexRange(rangeBuilder);
1275
+ }
1276
+ return new QueryImpl({
1277
+ source: {
1278
+ type: "IndexRange",
1279
+ indexName: this.tableName + "." + indexName,
1280
+ range: rangeBuilder.export(),
1281
+ order: null
1282
+ },
1283
+ operators: []
1284
+ });
1285
+ }
1286
+ withSearchIndex(indexName, searchFilter) {
1287
+ validateArg(indexName, 1, "withSearchIndex", "indexName");
1288
+ validateArg(searchFilter, 2, "withSearchIndex", "searchFilter");
1289
+ const searchFilterBuilder = SearchFilterBuilderImpl.new();
1290
+ return new QueryImpl({
1291
+ source: {
1292
+ type: "Search",
1293
+ indexName: this.tableName + "." + indexName,
1294
+ filters: searchFilter(searchFilterBuilder).export()
1295
+ },
1296
+ operators: []
1297
+ });
1298
+ }
1299
+ fullTableScan() {
1300
+ return new QueryImpl({
1301
+ source: {
1302
+ type: "FullTableScan",
1303
+ tableName: this.tableName,
1304
+ order: null
1305
+ },
1306
+ operators: []
1307
+ });
1308
+ }
1309
+ order(order) {
1310
+ return this.fullTableScan().order(order);
1311
+ }
1312
+ // This is internal API and should not be exposed to developers yet.
1313
+ async count() {
1314
+ const syscallJSON = await performAsyncSyscall("1.0/count", {
1315
+ table: this.tableName
1316
+ });
1317
+ const syscallResult = jsonToConvex(syscallJSON);
1318
+ return syscallResult;
1319
+ }
1320
+ filter(predicate) {
1321
+ return this.fullTableScan().filter(predicate);
1322
+ }
1323
+ limit(n) {
1324
+ return this.fullTableScan().limit(n);
1325
+ }
1326
+ collect() {
1327
+ return this.fullTableScan().collect();
1328
+ }
1329
+ take(n) {
1330
+ return this.fullTableScan().take(n);
1331
+ }
1332
+ paginate(paginationOpts) {
1333
+ return this.fullTableScan().paginate(paginationOpts);
1334
+ }
1335
+ first() {
1336
+ return this.fullTableScan().first();
1337
+ }
1338
+ unique() {
1339
+ return this.fullTableScan().unique();
1340
+ }
1341
+ [Symbol.asyncIterator]() {
1342
+ return this.fullTableScan()[Symbol.asyncIterator]();
1343
+ }
1344
+ }
1345
+ function throwClosedError(type) {
1346
+ throw new Error(
1347
+ type === "consumed" ? "This query is closed and can't emit any more values." : "This query has been chained with another operator and can't be reused."
1348
+ );
1349
+ }
1350
+ class QueryImpl {
1351
+ constructor(query) {
1352
+ __publicField$1(this, "state");
1353
+ __publicField$1(this, "tableNameForErrorMessages");
1354
+ this.state = { type: "preparing", query };
1355
+ if (query.source.type === "FullTableScan") {
1356
+ this.tableNameForErrorMessages = query.source.tableName;
1357
+ } else {
1358
+ this.tableNameForErrorMessages = query.source.indexName.split(".")[0];
1359
+ }
1360
+ }
1361
+ takeQuery() {
1362
+ if (this.state.type !== "preparing") {
1363
+ throw new Error(
1364
+ "A query can only be chained once and can't be chained after iteration begins."
1365
+ );
1366
+ }
1367
+ const query = this.state.query;
1368
+ this.state = { type: "closed" };
1369
+ return query;
1370
+ }
1371
+ startQuery() {
1372
+ if (this.state.type === "executing") {
1373
+ throw new Error("Iteration can only begin on a query once.");
1374
+ }
1375
+ if (this.state.type === "closed" || this.state.type === "consumed") {
1376
+ throwClosedError(this.state.type);
1377
+ }
1378
+ const query = this.state.query;
1379
+ const { queryId } = performSyscall("1.0/queryStream", { query, version });
1380
+ this.state = { type: "executing", queryId };
1381
+ return queryId;
1382
+ }
1383
+ closeQuery() {
1384
+ if (this.state.type === "executing") {
1385
+ const queryId = this.state.queryId;
1386
+ performSyscall("1.0/queryCleanup", { queryId });
1387
+ }
1388
+ this.state = { type: "consumed" };
1389
+ }
1390
+ order(order) {
1391
+ validateArg(order, 1, "order", "order");
1392
+ const query = this.takeQuery();
1393
+ if (query.source.type === "Search") {
1394
+ throw new Error(
1395
+ "Search queries must always be in relevance order. Can not set order manually."
1396
+ );
1397
+ }
1398
+ if (query.source.order !== null) {
1399
+ throw new Error("Queries may only specify order at most once");
1400
+ }
1401
+ query.source.order = order;
1402
+ return new QueryImpl(query);
1403
+ }
1404
+ filter(predicate) {
1405
+ validateArg(predicate, 1, "filter", "predicate");
1406
+ const query = this.takeQuery();
1407
+ if (query.operators.length >= MAX_QUERY_OPERATORS) {
1408
+ throw new Error(
1409
+ `Can't construct query with more than ${MAX_QUERY_OPERATORS} operators`
1410
+ );
1411
+ }
1412
+ query.operators.push({
1413
+ filter: serializeExpression(predicate(filterBuilderImpl))
1414
+ });
1415
+ return new QueryImpl(query);
1416
+ }
1417
+ limit(n) {
1418
+ validateArg(n, 1, "limit", "n");
1419
+ const query = this.takeQuery();
1420
+ query.operators.push({ limit: n });
1421
+ return new QueryImpl(query);
1422
+ }
1423
+ [Symbol.asyncIterator]() {
1424
+ this.startQuery();
1425
+ return this;
1426
+ }
1427
+ async next() {
1428
+ if (this.state.type === "closed" || this.state.type === "consumed") {
1429
+ throwClosedError(this.state.type);
1430
+ }
1431
+ const queryId = this.state.type === "preparing" ? this.startQuery() : this.state.queryId;
1432
+ const { value, done } = await performAsyncSyscall("1.0/queryStreamNext", {
1433
+ queryId
1434
+ });
1435
+ if (done) {
1436
+ this.closeQuery();
1437
+ }
1438
+ const convexValue = jsonToConvex(value);
1439
+ return { value: convexValue, done };
1440
+ }
1441
+ return() {
1442
+ this.closeQuery();
1443
+ return Promise.resolve({ done: true, value: void 0 });
1444
+ }
1445
+ async paginate(paginationOpts) {
1446
+ validateArg(paginationOpts, 1, "paginate", "options");
1447
+ if (typeof paginationOpts?.numItems !== "number" || paginationOpts.numItems < 0) {
1448
+ throw new Error(
1449
+ `\`options.numItems\` must be a positive number. Received \`${paginationOpts?.numItems}\`.`
1450
+ );
1451
+ }
1452
+ const query = this.takeQuery();
1453
+ const pageSize = paginationOpts.numItems;
1454
+ const cursor = paginationOpts.cursor;
1455
+ const endCursor = paginationOpts?.endCursor ?? null;
1456
+ const maximumRowsRead = paginationOpts.maximumRowsRead ?? null;
1457
+ const { page, isDone, continueCursor, splitCursor, pageStatus } = await performAsyncSyscall("1.0/queryPage", {
1458
+ query,
1459
+ cursor,
1460
+ endCursor,
1461
+ pageSize,
1462
+ maximumRowsRead,
1463
+ maximumBytesRead: paginationOpts.maximumBytesRead,
1464
+ version
1465
+ });
1466
+ return {
1467
+ page: page.map((json) => jsonToConvex(json)),
1468
+ isDone,
1469
+ continueCursor,
1470
+ splitCursor,
1471
+ pageStatus
1472
+ };
1473
+ }
1474
+ async collect() {
1475
+ const out = [];
1476
+ for await (const item of this) {
1477
+ out.push(item);
1478
+ }
1479
+ return out;
1480
+ }
1481
+ async take(n) {
1482
+ validateArg(n, 1, "take", "n");
1483
+ validateArgIsNonNegativeInteger(n, 1, "take", "n");
1484
+ return this.limit(n).collect();
1485
+ }
1486
+ async first() {
1487
+ const first_array = await this.take(1);
1488
+ return first_array.length === 0 ? null : first_array[0];
1489
+ }
1490
+ async unique() {
1491
+ const first_two_array = await this.take(2);
1492
+ if (first_two_array.length === 0) {
1493
+ return null;
1494
+ }
1495
+ if (first_two_array.length === 2) {
1496
+ throw new Error(`unique() query returned more than one result from table ${this.tableNameForErrorMessages}:
1497
+ [${first_two_array[0]._id}, ${first_two_array[1]._id}, ...]`);
1498
+ }
1499
+ return first_two_array[0];
1500
+ }
1501
+ }
1502
+ async function get(table, id, isSystem) {
1503
+ validateArg(id, 1, "get", "id");
1504
+ if (typeof id !== "string") {
1505
+ throw new Error(
1506
+ `Invalid argument \`id\` for \`db.get\`, expected string but got '${typeof id}': ${id}`
1507
+ );
1508
+ }
1509
+ const args = {
1510
+ id: convexToJson(id),
1511
+ isSystem,
1512
+ version,
1513
+ table
1514
+ };
1515
+ const syscallJSON = await performAsyncSyscall("1.0/get", args);
1516
+ return jsonToConvex(syscallJSON);
1517
+ }
1518
+ function setupReader() {
1519
+ const reader = (isSystem = false) => {
1520
+ return {
1521
+ get: async (arg0, arg1) => {
1522
+ return arg1 !== void 0 ? await get(arg0, arg1, isSystem) : await get(void 0, arg0, isSystem);
1523
+ },
1524
+ query: (tableName) => {
1525
+ return new TableReader(tableName, isSystem).query();
1526
+ },
1527
+ normalizeId: (tableName, id) => {
1528
+ validateArg(tableName, 1, "normalizeId", "tableName");
1529
+ validateArg(id, 2, "normalizeId", "id");
1530
+ const accessingSystemTable = tableName.startsWith("_");
1531
+ if (accessingSystemTable !== isSystem) {
1532
+ throw new Error(
1533
+ `${accessingSystemTable ? "System" : "User"} tables can only be accessed from db.${isSystem ? "" : "system."}normalizeId().`
1534
+ );
1535
+ }
1536
+ const syscallJSON = performSyscall("1.0/db/normalizeId", {
1537
+ table: tableName,
1538
+ idString: id
1539
+ });
1540
+ const syscallResult = jsonToConvex(syscallJSON);
1541
+ return syscallResult.id;
1542
+ },
1543
+ // We set the system reader on the next line
1544
+ system: null,
1545
+ table: (tableName) => {
1546
+ return new TableReader(tableName, isSystem);
1547
+ }
1548
+ };
1549
+ };
1550
+ const { system: _, ...rest } = reader(true);
1551
+ const r = reader();
1552
+ r.system = rest;
1553
+ return r;
1554
+ }
1555
+ async function insert(tableName, value) {
1556
+ if (tableName.startsWith("_")) {
1557
+ throw new Error("System tables (prefixed with `_`) are read-only.");
1558
+ }
1559
+ validateArg(tableName, 1, "insert", "table");
1560
+ validateArg(value, 2, "insert", "value");
1561
+ const syscallJSON = await performAsyncSyscall("1.0/insert", {
1562
+ table: tableName,
1563
+ value: convexToJson(value)
1564
+ });
1565
+ const syscallResult = jsonToConvex(syscallJSON);
1566
+ return syscallResult._id;
1567
+ }
1568
+ async function patch(table, id, value) {
1569
+ validateArg(id, 1, "patch", "id");
1570
+ validateArg(value, 2, "patch", "value");
1571
+ await performAsyncSyscall("1.0/shallowMerge", {
1572
+ id: convexToJson(id),
1573
+ value: patchValueToJson(value),
1574
+ table
1575
+ });
1576
+ }
1577
+ async function replace(table, id, value) {
1578
+ validateArg(id, 1, "replace", "id");
1579
+ validateArg(value, 2, "replace", "value");
1580
+ await performAsyncSyscall("1.0/replace", {
1581
+ id: convexToJson(id),
1582
+ value: convexToJson(value),
1583
+ table
1584
+ });
1585
+ }
1586
+ async function delete_(table, id) {
1587
+ validateArg(id, 1, "delete", "id");
1588
+ await performAsyncSyscall("1.0/remove", {
1589
+ id: convexToJson(id),
1590
+ table
1591
+ });
1592
+ }
1593
+ function setupWriter() {
1594
+ const reader = setupReader();
1595
+ return {
1596
+ get: reader.get,
1597
+ query: reader.query,
1598
+ normalizeId: reader.normalizeId,
1599
+ system: reader.system,
1600
+ insert: async (table, value) => {
1601
+ return await insert(table, value);
1602
+ },
1603
+ patch: async (arg0, arg1, arg2) => {
1604
+ return arg2 !== void 0 ? await patch(arg0, arg1, arg2) : await patch(void 0, arg0, arg1);
1605
+ },
1606
+ replace: async (arg0, arg1, arg2) => {
1607
+ return arg2 !== void 0 ? await replace(arg0, arg1, arg2) : await replace(void 0, arg0, arg1);
1608
+ },
1609
+ delete: async (arg0, arg1) => {
1610
+ return arg1 !== void 0 ? await delete_(arg0, arg1) : await delete_(void 0, arg0);
1611
+ },
1612
+ table: (tableName) => {
1613
+ return new TableWriter(tableName, false);
1614
+ }
1615
+ };
1616
+ }
1617
+ class TableReader {
1618
+ constructor(tableName, isSystem) {
1619
+ this.tableName = tableName;
1620
+ this.isSystem = isSystem;
1621
+ }
1622
+ async get(id) {
1623
+ return get(this.tableName, id, this.isSystem);
1624
+ }
1625
+ query() {
1626
+ const accessingSystemTable = this.tableName.startsWith("_");
1627
+ if (accessingSystemTable !== this.isSystem) {
1628
+ throw new Error(
1629
+ `${accessingSystemTable ? "System" : "User"} tables can only be accessed from db.${this.isSystem ? "" : "system."}query().`
1630
+ );
1631
+ }
1632
+ return new QueryInitializerImpl(this.tableName);
1633
+ }
1634
+ }
1635
+ class TableWriter extends TableReader {
1636
+ async insert(value) {
1637
+ return insert(this.tableName, value);
1638
+ }
1639
+ async patch(id, value) {
1640
+ return patch(this.tableName, id, value);
1641
+ }
1642
+ async replace(id, value) {
1643
+ return replace(this.tableName, id, value);
1644
+ }
1645
+ async delete(id) {
1646
+ return delete_(this.tableName, id);
1647
+ }
1648
+ }
1649
+ function setupMutationScheduler() {
1650
+ return {
1651
+ runAfter: async (delayMs, functionReference, args) => {
1652
+ const syscallArgs = runAfterSyscallArgs(delayMs, functionReference, args);
1653
+ return await performAsyncSyscall("1.0/schedule", syscallArgs);
1654
+ },
1655
+ runAt: async (ms_since_epoch_or_date, functionReference, args) => {
1656
+ const syscallArgs = runAtSyscallArgs(
1657
+ ms_since_epoch_or_date,
1658
+ functionReference,
1659
+ args
1660
+ );
1661
+ return await performAsyncSyscall("1.0/schedule", syscallArgs);
1662
+ },
1663
+ cancel: async (id) => {
1664
+ validateArg(id, 1, "cancel", "id");
1665
+ const args = { id: convexToJson(id) };
1666
+ await performAsyncSyscall("1.0/cancel_job", args);
1667
+ }
1668
+ };
1669
+ }
1670
+ function runAfterSyscallArgs(delayMs, functionReference, args) {
1671
+ if (typeof delayMs !== "number") {
1672
+ throw new Error("`delayMs` must be a number");
1673
+ }
1674
+ if (!isFinite(delayMs)) {
1675
+ throw new Error("`delayMs` must be a finite number");
1676
+ }
1677
+ if (delayMs < 0) {
1678
+ throw new Error("`delayMs` must be non-negative");
1679
+ }
1680
+ const functionArgs = parseArgs(args);
1681
+ const address = getFunctionAddress(functionReference);
1682
+ const ts = (Date.now() + delayMs) / 1e3;
1683
+ return {
1684
+ ...address,
1685
+ ts,
1686
+ args: convexToJson(functionArgs),
1687
+ version
1688
+ };
1689
+ }
1690
+ function runAtSyscallArgs(ms_since_epoch_or_date, functionReference, args) {
1691
+ let ts;
1692
+ if (ms_since_epoch_or_date instanceof Date) {
1693
+ ts = ms_since_epoch_or_date.valueOf() / 1e3;
1694
+ } else if (typeof ms_since_epoch_or_date === "number") {
1695
+ ts = ms_since_epoch_or_date / 1e3;
1696
+ } else {
1697
+ throw new Error("The invoke time must a Date or a timestamp");
1698
+ }
1699
+ const address = getFunctionAddress(functionReference);
1700
+ const functionArgs = parseArgs(args);
1701
+ return {
1702
+ ...address,
1703
+ ts,
1704
+ args: convexToJson(functionArgs),
1705
+ version
1706
+ };
1707
+ }
1708
+ function setupStorageReader(requestId) {
1709
+ return {
1710
+ getUrl: async (storageId) => {
1711
+ validateArg(storageId, 1, "getUrl", "storageId");
1712
+ return await performAsyncSyscall("1.0/storageGetUrl", {
1713
+ requestId,
1714
+ version,
1715
+ storageId
1716
+ });
1717
+ },
1718
+ getMetadata: async (storageId) => {
1719
+ return await performAsyncSyscall("1.0/storageGetMetadata", {
1720
+ requestId,
1721
+ version,
1722
+ storageId
1723
+ });
1724
+ }
1725
+ };
1726
+ }
1727
+ function setupStorageWriter(requestId) {
1728
+ const reader = setupStorageReader(requestId);
1729
+ return {
1730
+ generateUploadUrl: async () => {
1731
+ return await performAsyncSyscall("1.0/storageGenerateUploadUrl", {
1732
+ requestId,
1733
+ version
1734
+ });
1735
+ },
1736
+ delete: async (storageId) => {
1737
+ await performAsyncSyscall("1.0/storageDelete", {
1738
+ requestId,
1739
+ version,
1740
+ storageId
1741
+ });
1742
+ },
1743
+ getUrl: reader.getUrl,
1744
+ getMetadata: reader.getMetadata
1745
+ };
1746
+ }
1747
+ async function invokeMutation(func, argsStr) {
1748
+ const requestId = "";
1749
+ const args = jsonToConvex(JSON.parse(argsStr));
1750
+ const mutationCtx = {
1751
+ db: setupWriter(),
1752
+ auth: setupAuth(requestId),
1753
+ storage: setupStorageWriter(requestId),
1754
+ scheduler: setupMutationScheduler(),
1755
+ runQuery: (reference, args2) => runUdf("query", reference, args2),
1756
+ runMutation: (reference, args2) => runUdf("mutation", reference, args2)
1757
+ };
1758
+ const result = await invokeFunction(func, mutationCtx, args);
1759
+ validateReturnValue(result);
1760
+ return JSON.stringify(convexToJson(result === void 0 ? null : result));
1761
+ }
1762
+ function validateReturnValue(v2) {
1763
+ if (v2 instanceof QueryInitializerImpl || v2 instanceof QueryImpl) {
1764
+ throw new Error(
1765
+ "Return value is a Query. Results must be retrieved with `.collect()`, `.take(n), `.unique()`, or `.first()`."
1766
+ );
1767
+ }
1768
+ }
1769
+ async function invokeFunction(func, ctx, args) {
1770
+ let result;
1771
+ try {
1772
+ result = await Promise.resolve(func(ctx, ...args));
1773
+ } catch (thrown) {
1774
+ throw serializeConvexErrorData(thrown);
1775
+ }
1776
+ return result;
1777
+ }
1778
+ function dontCallDirectly(funcType, handler) {
1779
+ return (ctx, args) => {
1780
+ globalThis.console.warn(
1781
+ `Convex functions should not directly call other Convex functions. Consider calling a helper function instead. e.g. \`export const foo = ${funcType}(...); await foo(ctx);\` is not supported. See https://docs.convex.dev/production/best-practices/#use-helper-functions-to-write-shared-code`
1782
+ );
1783
+ return handler(ctx, args);
1784
+ };
1785
+ }
1786
+ function serializeConvexErrorData(thrown) {
1787
+ if (typeof thrown === "object" && thrown !== null && Symbol.for("ConvexError") in thrown) {
1788
+ const error = thrown;
1789
+ error.data = JSON.stringify(
1790
+ convexToJson(error.data === void 0 ? null : error.data)
1791
+ );
1792
+ error.ConvexErrorSymbol = Symbol.for("ConvexError");
1793
+ return error;
1794
+ } else {
1795
+ return thrown;
1796
+ }
1797
+ }
1798
+ function assertNotBrowser() {
1799
+ if (typeof window === "undefined" || window.__convexAllowFunctionsInBrowser) {
1800
+ return;
1801
+ }
1802
+ const isRealBrowser = Object.getOwnPropertyDescriptor(globalThis, "window")?.get?.toString().includes("[native code]") ?? false;
1803
+ if (isRealBrowser) {
1804
+ console.error(
1805
+ "Convex functions should not be imported in the browser. This will throw an error in future versions of `convex`. If this is a false negative, please report it to Convex support."
1806
+ );
1807
+ }
1808
+ }
1809
+ function strictReplacer(key, value) {
1810
+ if (value === void 0) {
1811
+ throw new Error(
1812
+ `Cannot serialize validator value \`undefined\` for ${key}`
1813
+ );
1814
+ }
1815
+ return value;
1816
+ }
1817
+ function exportArgs(functionDefinition) {
1818
+ return () => {
1819
+ let args = v.any();
1820
+ if (typeof functionDefinition === "object" && functionDefinition.args !== void 0) {
1821
+ args = asObjectValidator(functionDefinition.args);
1822
+ }
1823
+ return JSON.stringify(args.json, strictReplacer);
1824
+ };
1825
+ }
1826
+ function exportReturns(functionDefinition) {
1827
+ return () => {
1828
+ let returns;
1829
+ if (typeof functionDefinition === "object" && functionDefinition.returns !== void 0) {
1830
+ returns = asObjectValidator(functionDefinition.returns);
1831
+ }
1832
+ return JSON.stringify(returns ? returns.json : null, strictReplacer);
1833
+ };
1834
+ }
1835
+ const internalMutationGeneric = (functionDefinition) => {
1836
+ const handler = typeof functionDefinition === "function" ? functionDefinition : functionDefinition.handler;
1837
+ const func = dontCallDirectly(
1838
+ "internalMutation",
1839
+ handler
1840
+ );
1841
+ assertNotBrowser();
1842
+ func.isMutation = true;
1843
+ func.isInternal = true;
1844
+ func.invokeMutation = (argsStr) => invokeMutation(handler, argsStr);
1845
+ func.exportArgs = exportArgs(functionDefinition);
1846
+ func.exportReturns = exportReturns(functionDefinition);
1847
+ func._handler = handler;
1848
+ return func;
1849
+ };
1850
+ async function runUdf(udfType, f, args) {
1851
+ const queryArgs = parseArgs(args);
1852
+ const syscallArgs = {
1853
+ udfType,
1854
+ args: convexToJson(queryArgs),
1855
+ ...getFunctionAddress(f)
1856
+ };
1857
+ const result = await performAsyncSyscall("1.0/runUdf", syscallArgs);
1858
+ return jsonToConvex(result);
1859
+ }
1860
+ var __defProp = Object.defineProperty;
1861
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
1862
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
1863
+ class TableDefinition {
1864
+ /**
1865
+ * @internal
1866
+ */
1867
+ constructor(documentType) {
1868
+ __publicField(this, "indexes");
1869
+ __publicField(this, "stagedDbIndexes");
1870
+ __publicField(this, "searchIndexes");
1871
+ __publicField(this, "stagedSearchIndexes");
1872
+ __publicField(this, "vectorIndexes");
1873
+ __publicField(this, "stagedVectorIndexes");
1874
+ __publicField(this, "validator");
1875
+ this.indexes = [];
1876
+ this.stagedDbIndexes = [];
1877
+ this.searchIndexes = [];
1878
+ this.stagedSearchIndexes = [];
1879
+ this.vectorIndexes = [];
1880
+ this.stagedVectorIndexes = [];
1881
+ this.validator = documentType;
1882
+ }
1883
+ /**
1884
+ * This API is experimental: it may change or disappear.
1885
+ *
1886
+ * Returns indexes defined on this table.
1887
+ * Intended for the advanced use cases of dynamically deciding which index to use for a query.
1888
+ * If you think you need this, please chime in on ths issue in the Convex JS GitHub repo.
1889
+ * https://github.com/get-convex/convex-js/issues/49
1890
+ */
1891
+ " indexes"() {
1892
+ return this.indexes;
1893
+ }
1894
+ index(name, indexConfig) {
1895
+ if (Array.isArray(indexConfig)) {
1896
+ this.indexes.push({
1897
+ indexDescriptor: name,
1898
+ fields: indexConfig
1899
+ });
1900
+ } else if (indexConfig.staged) {
1901
+ this.stagedDbIndexes.push({
1902
+ indexDescriptor: name,
1903
+ fields: indexConfig.fields
1904
+ });
1905
+ } else {
1906
+ this.indexes.push({
1907
+ indexDescriptor: name,
1908
+ fields: indexConfig.fields
1909
+ });
1910
+ }
1911
+ return this;
1912
+ }
1913
+ searchIndex(name, indexConfig) {
1914
+ if (indexConfig.staged) {
1915
+ this.stagedSearchIndexes.push({
1916
+ indexDescriptor: name,
1917
+ searchField: indexConfig.searchField,
1918
+ filterFields: indexConfig.filterFields || []
1919
+ });
1920
+ } else {
1921
+ this.searchIndexes.push({
1922
+ indexDescriptor: name,
1923
+ searchField: indexConfig.searchField,
1924
+ filterFields: indexConfig.filterFields || []
1925
+ });
1926
+ }
1927
+ return this;
1928
+ }
1929
+ vectorIndex(name, indexConfig) {
1930
+ if (indexConfig.staged) {
1931
+ this.stagedVectorIndexes.push({
1932
+ indexDescriptor: name,
1933
+ vectorField: indexConfig.vectorField,
1934
+ dimensions: indexConfig.dimensions,
1935
+ filterFields: indexConfig.filterFields || []
1936
+ });
1937
+ } else {
1938
+ this.vectorIndexes.push({
1939
+ indexDescriptor: name,
1940
+ vectorField: indexConfig.vectorField,
1941
+ dimensions: indexConfig.dimensions,
1942
+ filterFields: indexConfig.filterFields || []
1943
+ });
1944
+ }
1945
+ return this;
1946
+ }
1947
+ /**
1948
+ * Work around for https://github.com/microsoft/TypeScript/issues/57035
1949
+ */
1950
+ self() {
1951
+ return this;
1952
+ }
1953
+ /**
1954
+ * Export the contents of this definition.
1955
+ *
1956
+ * This is called internally by the Convex framework.
1957
+ * @internal
1958
+ */
1959
+ export() {
1960
+ const documentType = this.validator.json;
1961
+ if (typeof documentType !== "object") {
1962
+ throw new Error(
1963
+ "Invalid validator: please make sure that the parameter of `defineTable` is valid (see https://docs.convex.dev/database/schemas)"
1964
+ );
1965
+ }
1966
+ return {
1967
+ indexes: this.indexes,
1968
+ stagedDbIndexes: this.stagedDbIndexes,
1969
+ searchIndexes: this.searchIndexes,
1970
+ stagedSearchIndexes: this.stagedSearchIndexes,
1971
+ vectorIndexes: this.vectorIndexes,
1972
+ stagedVectorIndexes: this.stagedVectorIndexes,
1973
+ documentType
1974
+ };
1975
+ }
1976
+ }
1977
+ function defineTable(documentSchema) {
1978
+ if (isValidator(documentSchema)) {
1979
+ return new TableDefinition(documentSchema);
1980
+ } else {
1981
+ return new TableDefinition(v.object(documentSchema));
1982
+ }
1983
+ }
1984
+ class SchemaDefinition {
1985
+ /**
1986
+ * @internal
1987
+ */
1988
+ constructor(tables, options) {
1989
+ __publicField(this, "tables");
1990
+ __publicField(this, "strictTableNameTypes");
1991
+ __publicField(this, "schemaValidation");
1992
+ this.tables = tables;
1993
+ this.schemaValidation = options?.schemaValidation === void 0 ? true : options.schemaValidation;
1994
+ }
1995
+ /**
1996
+ * Export the contents of this definition.
1997
+ *
1998
+ * This is called internally by the Convex framework.
1999
+ * @internal
2000
+ */
2001
+ export() {
2002
+ return JSON.stringify({
2003
+ tables: Object.entries(this.tables).map(([tableName, definition]) => {
2004
+ const {
2005
+ indexes,
2006
+ stagedDbIndexes,
2007
+ searchIndexes,
2008
+ stagedSearchIndexes,
2009
+ vectorIndexes,
2010
+ stagedVectorIndexes,
2011
+ documentType
2012
+ } = definition.export();
2013
+ return {
2014
+ tableName,
2015
+ indexes,
2016
+ stagedDbIndexes,
2017
+ searchIndexes,
2018
+ stagedSearchIndexes,
2019
+ vectorIndexes,
2020
+ stagedVectorIndexes,
2021
+ documentType
2022
+ };
2023
+ }),
2024
+ schemaValidation: this.schemaValidation
2025
+ });
2026
+ }
2027
+ }
2028
+ function defineSchema(schema, options) {
2029
+ return new SchemaDefinition(schema, options);
2030
+ }
2031
+ defineSchema({
2032
+ _scheduled_functions: defineTable({
2033
+ name: v.string(),
2034
+ args: v.array(v.any()),
2035
+ scheduledTime: v.float64(),
2036
+ completedTime: v.optional(v.float64()),
2037
+ state: v.union(
2038
+ v.object({ kind: v.literal("pending") }),
2039
+ v.object({ kind: v.literal("inProgress") }),
2040
+ v.object({ kind: v.literal("success") }),
2041
+ v.object({ kind: v.literal("failed"), error: v.string() }),
2042
+ v.object({ kind: v.literal("canceled") })
2043
+ )
2044
+ }),
2045
+ _storage: defineTable({
2046
+ sha256: v.string(),
2047
+ size: v.float64(),
2048
+ contentType: v.optional(v.string())
2049
+ })
2050
+ });
2051
+ class Logger {
2052
+ debug_;
2053
+ constructor(debug) {
2054
+ this.debug_ = debug;
2055
+ }
2056
+ log(message) {
2057
+ console.log(message);
2058
+ }
2059
+ error(message) {
2060
+ console.error(message);
2061
+ }
2062
+ warn(message) {
2063
+ console.warn(message);
2064
+ }
2065
+ debug(message) {
2066
+ if (this.debug_) {
2067
+ console.debug(message);
2068
+ }
2069
+ }
2070
+ }
2071
+ const DEFAULT_EXECUTION_BLOCKING = false;
2072
+ const normalizeConfiguration = (config) => {
2073
+ return {
2074
+ ...config,
2075
+ execution: {
2076
+ blocking: config.execution?.blocking ?? DEFAULT_EXECUTION_BLOCKING
2077
+ }
2078
+ };
2079
+ };
2080
+ const normalizeOptions = (options) => {
2081
+ return {
2082
+ ...options,
2083
+ store: options.store || "store",
2084
+ debug: options.debug || false,
2085
+ logger: options.logger || new Logger(options.debug || false),
2086
+ base: options.base || "kv"
2087
+ };
2088
+ };
2089
+ const defineMutationImplementation = (spec) => spec;
2090
+ const DeleteEntryImplementation = defineMutationImplementation({
2091
+ args: {
2092
+ key: v.string()
2093
+ },
2094
+ name: "deleteEntry",
2095
+ handler: async (context, args) => {
2096
+ const entries = await context.db.query("kvEntries").withIndex("byKey", (query) => query.eq("key", args.key)).collect();
2097
+ if (entries.length === 0) return false;
2098
+ for (const entry of entries) {
2099
+ await context.db.delete(entry._id);
2100
+ }
2101
+ return true;
2102
+ }
2103
+ });
2104
+ const GetEntryImplementation = defineMutationImplementation({
2105
+ args: {
2106
+ key: v.string()
2107
+ },
2108
+ name: "getEntry",
2109
+ handler: async (context, args) => {
2110
+ const entries = await context.db.query("kvEntries").withIndex("byKey", (query) => query.eq("key", args.key)).collect();
2111
+ if (entries.length === 0) {
2112
+ return {
2113
+ found: false,
2114
+ value: null,
2115
+ expiresAt: null
2116
+ };
2117
+ }
2118
+ const [head, ...duplicates] = entries.sort((a, b) => b.updatedAt - a.updatedAt);
2119
+ const now = Date.now();
2120
+ const isExpired = head.expiresAt !== null && head.expiresAt <= now;
2121
+ if (isExpired) {
2122
+ for (const entry of entries) {
2123
+ await context.db.delete(entry._id);
2124
+ }
2125
+ return {
2126
+ found: false,
2127
+ value: null,
2128
+ expiresAt: null
2129
+ };
2130
+ }
2131
+ for (const duplicate of duplicates) {
2132
+ await context.db.delete(duplicate._id);
2133
+ }
2134
+ return {
2135
+ found: true,
2136
+ value: head.value,
2137
+ expiresAt: head.expiresAt
2138
+ };
2139
+ }
2140
+ });
2141
+ const HasEntryImplementation = defineMutationImplementation({
2142
+ args: {
2143
+ key: v.string()
2144
+ },
2145
+ name: "hasEntry",
2146
+ handler: async (context, args) => {
2147
+ const entries = await context.db.query("kvEntries").withIndex("byKey", (query) => query.eq("key", args.key)).collect();
2148
+ if (entries.length === 0) return false;
2149
+ const [head, ...duplicates] = entries.sort((a, b) => b.updatedAt - a.updatedAt);
2150
+ const now = Date.now();
2151
+ const isExpired = head.expiresAt !== null && head.expiresAt <= now;
2152
+ if (isExpired) {
2153
+ for (const entry of entries) {
2154
+ await context.db.delete(entry._id);
2155
+ }
2156
+ return false;
2157
+ }
2158
+ for (const duplicate of duplicates) {
2159
+ await context.db.delete(duplicate._id);
2160
+ }
2161
+ return true;
2162
+ }
2163
+ });
2164
+ const resolveExpiration = (expiresAt, expiresInMs) => {
2165
+ if (expiresAt != null && expiresInMs != null) {
2166
+ throw new Error('Only one of "expiresAt" or "expiresInMs" can be provided.');
2167
+ }
2168
+ if (expiresAt != null) return expiresAt;
2169
+ if (expiresInMs != null) return Date.now() + expiresInMs;
2170
+ return null;
2171
+ };
2172
+ const SetEntryImplementation = defineMutationImplementation({
2173
+ args: {
2174
+ key: v.string(),
2175
+ value: v.any(),
2176
+ expiresAt: v.optional(v.union(v.number(), v.null())),
2177
+ expiresInMs: v.optional(v.union(v.number(), v.null()))
2178
+ },
2179
+ name: "setEntry",
2180
+ handler: async (context, args) => {
2181
+ const entries = await context.db.query("kvEntries").withIndex("byKey", (query) => query.eq("key", args.key)).collect();
2182
+ const expiration = resolveExpiration(args.expiresAt, args.expiresInMs);
2183
+ const now = Date.now();
2184
+ if (entries.length === 0) {
2185
+ await context.db.insert("kvEntries", {
2186
+ key: args.key,
2187
+ value: args.value,
2188
+ expiresAt: expiration,
2189
+ updatedAt: now
2190
+ });
2191
+ return;
2192
+ }
2193
+ const [head, ...duplicates] = entries;
2194
+ await context.db.patch(head._id, {
2195
+ value: args.value,
2196
+ expiresAt: expiration,
2197
+ updatedAt: now
2198
+ });
2199
+ for (const duplicate of duplicates) {
2200
+ await context.db.delete(duplicate._id);
2201
+ }
2202
+ }
2203
+ });
2204
+ const OPERATIONS = [
2205
+ SetEntryImplementation,
2206
+ GetEntryImplementation,
2207
+ HasEntryImplementation,
2208
+ DeleteEntryImplementation
2209
+ ];
2210
+ const StoreImplementation = defineMutationImplementation({
2211
+ name: "store",
2212
+ args: {
2213
+ operation: v.string(),
2214
+ args: v.any()
2215
+ },
2216
+ handler: async (context, args, configuration, options) => {
2217
+ const operation = OPERATIONS.find((op) => op.name === args.operation);
2218
+ if (!operation) throw new Error(`Unknown operation "${args.operation}"`);
2219
+ return operation.handler(context, args.args, configuration, options);
2220
+ }
2221
+ });
2222
+ async function storeDispatchTyped(operationName, args, context, _, options) {
2223
+ return await context.runMutation(`${options.base}:${options.store}`, {
2224
+ operation: operationName,
2225
+ args
2226
+ });
2227
+ }
2228
+ const dispatchStoreOperation = async (context, operation, args, execution, configuration, options) => {
2229
+ if ("runAction" in context) {
2230
+ return await storeDispatchTyped(
2231
+ operation,
2232
+ args,
2233
+ context,
2234
+ configuration,
2235
+ options
2236
+ );
2237
+ }
2238
+ if ("runMutation" in context) {
2239
+ if (execution.blocking) {
2240
+ return await StoreImplementation.handler(
2241
+ context,
2242
+ {
2243
+ operation,
2244
+ args
2245
+ },
2246
+ configuration,
2247
+ options
2248
+ );
2249
+ }
2250
+ await context.scheduler.runAfter(
2251
+ 0,
2252
+ `${options.base}:${options.store}`,
2253
+ {
2254
+ operation,
2255
+ args
2256
+ }
2257
+ );
2258
+ return null;
2259
+ }
2260
+ throw new Error("Invalid context provided.");
2261
+ };
2262
+ const SetImplementation = async (context, args, execution, configuration, options) => {
2263
+ await dispatchStoreOperation(
2264
+ context,
2265
+ "setEntry",
2266
+ args,
2267
+ execution,
2268
+ configuration,
2269
+ options
2270
+ );
2271
+ };
2272
+ const GetImplementation = async (context, args, configuration, options) => {
2273
+ const result = await dispatchStoreOperation(
2274
+ context,
2275
+ "getEntry",
2276
+ args,
2277
+ {
2278
+ blocking: true
2279
+ },
2280
+ configuration,
2281
+ options
2282
+ );
2283
+ if (!result || !result.found) return null;
2284
+ return result.value;
2285
+ };
2286
+ const GetOrDefaultImplementation = async (context, args, configuration, options) => {
2287
+ const value = await GetImplementation(context, { key: args.key }, configuration, options);
2288
+ if (value === null) return args.defaultValue;
2289
+ return value;
2290
+ };
2291
+ const HasImplementation = async (context, args, configuration, options) => {
2292
+ const result = await dispatchStoreOperation(
2293
+ context,
2294
+ "hasEntry",
2295
+ args,
2296
+ {
2297
+ blocking: true
2298
+ },
2299
+ configuration,
2300
+ options
2301
+ );
2302
+ return Boolean(result);
2303
+ };
2304
+ const DeleteImplementation = async (context, args, execution, configuration, options) => {
2305
+ const result = await dispatchStoreOperation(
2306
+ context,
2307
+ "deleteEntry",
2308
+ args,
2309
+ execution,
2310
+ configuration,
2311
+ options
2312
+ );
2313
+ return Boolean(result);
2314
+ };
2315
+ const kvTables = {
2316
+ kvEntries: defineTable({
2317
+ key: v.string(),
2318
+ value: v.any(),
2319
+ expiresAt: v.union(v.null(), v.number()),
2320
+ updatedAt: v.number()
2321
+ }).index("byKey", ["key"]).index("byExpiresAt", ["expiresAt"])
2322
+ };
2323
+ defineSchema(kvTables);
2324
+ const internalConvexKv = (configuration_, options_) => {
2325
+ const ConvexKvConfiguration = normalizeConfiguration(configuration_ || {});
2326
+ const ConvexKvOptions = normalizeOptions(options_ || {});
2327
+ return {
2328
+ kv: {
2329
+ /**
2330
+ * Stores a value for the provided key.
2331
+ * @param context the context, can be either an action or mutation context.
2332
+ * @param args the arguments for the set function.
2333
+ * @param execution execution options.
2334
+ * @returns void
2335
+ */
2336
+ set: (context, args, execution) => SetImplementation(
2337
+ context,
2338
+ args,
2339
+ {
2340
+ ...execution,
2341
+ blocking: execution?.blocking ?? ConvexKvConfiguration.execution.blocking
2342
+ },
2343
+ ConvexKvConfiguration,
2344
+ ConvexKvOptions
2345
+ ),
2346
+ /**
2347
+ * Stores a value with expiration metadata.
2348
+ * @param context the context, can be either an action or mutation context.
2349
+ * @param args the arguments for the setWithExpiration function.
2350
+ * @param execution execution options.
2351
+ * @returns void
2352
+ */
2353
+ setWithExpiration: (context, args, execution) => SetImplementation(
2354
+ context,
2355
+ args,
2356
+ {
2357
+ ...execution,
2358
+ blocking: execution?.blocking ?? ConvexKvConfiguration.execution.blocking
2359
+ },
2360
+ ConvexKvConfiguration,
2361
+ ConvexKvOptions
2362
+ ),
2363
+ /**
2364
+ * Retrieves a value by key.
2365
+ * Expired values are automatically treated as missing.
2366
+ */
2367
+ get: (context, args) => GetImplementation(
2368
+ context,
2369
+ args,
2370
+ ConvexKvConfiguration,
2371
+ ConvexKvOptions
2372
+ ),
2373
+ /**
2374
+ * Retrieves a value by key and falls back to defaultValue if missing.
2375
+ */
2376
+ getOrDefault: (context, args) => GetOrDefaultImplementation(
2377
+ context,
2378
+ args,
2379
+ ConvexKvConfiguration,
2380
+ ConvexKvOptions
2381
+ ),
2382
+ /**
2383
+ * Checks whether a non-expired value exists for a key.
2384
+ */
2385
+ has: (context, args) => HasImplementation(
2386
+ context,
2387
+ args,
2388
+ ConvexKvConfiguration,
2389
+ ConvexKvOptions
2390
+ ),
2391
+ /**
2392
+ * Deletes a key from the store.
2393
+ * @returns true when at least one entry was deleted.
2394
+ */
2395
+ delete: (context, args, execution) => DeleteImplementation(
2396
+ context,
2397
+ args,
2398
+ {
2399
+ ...execution,
2400
+ blocking: execution?.blocking ?? ConvexKvConfiguration.execution.blocking
2401
+ },
2402
+ ConvexKvConfiguration,
2403
+ ConvexKvOptions
2404
+ )
2405
+ },
2406
+ store: internalMutationGeneric({
2407
+ args: StoreImplementation.args,
2408
+ handler: async (context, args) => StoreImplementation.handler(
2409
+ context,
2410
+ args,
2411
+ ConvexKvConfiguration,
2412
+ ConvexKvOptions
2413
+ )
2414
+ })
2415
+ };
2416
+ };
2417
+ export {
2418
+ Logger,
2419
+ internalConvexKv,
2420
+ kvTables
2421
+ };