@tursodatabase/serverless 1.1.2-pre.1 → 1.1.3

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.
@@ -28,7 +28,7 @@ function encodeValue(value) {
28
28
  if (!Number.isFinite(value)) {
29
29
  throw new Error("Only finite numbers (not Infinity or NaN) can be passed as arguments");
30
30
  }
31
- if (Number.isInteger(value)) {
31
+ if (Number.isSafeInteger(value)) {
32
32
  return { type: "integer", value: value.toString() };
33
33
  }
34
34
  return { type: "float", value };
@@ -26,7 +26,7 @@ function encodeValue(value) {
26
26
  if (!Number.isFinite(value)) {
27
27
  throw new Error("Only finite numbers (not Infinity or NaN) can be passed as arguments");
28
28
  }
29
- if (Number.isInteger(value)) {
29
+ if (Number.isSafeInteger(value)) {
30
30
  return { type: "integer", value: value.toString() };
31
31
  }
32
32
  return { type: "float", value };
package/dist/index.cjs CHANGED
@@ -53,7 +53,7 @@ function encodeValue(value) {
53
53
  if (!Number.isFinite(value)) {
54
54
  throw new Error("Only finite numbers (not Infinity or NaN) can be passed as arguments");
55
55
  }
56
- if (Number.isInteger(value)) {
56
+ if (Number.isSafeInteger(value)) {
57
57
  return { type: "integer", value: value.toString() };
58
58
  }
59
59
  return { type: "float", value };
@@ -547,6 +547,37 @@ var Session = class {
547
547
  }
548
548
  };
549
549
 
550
+ // src/args.ts
551
+ function normalizeArgs(args) {
552
+ if (args === void 0) return [];
553
+ if (Array.isArray(args)) return args;
554
+ if (args !== null && typeof args === "object" && args.constructor === Object) {
555
+ return args;
556
+ }
557
+ return [args];
558
+ }
559
+ function isQueryOptions(value) {
560
+ return value != null && typeof value === "object" && !Array.isArray(value) && Object.prototype.hasOwnProperty.call(value, "queryTimeout");
561
+ }
562
+ function splitBindParameters(bindParameters) {
563
+ if (bindParameters.length === 0) {
564
+ return { params: void 0, queryOptions: void 0 };
565
+ }
566
+ if (isQueryOptions(bindParameters[bindParameters.length - 1])) {
567
+ if (bindParameters.length === 1) {
568
+ return { params: void 0, queryOptions: bindParameters[0] };
569
+ }
570
+ return {
571
+ params: bindParameters.length === 2 ? bindParameters[0] : bindParameters.slice(0, -1),
572
+ queryOptions: bindParameters[bindParameters.length - 1]
573
+ };
574
+ }
575
+ return {
576
+ params: bindParameters.length === 1 ? bindParameters[0] : bindParameters,
577
+ queryOptions: void 0
578
+ };
579
+ }
580
+
550
581
  // src/statement.ts
551
582
  var Statement = class _Statement {
552
583
  constructor(sessionConfig, sql, columns) {
@@ -678,7 +709,7 @@ var Statement = class _Statement {
678
709
  */
679
710
  async run(args, queryOptions) {
680
711
  return await this.withLock(async () => {
681
- const normalizedArgs = this.normalizeArgs(args);
712
+ const normalizedArgs = normalizeArgs(args);
682
713
  const result = await this.session.execute(this.sql, normalizedArgs, this.safeIntegerMode, queryOptions);
683
714
  return { changes: result.rowsAffected, lastInsertRowid: result.lastInsertRowid };
684
715
  });
@@ -700,7 +731,7 @@ var Statement = class _Statement {
700
731
  */
701
732
  async get(args, queryOptions) {
702
733
  return await this.withLock(async () => {
703
- const normalizedArgs = this.normalizeArgs(args);
734
+ const normalizedArgs = normalizeArgs(args);
704
735
  const result = await this.session.execute(this.sql, normalizedArgs, this.safeIntegerMode, queryOptions);
705
736
  const row = result.rows[0];
706
737
  if (!row) {
@@ -734,7 +765,7 @@ var Statement = class _Statement {
734
765
  */
735
766
  async all(args, queryOptions) {
736
767
  return await this.withLock(async () => {
737
- const normalizedArgs = this.normalizeArgs(args);
768
+ const normalizedArgs = normalizeArgs(args);
738
769
  const result = await this.session.execute(this.sql, normalizedArgs, this.safeIntegerMode, queryOptions);
739
770
  if (this.presentationMode === "pluck") {
740
771
  return result.rows.map((row) => row[0]);
@@ -777,7 +808,7 @@ var Statement = class _Statement {
777
808
  }
778
809
  return;
779
810
  }
780
- const normalizedArgs = this.normalizeArgs(args);
811
+ const normalizedArgs = normalizeArgs(args);
781
812
  const { entries } = await this.session.executeRaw(this.sql, normalizedArgs, queryOptions);
782
813
  let columns = [];
783
814
  for await (const entry of entries) {
@@ -809,22 +840,6 @@ var Statement = class _Statement {
809
840
  }
810
841
  }
811
842
  }
812
- /**
813
- * Normalize arguments to handle both single values and arrays.
814
- * Matches the behavior of the native bindings.
815
- */
816
- normalizeArgs(args) {
817
- if (args === void 0) {
818
- return [];
819
- }
820
- if (Array.isArray(args)) {
821
- return args;
822
- }
823
- if (args !== null && typeof args === "object" && args.constructor === Object) {
824
- return args;
825
- }
826
- return [args];
827
- }
828
843
  };
829
844
 
830
845
  // src/connection.ts
@@ -870,22 +885,89 @@ var Connection = class {
870
885
  if (!this.isOpen) {
871
886
  throw new TypeError("The database connection is not open");
872
887
  }
873
- const session = new Session(this.config);
874
- const description = await session.describe(sql);
875
- await session.close();
888
+ await this.execLock.acquire();
889
+ let description;
890
+ try {
891
+ description = await this.session.describe(sql);
892
+ } finally {
893
+ this.execLock.release();
894
+ }
876
895
  const stmt = Statement.fromSession(this.session, sql, description.cols, this.execLock);
877
896
  if (this.defaultSafeIntegerMode) {
878
897
  stmt.safeIntegers(true);
879
898
  }
880
899
  return stmt;
881
900
  }
901
+ /**
902
+ * Like `prepare(sql).run(args)` but in a single round trip — skips `describe`
903
+ * since run() does not need column metadata.
904
+ */
905
+ async run(sql, ...bindParameters) {
906
+ if (!this.isOpen) throw new TypeError("The database connection is not open");
907
+ const { params, queryOptions } = splitBindParameters(bindParameters);
908
+ await this.execLock.acquire();
909
+ try {
910
+ const result = await this.session.execute(sql, normalizeArgs(params), this.defaultSafeIntegerMode, queryOptions);
911
+ return { changes: result.rowsAffected, lastInsertRowid: result.lastInsertRowid };
912
+ } finally {
913
+ this.execLock.release();
914
+ }
915
+ }
916
+ /**
917
+ * Like `prepare(sql).get(args)` but in a single round trip.
918
+ */
919
+ async get(sql, ...bindParameters) {
920
+ if (!this.isOpen) throw new TypeError("The database connection is not open");
921
+ const { params, queryOptions } = splitBindParameters(bindParameters);
922
+ await this.execLock.acquire();
923
+ try {
924
+ const result = await this.session.execute(sql, normalizeArgs(params), this.defaultSafeIntegerMode, queryOptions);
925
+ const row = result.rows[0];
926
+ if (!row) return void 0;
927
+ const obj = {};
928
+ result.columns.forEach((col, i) => {
929
+ obj[col] = row[i];
930
+ });
931
+ return obj;
932
+ } finally {
933
+ this.execLock.release();
934
+ }
935
+ }
936
+ /**
937
+ * Like `prepare(sql).all(args)` but in a single round trip.
938
+ */
939
+ async all(sql, ...bindParameters) {
940
+ if (!this.isOpen) throw new TypeError("The database connection is not open");
941
+ const { params, queryOptions } = splitBindParameters(bindParameters);
942
+ await this.execLock.acquire();
943
+ try {
944
+ const result = await this.session.execute(sql, normalizeArgs(params), this.defaultSafeIntegerMode, queryOptions);
945
+ return result.rows.map((row) => {
946
+ const obj = {};
947
+ result.columns.forEach((col, i) => {
948
+ obj[col] = row[i];
949
+ });
950
+ return obj;
951
+ });
952
+ } finally {
953
+ this.execLock.release();
954
+ }
955
+ }
956
+ /**
957
+ * Like `prepare(sql).iterate(args)` but in a single round trip. Buffers the
958
+ * result set — the connection lock cannot be held across `yield` points
959
+ * without risking deadlock on nested calls.
960
+ */
961
+ async *iterate(sql, ...bindParameters) {
962
+ for (const row of await this.all(sql, ...bindParameters)) yield row;
963
+ }
882
964
  /**
883
965
  * Execute a SQL statement and return all results.
884
- *
966
+ *
885
967
  * @param sql - The SQL statement to execute
886
968
  * @param args - Optional array of parameter values
887
969
  * @returns Promise resolving to the complete result set
888
- *
970
+ *
889
971
  * @example
890
972
  * ```typescript
891
973
  * const result = await client.execute("SELECT * FROM users WHERE id = ?", [123]);
package/dist/index.d.cts CHANGED
@@ -291,11 +291,6 @@ declare class Statement {
291
291
  * ```
292
292
  */
293
293
  iterate(args?: any, queryOptions?: QueryOptions): AsyncGenerator<any>;
294
- /**
295
- * Normalize arguments to handle both single values and arrays.
296
- * Matches the behavior of the native bindings.
297
- */
298
- private normalizeArgs;
299
294
  }
300
295
 
301
296
  /**
@@ -376,6 +371,25 @@ declare class Connection {
376
371
  * ```
377
372
  */
378
373
  prepare(sql: string): Promise<Statement>;
374
+ /**
375
+ * Like `prepare(sql).run(args)` but in a single round trip — skips `describe`
376
+ * since run() does not need column metadata.
377
+ */
378
+ run(sql: string, ...bindParameters: any[]): Promise<any>;
379
+ /**
380
+ * Like `prepare(sql).get(args)` but in a single round trip.
381
+ */
382
+ get(sql: string, ...bindParameters: any[]): Promise<any>;
383
+ /**
384
+ * Like `prepare(sql).all(args)` but in a single round trip.
385
+ */
386
+ all(sql: string, ...bindParameters: any[]): Promise<any[]>;
387
+ /**
388
+ * Like `prepare(sql).iterate(args)` but in a single round trip. Buffers the
389
+ * result set — the connection lock cannot be held across `yield` points
390
+ * without risking deadlock on nested calls.
391
+ */
392
+ iterate(sql: string, ...bindParameters: any[]): AsyncGenerator<any>;
379
393
  /**
380
394
  * Execute a SQL statement and return all results.
381
395
  *
package/dist/index.d.ts CHANGED
@@ -291,11 +291,6 @@ declare class Statement {
291
291
  * ```
292
292
  */
293
293
  iterate(args?: any, queryOptions?: QueryOptions): AsyncGenerator<any>;
294
- /**
295
- * Normalize arguments to handle both single values and arrays.
296
- * Matches the behavior of the native bindings.
297
- */
298
- private normalizeArgs;
299
294
  }
300
295
 
301
296
  /**
@@ -376,6 +371,25 @@ declare class Connection {
376
371
  * ```
377
372
  */
378
373
  prepare(sql: string): Promise<Statement>;
374
+ /**
375
+ * Like `prepare(sql).run(args)` but in a single round trip — skips `describe`
376
+ * since run() does not need column metadata.
377
+ */
378
+ run(sql: string, ...bindParameters: any[]): Promise<any>;
379
+ /**
380
+ * Like `prepare(sql).get(args)` but in a single round trip.
381
+ */
382
+ get(sql: string, ...bindParameters: any[]): Promise<any>;
383
+ /**
384
+ * Like `prepare(sql).all(args)` but in a single round trip.
385
+ */
386
+ all(sql: string, ...bindParameters: any[]): Promise<any[]>;
387
+ /**
388
+ * Like `prepare(sql).iterate(args)` but in a single round trip. Buffers the
389
+ * result set — the connection lock cannot be held across `yield` points
390
+ * without risking deadlock on nested calls.
391
+ */
392
+ iterate(sql: string, ...bindParameters: any[]): AsyncGenerator<any>;
379
393
  /**
380
394
  * Execute a SQL statement and return all results.
381
395
  *
package/dist/index.js CHANGED
@@ -51,7 +51,7 @@ function encodeValue(value) {
51
51
  if (!Number.isFinite(value)) {
52
52
  throw new Error("Only finite numbers (not Infinity or NaN) can be passed as arguments");
53
53
  }
54
- if (Number.isInteger(value)) {
54
+ if (Number.isSafeInteger(value)) {
55
55
  return { type: "integer", value: value.toString() };
56
56
  }
57
57
  return { type: "float", value };
@@ -545,6 +545,37 @@ var Session = class {
545
545
  }
546
546
  };
547
547
 
548
+ // src/args.ts
549
+ function normalizeArgs(args) {
550
+ if (args === void 0) return [];
551
+ if (Array.isArray(args)) return args;
552
+ if (args !== null && typeof args === "object" && args.constructor === Object) {
553
+ return args;
554
+ }
555
+ return [args];
556
+ }
557
+ function isQueryOptions(value) {
558
+ return value != null && typeof value === "object" && !Array.isArray(value) && Object.prototype.hasOwnProperty.call(value, "queryTimeout");
559
+ }
560
+ function splitBindParameters(bindParameters) {
561
+ if (bindParameters.length === 0) {
562
+ return { params: void 0, queryOptions: void 0 };
563
+ }
564
+ if (isQueryOptions(bindParameters[bindParameters.length - 1])) {
565
+ if (bindParameters.length === 1) {
566
+ return { params: void 0, queryOptions: bindParameters[0] };
567
+ }
568
+ return {
569
+ params: bindParameters.length === 2 ? bindParameters[0] : bindParameters.slice(0, -1),
570
+ queryOptions: bindParameters[bindParameters.length - 1]
571
+ };
572
+ }
573
+ return {
574
+ params: bindParameters.length === 1 ? bindParameters[0] : bindParameters,
575
+ queryOptions: void 0
576
+ };
577
+ }
578
+
548
579
  // src/statement.ts
549
580
  var Statement = class _Statement {
550
581
  constructor(sessionConfig, sql, columns) {
@@ -676,7 +707,7 @@ var Statement = class _Statement {
676
707
  */
677
708
  async run(args, queryOptions) {
678
709
  return await this.withLock(async () => {
679
- const normalizedArgs = this.normalizeArgs(args);
710
+ const normalizedArgs = normalizeArgs(args);
680
711
  const result = await this.session.execute(this.sql, normalizedArgs, this.safeIntegerMode, queryOptions);
681
712
  return { changes: result.rowsAffected, lastInsertRowid: result.lastInsertRowid };
682
713
  });
@@ -698,7 +729,7 @@ var Statement = class _Statement {
698
729
  */
699
730
  async get(args, queryOptions) {
700
731
  return await this.withLock(async () => {
701
- const normalizedArgs = this.normalizeArgs(args);
732
+ const normalizedArgs = normalizeArgs(args);
702
733
  const result = await this.session.execute(this.sql, normalizedArgs, this.safeIntegerMode, queryOptions);
703
734
  const row = result.rows[0];
704
735
  if (!row) {
@@ -732,7 +763,7 @@ var Statement = class _Statement {
732
763
  */
733
764
  async all(args, queryOptions) {
734
765
  return await this.withLock(async () => {
735
- const normalizedArgs = this.normalizeArgs(args);
766
+ const normalizedArgs = normalizeArgs(args);
736
767
  const result = await this.session.execute(this.sql, normalizedArgs, this.safeIntegerMode, queryOptions);
737
768
  if (this.presentationMode === "pluck") {
738
769
  return result.rows.map((row) => row[0]);
@@ -775,7 +806,7 @@ var Statement = class _Statement {
775
806
  }
776
807
  return;
777
808
  }
778
- const normalizedArgs = this.normalizeArgs(args);
809
+ const normalizedArgs = normalizeArgs(args);
779
810
  const { entries } = await this.session.executeRaw(this.sql, normalizedArgs, queryOptions);
780
811
  let columns = [];
781
812
  for await (const entry of entries) {
@@ -807,22 +838,6 @@ var Statement = class _Statement {
807
838
  }
808
839
  }
809
840
  }
810
- /**
811
- * Normalize arguments to handle both single values and arrays.
812
- * Matches the behavior of the native bindings.
813
- */
814
- normalizeArgs(args) {
815
- if (args === void 0) {
816
- return [];
817
- }
818
- if (Array.isArray(args)) {
819
- return args;
820
- }
821
- if (args !== null && typeof args === "object" && args.constructor === Object) {
822
- return args;
823
- }
824
- return [args];
825
- }
826
841
  };
827
842
 
828
843
  // src/connection.ts
@@ -868,22 +883,89 @@ var Connection = class {
868
883
  if (!this.isOpen) {
869
884
  throw new TypeError("The database connection is not open");
870
885
  }
871
- const session = new Session(this.config);
872
- const description = await session.describe(sql);
873
- await session.close();
886
+ await this.execLock.acquire();
887
+ let description;
888
+ try {
889
+ description = await this.session.describe(sql);
890
+ } finally {
891
+ this.execLock.release();
892
+ }
874
893
  const stmt = Statement.fromSession(this.session, sql, description.cols, this.execLock);
875
894
  if (this.defaultSafeIntegerMode) {
876
895
  stmt.safeIntegers(true);
877
896
  }
878
897
  return stmt;
879
898
  }
899
+ /**
900
+ * Like `prepare(sql).run(args)` but in a single round trip — skips `describe`
901
+ * since run() does not need column metadata.
902
+ */
903
+ async run(sql, ...bindParameters) {
904
+ if (!this.isOpen) throw new TypeError("The database connection is not open");
905
+ const { params, queryOptions } = splitBindParameters(bindParameters);
906
+ await this.execLock.acquire();
907
+ try {
908
+ const result = await this.session.execute(sql, normalizeArgs(params), this.defaultSafeIntegerMode, queryOptions);
909
+ return { changes: result.rowsAffected, lastInsertRowid: result.lastInsertRowid };
910
+ } finally {
911
+ this.execLock.release();
912
+ }
913
+ }
914
+ /**
915
+ * Like `prepare(sql).get(args)` but in a single round trip.
916
+ */
917
+ async get(sql, ...bindParameters) {
918
+ if (!this.isOpen) throw new TypeError("The database connection is not open");
919
+ const { params, queryOptions } = splitBindParameters(bindParameters);
920
+ await this.execLock.acquire();
921
+ try {
922
+ const result = await this.session.execute(sql, normalizeArgs(params), this.defaultSafeIntegerMode, queryOptions);
923
+ const row = result.rows[0];
924
+ if (!row) return void 0;
925
+ const obj = {};
926
+ result.columns.forEach((col, i) => {
927
+ obj[col] = row[i];
928
+ });
929
+ return obj;
930
+ } finally {
931
+ this.execLock.release();
932
+ }
933
+ }
934
+ /**
935
+ * Like `prepare(sql).all(args)` but in a single round trip.
936
+ */
937
+ async all(sql, ...bindParameters) {
938
+ if (!this.isOpen) throw new TypeError("The database connection is not open");
939
+ const { params, queryOptions } = splitBindParameters(bindParameters);
940
+ await this.execLock.acquire();
941
+ try {
942
+ const result = await this.session.execute(sql, normalizeArgs(params), this.defaultSafeIntegerMode, queryOptions);
943
+ return result.rows.map((row) => {
944
+ const obj = {};
945
+ result.columns.forEach((col, i) => {
946
+ obj[col] = row[i];
947
+ });
948
+ return obj;
949
+ });
950
+ } finally {
951
+ this.execLock.release();
952
+ }
953
+ }
954
+ /**
955
+ * Like `prepare(sql).iterate(args)` but in a single round trip. Buffers the
956
+ * result set — the connection lock cannot be held across `yield` points
957
+ * without risking deadlock on nested calls.
958
+ */
959
+ async *iterate(sql, ...bindParameters) {
960
+ for (const row of await this.all(sql, ...bindParameters)) yield row;
961
+ }
880
962
  /**
881
963
  * Execute a SQL statement and return all results.
882
- *
964
+ *
883
965
  * @param sql - The SQL statement to execute
884
966
  * @param args - Optional array of parameter values
885
967
  * @returns Promise resolving to the complete result set
886
- *
968
+ *
887
969
  * @example
888
970
  * ```typescript
889
971
  * const result = await client.execute("SELECT * FROM users WHERE id = ?", [123]);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tursodatabase/serverless",
3
- "version": "1.1.2-pre.1",
3
+ "version": "1.1.3",
4
4
  "type": "module",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.js",