@airtable/blocks 1.10.2-experimental-640bd10-20220211 → 1.11.1
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 +12 -1
- package/dist/cjs/error_utils.js +9 -34
- package/dist/cjs/models/base.js +15 -0
- package/dist/cjs/models/field.js +99 -4
- package/dist/cjs/models/grouped_record_query_result.js +14 -5
- package/dist/cjs/models/linked_records_query_result.js +44 -86
- package/dist/cjs/models/mutations.js +234 -53
- package/dist/cjs/models/record.js +55 -310
- package/dist/cjs/models/record_query_result.js +1 -4
- package/dist/cjs/models/record_store.js +779 -557
- package/dist/cjs/models/table.js +6 -6
- package/dist/cjs/models/table_or_view_query_result.js +419 -526
- package/dist/cjs/models/view_data_store.js +295 -255
- package/dist/cjs/private_utils.js +0 -40
- package/dist/cjs/sdk.js +2 -12
- package/dist/cjs/testing/abstract_mock_airtable_interface.js +11 -57
- package/dist/cjs/types/airtable_interface.js +2 -17
- package/dist/cjs/types/mutations.js +1 -0
- package/dist/cjs/ui/use_records.js +1 -5
- package/dist/cjs/unstable_testing_utils.js +1 -55
- package/dist/cjs/watchable.js +1 -15
- package/dist/types/src/error_utils.d.ts +4 -2
- package/dist/types/src/error_utils.d.ts.map +1 -1
- package/dist/types/src/models/base.d.ts +10 -0
- package/dist/types/src/models/base.d.ts.map +1 -1
- package/dist/types/src/models/field.d.ts +58 -0
- package/dist/types/src/models/field.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/record.d.ts +3 -12
- package/dist/types/src/models/record.d.ts.map +1 -1
- package/dist/types/src/models/record_query_result.d.ts +2 -3
- 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 +5 -3
- 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 +1 -0
- 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 +1 -24
- 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/src/types/airtable_interface.d.ts +20 -59
- package/dist/types/src/types/airtable_interface.d.ts.map +1 -1
- package/dist/types/src/types/base.d.ts +1 -0
- package/dist/types/src/types/base.d.ts.map +1 -1
- package/dist/types/src/types/mutations.d.ts +25 -2
- package/dist/types/src/types/mutations.d.ts.map +1 -1
- package/dist/types/src/types/table.d.ts +2 -0
- package/dist/types/src/types/table.d.ts.map +1 -1
- package/dist/types/src/types/view.d.ts +8 -3
- 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 +1 -4
- 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/{src/testing → test/airtable_interface_mocks}/fixture_data.d.ts +19 -42
- package/dist/types/test/airtable_interface_mocks/fixture_data.d.ts.map +1 -0
- 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 +12 -19
- 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 +0 -2
- package/dist/types/test/test_helpers.d.ts.map +1 -1
- package/package.json +1 -2
- package/dist/cjs/models/query_manager.js +0 -328
- package/dist/cjs/testing/fixture_data.js +0 -268
- package/dist/cjs/testing/mock_base_data_stores.js +0 -876
- package/dist/cjs/types/block_query_spec.js +0 -85
- package/dist/types/src/models/query_manager.d.ts +0 -2
- package/dist/types/src/models/query_manager.d.ts.map +0 -1
- package/dist/types/src/testing/fixture_data.d.ts.map +0 -1
- package/dist/types/src/testing/mock_base_data_stores.d.ts +0 -55
- package/dist/types/src/testing/mock_base_data_stores.d.ts.map +0 -1
- package/dist/types/src/types/block_query_spec.d.ts +0 -139
- package/dist/types/src/types/block_query_spec.d.ts.map +0 -1
- package/dist/types/test/testing/fixture_data.test.d.ts +0 -2
- package/dist/types/test/testing/fixture_data.test.d.ts.map +0 -1
|
@@ -6,26 +6,18 @@ require("core-js/modules/es.symbol");
|
|
|
6
6
|
|
|
7
7
|
require("core-js/modules/es.symbol.description");
|
|
8
8
|
|
|
9
|
-
require("core-js/modules/es.array.concat");
|
|
10
|
-
|
|
11
9
|
require("core-js/modules/es.array.filter");
|
|
12
10
|
|
|
13
11
|
require("core-js/modules/es.array.iterator");
|
|
14
12
|
|
|
15
13
|
require("core-js/modules/es.array.map");
|
|
16
14
|
|
|
17
|
-
require("core-js/modules/es.object.get-own-property-descriptors");
|
|
18
|
-
|
|
19
15
|
require("core-js/modules/es.object.to-string");
|
|
20
16
|
|
|
21
17
|
require("core-js/modules/es.promise");
|
|
22
18
|
|
|
23
|
-
require("core-js/modules/es.set");
|
|
24
|
-
|
|
25
19
|
require("core-js/modules/es.string.starts-with");
|
|
26
20
|
|
|
27
|
-
require("core-js/modules/web.dom-collections.for-each");
|
|
28
|
-
|
|
29
21
|
require("core-js/modules/web.dom-collections.iterator");
|
|
30
22
|
|
|
31
23
|
Object.defineProperty(exports, "__esModule", {
|
|
@@ -33,6 +25,8 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
33
25
|
});
|
|
34
26
|
exports.default = exports.WatchableRecordStoreKeys = void 0;
|
|
35
27
|
|
|
28
|
+
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
|
29
|
+
|
|
36
30
|
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
|
|
37
31
|
|
|
38
32
|
require("regenerator-runtime/runtime");
|
|
@@ -41,9 +35,11 @@ var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/cl
|
|
|
41
35
|
|
|
42
36
|
var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
|
|
43
37
|
|
|
38
|
+
var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized"));
|
|
39
|
+
|
|
44
40
|
var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
|
|
45
41
|
|
|
46
|
-
var
|
|
42
|
+
var _get2 = _interopRequireDefault(require("@babel/runtime/helpers/get"));
|
|
47
43
|
|
|
48
44
|
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
|
|
49
45
|
|
|
@@ -55,20 +51,12 @@ var _private_utils = require("../private_utils");
|
|
|
55
51
|
|
|
56
52
|
var _error_utils = require("../error_utils");
|
|
57
53
|
|
|
58
|
-
var _warning = _interopRequireDefault(require("../warning"));
|
|
59
|
-
|
|
60
|
-
var _block_query_spec = require("../types/block_query_spec");
|
|
61
|
-
|
|
62
54
|
var _abstract_model_with_async_data = _interopRequireDefault(require("./abstract_model_with_async_data"));
|
|
63
55
|
|
|
64
56
|
var _record = _interopRequireDefault(require("./record"));
|
|
65
57
|
|
|
66
58
|
var _view_data_store = _interopRequireDefault(require("./view_data_store"));
|
|
67
59
|
|
|
68
|
-
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
|
|
69
|
-
|
|
70
|
-
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
|
|
71
|
-
|
|
72
60
|
var WatchableRecordStoreKeys = Object.freeze({
|
|
73
61
|
records: 'records',
|
|
74
62
|
recordIds: 'recordIds',
|
|
@@ -83,9 +71,8 @@ var WatchableCellValuesInFieldKeyPrefix = 'cellValuesInField:';
|
|
|
83
71
|
*/
|
|
84
72
|
|
|
85
73
|
/**
|
|
86
|
-
* One RecordStore exists per table, and
|
|
87
|
-
*
|
|
88
|
-
* Table itself is for schema information only, so isn't the appropriate place for record data.
|
|
74
|
+
* One RecordStore exists per table, and contains all the record data associated with that table.
|
|
75
|
+
* Table itself is for schema information only, so isn't the appropriate place for this data.
|
|
89
76
|
*
|
|
90
77
|
* @internal
|
|
91
78
|
*/
|
|
@@ -98,6 +85,16 @@ function (_AbstractModelWithAsy) {
|
|
|
98
85
|
value: function _isWatchableKey(key) {
|
|
99
86
|
return (0, _private_utils.isEnumValue)(WatchableRecordStoreKeys, key) || key.startsWith(WatchableCellValuesInFieldKeyPrefix);
|
|
100
87
|
}
|
|
88
|
+
}, {
|
|
89
|
+
key: "_shouldLoadDataForKey",
|
|
90
|
+
value: function _shouldLoadDataForKey(key) {
|
|
91
|
+
// "Data" means *all* cell values in the table. If only watching records/recordIds,
|
|
92
|
+
// we'll just load record metadata (id, createdTime, commentCount).
|
|
93
|
+
// If only watching specific fields, we'll just load cell values in those
|
|
94
|
+
// fields. Both of those scenarios are handled manually by this class,
|
|
95
|
+
// instead of relying on AbstractModelWithAsyncData.
|
|
96
|
+
return key === WatchableRecordStoreKeys.cellValues;
|
|
97
|
+
}
|
|
101
98
|
}]);
|
|
102
99
|
|
|
103
100
|
function RecordStore(sdk, tableId) {
|
|
@@ -109,15 +106,11 @@ function (_AbstractModelWithAsy) {
|
|
|
109
106
|
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "_recordModelsById", {});
|
|
110
107
|
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "_primaryFieldId", void 0);
|
|
111
108
|
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "_airtableInterface", void 0);
|
|
112
|
-
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "_queryManager", void 0);
|
|
113
109
|
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "_viewDataStoresByViewId", {});
|
|
114
|
-
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "
|
|
115
|
-
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "
|
|
116
|
-
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "
|
|
117
|
-
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "_loadedQuerySpecIds", new Set());
|
|
118
|
-
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "_forceUnloadCallbacks", []);
|
|
110
|
+
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "_areCellValuesLoadedByFieldId", {});
|
|
111
|
+
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "_pendingCellValuesLoadPromiseByFieldId", {});
|
|
112
|
+
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "_cellValuesRetainCountByFieldId", {});
|
|
119
113
|
_this._airtableInterface = sdk.__airtableInterface;
|
|
120
|
-
_this._queryManager = sdk._queryManager;
|
|
121
114
|
_this.tableId = tableId; // A bit of a hack, but we use the primary field ID to load record
|
|
122
115
|
// metadata (see _getFieldIdForCausingRecordMetadataToLoad). We copy the
|
|
123
116
|
// ID here instead of calling this.primaryField.id since that would crash
|
|
@@ -128,323 +121,96 @@ function (_AbstractModelWithAsy) {
|
|
|
128
121
|
}
|
|
129
122
|
|
|
130
123
|
(0, _createClass2.default)(RecordStore, [{
|
|
131
|
-
key: "_getRecordStoreForTable",
|
|
132
|
-
value: function _getRecordStoreForTable() {
|
|
133
|
-
if (!this._airtableRecordStoreForTable) {
|
|
134
|
-
var airtableRecordStoreForTable = this._airtableInterface.getTableRecordStoreIfExists(this.tableId);
|
|
135
|
-
|
|
136
|
-
(0, _error_utils.invariant)(airtableRecordStoreForTable, 'no RecordStoreForTable found for tableId %s', this.tableId);
|
|
137
|
-
this._airtableRecordStoreForTable = airtableRecordStoreForTable;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
return this._airtableRecordStoreForTable;
|
|
141
|
-
}
|
|
142
|
-
}, {
|
|
143
124
|
key: "getViewDataStore",
|
|
144
125
|
value: function getViewDataStore(viewId) {
|
|
145
126
|
if (this._viewDataStoresByViewId[viewId]) {
|
|
146
127
|
return this._viewDataStoresByViewId[viewId];
|
|
147
128
|
}
|
|
148
129
|
|
|
149
|
-
(0, _error_utils.invariant)(this._data.viewsById[viewId], 'view must exist');
|
|
150
|
-
// conflict with hyperbase ViewDataStore. Here we are using the SDK ViewDataStore
|
|
151
|
-
// which is a thin wrapper around the hyperbase one.
|
|
152
|
-
|
|
130
|
+
(0, _error_utils.invariant)(this._data.viewsById[viewId], 'view must exist');
|
|
153
131
|
var viewDataStore = new _view_data_store.default(this._sdk, this, viewId);
|
|
154
132
|
this._viewDataStoresByViewId[viewId] = viewDataStore;
|
|
155
133
|
return viewDataStore;
|
|
156
134
|
}
|
|
157
135
|
}, {
|
|
158
|
-
key: "
|
|
159
|
-
value: function
|
|
160
|
-
var
|
|
161
|
-
|
|
162
|
-
if (viewDataStoreIfExists && viewDataStoreIfExists.isDeleted) {
|
|
163
|
-
viewDataStoreIfExists.__onDataDeletion();
|
|
164
|
-
|
|
165
|
-
delete this._viewDataStoresByViewId[viewId];
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
}, {
|
|
169
|
-
key: "_findMatchingBlockSubscriptionChanges",
|
|
170
|
-
value: function _findMatchingBlockSubscriptionChanges(changes, changeTypeToMatch) {
|
|
171
|
-
return changes.filter(change => change.type === changeTypeToMatch && change.tableId === this.tableId);
|
|
172
|
-
}
|
|
173
|
-
}, {
|
|
174
|
-
key: "_constructBlockQuerySpecAndCallbackForWatchableKeyWithRecordQueryResult",
|
|
175
|
-
value: function _constructBlockQuerySpecAndCallbackForWatchableKeyWithRecordQueryResult(recordQueryResult, key, callbackForRegistration, context) {
|
|
176
|
-
var fieldSelectionDefinition;
|
|
177
|
-
var originThis = recordQueryResult;
|
|
178
|
-
var onChangeCallback;
|
|
179
|
-
|
|
180
|
-
switch (key) {
|
|
181
|
-
case WatchableRecordStoreKeys.records:
|
|
182
|
-
case WatchableRecordStoreKeys.recordIds:
|
|
183
|
-
fieldSelectionDefinition = {
|
|
184
|
-
type: _block_query_spec.BlockFieldSelectionSpecType.SPECIFIED_FIELDS,
|
|
185
|
-
fieldIds: []
|
|
186
|
-
};
|
|
187
|
-
|
|
188
|
-
onChangeCallback = changes => {
|
|
189
|
-
var addedRecordsChanges = this._findMatchingBlockSubscriptionChanges(changes, _block_query_spec.BlockQuerySubscriptionChangeType.ADDED_RECORD_IDS);
|
|
190
|
-
|
|
191
|
-
var removedRecordsChanges = this._findMatchingBlockSubscriptionChanges(changes, _block_query_spec.BlockQuerySubscriptionChangeType.REMOVED_RECORD_IDS);
|
|
192
|
-
|
|
193
|
-
var addedRecordIds = [];
|
|
194
|
-
var removedRecordIds = [];
|
|
195
|
-
var _iteratorNormalCompletion = true;
|
|
196
|
-
var _didIteratorError = false;
|
|
197
|
-
var _iteratorError = undefined;
|
|
198
|
-
|
|
199
|
-
try {
|
|
200
|
-
for (var _iterator = addedRecordsChanges[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
|
|
201
|
-
var addedRecordsChange = _step.value;
|
|
202
|
-
(0, _error_utils.invariant)(addedRecordsChange.type === _block_query_spec.BlockQuerySubscriptionChangeType.ADDED_RECORD_IDS, 'Added Records change is not a supported type');
|
|
203
|
-
addedRecordIds = addedRecordIds.concat(addedRecordsChange.recordIds);
|
|
204
|
-
}
|
|
205
|
-
} catch (err) {
|
|
206
|
-
_didIteratorError = true;
|
|
207
|
-
_iteratorError = err;
|
|
208
|
-
} finally {
|
|
209
|
-
try {
|
|
210
|
-
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
211
|
-
_iterator.return();
|
|
212
|
-
}
|
|
213
|
-
} finally {
|
|
214
|
-
if (_didIteratorError) {
|
|
215
|
-
throw _iteratorError;
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
var _iteratorNormalCompletion2 = true;
|
|
221
|
-
var _didIteratorError2 = false;
|
|
222
|
-
var _iteratorError2 = undefined;
|
|
223
|
-
|
|
224
|
-
try {
|
|
225
|
-
for (var _iterator2 = removedRecordsChanges[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
|
|
226
|
-
var removedRecordsChange = _step2.value;
|
|
227
|
-
(0, _error_utils.invariant)(removedRecordsChange.type === _block_query_spec.BlockQuerySubscriptionChangeType.REMOVED_RECORD_IDS, 'Removed Records change is not a supported type');
|
|
228
|
-
removedRecordIds = removedRecordIds.concat(removedRecordsChange.recordIds);
|
|
229
|
-
}
|
|
230
|
-
} catch (err) {
|
|
231
|
-
_didIteratorError2 = true;
|
|
232
|
-
_iteratorError2 = err;
|
|
233
|
-
} finally {
|
|
234
|
-
try {
|
|
235
|
-
if (!_iteratorNormalCompletion2 && _iterator2.return != null) {
|
|
236
|
-
_iterator2.return();
|
|
237
|
-
}
|
|
238
|
-
} finally {
|
|
239
|
-
if (_didIteratorError2) {
|
|
240
|
-
throw _iteratorError2;
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
var recordIdsChanged = {
|
|
246
|
-
addedRecordIds,
|
|
247
|
-
removedRecordIds
|
|
248
|
-
};
|
|
249
|
-
callbackForRegistration.call(context, originThis, key, recordIdsChanged);
|
|
250
|
-
};
|
|
251
|
-
|
|
252
|
-
break;
|
|
253
|
-
|
|
254
|
-
case WatchableRecordStoreKeys.cellValues:
|
|
255
|
-
fieldSelectionDefinition = {
|
|
256
|
-
type: _block_query_spec.BlockFieldSelectionSpecType.ALL_FIELDS_FROM_TABLE
|
|
257
|
-
};
|
|
258
|
-
|
|
259
|
-
onChangeCallback = changes => {
|
|
260
|
-
var modifiedCellValuesChanges = this._findMatchingBlockSubscriptionChanges(changes, _block_query_spec.BlockQuerySubscriptionChangeType.MODIFIED_CELL_VALUES_FOR_TABLE);
|
|
261
|
-
|
|
262
|
-
if (modifiedCellValuesChanges.length === 0) {
|
|
263
|
-
callbackForRegistration.call(context, originThis, key);
|
|
264
|
-
return;
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
var recordsAndFieldsChanged = {
|
|
268
|
-
recordIds: [],
|
|
269
|
-
fieldIds: []
|
|
270
|
-
};
|
|
271
|
-
var _iteratorNormalCompletion3 = true;
|
|
272
|
-
var _didIteratorError3 = false;
|
|
273
|
-
var _iteratorError3 = undefined;
|
|
274
|
-
|
|
275
|
-
try {
|
|
276
|
-
for (var _iterator3 = modifiedCellValuesChanges[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
|
|
277
|
-
var modifiedCellValuesChange = _step3.value;
|
|
278
|
-
(0, _error_utils.invariant)(modifiedCellValuesChange.type === _block_query_spec.BlockQuerySubscriptionChangeType.MODIFIED_CELL_VALUES_FOR_TABLE, 'Modified cell value change is not a supported type');
|
|
279
|
-
var fieldIdsByRecordId = modifiedCellValuesChange.fieldIdsByRecordId,
|
|
280
|
-
fieldIds = modifiedCellValuesChange.fieldIds;
|
|
281
|
-
recordsAndFieldsChanged.recordIds = recordsAndFieldsChanged.recordIds.concat(Object.keys(fieldIdsByRecordId));
|
|
282
|
-
recordsAndFieldsChanged.fieldIds = recordsAndFieldsChanged.fieldIds.concat(fieldIds);
|
|
283
|
-
}
|
|
284
|
-
} catch (err) {
|
|
285
|
-
_didIteratorError3 = true;
|
|
286
|
-
_iteratorError3 = err;
|
|
287
|
-
} finally {
|
|
288
|
-
try {
|
|
289
|
-
if (!_iteratorNormalCompletion3 && _iterator3.return != null) {
|
|
290
|
-
_iterator3.return();
|
|
291
|
-
}
|
|
292
|
-
} finally {
|
|
293
|
-
if (_didIteratorError3) {
|
|
294
|
-
throw _iteratorError3;
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
callbackForRegistration.call(context, originThis, key, recordsAndFieldsChanged);
|
|
300
|
-
};
|
|
301
|
-
|
|
302
|
-
break;
|
|
303
|
-
|
|
304
|
-
default:
|
|
305
|
-
{
|
|
306
|
-
// Since this watch class is only called internally from within the SDK
|
|
307
|
-
// an error here is an internal SDK error.
|
|
308
|
-
(0, _error_utils.invariant)(key.startsWith(WatchableCellValuesInFieldKeyPrefix), 'Internal error - Unrecognized watch key on record_store: %s', key);
|
|
309
|
-
var fieldId = key.substring(WatchableCellValuesInFieldKeyPrefix.length); // Assert that fieldId is validly formatted, not that it is a valid fieldId in this table
|
|
310
|
-
|
|
311
|
-
(0, _error_utils.invariant)((0, _private_utils.isFieldId)(fieldId), 'fieldId passed as watchable fieldId is not a valid format' + fieldId);
|
|
312
|
-
fieldSelectionDefinition = {
|
|
313
|
-
type: _block_query_spec.BlockFieldSelectionSpecType.SPECIFIED_FIELDS,
|
|
314
|
-
fieldIds: [fieldId]
|
|
315
|
-
};
|
|
316
|
-
|
|
317
|
-
onChangeCallback = changes => {
|
|
318
|
-
var modifiedCellValuesChanges = this._findMatchingBlockSubscriptionChanges(changes, _block_query_spec.BlockQuerySubscriptionChangeType.MODIFIED_CELL_VALUES_FOR_TABLE);
|
|
319
|
-
|
|
320
|
-
if (modifiedCellValuesChanges.length === 0) {
|
|
321
|
-
callbackForRegistration.call(context, originThis, key);
|
|
322
|
-
return;
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
var recordsChanged = [];
|
|
326
|
-
var _iteratorNormalCompletion4 = true;
|
|
327
|
-
var _didIteratorError4 = false;
|
|
328
|
-
var _iteratorError4 = undefined;
|
|
329
|
-
|
|
330
|
-
try {
|
|
331
|
-
for (var _iterator4 = modifiedCellValuesChanges[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {
|
|
332
|
-
var modifiedCellValuesChange = _step4.value;
|
|
333
|
-
(0, _error_utils.invariant)(modifiedCellValuesChange.type === _block_query_spec.BlockQuerySubscriptionChangeType.MODIFIED_CELL_VALUES_FOR_TABLE, 'Modified cell value change is not a supported type');
|
|
334
|
-
recordsChanged = recordsChanged.concat(Object.keys(modifiedCellValuesChange.fieldIdsByRecordId));
|
|
335
|
-
} // Why is this callback format different than when watching just cellValues?
|
|
336
|
-
// It's because in the past this was the format we used: https://github.com/Hyperbase/blocks-sdk/blob/32b6c59944f0d89d2c0b3b61b7db615145a8856b/packages/sdk/src/models/record_store.ts#L547-L554
|
|
337
|
-
|
|
338
|
-
} catch (err) {
|
|
339
|
-
_didIteratorError4 = true;
|
|
340
|
-
_iteratorError4 = err;
|
|
341
|
-
} finally {
|
|
342
|
-
try {
|
|
343
|
-
if (!_iteratorNormalCompletion4 && _iterator4.return != null) {
|
|
344
|
-
_iterator4.return();
|
|
345
|
-
}
|
|
346
|
-
} finally {
|
|
347
|
-
if (_didIteratorError4) {
|
|
348
|
-
throw _iteratorError4;
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
}
|
|
136
|
+
key: "watch",
|
|
137
|
+
value: function watch(keys, callback, context) {
|
|
138
|
+
var validKeys = (0, _get2.default)((0, _getPrototypeOf2.default)(RecordStore.prototype), "watch", this).call(this, keys, callback, context);
|
|
352
139
|
|
|
353
|
-
|
|
354
|
-
};
|
|
140
|
+
var fieldIdsToLoad = this._getFieldIdsToLoadFromWatchableKeys(validKeys);
|
|
355
141
|
|
|
356
|
-
|
|
357
|
-
|
|
142
|
+
if (fieldIdsToLoad.length > 0) {
|
|
143
|
+
(0, _private_utils.fireAndForgetPromise)(this.loadCellValuesInFieldIdsAsync.bind(this, fieldIdsToLoad));
|
|
358
144
|
}
|
|
359
145
|
|
|
360
|
-
return {
|
|
361
|
-
querySpecToSubscribeWith: recordQueryResult.__constructQuerySpecForBlockFieldSelectionSpec(fieldSelectionDefinition),
|
|
362
|
-
onChangeCallback
|
|
363
|
-
};
|
|
364
|
-
}
|
|
365
|
-
}, {
|
|
366
|
-
key: "watch",
|
|
367
|
-
value: function watch(keys, callbackForRegistration, context) {
|
|
368
|
-
throw (0, _error_utils.spawnError)('Must not call watch on record_store directly');
|
|
369
|
-
}
|
|
370
|
-
}, {
|
|
371
|
-
key: "watchWithRecordQueryResult",
|
|
372
|
-
value: function watchWithRecordQueryResult(_ref) {
|
|
373
|
-
var priority = _ref.priority,
|
|
374
|
-
recordQueryResult = _ref.recordQueryResult,
|
|
375
|
-
keys = _ref.keys,
|
|
376
|
-
callbackForRegistration = _ref.callbackForRegistration,
|
|
377
|
-
context = _ref.context;
|
|
378
|
-
|
|
379
|
-
// Note that we do not call super.watch(), we use the
|
|
380
|
-
// alternative this._queryManager.watchWithQuerySpec
|
|
381
|
-
this._assertNotForceUnloaded();
|
|
382
|
-
|
|
383
|
-
var validKeys = this._getWatchableValidKeysOrThrow(keys, 'table watch');
|
|
384
|
-
|
|
385
|
-
validKeys.forEach(validKey => {
|
|
386
|
-
var _this$_constructBlock = this._constructBlockQuerySpecAndCallbackForWatchableKeyWithRecordQueryResult(recordQueryResult, validKey, callbackForRegistration, context),
|
|
387
|
-
querySpecToSubscribeWith = _this$_constructBlock.querySpecToSubscribeWith,
|
|
388
|
-
onChangeCallback = _this$_constructBlock.onChangeCallback;
|
|
389
|
-
|
|
390
|
-
var onChangeCallbackThatIncrementsWatchChangeCount = args => {
|
|
391
|
-
// Normally calling __incrementOnChangeCount is handled by queryManager.watchWithQuerySpec
|
|
392
|
-
// however it will only increment the change count on the recordStore. In this case we ALSO
|
|
393
|
-
// need to increment the change count on the recordQueryResult.
|
|
394
|
-
recordQueryResult.__incrementOnChangeCount();
|
|
395
|
-
|
|
396
|
-
onChangeCallback(args);
|
|
397
|
-
};
|
|
398
|
-
|
|
399
|
-
this._queryManager.watchWithQuerySpec(priority, querySpecToSubscribeWith, this, validKey, onChangeCallbackThatIncrementsWatchChangeCount, callbackForRegistration, context);
|
|
400
|
-
});
|
|
401
146
|
return validKeys;
|
|
402
147
|
}
|
|
403
148
|
}, {
|
|
404
149
|
key: "unwatch",
|
|
405
|
-
value: function unwatch(keys,
|
|
406
|
-
|
|
407
|
-
// so no watches are subscribed
|
|
408
|
-
if (this._isForceUnloaded) {
|
|
409
|
-
return [];
|
|
410
|
-
} // We warn instead of throw here because we used to warn instead of throw and don't
|
|
411
|
-
// want to make a breaking change.
|
|
150
|
+
value: function unwatch(keys, callback, context) {
|
|
151
|
+
var validKeys = (0, _get2.default)((0, _getPrototypeOf2.default)(RecordStore.prototype), "unwatch", this).call(this, keys, callback, context);
|
|
412
152
|
|
|
153
|
+
var fieldIdsToUnload = this._getFieldIdsToLoadFromWatchableKeys(validKeys);
|
|
413
154
|
|
|
414
|
-
|
|
155
|
+
if (fieldIdsToUnload.length > 0) {
|
|
156
|
+
this.unloadCellValuesInFieldIds(fieldIdsToUnload);
|
|
157
|
+
}
|
|
415
158
|
|
|
416
|
-
validKeys.forEach(key => this._queryManager.unwatchFromQueryKey(key, callbackForRegistration, context));
|
|
417
159
|
return validKeys;
|
|
418
160
|
}
|
|
419
161
|
}, {
|
|
420
|
-
key: "
|
|
421
|
-
value: function
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
162
|
+
key: "_getFieldIdsToLoadFromWatchableKeys",
|
|
163
|
+
value: function _getFieldIdsToLoadFromWatchableKeys(keys) {
|
|
164
|
+
var fieldIdsToLoad = [];
|
|
165
|
+
var _iteratorNormalCompletion = true;
|
|
166
|
+
var _didIteratorError = false;
|
|
167
|
+
var _iteratorError = undefined;
|
|
168
|
+
|
|
169
|
+
try {
|
|
170
|
+
for (var _iterator = keys[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
|
|
171
|
+
var key = _step.value;
|
|
172
|
+
|
|
173
|
+
if (key.startsWith(WatchableCellValuesInFieldKeyPrefix)) {
|
|
174
|
+
var fieldId = key.substring(WatchableCellValuesInFieldKeyPrefix.length);
|
|
175
|
+
fieldIdsToLoad.push(fieldId);
|
|
176
|
+
} else if (key === WatchableRecordStoreKeys.records || key === WatchableRecordStoreKeys.recordIds) {
|
|
177
|
+
fieldIdsToLoad.push(this._getFieldIdForCausingRecordMetadataToLoad());
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
} catch (err) {
|
|
181
|
+
_didIteratorError = true;
|
|
182
|
+
_iteratorError = err;
|
|
183
|
+
} finally {
|
|
184
|
+
try {
|
|
185
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
186
|
+
_iterator.return();
|
|
187
|
+
}
|
|
188
|
+
} finally {
|
|
189
|
+
if (_didIteratorError) {
|
|
190
|
+
throw _iteratorError;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
425
194
|
|
|
195
|
+
return fieldIdsToLoad;
|
|
196
|
+
}
|
|
426
197
|
}, {
|
|
427
198
|
key: "_onChangeIsDataLoaded",
|
|
428
|
-
value: function _onChangeIsDataLoaded() {
|
|
429
|
-
|
|
430
|
-
}
|
|
199
|
+
value: function _onChangeIsDataLoaded() {} // noop
|
|
200
|
+
|
|
431
201
|
/**
|
|
432
202
|
* The records in this table. The order is arbitrary since records are
|
|
433
203
|
* only ordered in the context of a specific view.
|
|
434
204
|
*/
|
|
435
205
|
|
|
436
|
-
}, {
|
|
437
|
-
key: "isRecordLoaded",
|
|
438
|
-
value: function isRecordLoaded(recordId) {
|
|
439
|
-
return this._getRecordStoreForTable().isRecordPartiallyLoaded(recordId);
|
|
440
|
-
}
|
|
441
206
|
}, {
|
|
442
207
|
key: "getRecordByIdIfExists",
|
|
443
208
|
value: function getRecordByIdIfExists(recordId) {
|
|
444
|
-
|
|
209
|
+
var recordsById = this._data.recordsById;
|
|
210
|
+
(0, _error_utils.invariant)(recordsById, 'Record metadata is not loaded');
|
|
445
211
|
(0, _error_utils.invariant)(typeof recordId === 'string', 'getRecordById expects a string');
|
|
446
212
|
|
|
447
|
-
if (!
|
|
213
|
+
if (!recordsById[recordId]) {
|
|
448
214
|
return null;
|
|
449
215
|
} else {
|
|
450
216
|
if (this._recordModelsById[recordId]) {
|
|
@@ -459,64 +225,76 @@ function (_AbstractModelWithAsy) {
|
|
|
459
225
|
}, {
|
|
460
226
|
key: "__onDataDeletion",
|
|
461
227
|
value: function __onDataDeletion() {
|
|
462
|
-
|
|
228
|
+
// also need to call unloadCellValuesInFieldIds because otherwise
|
|
229
|
+
// on the hyperbase side, the old record store would still be subscribed
|
|
230
|
+
// to the cell values and it will refuse a request for new subscription
|
|
231
|
+
for (var _i = 0, _Object$keys = Object.keys(this._cellValuesRetainCountByFieldId); _i < _Object$keys.length; _i++) {
|
|
232
|
+
var fieldId = _Object$keys[_i];
|
|
233
|
+
|
|
234
|
+
while (this._cellValuesRetainCountByFieldId[fieldId] && this._cellValuesRetainCountByFieldId[fieldId] > 0) {
|
|
235
|
+
this.unloadCellValuesInFieldIds([fieldId]);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
this._forceUnload(); // similarly unsubscribe from the view data.
|
|
240
|
+
// this comes after _forceUnload to avoid over releasing the table data.
|
|
463
241
|
|
|
464
|
-
this._queryManager.forceUnloadWatchesOnWatchableModel(this);
|
|
465
242
|
|
|
466
|
-
var
|
|
467
|
-
var
|
|
468
|
-
var
|
|
243
|
+
var _iteratorNormalCompletion2 = true;
|
|
244
|
+
var _didIteratorError2 = false;
|
|
245
|
+
var _iteratorError2 = undefined;
|
|
469
246
|
|
|
470
247
|
try {
|
|
471
|
-
for (var
|
|
472
|
-
var
|
|
473
|
-
forceUnloadCallback();
|
|
474
|
-
} // similarly unsubscribe from the view data.
|
|
475
|
-
// this comes after _forceUnload to avoid over releasing the table data.
|
|
248
|
+
for (var _iterator2 = (0, _private_utils.values)(this._viewDataStoresByViewId)[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
|
|
249
|
+
var viewDataStore = _step2.value;
|
|
476
250
|
|
|
251
|
+
viewDataStore.__onDataDeletion();
|
|
252
|
+
}
|
|
477
253
|
} catch (err) {
|
|
478
|
-
|
|
479
|
-
|
|
254
|
+
_didIteratorError2 = true;
|
|
255
|
+
_iteratorError2 = err;
|
|
480
256
|
} finally {
|
|
481
257
|
try {
|
|
482
|
-
if (!
|
|
483
|
-
|
|
258
|
+
if (!_iteratorNormalCompletion2 && _iterator2.return != null) {
|
|
259
|
+
_iterator2.return();
|
|
484
260
|
}
|
|
485
261
|
} finally {
|
|
486
|
-
if (
|
|
487
|
-
throw
|
|
262
|
+
if (_didIteratorError2) {
|
|
263
|
+
throw _iteratorError2;
|
|
488
264
|
}
|
|
489
265
|
}
|
|
490
266
|
}
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Record metadata means record IDs, createdTime, and commentCount are loaded.
|
|
270
|
+
* Record metadata must be loaded before creating, deleting, or updating records.
|
|
271
|
+
*/
|
|
491
272
|
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
273
|
+
}, {
|
|
274
|
+
key: "loadRecordMetadataAsync",
|
|
275
|
+
value: function loadRecordMetadataAsync() {
|
|
276
|
+
return _regenerator.default.async(function loadRecordMetadataAsync$(_context) {
|
|
277
|
+
while (1) {
|
|
278
|
+
switch (_context.prev = _context.next) {
|
|
279
|
+
case 0:
|
|
280
|
+
_context.next = 2;
|
|
281
|
+
return _regenerator.default.awrap(this.loadCellValuesInFieldIdsAsync([this._getFieldIdForCausingRecordMetadataToLoad()]));
|
|
495
282
|
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
var viewDataStore = _step6.value;
|
|
283
|
+
case 2:
|
|
284
|
+
return _context.abrupt("return", _context.sent);
|
|
499
285
|
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
_didIteratorError6 = true;
|
|
504
|
-
_iteratorError6 = err;
|
|
505
|
-
} finally {
|
|
506
|
-
try {
|
|
507
|
-
if (!_iteratorNormalCompletion6 && _iterator6.return != null) {
|
|
508
|
-
_iterator6.return();
|
|
509
|
-
}
|
|
510
|
-
} finally {
|
|
511
|
-
if (_didIteratorError6) {
|
|
512
|
-
throw _iteratorError6;
|
|
286
|
+
case 3:
|
|
287
|
+
case "end":
|
|
288
|
+
return _context.stop();
|
|
513
289
|
}
|
|
514
290
|
}
|
|
515
|
-
}
|
|
516
|
-
}
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
291
|
+
}, null, this);
|
|
292
|
+
}
|
|
293
|
+
}, {
|
|
294
|
+
key: "unloadRecordMetadata",
|
|
295
|
+
value: function unloadRecordMetadata() {
|
|
296
|
+
this.unloadCellValuesInFieldIds([this._getFieldIdForCausingRecordMetadataToLoad()]);
|
|
297
|
+
}
|
|
520
298
|
}, {
|
|
521
299
|
key: "_getFieldIdForCausingRecordMetadataToLoad",
|
|
522
300
|
value: function _getFieldIdForCausingRecordMetadataToLoad() {
|
|
@@ -527,276 +305,721 @@ function (_AbstractModelWithAsy) {
|
|
|
527
305
|
return this._primaryFieldId;
|
|
528
306
|
}
|
|
529
307
|
}, {
|
|
530
|
-
key: "
|
|
531
|
-
value: function
|
|
532
|
-
return this.
|
|
533
|
-
}
|
|
534
|
-
}, {
|
|
535
|
-
key: "getRecordCellValueByFieldId",
|
|
536
|
-
value: function getRecordCellValueByFieldId(recordId, fieldId) {
|
|
537
|
-
return this._getRecordStoreForTable().getRecordCellValueByFieldId(recordId, fieldId);
|
|
308
|
+
key: "areCellValuesLoadedForFieldId",
|
|
309
|
+
value: function areCellValuesLoadedForFieldId(fieldId) {
|
|
310
|
+
return this.isDataLoaded || this._areCellValuesLoadedByFieldId[fieldId] || false;
|
|
538
311
|
}
|
|
539
312
|
}, {
|
|
540
|
-
key: "
|
|
541
|
-
value: function
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
key: "getRecordCreatedTime",
|
|
546
|
-
value: function getRecordCreatedTime(recordId) {
|
|
547
|
-
return this._getRecordStoreForTable().getRecordCreatedTime(recordId);
|
|
548
|
-
}
|
|
549
|
-
}, {
|
|
550
|
-
key: "_loadCellValuesForQueryAsync",
|
|
551
|
-
value: function _loadCellValuesForQueryAsync(query) {
|
|
552
|
-
var querySpecIdPromise, onForceUnload, querySpecId;
|
|
553
|
-
return _regenerator.default.async(function _loadCellValuesForQueryAsync$(_context2) {
|
|
313
|
+
key: "loadCellValuesInFieldIdsAsync",
|
|
314
|
+
value: function loadCellValuesInFieldIdsAsync(fieldIds) {
|
|
315
|
+
var fieldIdsWhichAreNotAlreadyLoadedOrLoading, pendingLoadPromises, _iteratorNormalCompletion3, _didIteratorError3, _iteratorError3, _iterator3, _step3, _fieldId, pendingLoadPromise, loadFieldsWhichAreNotAlreadyLoadedOrLoadingPromise, _iteratorNormalCompletion4, _didIteratorError4, _iteratorError4, _iterator4, _step4, fieldId;
|
|
316
|
+
|
|
317
|
+
return _regenerator.default.async(function loadCellValuesInFieldIdsAsync$(_context2) {
|
|
554
318
|
while (1) {
|
|
555
319
|
switch (_context2.prev = _context2.next) {
|
|
556
320
|
case 0:
|
|
557
|
-
this._assertNotForceUnloaded();
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
321
|
+
this._assertNotForceUnloaded();
|
|
322
|
+
|
|
323
|
+
fieldIdsWhichAreNotAlreadyLoadedOrLoading = [];
|
|
324
|
+
pendingLoadPromises = [];
|
|
325
|
+
_iteratorNormalCompletion3 = true;
|
|
326
|
+
_didIteratorError3 = false;
|
|
327
|
+
_iteratorError3 = undefined;
|
|
328
|
+
_context2.prev = 6;
|
|
329
|
+
|
|
330
|
+
for (_iterator3 = fieldIds[Symbol.iterator](); !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
|
|
331
|
+
_fieldId = _step3.value;
|
|
332
|
+
|
|
333
|
+
if (this._cellValuesRetainCountByFieldId[_fieldId] !== undefined) {
|
|
334
|
+
this._cellValuesRetainCountByFieldId[_fieldId]++;
|
|
335
|
+
} else {
|
|
336
|
+
this._cellValuesRetainCountByFieldId[_fieldId] = 1;
|
|
337
|
+
} // NOTE: we don't use this.areCellValuesLoadedForFieldId() here because
|
|
338
|
+
// that will return true if the cell values are loaded as a result
|
|
339
|
+
// of the entire table being loaded. In that scenario, we still
|
|
340
|
+
// want to separately load the cell values for the field so there
|
|
341
|
+
// is a separate subscription. Otherwise, when the table data unloads,
|
|
342
|
+
// the field data would unload as well. This can be improved by just
|
|
343
|
+
// subscribing to the field data without fetching it, since the cell
|
|
344
|
+
// values are already in the block frame.
|
|
345
|
+
|
|
346
|
+
|
|
347
|
+
if (!this._areCellValuesLoadedByFieldId[_fieldId]) {
|
|
348
|
+
pendingLoadPromise = this._pendingCellValuesLoadPromiseByFieldId[_fieldId];
|
|
349
|
+
|
|
350
|
+
if (pendingLoadPromise) {
|
|
351
|
+
pendingLoadPromises.push(pendingLoadPromise);
|
|
352
|
+
} else {
|
|
353
|
+
fieldIdsWhichAreNotAlreadyLoadedOrLoading.push(_fieldId);
|
|
586
354
|
}
|
|
587
|
-
}
|
|
588
|
-
}
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
_context2.next = 14;
|
|
359
|
+
break;
|
|
360
|
+
|
|
361
|
+
case 10:
|
|
362
|
+
_context2.prev = 10;
|
|
363
|
+
_context2.t0 = _context2["catch"](6);
|
|
364
|
+
_didIteratorError3 = true;
|
|
365
|
+
_iteratorError3 = _context2.t0;
|
|
589
366
|
|
|
590
|
-
|
|
367
|
+
case 14:
|
|
368
|
+
_context2.prev = 14;
|
|
369
|
+
_context2.prev = 15;
|
|
591
370
|
|
|
592
|
-
|
|
593
|
-
|
|
371
|
+
if (!_iteratorNormalCompletion3 && _iterator3.return != null) {
|
|
372
|
+
_iterator3.return();
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
case 17:
|
|
376
|
+
_context2.prev = 17;
|
|
377
|
+
|
|
378
|
+
if (!_didIteratorError3) {
|
|
379
|
+
_context2.next = 20;
|
|
380
|
+
break;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
throw _iteratorError3;
|
|
384
|
+
|
|
385
|
+
case 20:
|
|
386
|
+
return _context2.finish(17);
|
|
387
|
+
|
|
388
|
+
case 21:
|
|
389
|
+
return _context2.finish(14);
|
|
390
|
+
|
|
391
|
+
case 22:
|
|
392
|
+
if (!(fieldIdsWhichAreNotAlreadyLoadedOrLoading.length > 0)) {
|
|
393
|
+
_context2.next = 45;
|
|
394
|
+
break;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
// Could inline _loadCellValuesInFieldIdsAsync, but following the
|
|
398
|
+
// pattern from AbstractModelWithAsyncData where the public method
|
|
399
|
+
// is responsible for updating retain counts and the private method
|
|
400
|
+
// actually fetches data.
|
|
401
|
+
loadFieldsWhichAreNotAlreadyLoadedOrLoadingPromise = this._loadCellValuesInFieldIdsAsync(fieldIdsWhichAreNotAlreadyLoadedOrLoading);
|
|
402
|
+
pendingLoadPromises.push(loadFieldsWhichAreNotAlreadyLoadedOrLoadingPromise);
|
|
403
|
+
_iteratorNormalCompletion4 = true;
|
|
404
|
+
_didIteratorError4 = false;
|
|
405
|
+
_iteratorError4 = undefined;
|
|
406
|
+
_context2.prev = 28;
|
|
407
|
+
|
|
408
|
+
for (_iterator4 = fieldIdsWhichAreNotAlreadyLoadedOrLoading[Symbol.iterator](); !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {
|
|
409
|
+
fieldId = _step4.value;
|
|
410
|
+
this._pendingCellValuesLoadPromiseByFieldId[fieldId] = loadFieldsWhichAreNotAlreadyLoadedOrLoadingPromise;
|
|
411
|
+
} // Doing `.then` instead of performing these actions directly in
|
|
412
|
+
// _loadCellValuesInFieldIdsAsync so this is similar to
|
|
413
|
+
// AbstractModelWithAsyncData. The idea is to refactor to avoid code
|
|
414
|
+
// duplication, so keeping them similar for now hopefully will make the
|
|
415
|
+
// refactor simpler.
|
|
416
|
+
|
|
417
|
+
|
|
418
|
+
_context2.next = 36;
|
|
419
|
+
break;
|
|
420
|
+
|
|
421
|
+
case 32:
|
|
422
|
+
_context2.prev = 32;
|
|
423
|
+
_context2.t1 = _context2["catch"](28);
|
|
424
|
+
_didIteratorError4 = true;
|
|
425
|
+
_iteratorError4 = _context2.t1;
|
|
426
|
+
|
|
427
|
+
case 36:
|
|
428
|
+
_context2.prev = 36;
|
|
429
|
+
_context2.prev = 37;
|
|
430
|
+
|
|
431
|
+
if (!_iteratorNormalCompletion4 && _iterator4.return != null) {
|
|
432
|
+
_iterator4.return();
|
|
433
|
+
}
|
|
594
434
|
|
|
595
|
-
case
|
|
596
|
-
|
|
435
|
+
case 39:
|
|
436
|
+
_context2.prev = 39;
|
|
597
437
|
|
|
598
|
-
|
|
438
|
+
if (!_didIteratorError4) {
|
|
439
|
+
_context2.next = 42;
|
|
440
|
+
break;
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
throw _iteratorError4;
|
|
444
|
+
|
|
445
|
+
case 42:
|
|
446
|
+
return _context2.finish(39);
|
|
599
447
|
|
|
600
|
-
|
|
448
|
+
case 43:
|
|
449
|
+
return _context2.finish(36);
|
|
601
450
|
|
|
602
|
-
case
|
|
451
|
+
case 44:
|
|
452
|
+
loadFieldsWhichAreNotAlreadyLoadedOrLoadingPromise.then(changedKeys => {
|
|
453
|
+
var _iteratorNormalCompletion5 = true;
|
|
454
|
+
var _didIteratorError5 = false;
|
|
455
|
+
var _iteratorError5 = undefined;
|
|
456
|
+
|
|
457
|
+
try {
|
|
458
|
+
for (var _iterator5 = fieldIdsWhichAreNotAlreadyLoadedOrLoading[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) {
|
|
459
|
+
var fieldId = _step5.value;
|
|
460
|
+
this._areCellValuesLoadedByFieldId[fieldId] = true;
|
|
461
|
+
this._pendingCellValuesLoadPromiseByFieldId[fieldId] = undefined;
|
|
462
|
+
}
|
|
463
|
+
} catch (err) {
|
|
464
|
+
_didIteratorError5 = true;
|
|
465
|
+
_iteratorError5 = err;
|
|
466
|
+
} finally {
|
|
467
|
+
try {
|
|
468
|
+
if (!_iteratorNormalCompletion5 && _iterator5.return != null) {
|
|
469
|
+
_iterator5.return();
|
|
470
|
+
}
|
|
471
|
+
} finally {
|
|
472
|
+
if (_didIteratorError5) {
|
|
473
|
+
throw _iteratorError5;
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
var _iteratorNormalCompletion6 = true;
|
|
479
|
+
var _didIteratorError6 = false;
|
|
480
|
+
var _iteratorError6 = undefined;
|
|
481
|
+
|
|
482
|
+
try {
|
|
483
|
+
for (var _iterator6 = changedKeys[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) {
|
|
484
|
+
var key = _step6.value;
|
|
485
|
+
|
|
486
|
+
this._onChange(key);
|
|
487
|
+
}
|
|
488
|
+
} catch (err) {
|
|
489
|
+
_didIteratorError6 = true;
|
|
490
|
+
_iteratorError6 = err;
|
|
491
|
+
} finally {
|
|
492
|
+
try {
|
|
493
|
+
if (!_iteratorNormalCompletion6 && _iterator6.return != null) {
|
|
494
|
+
_iterator6.return();
|
|
495
|
+
}
|
|
496
|
+
} finally {
|
|
497
|
+
if (_didIteratorError6) {
|
|
498
|
+
throw _iteratorError6;
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
});
|
|
503
|
+
|
|
504
|
+
case 45:
|
|
505
|
+
_context2.next = 47;
|
|
506
|
+
return _regenerator.default.awrap(Promise.all(pendingLoadPromises));
|
|
507
|
+
|
|
508
|
+
case 47:
|
|
603
509
|
case "end":
|
|
604
510
|
return _context2.stop();
|
|
605
511
|
}
|
|
606
512
|
}
|
|
607
|
-
}, null, this);
|
|
513
|
+
}, null, this, [[6, 10, 14, 22], [15,, 17, 21], [28, 32, 36, 44], [37,, 39, 43]]);
|
|
608
514
|
}
|
|
609
515
|
}, {
|
|
610
|
-
key: "
|
|
611
|
-
value: function
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
516
|
+
key: "_loadCellValuesInFieldIdsAsync",
|
|
517
|
+
value: function _loadCellValuesInFieldIdsAsync(fieldIds) {
|
|
518
|
+
var _ref, newRecordsById, existingRecordsById, _iteratorNormalCompletion7, _didIteratorError7, _iteratorError7, _iterator7, _step7, _step7$value, recordId, newRecordObj, existingRecordObj, isCommentCountTypesSame, isCreatedTimeTypesSame, existingCellValuesByFieldId, i, fieldId, changedKeys;
|
|
519
|
+
|
|
520
|
+
return _regenerator.default.async(function _loadCellValuesInFieldIdsAsync$(_context3) {
|
|
521
|
+
while (1) {
|
|
522
|
+
switch (_context3.prev = _context3.next) {
|
|
523
|
+
case 0:
|
|
524
|
+
_context3.next = 2;
|
|
525
|
+
return _regenerator.default.awrap(this._airtableInterface.fetchAndSubscribeToCellValuesInFieldsAsync(this.tableId, fieldIds));
|
|
526
|
+
|
|
527
|
+
case 2:
|
|
528
|
+
_ref = _context3.sent;
|
|
529
|
+
newRecordsById = _ref.recordsById;
|
|
530
|
+
|
|
531
|
+
// Merge with existing data.
|
|
532
|
+
if (!this._data.recordsById) {
|
|
533
|
+
this._data.recordsById = {};
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
existingRecordsById = this._data.recordsById;
|
|
537
|
+
_iteratorNormalCompletion7 = true;
|
|
538
|
+
_didIteratorError7 = false;
|
|
539
|
+
_iteratorError7 = undefined;
|
|
540
|
+
_context3.prev = 9;
|
|
541
|
+
|
|
542
|
+
for (_iterator7 = (0, _private_utils.entries)((0, _private_utils.cast)(newRecordsById))[Symbol.iterator](); !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) {
|
|
543
|
+
_step7$value = (0, _slicedToArray2.default)(_step7.value, 2), recordId = _step7$value[0], newRecordObj = _step7$value[1];
|
|
544
|
+
|
|
545
|
+
if (!(0, _private_utils.has)(existingRecordsById, recordId)) {
|
|
546
|
+
existingRecordsById[recordId] = newRecordObj;
|
|
547
|
+
} else {
|
|
548
|
+
existingRecordObj = existingRecordsById[recordId]; // Metadata (createdTime, commentCount) should generally be up to date,
|
|
549
|
+
// but can be out of date in the rare scenario where realtime
|
|
550
|
+
// data has not yet been delivered to the SDK, but is populated in hyperbase
|
|
551
|
+
// at the time this new fetch is executed.
|
|
552
|
+
// istanbul ignore next
|
|
553
|
+
|
|
554
|
+
if (existingRecordObj.commentCount !== newRecordObj.commentCount) {
|
|
555
|
+
isCommentCountTypesSame = typeof existingRecordObj.commentCount !== typeof newRecordObj.commentCount;
|
|
556
|
+
(0, _error_utils.logErrorToSentry)('comment count out of sync - types are same: %s', {
|
|
557
|
+
isCommentCountTypesSame
|
|
558
|
+
});
|
|
559
|
+
} // istanbul ignore next
|
|
560
|
+
|
|
561
|
+
|
|
562
|
+
if (existingRecordObj.createdTime !== newRecordObj.createdTime) {
|
|
563
|
+
isCreatedTimeTypesSame = typeof existingRecordObj.createdTime !== typeof newRecordObj.createdTime;
|
|
564
|
+
(0, _error_utils.logErrorToSentry)('created time out of sync - types are same: %s', {
|
|
565
|
+
isCreatedTimeTypesSame
|
|
566
|
+
});
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
if (!existingRecordObj.cellValuesByFieldId) {
|
|
570
|
+
existingRecordObj.cellValuesByFieldId = {};
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
existingCellValuesByFieldId = existingRecordObj.cellValuesByFieldId;
|
|
574
|
+
|
|
575
|
+
for (i = 0; i < fieldIds.length; i++) {
|
|
576
|
+
fieldId = fieldIds[i];
|
|
577
|
+
existingCellValuesByFieldId[fieldId] = newRecordObj.cellValuesByFieldId ? newRecordObj.cellValuesByFieldId[fieldId] : undefined;
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
_context3.next = 17;
|
|
583
|
+
break;
|
|
584
|
+
|
|
585
|
+
case 13:
|
|
586
|
+
_context3.prev = 13;
|
|
587
|
+
_context3.t0 = _context3["catch"](9);
|
|
588
|
+
_didIteratorError7 = true;
|
|
589
|
+
_iteratorError7 = _context3.t0;
|
|
590
|
+
|
|
591
|
+
case 17:
|
|
592
|
+
_context3.prev = 17;
|
|
593
|
+
_context3.prev = 18;
|
|
594
|
+
|
|
595
|
+
if (!_iteratorNormalCompletion7 && _iterator7.return != null) {
|
|
596
|
+
_iterator7.return();
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
case 20:
|
|
600
|
+
_context3.prev = 20;
|
|
601
|
+
|
|
602
|
+
if (!_didIteratorError7) {
|
|
603
|
+
_context3.next = 23;
|
|
604
|
+
break;
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
throw _iteratorError7;
|
|
608
|
+
|
|
609
|
+
case 23:
|
|
610
|
+
return _context3.finish(20);
|
|
611
|
+
|
|
612
|
+
case 24:
|
|
613
|
+
return _context3.finish(17);
|
|
615
614
|
|
|
616
|
-
|
|
615
|
+
case 25:
|
|
616
|
+
changedKeys = fieldIds.map(fieldId => WatchableCellValuesInFieldKeyPrefix + fieldId); // Need to trigger onChange for records and recordIds since watching either
|
|
617
|
+
// of those causes record metadata to be loaded (via _getFieldIdForCausingRecordMetadataToLoad)
|
|
618
|
+
// and by convention we trigger a change event when data loads.
|
|
619
|
+
|
|
620
|
+
changedKeys.push(WatchableRecordStoreKeys.records);
|
|
621
|
+
changedKeys.push(WatchableRecordStoreKeys.recordIds); // Also trigger cellValues changes since the cell values in the fields
|
|
622
|
+
// are now loaded.
|
|
623
|
+
|
|
624
|
+
changedKeys.push(WatchableRecordStoreKeys.cellValues);
|
|
625
|
+
return _context3.abrupt("return", changedKeys);
|
|
626
|
+
|
|
627
|
+
case 30:
|
|
628
|
+
case "end":
|
|
629
|
+
return _context3.stop();
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
}, null, this, [[9, 13, 17, 25], [18,, 20, 24]]);
|
|
617
633
|
}
|
|
618
634
|
}, {
|
|
619
|
-
key: "
|
|
620
|
-
value: function
|
|
621
|
-
this.
|
|
635
|
+
key: "unloadCellValuesInFieldIds",
|
|
636
|
+
value: function unloadCellValuesInFieldIds(fieldIds) {
|
|
637
|
+
if (this._isForceUnloaded) {
|
|
638
|
+
return;
|
|
639
|
+
}
|
|
622
640
|
|
|
623
|
-
var
|
|
624
|
-
var
|
|
625
|
-
var
|
|
641
|
+
var fieldIdsWithZeroRetainCount = [];
|
|
642
|
+
var _iteratorNormalCompletion8 = true;
|
|
643
|
+
var _didIteratorError8 = false;
|
|
644
|
+
var _iteratorError8 = undefined;
|
|
626
645
|
|
|
627
646
|
try {
|
|
628
|
-
for (var
|
|
629
|
-
var
|
|
647
|
+
for (var _iterator8 = fieldIds[Symbol.iterator](), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = true) {
|
|
648
|
+
var fieldId = _step8.value;
|
|
649
|
+
var fieldRetainCount = this._cellValuesRetainCountByFieldId[fieldId] || 0;
|
|
650
|
+
fieldRetainCount--;
|
|
651
|
+
|
|
652
|
+
if (fieldRetainCount < 0) {
|
|
653
|
+
console.log('Field data over-released'); // eslint-disable-line no-console
|
|
630
654
|
|
|
631
|
-
|
|
655
|
+
fieldRetainCount = 0;
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
this._cellValuesRetainCountByFieldId[fieldId] = fieldRetainCount;
|
|
632
659
|
|
|
633
|
-
if (
|
|
634
|
-
|
|
660
|
+
if (fieldRetainCount === 0) {
|
|
661
|
+
fieldIdsWithZeroRetainCount.push(fieldId);
|
|
635
662
|
}
|
|
636
663
|
}
|
|
637
664
|
} catch (err) {
|
|
638
|
-
|
|
639
|
-
|
|
665
|
+
_didIteratorError8 = true;
|
|
666
|
+
_iteratorError8 = err;
|
|
640
667
|
} finally {
|
|
641
668
|
try {
|
|
642
|
-
if (!
|
|
643
|
-
|
|
669
|
+
if (!_iteratorNormalCompletion8 && _iterator8.return != null) {
|
|
670
|
+
_iterator8.return();
|
|
644
671
|
}
|
|
645
672
|
} finally {
|
|
646
|
-
if (
|
|
647
|
-
throw
|
|
673
|
+
if (_didIteratorError8) {
|
|
674
|
+
throw _iteratorError8;
|
|
648
675
|
}
|
|
649
676
|
}
|
|
650
677
|
}
|
|
651
|
-
}
|
|
652
|
-
}, {
|
|
653
|
-
key: "loadViewDataStoreAndCellValuesForFieldIdsAsync",
|
|
654
|
-
value: function loadViewDataStoreAndCellValuesForFieldIdsAsync(viewId, fieldIdsToLoadOrNullIfAllFields) {
|
|
655
|
-
var fieldSelection;
|
|
656
|
-
return _regenerator.default.async(function loadViewDataStoreAndCellValuesForFieldIdsAsync$(_context3) {
|
|
657
|
-
while (1) {
|
|
658
|
-
switch (_context3.prev = _context3.next) {
|
|
659
|
-
case 0:
|
|
660
|
-
// We do not need to initialize a ViewDataStore, as it's a thin wrapper around the
|
|
661
|
-
// hyperbase viewMetadataStore which can be initialized after a query inflates the data.
|
|
662
|
-
// A complicating factor is what happens if (this) recordStore or viewDataStore are
|
|
663
|
-
// forceUnload'ed. It is fine to track the query in only record store because:
|
|
664
|
-
// - If either is force unloaded without the other the query must be kept active
|
|
665
|
-
// - If a recordStore is force unloaded the children viewDataStores are also unloaded
|
|
666
|
-
// because the table has been deleted. Therefore we can track it in only record_store.
|
|
667
|
-
fieldSelection = fieldIdsToLoadOrNullIfAllFields ? {
|
|
668
|
-
type: _block_query_spec.BlockFieldSelectionSpecType.SPECIFIED_FIELDS,
|
|
669
|
-
fieldIds: fieldIdsToLoadOrNullIfAllFields
|
|
670
|
-
} : {
|
|
671
|
-
type: _block_query_spec.BlockFieldSelectionSpecType.ALL_FIELDS_FROM_TABLE
|
|
672
|
-
}; // By issuing this query we both populate cell values requested AND view metadata
|
|
673
|
-
// Cell values requested will be accessible inside record_store
|
|
674
|
-
|
|
675
|
-
_context3.next = 3;
|
|
676
|
-
return _regenerator.default.awrap(this._loadCellValuesForQueryAsync({
|
|
677
|
-
sourceType: _block_query_spec.BlockQuerySourceType.VIEW,
|
|
678
|
-
sourceViewId: viewId,
|
|
679
|
-
recordSelection: {
|
|
680
|
-
fieldSelection
|
|
681
|
-
},
|
|
682
|
-
viewMetadataSelection: {
|
|
683
|
-
shouldIncludeVisibleRecordIds: true,
|
|
684
|
-
shouldIncludeFieldOrder: true,
|
|
685
|
-
shouldIncludeGroups: true,
|
|
686
|
-
shouldIncludeGroupingLevels: true,
|
|
687
|
-
shouldIncludeColorsForRecordId: true
|
|
688
|
-
}
|
|
689
|
-
}));
|
|
690
678
|
|
|
691
|
-
|
|
692
|
-
|
|
679
|
+
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(() => {
|
|
684
|
+
// Make sure the retain count is still zero, since it may
|
|
685
|
+
// have been incremented before the timeout fired.
|
|
686
|
+
var fieldIdsToUnload = fieldIdsWithZeroRetainCount.filter(fieldId => {
|
|
687
|
+
return this._cellValuesRetainCountByFieldId[fieldId] === 0;
|
|
688
|
+
});
|
|
689
|
+
|
|
690
|
+
if (fieldIdsToUnload.length > 0) {
|
|
691
|
+
// Set _areCellValuesLoadedByFieldId to false before calling _unloadCellValuesInFieldIds
|
|
692
|
+
// since _unloadCellValuesInFieldIds will check if *any* fields are still loaded.
|
|
693
|
+
var _iteratorNormalCompletion9 = true;
|
|
694
|
+
var _didIteratorError9 = false;
|
|
695
|
+
var _iteratorError9 = undefined;
|
|
693
696
|
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
+
try {
|
|
698
|
+
for (var _iterator9 = fieldIdsToUnload[Symbol.iterator](), _step9; !(_iteratorNormalCompletion9 = (_step9 = _iterator9.next()).done); _iteratorNormalCompletion9 = true) {
|
|
699
|
+
var fieldId = _step9.value;
|
|
700
|
+
this._areCellValuesLoadedByFieldId[fieldId] = false;
|
|
701
|
+
}
|
|
702
|
+
} catch (err) {
|
|
703
|
+
_didIteratorError9 = true;
|
|
704
|
+
_iteratorError9 = err;
|
|
705
|
+
} finally {
|
|
706
|
+
try {
|
|
707
|
+
if (!_iteratorNormalCompletion9 && _iterator9.return != null) {
|
|
708
|
+
_iterator9.return();
|
|
709
|
+
}
|
|
710
|
+
} finally {
|
|
711
|
+
if (_didIteratorError9) {
|
|
712
|
+
throw _iteratorError9;
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
this._unloadCellValuesInFieldIds(fieldIdsToUnload);
|
|
697
718
|
}
|
|
698
|
-
}
|
|
699
|
-
}
|
|
719
|
+
}, _abstract_model_with_async_data.default.__DATA_UNLOAD_DELAY_MS);
|
|
720
|
+
}
|
|
700
721
|
}
|
|
701
722
|
}, {
|
|
702
|
-
key: "
|
|
703
|
-
value: function
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
this.
|
|
723
|
+
key: "_unloadCellValuesInFieldIds",
|
|
724
|
+
value: function _unloadCellValuesInFieldIds(fieldIds) {
|
|
725
|
+
this._airtableInterface.unsubscribeFromCellValuesInFields(this.tableId, fieldIds);
|
|
726
|
+
|
|
727
|
+
this._afterUnloadDataOrUnloadCellValuesInFieldIds(fieldIds);
|
|
707
728
|
}
|
|
708
729
|
}, {
|
|
709
|
-
key: "
|
|
710
|
-
value: function
|
|
711
|
-
var
|
|
712
|
-
|
|
730
|
+
key: "_loadDataAsync",
|
|
731
|
+
value: function _loadDataAsync() {
|
|
732
|
+
var tableData, changedKeys, _iteratorNormalCompletion10, _didIteratorError10, _iteratorError10, _iterator10, _step10, fieldId;
|
|
733
|
+
|
|
734
|
+
return _regenerator.default.async(function _loadDataAsync$(_context4) {
|
|
713
735
|
while (1) {
|
|
714
736
|
switch (_context4.prev = _context4.next) {
|
|
715
737
|
case 0:
|
|
716
738
|
_context4.next = 2;
|
|
717
|
-
return _regenerator.default.awrap(this.
|
|
718
|
-
sourceType: _block_query_spec.BlockQuerySourceType.TABLE,
|
|
719
|
-
recordSelection: {
|
|
720
|
-
fieldSelection: {
|
|
721
|
-
type: _block_query_spec.BlockFieldSelectionSpecType.SPECIFIED_FIELDS,
|
|
722
|
-
fieldIds
|
|
723
|
-
}
|
|
724
|
-
}
|
|
725
|
-
}));
|
|
739
|
+
return _regenerator.default.awrap(this._airtableInterface.fetchAndSubscribeToTableDataAsync(this.tableId));
|
|
726
740
|
|
|
727
741
|
case 2:
|
|
728
|
-
|
|
729
|
-
this.
|
|
730
|
-
|
|
742
|
+
tableData = _context4.sent;
|
|
743
|
+
this._data.recordsById = tableData.recordsById;
|
|
744
|
+
changedKeys = [WatchableRecordStoreKeys.records, WatchableRecordStoreKeys.recordIds, WatchableRecordStoreKeys.cellValues];
|
|
745
|
+
_iteratorNormalCompletion10 = true;
|
|
746
|
+
_didIteratorError10 = false;
|
|
747
|
+
_iteratorError10 = undefined;
|
|
748
|
+
_context4.prev = 8;
|
|
749
|
+
|
|
750
|
+
for (_iterator10 = (0, _private_utils.keys)(this._data.fieldsById)[Symbol.iterator](); !(_iteratorNormalCompletion10 = (_step10 = _iterator10.next()).done); _iteratorNormalCompletion10 = true) {
|
|
751
|
+
fieldId = _step10.value;
|
|
752
|
+
changedKeys.push(WatchableCellValuesInFieldKeyPrefix + fieldId);
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
_context4.next = 16;
|
|
756
|
+
break;
|
|
731
757
|
|
|
732
|
-
case
|
|
758
|
+
case 12:
|
|
759
|
+
_context4.prev = 12;
|
|
760
|
+
_context4.t0 = _context4["catch"](8);
|
|
761
|
+
_didIteratorError10 = true;
|
|
762
|
+
_iteratorError10 = _context4.t0;
|
|
763
|
+
|
|
764
|
+
case 16:
|
|
765
|
+
_context4.prev = 16;
|
|
766
|
+
_context4.prev = 17;
|
|
767
|
+
|
|
768
|
+
if (!_iteratorNormalCompletion10 && _iterator10.return != null) {
|
|
769
|
+
_iterator10.return();
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
case 19:
|
|
773
|
+
_context4.prev = 19;
|
|
774
|
+
|
|
775
|
+
if (!_didIteratorError10) {
|
|
776
|
+
_context4.next = 22;
|
|
777
|
+
break;
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
throw _iteratorError10;
|
|
781
|
+
|
|
782
|
+
case 22:
|
|
783
|
+
return _context4.finish(19);
|
|
784
|
+
|
|
785
|
+
case 23:
|
|
786
|
+
return _context4.finish(16);
|
|
787
|
+
|
|
788
|
+
case 24:
|
|
789
|
+
return _context4.abrupt("return", changedKeys);
|
|
790
|
+
|
|
791
|
+
case 25:
|
|
733
792
|
case "end":
|
|
734
793
|
return _context4.stop();
|
|
735
794
|
}
|
|
736
795
|
}
|
|
737
|
-
}, null, this);
|
|
796
|
+
}, null, this, [[8, 12, 16, 24], [17,, 19, 23]]);
|
|
738
797
|
}
|
|
739
798
|
}, {
|
|
740
|
-
key: "
|
|
741
|
-
value: function
|
|
742
|
-
|
|
743
|
-
return _regenerator.default.async(function loadAllCellValuesAsync$(_context5) {
|
|
744
|
-
while (1) {
|
|
745
|
-
switch (_context5.prev = _context5.next) {
|
|
746
|
-
case 0:
|
|
747
|
-
_context5.next = 2;
|
|
748
|
-
return _regenerator.default.awrap(this._loadCellValuesForQueryAsync({
|
|
749
|
-
sourceType: _block_query_spec.BlockQuerySourceType.TABLE,
|
|
750
|
-
recordSelection: {
|
|
751
|
-
fieldSelection: {
|
|
752
|
-
type: _block_query_spec.BlockFieldSelectionSpecType.ALL_FIELDS_FROM_TABLE
|
|
753
|
-
}
|
|
754
|
-
}
|
|
755
|
-
}));
|
|
799
|
+
key: "_unloadData",
|
|
800
|
+
value: function _unloadData() {
|
|
801
|
+
this._airtableInterface.unsubscribeFromTableData(this.tableId);
|
|
756
802
|
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
803
|
+
this._afterUnloadDataOrUnloadCellValuesInFieldIds();
|
|
804
|
+
}
|
|
805
|
+
}, {
|
|
806
|
+
key: "_afterUnloadDataOrUnloadCellValuesInFieldIds",
|
|
807
|
+
value: function _afterUnloadDataOrUnloadCellValuesInFieldIds(unloadedFieldIds) {
|
|
808
|
+
var areAnyFieldsLoaded = this.isDataLoaded || (0, _private_utils.values)(this._areCellValuesLoadedByFieldId).some(isLoaded => isLoaded);
|
|
809
|
+
|
|
810
|
+
if (!this.isDeleted) {
|
|
811
|
+
if (!areAnyFieldsLoaded) {
|
|
812
|
+
this._data.recordsById = undefined;
|
|
813
|
+
} else if (!this.isDataLoaded) {
|
|
814
|
+
var fieldIdsToClear;
|
|
815
|
+
|
|
816
|
+
if (unloadedFieldIds) {
|
|
817
|
+
// Specific fields were unloaded, so clear out the cell values for those fields.
|
|
818
|
+
fieldIdsToClear = unloadedFieldIds;
|
|
819
|
+
} else {
|
|
820
|
+
// The entire table was unloaded, but some individual fields are still loaded.
|
|
821
|
+
// We need to clear out the cell values of every field that was unloaded.
|
|
822
|
+
// This is kind of slow, but hopefully uncommon.
|
|
823
|
+
var fieldIds = Object.keys(this._data.fieldsById);
|
|
824
|
+
fieldIdsToClear = fieldIds.filter(fieldId => !this._areCellValuesLoadedByFieldId[fieldId]);
|
|
825
|
+
}
|
|
761
826
|
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
827
|
+
var recordsById = this._data.recordsById;
|
|
828
|
+
var _iteratorNormalCompletion11 = true;
|
|
829
|
+
var _didIteratorError11 = false;
|
|
830
|
+
var _iteratorError11 = undefined;
|
|
831
|
+
|
|
832
|
+
try {
|
|
833
|
+
for (var _iterator11 = (0, _private_utils.values)(recordsById || {})[Symbol.iterator](), _step11; !(_iteratorNormalCompletion11 = (_step11 = _iterator11.next()).done); _iteratorNormalCompletion11 = true) {
|
|
834
|
+
var recordObj = _step11.value;
|
|
835
|
+
|
|
836
|
+
for (var i = 0; i < fieldIdsToClear.length; i++) {
|
|
837
|
+
var fieldId = fieldIdsToClear[i];
|
|
838
|
+
|
|
839
|
+
if (recordObj.cellValuesByFieldId) {
|
|
840
|
+
recordObj.cellValuesByFieldId[fieldId] = undefined;
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
} catch (err) {
|
|
845
|
+
_didIteratorError11 = true;
|
|
846
|
+
_iteratorError11 = err;
|
|
847
|
+
} finally {
|
|
848
|
+
try {
|
|
849
|
+
if (!_iteratorNormalCompletion11 && _iterator11.return != null) {
|
|
850
|
+
_iterator11.return();
|
|
851
|
+
}
|
|
852
|
+
} finally {
|
|
853
|
+
if (_didIteratorError11) {
|
|
854
|
+
throw _iteratorError11;
|
|
855
|
+
}
|
|
856
|
+
}
|
|
765
857
|
}
|
|
766
858
|
}
|
|
767
|
-
}
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
if (!areAnyFieldsLoaded) {
|
|
862
|
+
this._recordModelsById = {};
|
|
863
|
+
}
|
|
768
864
|
}
|
|
769
865
|
}, {
|
|
770
|
-
key: "
|
|
771
|
-
value: function
|
|
772
|
-
this.
|
|
866
|
+
key: "triggerOnChangeForDirtyPaths",
|
|
867
|
+
value: function triggerOnChangeForDirtyPaths(dirtyPaths) {
|
|
868
|
+
if (this.isRecordMetadataLoaded && dirtyPaths.recordsById) {
|
|
869
|
+
// Since tables don't have a record order, need to detect if a record
|
|
870
|
+
// was created or deleted and trigger onChange for records.
|
|
871
|
+
var dirtyFieldIdsSet = {};
|
|
872
|
+
var addedRecordIds = [];
|
|
873
|
+
var removedRecordIds = [];
|
|
874
|
+
var _iteratorNormalCompletion12 = true;
|
|
875
|
+
var _didIteratorError12 = false;
|
|
876
|
+
var _iteratorError12 = undefined;
|
|
773
877
|
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
878
|
+
try {
|
|
879
|
+
for (var _iterator12 = (0, _private_utils.entries)(dirtyPaths.recordsById)[Symbol.iterator](), _step12; !(_iteratorNormalCompletion12 = (_step12 = _iterator12.next()).done); _iteratorNormalCompletion12 = true) {
|
|
880
|
+
var _step12$value = (0, _slicedToArray2.default)(_step12.value, 2),
|
|
881
|
+
recordId = _step12$value[0],
|
|
882
|
+
dirtyRecordPaths = _step12$value[1];
|
|
883
|
+
|
|
884
|
+
if (dirtyRecordPaths && dirtyRecordPaths._isDirty) {
|
|
885
|
+
// If the entire record is dirty, it was either created or deleted.
|
|
886
|
+
(0, _error_utils.invariant)(this._data.recordsById, 'No recordsById');
|
|
887
|
+
|
|
888
|
+
if ((0, _private_utils.has)(this._data.recordsById, recordId)) {
|
|
889
|
+
addedRecordIds.push(recordId);
|
|
890
|
+
} else {
|
|
891
|
+
removedRecordIds.push(recordId);
|
|
892
|
+
var recordModel = this._recordModelsById[recordId];
|
|
893
|
+
|
|
894
|
+
if (recordModel) {
|
|
895
|
+
// Remove the Record model if it was deleted.
|
|
896
|
+
delete this._recordModelsById[recordId];
|
|
897
|
+
}
|
|
898
|
+
}
|
|
899
|
+
} else {
|
|
900
|
+
var _recordModel = this._recordModelsById[recordId];
|
|
777
901
|
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
while (1) {
|
|
783
|
-
switch (_context6.prev = _context6.next) {
|
|
784
|
-
case 0:
|
|
785
|
-
throw (0, _error_utils.spawnError)('Internal error - SDK called loadData on record_store');
|
|
902
|
+
if (_recordModel) {
|
|
903
|
+
_recordModel.__triggerOnChangeForDirtyPaths(dirtyRecordPaths);
|
|
904
|
+
}
|
|
905
|
+
}
|
|
786
906
|
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
907
|
+
var cellValuesByFieldId = dirtyRecordPaths.cellValuesByFieldId;
|
|
908
|
+
|
|
909
|
+
if (cellValuesByFieldId) {
|
|
910
|
+
for (var _i2 = 0, _Object$keys2 = Object.keys(cellValuesByFieldId); _i2 < _Object$keys2.length; _i2++) {
|
|
911
|
+
var fieldId = _Object$keys2[_i2];
|
|
912
|
+
dirtyFieldIdsSet[fieldId] = true;
|
|
913
|
+
}
|
|
914
|
+
}
|
|
915
|
+
} // Now that we've composed our created/deleted record ids arrays, let's fire
|
|
916
|
+
// the records onChange event if any records were created or deleted.
|
|
917
|
+
|
|
918
|
+
} catch (err) {
|
|
919
|
+
_didIteratorError12 = true;
|
|
920
|
+
_iteratorError12 = err;
|
|
921
|
+
} finally {
|
|
922
|
+
try {
|
|
923
|
+
if (!_iteratorNormalCompletion12 && _iterator12.return != null) {
|
|
924
|
+
_iterator12.return();
|
|
925
|
+
}
|
|
926
|
+
} finally {
|
|
927
|
+
if (_didIteratorError12) {
|
|
928
|
+
throw _iteratorError12;
|
|
929
|
+
}
|
|
790
930
|
}
|
|
791
931
|
}
|
|
792
|
-
});
|
|
793
|
-
} // Maybe add a comment "pending removal of inheriting from parent class AbstractModelWithAsyncData"
|
|
794
|
-
// istanbul ignore next
|
|
795
932
|
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
933
|
+
if (addedRecordIds.length > 0 || removedRecordIds.length > 0) {
|
|
934
|
+
this._onChange(WatchableRecordStoreKeys.records, {
|
|
935
|
+
addedRecordIds,
|
|
936
|
+
removedRecordIds
|
|
937
|
+
});
|
|
938
|
+
|
|
939
|
+
this._onChange(WatchableRecordStoreKeys.recordIds, {
|
|
940
|
+
addedRecordIds,
|
|
941
|
+
removedRecordIds
|
|
942
|
+
});
|
|
943
|
+
} // NOTE: this is an experimental (and somewhat messy) way to watch
|
|
944
|
+
// for changes to cells in a table, as an alternative to implementing
|
|
945
|
+
// full event bubbling. For now, it unblocks the things we want to
|
|
946
|
+
// build, but we may replace it.
|
|
947
|
+
// If we keep it, could be more efficient by not calling _onChange
|
|
948
|
+
// if there are no subscribers.
|
|
949
|
+
// TODO: don't trigger changes for fields that aren't supposed to be loaded
|
|
950
|
+
// (in some cases, e.g. record created, liveapp will send cell values
|
|
951
|
+
// that we're not subscribed to).
|
|
952
|
+
|
|
953
|
+
|
|
954
|
+
var fieldIds = Object.freeze(Object.keys(dirtyFieldIdsSet));
|
|
955
|
+
var recordIds = Object.freeze(Object.keys(dirtyPaths.recordsById));
|
|
956
|
+
|
|
957
|
+
if (fieldIds.length > 0 && recordIds.length > 0) {
|
|
958
|
+
this._onChange(WatchableRecordStoreKeys.cellValues, {
|
|
959
|
+
recordIds,
|
|
960
|
+
fieldIds
|
|
961
|
+
});
|
|
962
|
+
}
|
|
963
|
+
|
|
964
|
+
var _iteratorNormalCompletion13 = true;
|
|
965
|
+
var _didIteratorError13 = false;
|
|
966
|
+
var _iteratorError13 = undefined;
|
|
967
|
+
|
|
968
|
+
try {
|
|
969
|
+
for (var _iterator13 = fieldIds[Symbol.iterator](), _step13; !(_iteratorNormalCompletion13 = (_step13 = _iterator13.next()).done); _iteratorNormalCompletion13 = true) {
|
|
970
|
+
var _fieldId2 = _step13.value;
|
|
971
|
+
|
|
972
|
+
this._onChange(WatchableCellValuesInFieldKeyPrefix + _fieldId2, recordIds, _fieldId2);
|
|
973
|
+
}
|
|
974
|
+
} catch (err) {
|
|
975
|
+
_didIteratorError13 = true;
|
|
976
|
+
_iteratorError13 = err;
|
|
977
|
+
} finally {
|
|
978
|
+
try {
|
|
979
|
+
if (!_iteratorNormalCompletion13 && _iterator13.return != null) {
|
|
980
|
+
_iterator13.return();
|
|
981
|
+
}
|
|
982
|
+
} finally {
|
|
983
|
+
if (_didIteratorError13) {
|
|
984
|
+
throw _iteratorError13;
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
}
|
|
988
|
+
}
|
|
989
|
+
|
|
990
|
+
if (dirtyPaths.viewOrder) {
|
|
991
|
+
// clean up deleted views
|
|
992
|
+
var _iteratorNormalCompletion14 = true;
|
|
993
|
+
var _didIteratorError14 = false;
|
|
994
|
+
var _iteratorError14 = undefined;
|
|
995
|
+
|
|
996
|
+
try {
|
|
997
|
+
for (var _iterator14 = (0, _private_utils.entries)(this._viewDataStoresByViewId)[Symbol.iterator](), _step14; !(_iteratorNormalCompletion14 = (_step14 = _iterator14.next()).done); _iteratorNormalCompletion14 = true) {
|
|
998
|
+
var _step14$value = (0, _slicedToArray2.default)(_step14.value, 2),
|
|
999
|
+
viewId = _step14$value[0],
|
|
1000
|
+
viewDataStore = _step14$value[1];
|
|
1001
|
+
|
|
1002
|
+
if (viewDataStore.isDeleted) {
|
|
1003
|
+
viewDataStore.__onDataDeletion();
|
|
1004
|
+
|
|
1005
|
+
delete this._viewDataStoresByViewId[viewId];
|
|
1006
|
+
}
|
|
1007
|
+
}
|
|
1008
|
+
} catch (err) {
|
|
1009
|
+
_didIteratorError14 = true;
|
|
1010
|
+
_iteratorError14 = err;
|
|
1011
|
+
} finally {
|
|
1012
|
+
try {
|
|
1013
|
+
if (!_iteratorNormalCompletion14 && _iterator14.return != null) {
|
|
1014
|
+
_iterator14.return();
|
|
1015
|
+
}
|
|
1016
|
+
} finally {
|
|
1017
|
+
if (_didIteratorError14) {
|
|
1018
|
+
throw _iteratorError14;
|
|
1019
|
+
}
|
|
1020
|
+
}
|
|
1021
|
+
}
|
|
1022
|
+
}
|
|
800
1023
|
}
|
|
801
1024
|
}, {
|
|
802
1025
|
key: "_dataOrNullIfDeleted",
|
|
@@ -808,7 +1031,9 @@ function (_AbstractModelWithAsy) {
|
|
|
808
1031
|
}, {
|
|
809
1032
|
key: "records",
|
|
810
1033
|
get: function get() {
|
|
811
|
-
var
|
|
1034
|
+
var recordsById = this._data.recordsById;
|
|
1035
|
+
(0, _error_utils.invariant)(recordsById, 'Record metadata is not loaded');
|
|
1036
|
+
var records = Object.keys(recordsById).map(recordId => {
|
|
812
1037
|
var record = this.getRecordByIdIfExists(recordId);
|
|
813
1038
|
(0, _error_utils.invariant)(record, 'record');
|
|
814
1039
|
return record;
|
|
@@ -823,17 +1048,14 @@ function (_AbstractModelWithAsy) {
|
|
|
823
1048
|
}, {
|
|
824
1049
|
key: "recordIds",
|
|
825
1050
|
get: function get() {
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
(0, _error_utils.invariant)(recordIds, 'Record metadata is not loaded');
|
|
831
|
-
return recordIds;
|
|
1051
|
+
var recordsById = this._data.recordsById;
|
|
1052
|
+
(0, _error_utils.invariant)(recordsById, 'Record metadata is not loaded');
|
|
1053
|
+
return Object.keys(recordsById);
|
|
832
1054
|
}
|
|
833
1055
|
}, {
|
|
834
|
-
key: "
|
|
1056
|
+
key: "isRecordMetadataLoaded",
|
|
835
1057
|
get: function get() {
|
|
836
|
-
return this.
|
|
1058
|
+
return !!this._data.recordsById;
|
|
837
1059
|
}
|
|
838
1060
|
}]);
|
|
839
1061
|
return RecordStore;
|