@airtable/blocks 1.10.1 → 1.10.2-experimental-640bd10-20220211
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 +5 -1
- package/dist/cjs/error_utils.js +44 -2
- package/dist/cjs/models/grouped_record_query_result.js +5 -14
- package/dist/cjs/models/linked_records_query_result.js +78 -27
- package/dist/cjs/models/mutations.js +18 -162
- package/dist/cjs/models/query_manager.js +328 -0
- package/dist/cjs/models/record.js +310 -55
- package/dist/cjs/models/record_query_result.js +4 -1
- package/dist/cjs/models/record_store.js +557 -765
- package/dist/cjs/models/table.js +6 -6
- package/dist/cjs/models/table_or_view_query_result.js +526 -419
- package/dist/cjs/models/view_data_store.js +255 -295
- package/dist/cjs/private_utils.js +40 -0
- package/dist/cjs/sdk.js +12 -2
- package/dist/cjs/testing/abstract_mock_airtable_interface.js +57 -11
- package/dist/cjs/testing/fixture_data.js +268 -0
- package/dist/cjs/testing/mock_base_data_stores.js +876 -0
- package/dist/cjs/types/airtable_interface.js +17 -2
- package/dist/cjs/types/block_query_spec.js +85 -0
- package/dist/cjs/ui/use_records.js +5 -1
- package/dist/cjs/unstable_testing_utils.js +55 -1
- package/dist/cjs/watchable.js +15 -1
- package/dist/types/src/error_utils.d.ts +6 -0
- package/dist/types/src/error_utils.d.ts.map +1 -1
- package/dist/types/src/models/grouped_record_query_result.d.ts +3 -3
- package/dist/types/src/models/grouped_record_query_result.d.ts.map +1 -1
- package/dist/types/src/models/linked_records_query_result.d.ts.map +1 -1
- package/dist/types/src/models/mutations.d.ts.map +1 -1
- package/dist/types/src/models/query_manager.d.ts +2 -0
- package/dist/types/src/models/query_manager.d.ts.map +1 -0
- package/dist/types/src/models/record.d.ts +12 -3
- package/dist/types/src/models/record.d.ts.map +1 -1
- package/dist/types/src/models/record_query_result.d.ts +3 -2
- package/dist/types/src/models/record_query_result.d.ts.map +1 -1
- package/dist/types/src/models/record_store.d.ts.map +1 -1
- package/dist/types/src/models/table_or_view_query_result.d.ts +3 -5
- package/dist/types/src/models/table_or_view_query_result.d.ts.map +1 -1
- package/dist/types/src/models/view_data_store.d.ts +0 -1
- package/dist/types/src/models/view_data_store.d.ts.map +1 -1
- package/dist/types/src/models/view_metadata_query_result.d.ts +1 -1
- package/dist/types/src/models/view_metadata_query_result.d.ts.map +1 -1
- package/dist/types/src/private_utils.d.ts +24 -1
- package/dist/types/src/private_utils.d.ts.map +1 -1
- package/dist/types/src/sdk.d.ts.map +1 -1
- package/dist/types/src/testing/abstract_mock_airtable_interface.d.ts +11 -11
- package/dist/types/src/testing/abstract_mock_airtable_interface.d.ts.map +1 -1
- package/dist/types/{test/airtable_interface_mocks → src/testing}/fixture_data.d.ts +42 -19
- package/dist/types/src/testing/fixture_data.d.ts.map +1 -0
- package/dist/types/src/testing/mock_base_data_stores.d.ts +55 -0
- package/dist/types/src/testing/mock_base_data_stores.d.ts.map +1 -0
- package/dist/types/src/types/airtable_interface.d.ts +59 -20
- package/dist/types/src/types/airtable_interface.d.ts.map +1 -1
- package/dist/types/src/types/block_query_spec.d.ts +139 -0
- package/dist/types/src/types/block_query_spec.d.ts.map +1 -0
- package/dist/types/src/types/table.d.ts +0 -2
- package/dist/types/src/types/table.d.ts.map +1 -1
- package/dist/types/src/types/view.d.ts +3 -8
- package/dist/types/src/types/view.d.ts.map +1 -1
- package/dist/types/src/ui/record_card.d.ts +1 -1
- package/dist/types/src/unstable_testing_utils.d.ts +4 -1
- package/dist/types/src/unstable_testing_utils.d.ts.map +1 -1
- package/dist/types/src/watchable.d.ts.map +1 -1
- package/dist/types/test/airtable_interface_mocks/linked_records.d.ts +1 -1
- package/dist/types/test/airtable_interface_mocks/linked_records.d.ts.map +1 -1
- package/dist/types/test/airtable_interface_mocks/mock_airtable_interface.d.ts +19 -12
- package/dist/types/test/airtable_interface_mocks/mock_airtable_interface.d.ts.map +1 -1
- package/dist/types/test/airtable_interface_mocks/project_tracker.d.ts +1 -1
- package/dist/types/test/airtable_interface_mocks/project_tracker.d.ts.map +1 -1
- package/dist/types/test/test_helpers.d.ts +2 -0
- package/dist/types/test/test_helpers.d.ts.map +1 -1
- package/dist/types/test/testing/fixture_data.test.d.ts +2 -0
- package/dist/types/test/testing/fixture_data.test.d.ts.map +1 -0
- package/package.json +2 -1
- package/dist/types/test/airtable_interface_mocks/fixture_data.d.ts.map +0 -1
|
@@ -2,13 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
4
|
|
|
5
|
-
require("core-js/modules/es.
|
|
6
|
-
|
|
7
|
-
require("core-js/modules/es.symbol.description");
|
|
8
|
-
|
|
9
|
-
require("core-js/modules/es.array.filter");
|
|
10
|
-
|
|
11
|
-
require("core-js/modules/es.array.iterator");
|
|
5
|
+
require("core-js/modules/es.array.find");
|
|
12
6
|
|
|
13
7
|
require("core-js/modules/es.array.map");
|
|
14
8
|
|
|
@@ -16,17 +10,17 @@ require("core-js/modules/es.array.slice");
|
|
|
16
10
|
|
|
17
11
|
require("core-js/modules/es.object.to-string");
|
|
18
12
|
|
|
13
|
+
require("core-js/modules/es.object.values");
|
|
14
|
+
|
|
19
15
|
require("core-js/modules/es.promise");
|
|
20
16
|
|
|
21
|
-
require("core-js/modules/web.dom-collections.
|
|
17
|
+
require("core-js/modules/web.dom-collections.for-each");
|
|
22
18
|
|
|
23
19
|
Object.defineProperty(exports, "__esModule", {
|
|
24
20
|
value: true
|
|
25
21
|
});
|
|
26
22
|
exports.default = exports.WatchableViewDataStoreKeys = void 0;
|
|
27
23
|
|
|
28
|
-
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
|
29
|
-
|
|
30
24
|
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
|
|
31
25
|
|
|
32
26
|
require("regenerator-runtime/runtime");
|
|
@@ -35,11 +29,9 @@ var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/cl
|
|
|
35
29
|
|
|
36
30
|
var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
|
|
37
31
|
|
|
38
|
-
var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized"));
|
|
39
|
-
|
|
40
32
|
var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
|
|
41
33
|
|
|
42
|
-
var
|
|
34
|
+
var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized"));
|
|
43
35
|
|
|
44
36
|
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
|
|
45
37
|
|
|
@@ -51,11 +43,14 @@ var _private_utils = require("../private_utils");
|
|
|
51
43
|
|
|
52
44
|
var _error_utils = require("../error_utils");
|
|
53
45
|
|
|
46
|
+
var _airtable_interface = require("../types/airtable_interface");
|
|
47
|
+
|
|
48
|
+
var _block_query_spec = require("../types/block_query_spec");
|
|
49
|
+
|
|
54
50
|
var _abstract_model_with_async_data = _interopRequireDefault(require("./abstract_model_with_async_data"));
|
|
55
51
|
|
|
56
52
|
var WatchableViewDataStoreKeys = Object.freeze({
|
|
57
53
|
visibleRecords: 'visibleRecords',
|
|
58
|
-
visibleRecordIds: 'visibleRecordIds',
|
|
59
54
|
groups: 'groups',
|
|
60
55
|
groupLevels: 'groupLevels',
|
|
61
56
|
recordColors: 'recordColors',
|
|
@@ -66,9 +61,11 @@ var WatchableViewDataStoreKeys = Object.freeze({
|
|
|
66
61
|
|
|
67
62
|
exports.WatchableViewDataStoreKeys = WatchableViewDataStoreKeys;
|
|
68
63
|
|
|
69
|
-
// ViewDataStore
|
|
64
|
+
// ViewDataStore manages loadable data for a specific view. That means the set of visible records,
|
|
70
65
|
// and field order/visibility information. View itself only contains core schema information. The
|
|
71
|
-
// data here doesn't belong in View as it's record data or conditionally loaded
|
|
66
|
+
// data here doesn't belong in View as it's record data or conditionally loaded and therefore
|
|
67
|
+
// loaded via queries (and therefore managed by publicAirtableInterface)
|
|
68
|
+
// TODO: (#proj-blocks-sdk-record-limits) Remove AbstractModelWithAsyncData
|
|
72
69
|
|
|
73
70
|
/** @internal */
|
|
74
71
|
var ViewDataStore =
|
|
@@ -80,11 +77,6 @@ function (_AbstractModelWithAsy) {
|
|
|
80
77
|
value: function _isWatchableKey(key) {
|
|
81
78
|
return (0, _private_utils.isEnumValue)(WatchableViewDataStoreKeys, key);
|
|
82
79
|
}
|
|
83
|
-
}, {
|
|
84
|
-
key: "_shouldLoadDataForKey",
|
|
85
|
-
value: function _shouldLoadDataForKey(key) {
|
|
86
|
-
return true;
|
|
87
|
-
}
|
|
88
80
|
}]);
|
|
89
81
|
|
|
90
82
|
function ViewDataStore(sdk, parentRecordStore, viewId) {
|
|
@@ -94,16 +86,38 @@ function (_AbstractModelWithAsy) {
|
|
|
94
86
|
_this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(ViewDataStore).call(this, sdk, "".concat(viewId, "-ViewDataStore")));
|
|
95
87
|
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "viewId", void 0);
|
|
96
88
|
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "parentRecordStore", void 0);
|
|
97
|
-
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "
|
|
98
|
-
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "
|
|
89
|
+
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "_publicViewStore", void 0);
|
|
90
|
+
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "_queryManager", void 0);
|
|
91
|
+
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "_queryIdFromReferenceCountedLoadData", null);
|
|
99
92
|
_this.parentRecordStore = parentRecordStore;
|
|
100
|
-
_this.
|
|
101
|
-
_this._mostRecentTableLoadPromise = null;
|
|
93
|
+
_this._queryManager = sdk._queryManager;
|
|
102
94
|
_this.viewId = viewId;
|
|
95
|
+
|
|
96
|
+
var publicViewStore = _this.parentRecordStore._airtableInterface.getViewMetadataStoreIfExists(_this.parentRecordStore.tableId, viewId);
|
|
97
|
+
|
|
98
|
+
(0, _error_utils.invariant)(publicViewStore, 'PublicViewStore must exist for all valid viewIds');
|
|
99
|
+
_this._publicViewStore = publicViewStore;
|
|
103
100
|
return _this;
|
|
104
101
|
}
|
|
105
102
|
|
|
106
103
|
(0, _createClass2.default)(ViewDataStore, [{
|
|
104
|
+
key: "_assertExistsAndLoaded",
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* @internal
|
|
108
|
+
*/
|
|
109
|
+
value: function _assertExistsAndLoaded() {
|
|
110
|
+
// Access data in order to throw if the data has been deleted / isn't loaded
|
|
111
|
+
var data = this._dataOrNullIfDeleted; // Currently it is not possible for the ViewDataStore to spawn an error on deletion
|
|
112
|
+
// because the parent TableOrViewQueryResult or ViewMetadataQueryResult throw their own
|
|
113
|
+
// errors when the view is deleted.
|
|
114
|
+
// istanbul ignore if
|
|
115
|
+
|
|
116
|
+
if (data === null) {
|
|
117
|
+
throw this._spawnErrorForDeletion();
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}, {
|
|
107
121
|
key: "_onChangeIsDataLoaded",
|
|
108
122
|
value: function _onChangeIsDataLoaded() {// noop
|
|
109
123
|
}
|
|
@@ -111,212 +125,58 @@ function (_AbstractModelWithAsy) {
|
|
|
111
125
|
key: "__onDataDeletion",
|
|
112
126
|
value: function __onDataDeletion() {
|
|
113
127
|
this._forceUnload();
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
key: "loadDataAsync",
|
|
117
|
-
value: function loadDataAsync() {
|
|
118
|
-
var tableLoadPromise;
|
|
119
|
-
return _regenerator.default.async(function loadDataAsync$(_context) {
|
|
120
|
-
while (1) {
|
|
121
|
-
switch (_context.prev = _context.next) {
|
|
122
|
-
case 0:
|
|
123
|
-
// Override this method to also load table data.
|
|
124
|
-
// NOTE: it's important that we call loadDataAsync on the table here and not in
|
|
125
|
-
// _loadDataAsync since we want the retain counts for the view and table to increase/decrease
|
|
126
|
-
// in lock-step. If we load table data in _loadDataAsync, the table's retain
|
|
127
|
-
// count only increments some of the time, which leads to unexpected behavior.
|
|
128
|
-
tableLoadPromise = this.parentRecordStore.loadRecordMetadataAsync();
|
|
129
|
-
this._mostRecentTableLoadPromise = tableLoadPromise;
|
|
130
|
-
_context.next = 4;
|
|
131
|
-
return _regenerator.default.awrap((0, _get2.default)((0, _getPrototypeOf2.default)(ViewDataStore.prototype), "loadDataAsync", this).call(this));
|
|
132
|
-
|
|
133
|
-
case 4:
|
|
134
|
-
case "end":
|
|
135
|
-
return _context.stop();
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
}, null, this);
|
|
128
|
+
|
|
129
|
+
this._queryManager.forceUnloadWatchesOnWatchableModel(this);
|
|
139
130
|
}
|
|
140
131
|
}, {
|
|
141
132
|
key: "_loadDataAsync",
|
|
142
133
|
value: function _loadDataAsync() {
|
|
143
|
-
var
|
|
144
|
-
|
|
145
|
-
return _regenerator.default.async(function _loadDataAsync$(_context2) {
|
|
134
|
+
var changedKeysOnLoad;
|
|
135
|
+
return _regenerator.default.async(function _loadDataAsync$(_context) {
|
|
146
136
|
while (1) {
|
|
147
|
-
switch (
|
|
137
|
+
switch (_context.prev = _context.next) {
|
|
148
138
|
case 0:
|
|
149
|
-
//
|
|
150
|
-
//
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
return _regenerator.default.awrap(
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
this._data.colorsByRecordId = viewData.colorsByRecordId;
|
|
165
|
-
|
|
166
|
-
if (!this._data.colorsByRecordId) {
|
|
167
|
-
_context2.next = 32;
|
|
168
|
-
break;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
_iteratorNormalCompletion = true;
|
|
172
|
-
_didIteratorError = false;
|
|
173
|
-
_iteratorError = undefined;
|
|
174
|
-
_context2.prev = 16;
|
|
175
|
-
|
|
176
|
-
for (_iterator = this.visibleRecords[Symbol.iterator](); !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
|
|
177
|
-
record = _step.value;
|
|
178
|
-
|
|
179
|
-
if ((0, _private_utils.has)(this._data.colorsByRecordId, record.id)) {
|
|
180
|
-
record.__triggerOnChangeForRecordColorInViewId(this.viewId);
|
|
139
|
+
// TODO: (#proj-blocks-sdk-record-limits) Do we want to remove this reference counting semantic?
|
|
140
|
+
// We can assume that each query is identical, but it might be helpful to have all queries be
|
|
141
|
+
// registered across the bridge so that we can track utilization.
|
|
142
|
+
(0, _error_utils.invariant)(this._queryIdFromReferenceCountedLoadData === null, 'Can not reissue an identical view data store query');
|
|
143
|
+
_context.next = 3;
|
|
144
|
+
return _regenerator.default.awrap(this._queryManager.fetchAndSubscribeToQueryAsync({
|
|
145
|
+
sourceType: _block_query_spec.BlockQuerySourceType.VIEW,
|
|
146
|
+
sourceTableId: this.parentRecordStore.tableId,
|
|
147
|
+
sourceViewId: this.viewId,
|
|
148
|
+
viewMetadataSelection: {
|
|
149
|
+
shouldIncludeVisibleRecordIds: true,
|
|
150
|
+
shouldIncludeFieldOrder: true,
|
|
151
|
+
shouldIncludeGroups: true,
|
|
152
|
+
shouldIncludeGroupingLevels: true,
|
|
153
|
+
shouldIncludeColorsForRecordId: true
|
|
181
154
|
}
|
|
182
|
-
}
|
|
155
|
+
}));
|
|
183
156
|
|
|
184
|
-
|
|
185
|
-
|
|
157
|
+
case 3:
|
|
158
|
+
this._queryIdFromReferenceCountedLoadData = _context.sent;
|
|
159
|
+
changedKeysOnLoad = Object.values(WatchableViewDataStoreKeys);
|
|
186
160
|
|
|
187
|
-
|
|
188
|
-
_context2.prev = 20;
|
|
189
|
-
_context2.t0 = _context2["catch"](16);
|
|
190
|
-
_didIteratorError = true;
|
|
191
|
-
_iteratorError = _context2.t0;
|
|
161
|
+
this._queryManager.onLoadKeys(this, changedKeysOnLoad);
|
|
192
162
|
|
|
193
|
-
|
|
194
|
-
_context2.prev = 24;
|
|
195
|
-
_context2.prev = 25;
|
|
163
|
+
return _context.abrupt("return", []);
|
|
196
164
|
|
|
197
|
-
|
|
198
|
-
_iterator.return();
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
case 27:
|
|
202
|
-
_context2.prev = 27;
|
|
203
|
-
|
|
204
|
-
if (!_didIteratorError) {
|
|
205
|
-
_context2.next = 30;
|
|
206
|
-
break;
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
throw _iteratorError;
|
|
210
|
-
|
|
211
|
-
case 30:
|
|
212
|
-
return _context2.finish(27);
|
|
213
|
-
|
|
214
|
-
case 31:
|
|
215
|
-
return _context2.finish(24);
|
|
216
|
-
|
|
217
|
-
case 32:
|
|
218
|
-
return _context2.abrupt("return", [WatchableViewDataStoreKeys.visibleRecords, WatchableViewDataStoreKeys.visibleRecordIds, WatchableViewDataStoreKeys.allFieldIds, WatchableViewDataStoreKeys.groups, WatchableViewDataStoreKeys.groupLevels, WatchableViewDataStoreKeys.visibleFieldIds, WatchableViewDataStoreKeys.recordColors]);
|
|
219
|
-
|
|
220
|
-
case 33:
|
|
165
|
+
case 7:
|
|
221
166
|
case "end":
|
|
222
|
-
return
|
|
167
|
+
return _context.stop();
|
|
223
168
|
}
|
|
224
169
|
}
|
|
225
|
-
}, null, this
|
|
226
|
-
}
|
|
227
|
-
}, {
|
|
228
|
-
key: "unloadData",
|
|
229
|
-
value: function unloadData() {
|
|
230
|
-
// Override this method to also unload the table's data.
|
|
231
|
-
// NOTE: it's important that we do this here, since we want the view and table's
|
|
232
|
-
// retain counts to increment/decrement in lock-step. If we unload the table's
|
|
233
|
-
// data in _unloadData, it leads to unexpected behavior.
|
|
234
|
-
(0, _get2.default)((0, _getPrototypeOf2.default)(ViewDataStore.prototype), "unloadData", this).call(this);
|
|
235
|
-
this.parentRecordStore.unloadRecordMetadata();
|
|
170
|
+
}, null, this);
|
|
236
171
|
}
|
|
237
172
|
}, {
|
|
238
173
|
key: "_unloadData",
|
|
239
174
|
value: function _unloadData() {
|
|
240
|
-
this.
|
|
175
|
+
(0, _error_utils.invariant)(this._queryIdFromReferenceCountedLoadData, 'Can not unsubscribe from a view store that is not subscribed');
|
|
241
176
|
|
|
242
|
-
this.
|
|
177
|
+
this._queryManager.unsubscribeFromQueryId(this._queryIdFromReferenceCountedLoadData);
|
|
243
178
|
|
|
244
|
-
|
|
245
|
-
this._data.visibleRecordIds = undefined;
|
|
246
|
-
this._data.groups = undefined;
|
|
247
|
-
this._data.colorsByRecordId = undefined;
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
}, {
|
|
251
|
-
key: "__generateChangesForParentTableAddMultipleRecords",
|
|
252
|
-
value: function __generateChangesForParentTableAddMultipleRecords(recordIds) {
|
|
253
|
-
var newVisibleRecordIds = [...this.visibleRecordIds, ...recordIds];
|
|
254
|
-
return [{
|
|
255
|
-
path: ['tablesById', this.parentRecordStore.tableId, 'viewsById', this.viewId, 'visibleRecordIds'],
|
|
256
|
-
value: newVisibleRecordIds
|
|
257
|
-
}];
|
|
258
|
-
}
|
|
259
|
-
}, {
|
|
260
|
-
key: "__generateChangesForParentTableDeleteMultipleRecords",
|
|
261
|
-
value: function __generateChangesForParentTableDeleteMultipleRecords(recordIds) {
|
|
262
|
-
var recordIdsToDeleteSet = {};
|
|
263
|
-
var _iteratorNormalCompletion2 = true;
|
|
264
|
-
var _didIteratorError2 = false;
|
|
265
|
-
var _iteratorError2 = undefined;
|
|
266
|
-
|
|
267
|
-
try {
|
|
268
|
-
for (var _iterator2 = recordIds[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
|
|
269
|
-
var recordId = _step2.value;
|
|
270
|
-
recordIdsToDeleteSet[recordId] = true;
|
|
271
|
-
}
|
|
272
|
-
} catch (err) {
|
|
273
|
-
_didIteratorError2 = true;
|
|
274
|
-
_iteratorError2 = err;
|
|
275
|
-
} finally {
|
|
276
|
-
try {
|
|
277
|
-
if (!_iteratorNormalCompletion2 && _iterator2.return != null) {
|
|
278
|
-
_iterator2.return();
|
|
279
|
-
}
|
|
280
|
-
} finally {
|
|
281
|
-
if (_didIteratorError2) {
|
|
282
|
-
throw _iteratorError2;
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
var newVisibleRecordIds = this.visibleRecordIds.filter(recordId => !recordIdsToDeleteSet[recordId]);
|
|
288
|
-
var changePayload = [{
|
|
289
|
-
path: ['tablesById', this.parentRecordStore.tableId, 'viewsById', this.viewId, 'visibleRecordIds'],
|
|
290
|
-
value: newVisibleRecordIds
|
|
291
|
-
}];
|
|
292
|
-
|
|
293
|
-
if (this._data.groups) {
|
|
294
|
-
var newGroups = this.__recursivelyRemoveRecordsFromGroupsInPlace((0, _private_utils.cloneDeep)(this._data.groups), recordIdsToDeleteSet);
|
|
295
|
-
|
|
296
|
-
changePayload.push({
|
|
297
|
-
path: ['tablesById', this.parentRecordStore.tableId, 'viewsById', this.viewId, 'groups'],
|
|
298
|
-
value: newGroups
|
|
299
|
-
});
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
return changePayload;
|
|
303
|
-
}
|
|
304
|
-
}, {
|
|
305
|
-
key: "__recursivelyRemoveRecordsFromGroupsInPlace",
|
|
306
|
-
value: function __recursivelyRemoveRecordsFromGroupsInPlace(groups, recordIdsToDeleteSet) {
|
|
307
|
-
if (!groups || groups.length === 0) {
|
|
308
|
-
return groups;
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
return groups.map(group => {
|
|
312
|
-
if (group.visibleRecordIds) {
|
|
313
|
-
group.visibleRecordIds = group.visibleRecordIds.filter(id => !recordIdsToDeleteSet[id]);
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
this.__recursivelyRemoveRecordsFromGroupsInPlace(group.groups, recordIdsToDeleteSet);
|
|
317
|
-
|
|
318
|
-
return group;
|
|
319
|
-
});
|
|
179
|
+
this._queryIdFromReferenceCountedLoadData = null;
|
|
320
180
|
}
|
|
321
181
|
/**
|
|
322
182
|
* The record IDs that are not filtered out of this view.
|
|
@@ -334,107 +194,197 @@ function (_AbstractModelWithAsy) {
|
|
|
334
194
|
* @param recordOrRecordId the record/record id to get the color for
|
|
335
195
|
*/
|
|
336
196
|
value: function getRecordColor(record) {
|
|
337
|
-
var _ref3, _this$_data$colorsByR;
|
|
338
|
-
|
|
339
197
|
(0, _error_utils.invariant)(this.isDataLoaded, 'View data is not loaded');
|
|
340
|
-
|
|
198
|
+
|
|
199
|
+
this._assertExistsAndLoaded();
|
|
200
|
+
|
|
201
|
+
return this._publicViewStore.getColorForRecordId(record.id);
|
|
341
202
|
}
|
|
342
203
|
}, {
|
|
343
|
-
key: "
|
|
344
|
-
value: function
|
|
345
|
-
|
|
346
|
-
this._onChange(WatchableViewDataStoreKeys.visibleRecords);
|
|
204
|
+
key: "_findBlockSubscriptionChangedMatchingSubscriptionChangeTypeForViewIfExists",
|
|
205
|
+
value: function _findBlockSubscriptionChangedMatchingSubscriptionChangeTypeForViewIfExists(changes, changeTypeToMatch) {
|
|
206
|
+
var _changes$find;
|
|
347
207
|
|
|
348
|
-
|
|
349
|
-
|
|
208
|
+
return (_changes$find = changes.find(change => change.type === changeTypeToMatch && change.tableId === this.parentRecordStore.tableId && change.viewId === this.viewId)) !== null && _changes$find !== void 0 ? _changes$find : null;
|
|
209
|
+
}
|
|
210
|
+
}, {
|
|
211
|
+
key: "_constructBlockQuerySpecForWatchableKey",
|
|
212
|
+
value: function _constructBlockQuerySpecForWatchableKey(key, callbackForRegistration, context) {
|
|
213
|
+
var querySpecOptions = {};
|
|
214
|
+
|
|
215
|
+
var wrappedCallbackForQueryChange = () => {
|
|
216
|
+
callbackForRegistration.call(context, this, key);
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
switch (key) {
|
|
220
|
+
case WatchableViewDataStoreKeys.visibleRecords:
|
|
221
|
+
querySpecOptions.shouldIncludeVisibleRecordIds = true;
|
|
222
|
+
break;
|
|
223
|
+
|
|
224
|
+
case WatchableViewDataStoreKeys.groups:
|
|
225
|
+
{
|
|
226
|
+
querySpecOptions.shouldIncludeGroups = true;
|
|
227
|
+
break;
|
|
228
|
+
}
|
|
350
229
|
|
|
351
|
-
|
|
352
|
-
|
|
230
|
+
case WatchableViewDataStoreKeys.groupLevels:
|
|
231
|
+
{
|
|
232
|
+
querySpecOptions.shouldIncludeGroupingLevels = true;
|
|
233
|
+
break;
|
|
234
|
+
}
|
|
353
235
|
|
|
236
|
+
case WatchableViewDataStoreKeys.recordColors:
|
|
237
|
+
{
|
|
238
|
+
querySpecOptions.shouldIncludeColorsForRecordId = true;
|
|
354
239
|
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
// change since we derive group information from the groupLevels (fieldId)
|
|
240
|
+
wrappedCallbackForQueryChange = changes => {
|
|
241
|
+
var recordColorsChange = this._findBlockSubscriptionChangedMatchingSubscriptionChangeTypeForViewIfExists(changes, _block_query_spec.BlockQuerySubscriptionChangeType.CHANGED_COLORS_BY_RECORD_ID_FOR_VIEW);
|
|
358
242
|
|
|
243
|
+
var recordIdsOrNull = null;
|
|
359
244
|
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
245
|
+
if (recordColorsChange) {
|
|
246
|
+
(0, _error_utils.invariant)(recordColorsChange.type === _block_query_spec.BlockQuerySubscriptionChangeType.CHANGED_COLORS_BY_RECORD_ID_FOR_VIEW, 'Invalid record colors change event');
|
|
247
|
+
recordIdsOrNull = recordColorsChange.recordIds;
|
|
248
|
+
} // We also always call this, even if no recordColors changed to closely mirror
|
|
249
|
+
// the old version of the SDK (https://github.com/Hyperbase/blocks-sdk/blob/8e3ac1a37be9c9850e64085975b102a483116080/packages/sdk/src/models/view_data_store.ts#L319-L361)
|
|
250
|
+
// In the future, this should not be the case (don't call callback if nothing changed)
|
|
363
251
|
|
|
364
|
-
if (dirtyPaths.groupLevels) {
|
|
365
|
-
this._onChange(WatchableViewDataStoreKeys.groupLevels);
|
|
366
|
-
}
|
|
367
252
|
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
// Checking isRecordMetadataLoaded fixes a timing issue:
|
|
373
|
-
// When a new table loads in liveapp, we'll receive the record
|
|
374
|
-
// colors before getting the response to our loadData call.
|
|
375
|
-
// This is a temporary fix: we need a more general solution to
|
|
376
|
-
// avoid processing events associated with subscriptions whose
|
|
377
|
-
// data we haven't received yet.
|
|
378
|
-
if (this.parentRecordStore.isRecordMetadataLoaded) {
|
|
379
|
-
var _iteratorNormalCompletion3 = true;
|
|
380
|
-
var _didIteratorError3 = false;
|
|
381
|
-
var _iteratorError3 = undefined;
|
|
382
|
-
|
|
383
|
-
try {
|
|
384
|
-
for (var _iterator3 = changedRecordIds[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
|
|
385
|
-
var recordId = _step3.value;
|
|
386
|
-
var record = this.parentRecordStore.getRecordByIdIfExists(recordId); // Similar to above, we could be receiving the change notification
|
|
387
|
-
// for a record color before receiving the new record itself.
|
|
388
|
-
|
|
389
|
-
if (record) {
|
|
390
|
-
record.__triggerOnChangeForRecordColorInViewId(this.viewId);
|
|
391
|
-
}
|
|
392
|
-
}
|
|
393
|
-
} catch (err) {
|
|
394
|
-
_didIteratorError3 = true;
|
|
395
|
-
_iteratorError3 = err;
|
|
396
|
-
} finally {
|
|
397
|
-
try {
|
|
398
|
-
if (!_iteratorNormalCompletion3 && _iterator3.return != null) {
|
|
399
|
-
_iterator3.return();
|
|
400
|
-
}
|
|
401
|
-
} finally {
|
|
402
|
-
if (_didIteratorError3) {
|
|
403
|
-
throw _iteratorError3;
|
|
404
|
-
}
|
|
405
|
-
}
|
|
406
|
-
}
|
|
253
|
+
callbackForRegistration.call(context, this, key, recordIdsOrNull);
|
|
254
|
+
};
|
|
255
|
+
|
|
256
|
+
break;
|
|
407
257
|
}
|
|
408
|
-
}
|
|
409
258
|
|
|
410
|
-
|
|
259
|
+
case WatchableViewDataStoreKeys.allFieldIds:
|
|
260
|
+
{
|
|
261
|
+
querySpecOptions.shouldIncludeFieldOrder = true;
|
|
262
|
+
break;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
case WatchableViewDataStoreKeys.visibleFieldIds:
|
|
266
|
+
{
|
|
267
|
+
// TODO: This will trigger even if fieldIds which aren't visible in the view change.
|
|
268
|
+
// This is NOT a regression, a fix would be to add an intermediate callback
|
|
269
|
+
// which swallows changes if the visible fieldOrder does not change.
|
|
270
|
+
querySpecOptions.shouldIncludeFieldOrder = true;
|
|
271
|
+
break;
|
|
272
|
+
}
|
|
273
|
+
// TypeScript ensures that key is of type never so we don't need to test this via istanbul
|
|
274
|
+
// istanbul ignore next
|
|
275
|
+
|
|
276
|
+
default:
|
|
277
|
+
throw (0, _error_utils.spawnExhaustiveSwitchError)(key);
|
|
411
278
|
}
|
|
279
|
+
|
|
280
|
+
return {
|
|
281
|
+
querySpecToSubscribeWith: {
|
|
282
|
+
sourceType: _block_query_spec.BlockQuerySourceType.VIEW,
|
|
283
|
+
sourceTableId: this.parentRecordStore.tableId,
|
|
284
|
+
sourceViewId: this.viewId,
|
|
285
|
+
viewMetadataSelection: querySpecOptions
|
|
286
|
+
},
|
|
287
|
+
wrappedCallbackForQueryChange
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Watching a key that needs to load data asynchronously will automatically
|
|
292
|
+
* cause the data to be fetched. Once the data is available, the callback
|
|
293
|
+
* will be called.
|
|
294
|
+
*
|
|
295
|
+
* @inheritdoc
|
|
296
|
+
*/
|
|
297
|
+
|
|
298
|
+
}, {
|
|
299
|
+
key: "watch",
|
|
300
|
+
value: function watch(keys, callbackForWatchKey, context) {
|
|
301
|
+
return this._internalWatch(_airtable_interface.BlockQueryCallbackPriority.BLOCK_CODE, keys, callbackForWatchKey, context);
|
|
302
|
+
}
|
|
303
|
+
}, {
|
|
304
|
+
key: "watchFromSdk",
|
|
305
|
+
value: function watchFromSdk(keys, callbackForWatchKey, context) {
|
|
306
|
+
return this._internalWatch(_airtable_interface.BlockQueryCallbackPriority.SDK, keys, callbackForWatchKey, context);
|
|
307
|
+
}
|
|
308
|
+
}, {
|
|
309
|
+
key: "_internalWatch",
|
|
310
|
+
value: function _internalWatch(priority, keys, callbackForWatchKey, context) {
|
|
311
|
+
this._assertNotForceUnloaded();
|
|
312
|
+
|
|
313
|
+
var validKeys = this._getWatchableValidKeysOrThrow(keys, 'view watch');
|
|
314
|
+
|
|
315
|
+
validKeys.forEach(validKey => {
|
|
316
|
+
var _this$_constructBlock = this._constructBlockQuerySpecForWatchableKey(validKey, callbackForWatchKey, context),
|
|
317
|
+
querySpecToSubscribeWith = _this$_constructBlock.querySpecToSubscribeWith,
|
|
318
|
+
wrappedCallbackForQueryChange = _this$_constructBlock.wrappedCallbackForQueryChange;
|
|
319
|
+
|
|
320
|
+
this._queryManager.watchWithQuerySpec(priority, querySpecToSubscribeWith, this, validKey, wrappedCallbackForQueryChange, callbackForWatchKey, context);
|
|
321
|
+
});
|
|
322
|
+
return validKeys;
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Unwatching a key that needs to load data asynchronously will automatically
|
|
326
|
+
* cause the data to be released. Once the data is available, the callback
|
|
327
|
+
* will be called.
|
|
328
|
+
*
|
|
329
|
+
* @inheritdoc
|
|
330
|
+
*/
|
|
331
|
+
|
|
332
|
+
}, {
|
|
333
|
+
key: "unwatch",
|
|
334
|
+
value: function unwatch(keys, callbackForRegistration, context) {
|
|
335
|
+
// We have already unsubscribed from all watches (because query-based watches force data to be loaded)
|
|
336
|
+
// so no watches are subscribed
|
|
337
|
+
if (this._isForceUnloaded) {
|
|
338
|
+
return [];
|
|
339
|
+
} // We warn instead of throw here because we used to warn instead of throw and don't
|
|
340
|
+
// want to make a breaking change.
|
|
341
|
+
|
|
342
|
+
|
|
343
|
+
var validKeys = this._getWatchableValidKeysOrThrow(keys, 'view unwatch', true);
|
|
344
|
+
|
|
345
|
+
validKeys.forEach(key => this._queryManager.unwatchFromQueryKey(key, callbackForRegistration, context));
|
|
346
|
+
return validKeys;
|
|
347
|
+
}
|
|
348
|
+
}, {
|
|
349
|
+
key: "triggerOnChangeForDirtyPaths",
|
|
350
|
+
value: function triggerOnChangeForDirtyPaths(dirtyPaths) {// This is only triggered for changes to values in the type ViewData, which is
|
|
351
|
+
// populated and kept up to date by watching base schema (aka the view's id, name, type).
|
|
352
|
+
// None of these are watchable, so we don't need to call this._onChange() for them.
|
|
353
|
+
// In the future we may want to make the view's name watchable, which is the only property
|
|
354
|
+
// here that we'd expect to change. In this case, it would be handled here.
|
|
412
355
|
}
|
|
413
356
|
}, {
|
|
414
357
|
key: "_dataOrNullIfDeleted",
|
|
415
358
|
get: function get() {
|
|
416
|
-
var
|
|
359
|
+
var _ref;
|
|
417
360
|
|
|
418
361
|
var tableData = this._baseData.tablesById[this.parentRecordStore.tableId];
|
|
419
|
-
return (
|
|
362
|
+
return (_ref = tableData === null || tableData === void 0 ? void 0 : tableData.viewsById[this.viewId]) !== null && _ref !== void 0 ? _ref : null;
|
|
420
363
|
}
|
|
421
364
|
}, {
|
|
422
365
|
key: "isDataLoaded",
|
|
423
366
|
get: function get() {
|
|
424
|
-
return this._isDataLoaded
|
|
367
|
+
return this._isDataLoaded;
|
|
368
|
+
}
|
|
369
|
+
}, {
|
|
370
|
+
key: "isRecordDataLoadedForView",
|
|
371
|
+
get: function get() {
|
|
372
|
+
// We _currently_ only issue queries that also load cell data in the view which
|
|
373
|
+
// is synchronously returned with all other view data, so we can collapse this
|
|
374
|
+
// to if the viewData has loaded.
|
|
375
|
+
// TODO: (#proj-blocks-sdk-record-limits) Actually track if all cell data is loaded
|
|
376
|
+
// based on issued queries from ViewDataStore
|
|
377
|
+
return this.isDataLoaded;
|
|
425
378
|
}
|
|
426
379
|
}, {
|
|
427
380
|
key: "visibleRecordIds",
|
|
428
381
|
get: function get() {
|
|
429
|
-
|
|
430
|
-
(0, _error_utils.invariant)(visibleRecordIds, 'View data is not loaded'); // Freeze visibleRecordIds so users can't mutate it.
|
|
431
|
-
// If it changes from liveapp, we get an entire new array which will
|
|
432
|
-
// replace this one, so it's okay to freeze it.
|
|
382
|
+
this._assertExistsAndLoaded(); // Freezing the visibleRecordIds happens on the other side of the bridge
|
|
433
383
|
|
|
434
|
-
if (!Object.isFrozen(visibleRecordIds)) {
|
|
435
|
-
Object.freeze(visibleRecordIds);
|
|
436
|
-
}
|
|
437
384
|
|
|
385
|
+
var visibleRecordIds = this._publicViewStore.getVisibleRecordIds();
|
|
386
|
+
|
|
387
|
+
(0, _error_utils.invariant)(visibleRecordIds, 'View data is not loaded');
|
|
438
388
|
return visibleRecordIds;
|
|
439
389
|
}
|
|
440
390
|
/**
|
|
@@ -446,8 +396,12 @@ function (_AbstractModelWithAsy) {
|
|
|
446
396
|
}, {
|
|
447
397
|
key: "visibleRecords",
|
|
448
398
|
get: function get() {
|
|
449
|
-
(0, _error_utils.invariant)(this.
|
|
450
|
-
|
|
399
|
+
(0, _error_utils.invariant)(this.isRecordDataLoadedForView, 'Table data is not loaded for this view');
|
|
400
|
+
|
|
401
|
+
this._assertExistsAndLoaded();
|
|
402
|
+
|
|
403
|
+
var visibleRecordIds = this._publicViewStore.getVisibleRecordIds();
|
|
404
|
+
|
|
451
405
|
(0, _error_utils.invariant)(visibleRecordIds, 'View data is not loaded');
|
|
452
406
|
return visibleRecordIds.map(recordId => {
|
|
453
407
|
var record = this.parentRecordStore.getRecordByIdIfExists(recordId);
|
|
@@ -466,9 +420,9 @@ function (_AbstractModelWithAsy) {
|
|
|
466
420
|
}, {
|
|
467
421
|
key: "groups",
|
|
468
422
|
get: function get() {
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
return
|
|
423
|
+
this._assertExistsAndLoaded();
|
|
424
|
+
|
|
425
|
+
return this._publicViewStore.getGroups();
|
|
472
426
|
}
|
|
473
427
|
/**
|
|
474
428
|
* Gets the group config for this view, can be watched to know when groupLevels
|
|
@@ -478,23 +432,29 @@ function (_AbstractModelWithAsy) {
|
|
|
478
432
|
}, {
|
|
479
433
|
key: "groupLevels",
|
|
480
434
|
get: function get() {
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
return
|
|
435
|
+
this._assertExistsAndLoaded();
|
|
436
|
+
|
|
437
|
+
return this._publicViewStore.getGroupLevels();
|
|
484
438
|
}
|
|
485
439
|
}, {
|
|
486
440
|
key: "allFieldIds",
|
|
487
441
|
get: function get() {
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
442
|
+
this._assertExistsAndLoaded(); // TODO: (#proj-blocks-sdk-record-limits) Future sdk version shouldn't deep
|
|
443
|
+
// copy this, and it should be legal to return the frozen object directly
|
|
444
|
+
|
|
445
|
+
|
|
446
|
+
return (0, _private_utils.cloneDeep)(this._publicViewStore.getFieldOrder().fieldIds);
|
|
491
447
|
}
|
|
492
448
|
}, {
|
|
493
449
|
key: "visibleFieldIds",
|
|
494
450
|
get: function get() {
|
|
495
|
-
|
|
451
|
+
this._assertExistsAndLoaded();
|
|
452
|
+
|
|
453
|
+
var fieldOrder = this._publicViewStore.getFieldOrder();
|
|
454
|
+
|
|
496
455
|
(0, _error_utils.invariant)(fieldOrder, 'View data is not loaded');
|
|
497
|
-
var fieldIds = fieldOrder.fieldIds;
|
|
456
|
+
var fieldIds = fieldOrder.fieldIds; // Slice returns a mutable copy even though visibleFieldCount is readonly
|
|
457
|
+
|
|
498
458
|
return fieldIds.slice(0, fieldOrder.visibleFieldCount);
|
|
499
459
|
}
|
|
500
460
|
}]);
|