@xata.io/client 0.20.1 → 0.20.2

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/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # @xata.io/client
2
2
 
3
+ ## 0.20.2
4
+
5
+ ### Patch Changes
6
+
7
+ - [#756](https://github.com/xataio/client-ts/pull/756) [`27b73745`](https://github.com/xataio/client-ts/commit/27b737451227cf12774115ccb70649f6bbf76180) Thanks [@SferaDev](https://github.com/SferaDev)! - Fix update method with id in payload
8
+
9
+ - [#726](https://github.com/xataio/client-ts/pull/726) [`47a1f878`](https://github.com/xataio/client-ts/commit/47a1f87850a7178dad656a16d2584eee6ce68f29) Thanks [@SferaDev](https://github.com/SferaDev)! - Use transactions API internally for bulk operations
10
+
11
+ - [#726](https://github.com/xataio/client-ts/pull/726) [`adde9b10`](https://github.com/xataio/client-ts/commit/adde9b10708182295dee07c203c7bf737806e49e) Thanks [@SferaDev](https://github.com/SferaDev)! - Allow sending bulk operations of more than the limit
12
+
3
13
  ## 0.20.1
4
14
 
5
15
  ### Patch Changes
package/dist/index.cjs CHANGED
@@ -1,25 +1,5 @@
1
1
  'use strict';
2
2
 
3
- Object.defineProperty(exports, '__esModule', { value: true });
4
-
5
- function _interopNamespace(e) {
6
- if (e && e.__esModule) return e;
7
- var n = Object.create(null);
8
- if (e) {
9
- Object.keys(e).forEach(function (k) {
10
- if (k !== 'default') {
11
- var d = Object.getOwnPropertyDescriptor(e, k);
12
- Object.defineProperty(n, k, d.get ? d : {
13
- enumerable: true,
14
- get: function () { return e[k]; }
15
- });
16
- }
17
- });
18
- }
19
- n["default"] = e;
20
- return Object.freeze(n);
21
- }
22
-
23
3
  const defaultTrace = async (_name, fn, _options) => {
24
4
  return await fn({
25
5
  setAttributes: () => {
@@ -82,6 +62,13 @@ function deepMerge(a, b) {
82
62
  }
83
63
  return result;
84
64
  }
65
+ function chunk(array, chunkSize) {
66
+ const result = [];
67
+ for (let i = 0; i < array.length; i += chunkSize) {
68
+ result.push(array.slice(i, i + chunkSize));
69
+ }
70
+ return result;
71
+ }
85
72
 
86
73
  function getEnvironment() {
87
74
  try {
@@ -172,7 +159,7 @@ async function getGitBranch() {
172
159
  if (typeof require === "function") {
173
160
  return require(nodeModule).execSync(fullCmd, execOptions).trim();
174
161
  }
175
- const { execSync } = await (function (t) { return Promise.resolve().then(function () { return /*#__PURE__*/_interopNamespace(require(t)); }); })(nodeModule);
162
+ const { execSync } = await import(nodeModule);
176
163
  return execSync(fullCmd, execOptions).toString().trim();
177
164
  } catch (err) {
178
165
  }
@@ -205,7 +192,7 @@ function getFetchImplementation(userFetch) {
205
192
  return fetchImpl;
206
193
  }
207
194
 
208
- const VERSION = "0.20.1";
195
+ const VERSION = "0.20.2";
209
196
 
210
197
  class ErrorWithCause extends Error {
211
198
  constructor(message, options) {
@@ -1388,6 +1375,19 @@ class RecordsApi {
1388
1375
  ...this.extraProps
1389
1376
  });
1390
1377
  }
1378
+ branchTransaction({
1379
+ workspace,
1380
+ region,
1381
+ database,
1382
+ branch,
1383
+ operations
1384
+ }) {
1385
+ return operationsByTag.records.branchTransaction({
1386
+ pathParams: { workspace, region, dbBranchName: `${database}:${branch}` },
1387
+ body: { operations },
1388
+ ...this.extraProps
1389
+ });
1390
+ }
1391
1391
  }
1392
1392
  class SearchAndFilterApi {
1393
1393
  constructor(extraProps) {
@@ -2153,7 +2153,8 @@ var __privateMethod$2 = (obj, member, method) => {
2153
2153
  __accessCheck$4(obj, member, "access private method");
2154
2154
  return method;
2155
2155
  };
2156
- var _table, _getFetchProps, _db, _cache, _schemaTables$2, _trace, _insertRecordWithoutId, insertRecordWithoutId_fn, _insertRecordWithId, insertRecordWithId_fn, _bulkInsertTableRecords, bulkInsertTableRecords_fn, _updateRecordWithID, updateRecordWithID_fn, _upsertRecordWithID, upsertRecordWithID_fn, _deleteRecord, deleteRecord_fn, _setCacheQuery, setCacheQuery_fn, _getCacheQuery, getCacheQuery_fn, _getSchemaTables$1, getSchemaTables_fn$1;
2156
+ var _table, _getFetchProps, _db, _cache, _schemaTables$2, _trace, _insertRecordWithoutId, insertRecordWithoutId_fn, _insertRecordWithId, insertRecordWithId_fn, _insertRecords, insertRecords_fn, _updateRecordWithID, updateRecordWithID_fn, _updateRecords, updateRecords_fn, _upsertRecordWithID, upsertRecordWithID_fn, _deleteRecord, deleteRecord_fn, _deleteRecords, deleteRecords_fn, _setCacheQuery, setCacheQuery_fn, _getCacheQuery, getCacheQuery_fn, _getSchemaTables$1, getSchemaTables_fn$1;
2157
+ const BULK_OPERATION_MAX_SIZE = 1e3;
2157
2158
  class Repository extends Query {
2158
2159
  }
2159
2160
  class RestRepository extends Query {
@@ -2165,10 +2166,12 @@ class RestRepository extends Query {
2165
2166
  );
2166
2167
  __privateAdd$4(this, _insertRecordWithoutId);
2167
2168
  __privateAdd$4(this, _insertRecordWithId);
2168
- __privateAdd$4(this, _bulkInsertTableRecords);
2169
+ __privateAdd$4(this, _insertRecords);
2169
2170
  __privateAdd$4(this, _updateRecordWithID);
2171
+ __privateAdd$4(this, _updateRecords);
2170
2172
  __privateAdd$4(this, _upsertRecordWithID);
2171
2173
  __privateAdd$4(this, _deleteRecord);
2174
+ __privateAdd$4(this, _deleteRecords);
2172
2175
  __privateAdd$4(this, _setCacheQuery);
2173
2176
  __privateAdd$4(this, _getCacheQuery);
2174
2177
  __privateAdd$4(this, _getSchemaTables$1);
@@ -2202,20 +2205,22 @@ class RestRepository extends Query {
2202
2205
  if (Array.isArray(a)) {
2203
2206
  if (a.length === 0)
2204
2207
  return [];
2205
- const columns = isStringArray(b) ? b : void 0;
2206
- return __privateMethod$2(this, _bulkInsertTableRecords, bulkInsertTableRecords_fn).call(this, a, columns);
2208
+ const ids = await __privateMethod$2(this, _insertRecords, insertRecords_fn).call(this, a, { ifVersion, createOnly: true });
2209
+ const columns = isStringArray(b) ? b : ["*"];
2210
+ const result = await this.read(ids, columns);
2211
+ return result;
2207
2212
  }
2208
2213
  if (isString(a) && isObject(b)) {
2209
2214
  if (a === "")
2210
2215
  throw new Error("The id can't be empty");
2211
2216
  const columns = isStringArray(c) ? c : void 0;
2212
- return __privateMethod$2(this, _insertRecordWithId, insertRecordWithId_fn).call(this, a, b, columns, { createOnly: true, ifVersion });
2217
+ return await __privateMethod$2(this, _insertRecordWithId, insertRecordWithId_fn).call(this, a, b, columns, { createOnly: true, ifVersion });
2213
2218
  }
2214
2219
  if (isObject(a) && isString(a.id)) {
2215
2220
  if (a.id === "")
2216
2221
  throw new Error("The id can't be empty");
2217
2222
  const columns = isStringArray(b) ? b : void 0;
2218
- return __privateMethod$2(this, _insertRecordWithId, insertRecordWithId_fn).call(this, a.id, { ...a, id: void 0 }, columns, { createOnly: true, ifVersion });
2223
+ return await __privateMethod$2(this, _insertRecordWithId, insertRecordWithId_fn).call(this, a.id, { ...a, id: void 0 }, columns, { createOnly: true, ifVersion });
2219
2224
  }
2220
2225
  if (isObject(a)) {
2221
2226
  const columns = isStringArray(b) ? b : void 0;
@@ -2290,11 +2295,15 @@ class RestRepository extends Query {
2290
2295
  if (Array.isArray(a)) {
2291
2296
  if (a.length === 0)
2292
2297
  return [];
2293
- if (a.length > 100) {
2294
- console.warn("Bulk update operation is not optimized in the Xata API yet, this request might be slow");
2295
- }
2298
+ const existing = await this.read(a, ["id"]);
2299
+ const updates = a.filter((_item, index) => existing[index] !== null);
2300
+ await __privateMethod$2(this, _updateRecords, updateRecords_fn).call(this, updates, {
2301
+ ifVersion,
2302
+ upsert: false
2303
+ });
2296
2304
  const columns = isStringArray(b) ? b : ["*"];
2297
- return Promise.all(a.map((object) => this.update(object, columns)));
2305
+ const result = await this.read(a, columns);
2306
+ return result;
2298
2307
  }
2299
2308
  if (isString(a) && isObject(b)) {
2300
2309
  const columns = isStringArray(c) ? c : void 0;
@@ -2332,11 +2341,13 @@ class RestRepository extends Query {
2332
2341
  if (Array.isArray(a)) {
2333
2342
  if (a.length === 0)
2334
2343
  return [];
2335
- if (a.length > 100) {
2336
- console.warn("Bulk update operation is not optimized in the Xata API yet, this request might be slow");
2337
- }
2344
+ await __privateMethod$2(this, _updateRecords, updateRecords_fn).call(this, a, {
2345
+ ifVersion,
2346
+ upsert: true
2347
+ });
2338
2348
  const columns = isStringArray(b) ? b : ["*"];
2339
- return Promise.all(a.map((object) => this.createOrUpdate(object, columns)));
2349
+ const result = await this.read(a, columns);
2350
+ return result;
2340
2351
  }
2341
2352
  if (isString(a) && isObject(b)) {
2342
2353
  const columns = isStringArray(c) ? c : void 0;
@@ -2355,8 +2366,10 @@ class RestRepository extends Query {
2355
2366
  if (Array.isArray(a)) {
2356
2367
  if (a.length === 0)
2357
2368
  return [];
2369
+ const ids = await __privateMethod$2(this, _insertRecords, insertRecords_fn).call(this, a, { ifVersion, createOnly: false });
2358
2370
  const columns = isStringArray(b) ? b : ["*"];
2359
- return __privateMethod$2(this, _bulkInsertTableRecords, bulkInsertTableRecords_fn).call(this, a, columns);
2371
+ const result = await this.read(ids, columns);
2372
+ return result;
2360
2373
  }
2361
2374
  if (isString(a) && isObject(b)) {
2362
2375
  const columns = isStringArray(c) ? c : void 0;
@@ -2374,10 +2387,17 @@ class RestRepository extends Query {
2374
2387
  if (Array.isArray(a)) {
2375
2388
  if (a.length === 0)
2376
2389
  return [];
2377
- if (a.length > 100) {
2378
- console.warn("Bulk delete operation is not optimized in the Xata API yet, this request might be slow");
2379
- }
2380
- return Promise.all(a.map((id) => this.delete(id, b)));
2390
+ const ids = a.map((o) => {
2391
+ if (isString(o))
2392
+ return o;
2393
+ if (isString(o.id))
2394
+ return o.id;
2395
+ throw new Error("Invalid arguments for delete method");
2396
+ });
2397
+ const columns = isStringArray(b) ? b : ["*"];
2398
+ const result = await this.read(a, columns);
2399
+ await __privateMethod$2(this, _deleteRecords, deleteRecords_fn).call(this, ids);
2400
+ return result;
2381
2401
  }
2382
2402
  if (isString(a)) {
2383
2403
  return __privateMethod$2(this, _deleteRecord, deleteRecord_fn).call(this, a, b);
@@ -2545,31 +2565,40 @@ insertRecordWithId_fn = async function(recordId, object, columns = ["*"], { crea
2545
2565
  const schemaTables = await __privateMethod$2(this, _getSchemaTables$1, getSchemaTables_fn$1).call(this);
2546
2566
  return initObject(__privateGet$4(this, _db), schemaTables, __privateGet$4(this, _table), response, columns);
2547
2567
  };
2548
- _bulkInsertTableRecords = new WeakSet();
2549
- bulkInsertTableRecords_fn = async function(objects, columns = ["*"]) {
2568
+ _insertRecords = new WeakSet();
2569
+ insertRecords_fn = async function(objects, { createOnly, ifVersion }) {
2550
2570
  const fetchProps = await __privateGet$4(this, _getFetchProps).call(this);
2551
- const records = objects.map((object) => transformObjectLinks(object));
2552
- const response = await bulkInsertTableRecords({
2553
- pathParams: {
2554
- workspace: "{workspaceId}",
2555
- dbBranchName: "{dbBranch}",
2556
- region: "{region}",
2557
- tableName: __privateGet$4(this, _table)
2558
- },
2559
- queryParams: { columns },
2560
- body: { records },
2561
- ...fetchProps
2562
- });
2563
- if (!isResponseWithRecords(response)) {
2564
- throw new Error("Request included columns but server didn't include them");
2571
+ const chunkedOperations = chunk(
2572
+ objects.map((object) => ({
2573
+ insert: { table: __privateGet$4(this, _table), record: transformObjectLinks(object), createOnly, ifVersion }
2574
+ })),
2575
+ BULK_OPERATION_MAX_SIZE
2576
+ );
2577
+ const ids = [];
2578
+ for (const operations of chunkedOperations) {
2579
+ const { results } = await branchTransaction({
2580
+ pathParams: {
2581
+ workspace: "{workspaceId}",
2582
+ dbBranchName: "{dbBranch}",
2583
+ region: "{region}"
2584
+ },
2585
+ body: { operations },
2586
+ ...fetchProps
2587
+ });
2588
+ for (const result of results) {
2589
+ if (result.operation === "insert") {
2590
+ ids.push(result.id);
2591
+ } else {
2592
+ ids.push(null);
2593
+ }
2594
+ }
2565
2595
  }
2566
- const schemaTables = await __privateMethod$2(this, _getSchemaTables$1, getSchemaTables_fn$1).call(this);
2567
- return response.records?.map((item) => initObject(__privateGet$4(this, _db), schemaTables, __privateGet$4(this, _table), item, columns));
2596
+ return ids;
2568
2597
  };
2569
2598
  _updateRecordWithID = new WeakSet();
2570
2599
  updateRecordWithID_fn = async function(recordId, object, columns = ["*"], { ifVersion }) {
2571
2600
  const fetchProps = await __privateGet$4(this, _getFetchProps).call(this);
2572
- const record = transformObjectLinks(object);
2601
+ const { id: _id, ...record } = transformObjectLinks(object);
2573
2602
  try {
2574
2603
  const response = await updateRecordWithID({
2575
2604
  pathParams: {
@@ -2592,6 +2621,36 @@ updateRecordWithID_fn = async function(recordId, object, columns = ["*"], { ifVe
2592
2621
  throw e;
2593
2622
  }
2594
2623
  };
2624
+ _updateRecords = new WeakSet();
2625
+ updateRecords_fn = async function(objects, { ifVersion, upsert }) {
2626
+ const fetchProps = await __privateGet$4(this, _getFetchProps).call(this);
2627
+ const chunkedOperations = chunk(
2628
+ objects.map(({ id, ...object }) => ({
2629
+ update: { table: __privateGet$4(this, _table), id, ifVersion, upsert, fields: transformObjectLinks(object) }
2630
+ })),
2631
+ BULK_OPERATION_MAX_SIZE
2632
+ );
2633
+ const ids = [];
2634
+ for (const operations of chunkedOperations) {
2635
+ const { results } = await branchTransaction({
2636
+ pathParams: {
2637
+ workspace: "{workspaceId}",
2638
+ dbBranchName: "{dbBranch}",
2639
+ region: "{region}"
2640
+ },
2641
+ body: { operations },
2642
+ ...fetchProps
2643
+ });
2644
+ for (const result of results) {
2645
+ if (result.operation === "update") {
2646
+ ids.push(result.id);
2647
+ } else {
2648
+ ids.push(null);
2649
+ }
2650
+ }
2651
+ }
2652
+ return ids;
2653
+ };
2595
2654
  _upsertRecordWithID = new WeakSet();
2596
2655
  upsertRecordWithID_fn = async function(recordId, object, columns = ["*"], { ifVersion }) {
2597
2656
  const fetchProps = await __privateGet$4(this, _getFetchProps).call(this);
@@ -2634,6 +2693,25 @@ deleteRecord_fn = async function(recordId, columns = ["*"]) {
2634
2693
  throw e;
2635
2694
  }
2636
2695
  };
2696
+ _deleteRecords = new WeakSet();
2697
+ deleteRecords_fn = async function(recordIds) {
2698
+ const fetchProps = await __privateGet$4(this, _getFetchProps).call(this);
2699
+ const chunkedOperations = chunk(
2700
+ recordIds.map((id) => ({ delete: { table: __privateGet$4(this, _table), id } })),
2701
+ BULK_OPERATION_MAX_SIZE
2702
+ );
2703
+ for (const operations of chunkedOperations) {
2704
+ await branchTransaction({
2705
+ pathParams: {
2706
+ workspace: "{workspaceId}",
2707
+ dbBranchName: "{dbBranch}",
2708
+ region: "{region}"
2709
+ },
2710
+ body: { operations },
2711
+ ...fetchProps
2712
+ });
2713
+ }
2714
+ };
2637
2715
  _setCacheQuery = new WeakSet();
2638
2716
  setCacheQuery_fn = async function(query, meta, records) {
2639
2717
  await __privateGet$4(this, _cache).set(`query_${__privateGet$4(this, _table)}:${query.key()}`, { date: new Date(), meta, records });
@@ -2744,9 +2822,6 @@ const initObject = (db, schemaTables, table, object, selectedColumns) => {
2744
2822
  Object.freeze(result);
2745
2823
  return result;
2746
2824
  };
2747
- function isResponseWithRecords(value) {
2748
- return isObject(value) && Array.isArray(value.records);
2749
- }
2750
2825
  function extractId(value) {
2751
2826
  if (isString(value))
2752
2827
  return value;