@airtable/blocks 1.11.1 → 1.12.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.
Files changed (41) hide show
  1. package/dist/cjs/global_config.js +3 -3
  2. package/dist/cjs/models/base.js +10 -10
  3. package/dist/cjs/models/cursor.js +4 -6
  4. package/dist/cjs/models/field.js +3 -3
  5. package/dist/cjs/models/record_query_result.js +1 -1
  6. package/dist/cjs/models/record_store.js +68 -16
  7. package/dist/cjs/models/session.js +3 -3
  8. package/dist/cjs/models/table.js +25 -25
  9. package/dist/cjs/sdk.js +1 -1
  10. package/dist/cjs/settings_button.js +1 -1
  11. package/dist/cjs/ui/expand_record_picker_async.js +1 -1
  12. package/dist/cjs/ui/icon_config.js +4 -2
  13. package/dist/cjs/ui/initialize_block.js +3 -3
  14. package/dist/cjs/ui/use_global_config.js +1 -1
  15. package/dist/cjs/ui/use_loadable.js +3 -3
  16. package/dist/cjs/ui/use_record_action_data.js +11 -11
  17. package/dist/cjs/ui/use_settings_button.js +1 -1
  18. package/dist/cjs/ui/viewport_constraint.js +1 -1
  19. package/dist/cjs/viewport.js +9 -9
  20. package/dist/types/src/global_config.d.ts +3 -3
  21. package/dist/types/src/models/base.d.ts +9 -9
  22. package/dist/types/src/models/cursor.d.ts +4 -6
  23. package/dist/types/src/models/cursor.d.ts.map +1 -1
  24. package/dist/types/src/models/field.d.ts +3 -3
  25. package/dist/types/src/models/record_query_result.d.ts +2 -2
  26. package/dist/types/src/models/session.d.ts +3 -3
  27. package/dist/types/src/models/table.d.ts +25 -25
  28. package/dist/types/src/settings_button.d.ts +1 -1
  29. package/dist/types/src/ui/expand_record_picker_async.d.ts +1 -1
  30. package/dist/types/src/ui/icon_config.d.ts +5 -3
  31. package/dist/types/src/ui/icon_config.d.ts.map +1 -1
  32. package/dist/types/src/ui/initialize_block.d.ts +1 -1
  33. package/dist/types/src/ui/use_global_config.d.ts +1 -1
  34. package/dist/types/src/ui/use_loadable.d.ts +2 -2
  35. package/dist/types/src/ui/use_record_action_data.d.ts +11 -11
  36. package/dist/types/src/ui/use_settings_button.d.ts +1 -1
  37. package/dist/types/src/ui/viewport_constraint.d.ts +3 -3
  38. package/dist/types/src/ui/viewport_constraint.d.ts.map +1 -1
  39. package/dist/types/src/viewport.d.ts +9 -9
  40. package/package.json +1 -1
  41. package/CHANGELOG.md +0 -495
@@ -59,7 +59,7 @@ var _private_utils = require("./private_utils");
59
59
  // as a name seems a bit too vague in terms of intended usage).
60
60
 
61
61
  /**
62
- * A key-value store for persisting configuration options for an app installation.
62
+ * A key-value store for persisting configuration options for an extension installation.
63
63
  *
64
64
  * The contents will be synced in real-time to all logged-in users of the installation.
65
65
  * Contents will not be updated in real-time when the installation is running in
@@ -287,7 +287,7 @@ function (_Watchable) {
287
287
  * if (globalConfig.hasPermissionToSetPaths('favoriteColor', color)) {
288
288
  * globalConfig.setAsync('favoriteColor', color);
289
289
  * }
290
- * // The update is now applied within your app (eg will be
290
+ * // The update is now applied within your extension (eg will be
291
291
  * // reflected in globalConfig) but are still being saved to
292
292
  * // Airtable servers (e.g. may not be updated for other users yet)
293
293
  * }
@@ -423,7 +423,7 @@ function (_Watchable) {
423
423
  * if (globalConfig.hasPermissionToSetPaths(updates)) {
424
424
  * globalConfig.setPathsAsync(updates);
425
425
  * }
426
- * // The updates are now applied within your app (eg will be reflected in
426
+ * // The updates are now applied within your extension (eg will be reflected in
427
427
  * // globalConfig) but are still being saved to Airtable servers (e.g. they
428
428
  * // may not be updated for other users yet)
429
429
  * }
@@ -186,8 +186,8 @@ function (_AbstractModel) {
186
186
  * The user matching the given ID, name, or email address. Returns null if that user does not
187
187
  * exist or does not have access to this base.
188
188
  *
189
- * This method is convenient when building an app for a specific base, but for more generic
190
- * apps the best practice is to use the {@link getCollaboratorByIdIfExists} method instead.
189
+ * This method is convenient when building an extension for a specific base, but for more generic
190
+ * extensions the best practice is to use the {@link getCollaboratorByIdIfExists} method instead.
191
191
  *
192
192
  * @param collaboratorIdOrNameOrEmail The ID of the user.
193
193
  */
