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