@@ -254,8 +254,8 @@ function (_AbstractModel) {
254
254
  * or does not have access to this base. Use {@link getCollaboratorIfExists} instead if you are
255
255
  * unsure whether a collaborator with the given ID exists and has access to this base.
256
256
  *
257
- * This method is convenient when building an app for a specific base, but for more generic
258
- * apps the best practice is to use the {@link getCollaboratorById} method instead.
257
+ * This method is convenient when building an extension for a specific base, but for more generic
258
+ * extensions the best practice is to use the {@link getCollaboratorById} method instead.
259
259
  *
260
260
  * @param collaboratorIdOrNameOrEmail The ID of the user.
261
261
  */
@@ -397,8 +397,8 @@ function (_AbstractModel) {
397
397
  * The table matching the given ID or name. Returns `null` if no matching table exists within
398
398
  * this base.
399
399
  *
400
- * This method is convenient when building an app for a specific base, but for more generic
401
- * apps the best practice is to use the {@link getTableByIdIfExists} or
400
+ * This method is convenient when building an extension for a specific base, but for more generic
401
+ * extensions the best practice is to use the {@link getTableByIdIfExists} or
402
402
  * {@link getTableByNameIfExists} methods instead.
403
403
  *
404
404
  * @param tableIdOrName The ID or name of the table you're looking for.
@@ -416,8 +416,8 @@ function (_AbstractModel) {
416
416
  * Use {@link getTableIfExists} instead if you are unsure whether a table exists with the given
417
417
  * name/ID.
418
418
  *
419
- * This method is convenient when building an app for a specific base, but for more generic
420
- * apps the best practice is to use the {@link getTableById} or {@link getTableByName} methods
419
+ * This method is convenient when building an extension for a specific base, but for more generic
420
+ * extensions the best practice is to use the {@link getTableById} or {@link getTableByName} methods
421
421
  * instead.
422
422
  *
423
423
  * @param tableIdOrName The ID or name of the table you're looking for.
@@ -521,7 +521,7 @@ function (_AbstractModel) {
521
521
  *
522
522
  * This action is asynchronous. Unlike new records, new tables are **not** created
523
523
  * optimistically locally. You must `await` the returned promise before using the new
524
- * table in your app.
524
+ * table in your extension.
525
525
  *
526
526
  * @param name name for the table. must be case-insensitive unique
527
527
  * @param fields array of fields to create in the table: see below for an example. `name` and
@@ -607,7 +607,7 @@ function (_AbstractModel) {
607
607
  value: function getMaxRecordsPerTable() {
608
608
  var _this$_data$maxRowsPe;
609
609
 
610
- return (_this$_data$maxRowsPe = this._data.maxRowsPerTable) !== null && _this$_data$maxRowsPe !== void 0 ? _this$_data$maxRowsPe : 50000;
610
+ return (_this$_data$maxRowsPe = this._data.maxRowsPerTable) !== null && _this$_data$maxRowsPe !== void 0 ? _this$_data$maxRowsPe : 100000;
611
611
  }
612
612
  /**
613
613
  * @internal
@@ -268,9 +268,8 @@ function (_AbstractModelWithAsy) {
268
268
  key: "setActiveTable",
269
269
 
270
270
  /**
271
- * Sets the specified table to active in the Airtable UI. If the apps pane is fullscreen, the
272
- * table will still be set as active, but the apps pane will continue to be displayed
273
- * fullscreen.
271
+ * Sets the specified table to active in the Airtable UI. If the extension installation or extensions pane
272
+ * is fullscreen, fullscreen mode will be exited.
274
273
  *
275
274
  * @param tableOrTableId The target table or table ID to set as active in the Airtable main page.
276
275
  */
@@ -280,9 +279,8 @@ function (_AbstractModelWithAsy) {
280
279
  this._sdk.__airtableInterface.setActiveViewOrTable(tableId);
281
280
  }
282
281
  /**
283
- * Sets the specified view (and corresponding table) to active in the Airtable UI. If the apps
284
- * pane is fullscreen, the view will still be set as active, but the apps pane will continue
285
- * to be displayed fullscreen.
282
+ * Sets the specified view (and corresponding table) to active in the Airtable UI. If the extension
283
+ * installation or extensions pane is fullscreen, fullscreen mode will be exited.
286
284
  *
287
285
  * @param tableOrTableId The table or table ID that the target view belongs to.
288
286
  * @param viewOrViewId The target view or view ID to set as active in the Airtable main page.
@@ -225,7 +225,7 @@ function (_AbstractModel) {
225
225
  *
226
226
  * This action is asynchronous. Unlike updates to cell values, updates to field options are
227
227
  * **not** applied optimistically locally. You must `await` the returned promise before
228
- * relying on the change in your app.
228
+ * relying on the change in your extension.
229
229
  *
230
230
  * Optionally, you can pass an `opts` object as the second argument. See {@link UpdateFieldOptionsOpts}
231
231
  * for available options.
@@ -342,7 +342,7 @@ function (_AbstractModel) {
342
342
  *
343
343
  * This action is asynchronous. Unlike updates to cell values, updates to field name are
344
344
  * **not** applied optimistically locally. You must `await` the returned promise before
345
- * relying on the change in your app.
345
+ * relying on the change in your extension.
346
346
  *
347
347
  * @param name new name for the field
348
348
  *
@@ -440,7 +440,7 @@ function (_AbstractModel) {
440
440
  *
441
441
  * This action is asynchronous. Unlike updates to cell values, updates to field descriptions are
442
442
  * **not** applied optimistically locally. You must `await` the returned promise before
443
- * relying on the change in your app.
443
+ * relying on the change in your extension.
444
444
  *
445
445
  * @param description new description for the field
446
446
  *
@@ -127,7 +127,7 @@ function normalizeSortsOrGroups(table, sortsOrGroups) {
127
127
  * You can get one of these with `record.selectLinkedRecordsFromCell(someField)`.
128
128
  *
129
129
  * Once you've got a query result, you need to load it before you can start working with it -
130
- * apps don't load record data by default. We recommend using {@link useRecords},
130
+ * extensions don't load record data by default. We recommend using {@link useRecords},
131
131
  * {@link useRecordIds}, {@link useRecordById} or {@link useLoadable} to handle this.
132
132
  *
133
133
  * If you're not using a query result in a React component, you can manually load the data and
@@ -12,6 +12,8 @@ require("core-js/modules/es.array.iterator");
12
12
 
13
13
  require("core-js/modules/es.array.map");
14
14
 
15
+ require("core-js/modules/es.object.entries");
16
+
15
17
  require("core-js/modules/es.object.to-string");
16
18
 
17
19
  require("core-js/modules/es.promise");
@@ -110,6 +112,7 @@ function (_AbstractModelWithAsy) {
110
112
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "_areCellValuesLoadedByFieldId", {});
111
113
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "_pendingCellValuesLoadPromiseByFieldId", {});
112
114
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "_cellValuesRetainCountByFieldId", {});
115
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "_timeoutForRemovingFieldIds", null);
113
116
  _this._airtableInterface = sdk.__airtableInterface;
114
117
  _this.tableId = tableId; // A bit of a hack, but we use the primary field ID to load record
115
118
  // metadata (see _getFieldIdForCausingRecordMetadataToLoad). We copy the
@@ -502,10 +505,15 @@ function (_AbstractModelWithAsy) {
502
505
  });
503
506
 
504
507
  case 45:
505
- _context2.next = 47;
508
+ // Since we are incrementing fieldIds, it's necessary to restart any pending timeouts
509
+ // to unload data. This is because it's possible for a timeout to fire while a queryResult
510
+ // is actively unloading, and erroneously unload data. Data must be unloaded _after_ the queryResult.
511
+ this._restartTimeoutToUnloadFieldIdsIfTimeoutIsActive();
512
+
513
+ _context2.next = 48;
506
514
  return _regenerator.default.awrap(Promise.all(pendingLoadPromises));
507
515
 
508
- case 47:
516
+ case 48:
509
517
  case "end":
510
518
  return _context2.stop();
511
519
  }
@@ -638,7 +646,6 @@ function (_AbstractModelWithAsy) {
638
646
  return;
639
647
  }
640
648
 
641
- var fieldIdsWithZeroRetainCount = [];
642
649
  var _iteratorNormalCompletion8 = true;
643
650
  var _didIteratorError8 = false;
644
651
  var _iteratorError8 = undefined;
@@ -656,11 +663,10 @@ function (_AbstractModelWithAsy) {
656
663
  }
657
664
 
658
665
  this._cellValuesRetainCountByFieldId[fieldId] = fieldRetainCount;
666
+ } // Don't unload immediately. Wait a while in case something else
667
+ // requests the data, so we can avoid going back to liveapp or
668
+ // the network.
659
669
 
660
- if (fieldRetainCount === 0) {
661
- fieldIdsWithZeroRetainCount.push(fieldId);
662
- }
663
- }
664
670
  } catch (err) {
665
671
  _didIteratorError8 = true;
666
672
  _iteratorError8 = err;
@@ -676,16 +682,45 @@ function (_AbstractModelWithAsy) {
676
682
  }
677
683
  }
678
684
 
685
+ this._startTimeoutToUnloadForFieldIdsIfNeeded();
686
+ } // This unloads all fields where the retain count is at zero, and if any other
687
+ // request to unload fields is pending - cancels it and restarts it.
688
+ // This is important because fields must always be unloaded at least __DATA_UNLOAD_DELAY_MS
689
+ // after the unload is requested so that any QueryResults relying on them properly
690
+ // unload either first, or at the same time
691
+
692
+ }, {
693
+ key: "_startTimeoutToUnloadForFieldIdsIfNeeded",
694
+ value: function _startTimeoutToUnloadForFieldIdsIfNeeded() {
695
+ var fieldIdsWithZeroRetainCount = [];
696
+
697
+ for (var _i2 = 0, _Object$entries = Object.entries(this._cellValuesRetainCountByFieldId); _i2 < _Object$entries.length; _i2++) {
698
+ var _Object$entries$_i = (0, _slicedToArray2.default)(_Object$entries[_i2], 2),
699
+ fieldId = _Object$entries$_i[0],
700
+ retainCount = _Object$entries$_i[1];
701
+
702
+ if (retainCount === 0) {
703
+ fieldIdsWithZeroRetainCount.push(fieldId);
704
+ }
705
+ } // Cancel any pending timeouts before proceeding
706
+ // This should be canceled even if there aren't any fields to unload as that means
707
+ // that there has been loading that's occured that makes the pending request invalid
708
+
709
+
710
+ if (this._timeoutForRemovingFieldIds) {
711
+ clearTimeout(this._timeoutForRemovingFieldIds);
712
+ this._timeoutForRemovingFieldIds = null;
713
+ }
714
+
679
715
  if (fieldIdsWithZeroRetainCount.length > 0) {
680
- // Don't unload immediately. Wait a while in case something else
681
- // requests the data, so we can avoid going back to liveapp or
682
- // the network.
683
- setTimeout(() => {
716
+ this._timeoutForRemovingFieldIds = setTimeout(() => {
684
717
  // Make sure the retain count is still zero, since it may
685
718
  // have been incremented before the timeout fired.
686
719
  var fieldIdsToUnload = fieldIdsWithZeroRetainCount.filter(fieldId => {
687
- return this._cellValuesRetainCountByFieldId[fieldId] === 0;
688
- });
720
+ // It's necessary to also check that the field is loaded, as it's possible
721
+ // for an unload to trigger with fields that have already been removed.
722
+ return this._cellValuesRetainCountByFieldId[fieldId] === 0 && this._areCellValuesLoadedByFieldId[fieldId];
723
+ }); // istanbul ignore else
689
724
 
690
725
  if (fieldIdsToUnload.length > 0) {
691
726
  // Set _areCellValuesLoadedByFieldId to false before calling _unloadCellValuesInFieldIds
@@ -715,10 +750,23 @@ function (_AbstractModelWithAsy) {
715
750
  }
716
751
 
717
752
  this._unloadCellValuesInFieldIds(fieldIdsToUnload);
753
+ } else {
754
+ // This shouldn't be possible because we always cancel the timer if fieldIds loadedness
755
+ // status ever changes
756
+ (0, _error_utils.logErrorToSentry)('fieldIdsToUnload is empty, this likely means the unload timer is not properly reset.');
718
757
  }
758
+
759
+ this._timeoutForRemovingFieldIds = null;
719
760
  }, _abstract_model_with_async_data.default.__DATA_UNLOAD_DELAY_MS);
720
761
  }
721
762
  }
763
+ }, {
764
+ key: "_restartTimeoutToUnloadFieldIdsIfTimeoutIsActive",
765
+ value: function _restartTimeoutToUnloadFieldIdsIfTimeoutIsActive() {
766
+ if (this._timeoutForRemovingFieldIds) {
767
+ this._startTimeoutToUnloadForFieldIdsIfNeeded();
768
+ }
769
+ }
722
770
  }, {
723
771
  key: "_unloadCellValuesInFieldIds",
724
772
  value: function _unloadCellValuesInFieldIds(fieldIds) {
@@ -811,11 +859,15 @@ function (_AbstractModelWithAsy) {
811
859
  if (!areAnyFieldsLoaded) {
812
860
  this._data.recordsById = undefined;
813
861
  } else if (!this.isDataLoaded) {
814
- var fieldIdsToClear;
862
+ var fieldIdsToClear; // This should be impossible - for fields should always be loaded
863
+ // when attempting to unload specific fields. This codepath was previously possible
864
+ // due to a bug. It could be converted to an invariant, but that is higher risk.
865
+ // istanbul ignore if
815
866
 
816
867
  if (unloadedFieldIds) {
817
868
  // Specific fields were unloaded, so clear out the cell values for those fields.
818
869
  fieldIdsToClear = unloadedFieldIds;
870
+ (0, _error_utils.logErrorToSentry)('Field Ids are being unloaded when record_store is unloaded');
819
871
  } else {
820
872
  // The entire table was unloaded, but some individual fields are still loaded.
821
873
  // We need to clear out the cell values of every field that was unloaded.
@@ -907,8 +959,8 @@ function (_AbstractModelWithAsy) {
907
959
  var cellValuesByFieldId = dirtyRecordPaths.cellValuesByFieldId;
908
960
 
909
961
  if (cellValuesByFieldId) {
910
- for (var _i2 = 0, _Object$keys2 = Object.keys(cellValuesByFieldId); _i2 < _Object$keys2.length; _i2++) {
911
- var fieldId = _Object$keys2[_i2];
962
+ for (var _i3 = 0, _Object$keys2 = Object.keys(cellValuesByFieldId); _i3 < _Object$keys2.length; _i3++) {
963
+ var fieldId = _Object$keys2[_i3];
912
964
  dirtyFieldIdsSet[fieldId] = true;
913
965
  }
914
966
  }
@@ -72,7 +72,7 @@ var WatchableSessionKeys = Object.freeze({
72
72
  * if (session.currentUser !== null) {
73
73
  * return <span>The current user's name is {session.currentUser.name}</span>;
74
74
  * } else {
75
- * return <span>This app is being viewed in a public share</span>;
75
+ * return <span>This extension is being viewed in a public share</span>;
76
76
  * }
77
77
  * }
78
78
  * ```
@@ -384,7 +384,7 @@ function (_AbstractModel) {
384
384
  return this._sessionData;
385
385
  }
386
386
  /**
387
- * The current user, or `null` if the app is running in a publicly shared base.
387
+ * The current user, or `null` if the extension is running in a publicly shared base.
388
388
  *
389
389
  * @example
390
390
  * ```js
@@ -394,7 +394,7 @@ function (_AbstractModel) {
394
394
  * const session = useSession();
395
395
  *
396
396
  * if (!session.currentUser) {
397
- * return <div>This app is being used in a public share.</div>;
397
+ * return <div>This extension is being used in a public share.</div>;
398
398
  * }
399
399
  *
400
400
  * return <ul>
@@ -279,8 +279,8 @@ function (_AbstractModel) {
279
279
  * The field matching the given ID or name. Returns `null` if no matching field exists within
280
280
  * this table.
281
281
  *
282
- * This method is convenient when building an app for a specific base, but for more generic
283
- * apps the best practice is to use the {@link getFieldByIdIfExists} or
282
+ * This method is convenient when building an extension for a specific base, but for more generic
283
+ * extensions the best practice is to use the {@link getFieldByIdIfExists} or
284
284
  * {@link getFieldByNameIfExists} methods instead.
285
285
  *
286
286
  * @param fieldIdOrName The ID or name of the field you're looking for.
@@ -298,8 +298,8 @@ function (_AbstractModel) {
298
298
  * Use {@link getFieldIfExists} instead if you are unsure whether a field exists with the given
299
299
  * name/ID.
300
300
  *
301
- * This method is convenient when building an app for a specific base, but for more generic
302
- * apps the best practice is to use the {@link getFieldById} or {@link getFieldByName} methods
301
+ * This method is convenient when building an extension for a specific base, but for more generic
302
+ * extensions the best practice is to use the {@link getFieldById} or {@link getFieldByName} methods
303
303
  * instead.
304
304
  *
305
305
  * @param fieldIdOrName The ID or name of the field you're looking for.
@@ -460,8 +460,8 @@ function (_AbstractModel) {
460
460
  * The view matching the given ID or name. Returns `null` if no matching view exists within
461
461
  * this table.
462
462
  *
463
- * This method is convenient when building an app for a specific base, but for more generic
464
- * apps the best practice is to use the {@link getViewByIdIfExists} or
463
+ * This method is convenient when building an extension for a specific base, but for more generic
464
+ * extensions the best practice is to use the {@link getViewByIdIfExists} or
465
465
  * {@link getViewByNameIfExists} methods instead.
466
466
  *
467
467
  * @param viewIdOrName The ID or name of the view you're looking for.
@@ -479,8 +479,8 @@ function (_AbstractModel) {
479
479
  * Use {@link getViewIfExists} instead if you are unsure whether a view exists with the given
480
480
  * name/ID.
481
481
  *
482
- * This method is convenient when building an app for a specific base, but for more generic
483
- * apps the best practice is to use the {@link getViewById} or {@link getViewByName} methods
482
+ * This method is convenient when building an extension for a specific base, but for more generic
483
+ * extensions the best practice is to use the {@link getViewById} or {@link getViewByName} methods
484
484
  * instead.
485
485
  *
486
486
  * @param viewIdOrName The ID or name of the view you're looking for.
@@ -662,7 +662,7 @@ function (_AbstractModel) {
662
662
  *
663
663
  * This action is asynchronous: `await` the returned promise if you wish to wait for the updated
664
664
  * cell values to be persisted to Airtable servers.
665
- * Updates are applied optimistically locally, so your changes will be reflected in your app
665
+ * Updates are applied optimistically locally, so your changes will be reflected in your extension
666
666
  * before the promise resolves.
667
667
  *
668
668
  * @param recordOrRecordId the record to update
@@ -673,7 +673,7 @@ function (_AbstractModel) {
673
673
  * if (table.hasPermissionToUpdateRecord(record, recordFields)) {
674
674
  * table.updateRecordAsync(record, recordFields);
675
675
  * }
676
- * // The updated values will now show in your app (eg in
676
+ * // The updated values will now show in your extension (eg in
677
677
  * // `table.selectRecords()` result) but are still being saved to Airtable
678
678
  * // servers (e.g. other users may not be able to see them yet).
679
679
  * }
@@ -768,7 +768,7 @@ function (_AbstractModel) {
768
768
  *
769
769
  * // Check if user could update specific fields, when you don't know the
770
770
  * // specific record that will be updated yet. (for example, if the field is
771
- * // selected by the user and you want to check if your app can write to it).
771
+ * // selected by the user and you want to check if your extension can write to it).
772
772
  * const updateUnknownRecordCheckResult =
773
773
  * table.checkPermissionsForUpdateRecord(undefined, {
774
774
  * 'My field name': 'updated value',
@@ -779,7 +779,7 @@ function (_AbstractModel) {
779
779
  *
780
780
  * // Check if user could perform updates within the table, without knowing the
781
781
  * // specific record or fields that will be updated yet (e.g., to render your
782
- * // app in "read only" mode).
782
+ * // extension in "read only" mode).
783
783
  * const updateUnknownRecordAndFieldsCheckResult =
784
784
  * table.checkPermissionsForUpdateRecord();
785
785
  * ```
@@ -829,7 +829,7 @@ function (_AbstractModel) {
829
829
  *
830
830
  * // Check if user could update specific fields, when you don't know the
831
831
  * // specific record that will be updated yet (e.g. if the field is selected
832
- * // by the user and you want to check if your app can write to it).
832
+ * // by the user and you want to check if your extension can write to it).
833
833
  * const canUpdateUnknownRecord =
834
834
  * table.hasPermissionToUpdateRecord(undefined, {
835
835
  * 'My field name': 'updated value',
@@ -840,7 +840,7 @@ function (_AbstractModel) {
840
840
  *
841
841
  * // Check if user could perform updates within the table, without knowing the
842
842
  * // specific record or fields that will be updated yet. (for example, to
843
- * // render your app in "read only" mode)
843
+ * // render your extension in "read only" mode)
844
844
  * const canUpdateUnknownRecordAndFields = table.hasPermissionToUpdateRecord();
845
845
  * ```
846
846
  */
@@ -864,7 +864,7 @@ function (_AbstractModel) {
864
864
  *
865
865
  * This action is asynchronous: `await` the returned promise if you wish to wait for the
866
866
  * updates to be persisted to Airtable servers.
867
- * Updates are applied optimistically locally, so your changes will be reflected in your app
867
+ * Updates are applied optimistically locally, so your changes will be reflected in your extension
868
868
  * before the promise resolves.
869
869
  *
870
870
  * @param records Array of objects containing recordId and fields/cellValues to update for that record (specified as an object mapping `FieldId` or field name to cell value)
@@ -911,7 +911,7 @@ function (_AbstractModel) {
911
911
  * if (table.hasPermissionToUpdateRecords(recordsToUpdate)) {
912
912
  * table.updateRecordsAsync(recordsToUpdate);
913
913
  * }
914
- * // The records are now updated within your app (eg will be reflected in
914
+ * // The records are now updated within your extension (eg will be reflected in
915
915
  * // `table.selectRecords()`) but are still being saved to Airtable servers
916
916
  * // (e.g. they may not be updated for other users yet).
917
917
  * }
@@ -1093,7 +1093,7 @@ function (_AbstractModel) {
1093
1093
  *
1094
1094
  * This action is asynchronous: `await` the returned promise if you wish to wait for the
1095
1095
  * delete to be persisted to Airtable servers.
1096
- * Updates are applied optimistically locally, so your changes will be reflected in your app
1096
+ * Updates are applied optimistically locally, so your changes will be reflected in your extension
1097
1097
  * before the promise resolves.
1098
1098
  *
1099
1099
  * @param recordOrRecordId the record to be deleted
@@ -1103,7 +1103,7 @@ function (_AbstractModel) {
1103
1103
  * if (table.hasPermissionToDeleteRecord(record)) {
1104
1104
  * table.deleteRecordAsync(record);
1105
1105
  * }
1106
- * // The record is now deleted within your app (eg will not be returned
1106
+ * // The record is now deleted within your extension (eg will not be returned
1107
1107
  * // in `table.selectRecords`) but it is still being saved to Airtable
1108
1108
  * // servers (e.g. it may not look deleted to other users yet).
1109
1109
  * }
@@ -1208,7 +1208,7 @@ function (_AbstractModel) {
1208
1208
  *
1209
1209
  * This action is asynchronous: `await` the returned promise if you wish to wait for the
1210
1210
  * delete to be persisted to Airtable servers.
1211
- * Updates are applied optimistically locally, so your changes will be reflected in your app
1211
+ * Updates are applied optimistically locally, so your changes will be reflected in your extension
1212
1212
  * before the promise resolves.
1213
1213
  *
1214
1214
  * @param recordsOrRecordIds Array of Records and RecordIds
@@ -1219,7 +1219,7 @@ function (_AbstractModel) {
1219
1219
  * if (table.hasPermissionToDeleteRecords(records)) {
1220
1220
  * table.deleteRecordsAsync(records);
1221
1221
  * }
1222
- * // The records are now deleted within your app (eg will not be
1222
+ * // The records are now deleted within your extension (eg will not be
1223
1223
  * // returned in `table.selectRecords()`) but are still being saved to
1224
1224
  * // Airtable servers (e.g. they may not look deleted to other users yet).
1225
1225
  * }
@@ -1336,7 +1336,7 @@ function (_AbstractModel) {
1336
1336
  *
1337
1337
  * This action is asynchronous: `await` the returned promise if you wish to wait for the new
1338
1338
  * record to be persisted to Airtable servers.
1339
- * Updates are applied optimistically locally, so your changes will be reflected in your app
1339
+ * Updates are applied optimistically locally, so your changes will be reflected in your extension
1340
1340
  * before the promise resolves.
1341
1341
  *
1342
1342
  * The returned promise will resolve to the RecordId of the new record once it is persisted.
@@ -1348,7 +1348,7 @@ function (_AbstractModel) {
1348
1348
  * if (table.hasPermissionToCreateRecord(recordFields)) {
1349
1349
  * table.createRecordAsync(recordFields);
1350
1350
  * }
1351
- * // You can now access the new record in your app (eg
1351
+ * // You can now access the new record in your extension (eg
1352
1352
  * // `table.selectRecords()`) but it is still being saved to Airtable
1353
1353
  * // servers (e.g. other users may not be able to see it yet).
1354
1354
  * }
@@ -1507,7 +1507,7 @@ function (_AbstractModel) {
1507
1507
  *
1508
1508
  * This action is asynchronous: `await` the returned promise if you wish to wait for the new
1509
1509
  * record to be persisted to Airtable servers.
1510
- * Updates are applied optimistically locally, so your changes will be reflected in your app
1510
+ * Updates are applied optimistically locally, so your changes will be reflected in your extension
1511
1511
  * before the promise resolves.
1512
1512
  *
1513
1513
  * The returned promise will resolve to an array of RecordIds of the new records once the new
@@ -1551,7 +1551,7 @@ function (_AbstractModel) {
1551
1551
  * if (table.hasPermissionToCreateRecords(recordDefs)) {
1552
1552
  * table.createRecordsAsync(recordDefs);
1553
1553
  * }
1554
- * // You can now access the new records in your app (e.g.
1554
+ * // You can now access the new records in your extension (e.g.
1555
1555
  * // `table.selectRecords()`) but they are still being saved to Airtable
1556
1556
  * // servers (e.g. other users may not be able to see them yet.)
1557
1557
  * }
@@ -1805,7 +1805,7 @@ function (_AbstractModel) {
1805
1805
  *
1806
1806
  * This action is asynchronous. Unlike new records, new fields are **not** created
1807
1807
  * optimistically locally. You must `await` the returned promise before using the new
1808
- * field in your app.
1808
+ * field in your extension.
1809
1809
  *
1810
1810
  * @param name name for the field. must be case-insensitive unique
1811
1811
  * @param type type for the field
package/dist/cjs/sdk.js CHANGED
@@ -330,4 +330,4 @@ function () {
330
330
  }();
331
331
 
332
332
  exports.default = BlockSdk;
333
- (0, _defineProperty2.default)(BlockSdk, "VERSION", "1.11.1");
333
+ (0, _defineProperty2.default)(BlockSdk, "VERSION", "1.12.0");
@@ -39,7 +39,7 @@ var WatchableSettingsButtonKeys = Object.freeze({
39
39
  */
40
40
 
41
41
  /**
42
- * Interface to the settings button that lives outside the app's viewport.
42
+ * Interface to the settings button that lives outside the extension's viewport.
43
43
  *
44
44
  * The {@link useSettingsButton} hook is the recommended way to use the settings button, but you can
45
45
  * also use it with {@link useWatchable} if you want more granular control (for example, to only
@@ -25,7 +25,7 @@ var _error_utils = require("../error_utils");
25
25
 
26
26
  /**
27
27
  * Expands a list of records in the Airtable UI, and prompts the user to pick
28
- * one. The selected record is returned to the app, and the modal is
28
+ * one. The selected record is returned to the extension, and the modal is
29
29
  * automatically closed.
30
30
  *
31
31
  * If the user dismisses the modal, or another one is opened before this one