@airtable/blocks 1.3.0 → 1.5.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.
Files changed (125) hide show
  1. package/CHANGELOG.md +30 -1
  2. package/dist/cjs/index.js +30 -11
  3. package/dist/cjs/injected/airtable_interface.js +2 -1
  4. package/dist/cjs/models/cursor.js +4 -6
  5. package/dist/cjs/models/field.js +24 -0
  6. package/dist/cjs/models/grouped_record_query_result.js +475 -0
  7. package/dist/cjs/models/models.js +30 -0
  8. package/dist/cjs/models/mutations.js +41 -9
  9. package/dist/cjs/models/record_query_result.js +37 -12
  10. package/dist/cjs/models/session.js +65 -23
  11. package/dist/cjs/models/table_or_view_query_result.js +306 -97
  12. package/dist/cjs/models/view.js +71 -1
  13. package/dist/cjs/models/view_data_store.js +62 -20
  14. package/dist/cjs/models/view_metadata_query_result.js +41 -8
  15. package/dist/cjs/sdk.js +2 -2
  16. package/dist/cjs/testing/mock_airtable_interface.js +1 -110
  17. package/dist/cjs/types/airtable_interface.js +19 -1
  18. package/dist/cjs/types/mutations.js +2 -1
  19. package/dist/cjs/types/view.js +1 -0
  20. package/dist/cjs/ui/confirmation_dialog.js +12 -4
  21. package/dist/cjs/ui/expand_record.js +5 -5
  22. package/dist/cjs/ui/expand_record_list.js +2 -5
  23. package/dist/cjs/ui/expand_record_picker_async.js +9 -16
  24. package/dist/cjs/ui/form_field.js +2 -2
  25. package/dist/cjs/ui/icon_config.js +11 -4
  26. package/dist/cjs/ui/initialize_block.js +62 -10
  27. package/dist/cjs/ui/ui.js +9 -2
  28. package/dist/cjs/ui/use_loadable.js +2 -2
  29. package/dist/cjs/ui/use_records.js +54 -40
  30. package/dist/cjs/ui/use_view_metadata.js +1 -1
  31. package/dist/cjs/unstable_testing_utils.js +163 -0
  32. package/dist/types/src/color_utils.d.ts +4 -4
  33. package/dist/types/src/color_utils.d.ts.map +1 -1
  34. package/dist/types/src/index.d.ts +2 -2
  35. package/dist/types/src/index.d.ts.map +1 -1
  36. package/dist/types/src/injected/airtable_interface.d.ts.map +1 -1
  37. package/dist/types/src/models/cursor.d.ts +4 -6
  38. package/dist/types/src/models/cursor.d.ts.map +1 -1
  39. package/dist/types/src/models/field.d.ts +17 -1
  40. package/dist/types/src/models/field.d.ts.map +1 -1
  41. package/dist/types/src/models/grouped_record_query_result.d.ts +61 -0
  42. package/dist/types/src/models/grouped_record_query_result.d.ts.map +1 -0
  43. package/dist/types/src/models/models.d.ts +4 -1
  44. package/dist/types/src/models/models.d.ts.map +1 -1
  45. package/dist/types/src/models/mutations.d.ts.map +1 -1
  46. package/dist/types/src/models/record.d.ts +0 -2
  47. package/dist/types/src/models/record.d.ts.map +1 -1
  48. package/dist/types/src/models/record_query_result.d.ts +22 -0
  49. package/dist/types/src/models/record_query_result.d.ts.map +1 -1
  50. package/dist/types/src/models/session.d.ts +65 -23
  51. package/dist/types/src/models/session.d.ts.map +1 -1
  52. package/dist/types/src/models/table_or_view_query_result.d.ts +21 -0
  53. package/dist/types/src/models/table_or_view_query_result.d.ts.map +1 -1
  54. package/dist/types/src/models/view.d.ts +26 -1
  55. package/dist/types/src/models/view.d.ts.map +1 -1
  56. package/dist/types/src/models/view_data_store.d.ts +2 -0
  57. package/dist/types/src/models/view_data_store.d.ts.map +1 -1
  58. package/dist/types/src/models/view_metadata_query_result.d.ts +21 -0
  59. package/dist/types/src/models/view_metadata_query_result.d.ts.map +1 -1
  60. package/dist/types/src/sdk.d.ts +3 -0
  61. package/dist/types/src/sdk.d.ts.map +1 -1
  62. package/dist/types/src/testing/mock_airtable_interface.d.ts +79 -0
  63. package/dist/types/src/testing/mock_airtable_interface.d.ts.map +1 -1
  64. package/dist/types/src/types/airtable_interface.d.ts +28 -1
  65. package/dist/types/src/types/airtable_interface.d.ts.map +1 -1
  66. package/dist/types/src/types/field.d.ts +241 -1
  67. package/dist/types/src/types/field.d.ts.map +1 -1
  68. package/dist/types/src/types/mutations.d.ts +19 -3
  69. package/dist/types/src/types/mutations.d.ts.map +1 -1
  70. package/dist/types/src/types/view.d.ts +26 -1
  71. package/dist/types/src/types/view.d.ts.map +1 -1
  72. package/dist/types/src/ui/confirmation_dialog.d.ts +8 -0
  73. package/dist/types/src/ui/confirmation_dialog.d.ts.map +1 -1
  74. package/dist/types/src/ui/expand_record.d.ts +1 -0
  75. package/dist/types/src/ui/expand_record.d.ts.map +1 -1
  76. package/dist/types/src/ui/expand_record_list.d.ts.map +1 -1
  77. package/dist/types/src/ui/expand_record_picker_async.d.ts +0 -3
  78. package/dist/types/src/ui/expand_record_picker_async.d.ts.map +1 -1
  79. package/dist/types/src/ui/icon_config.d.ts +15 -8
  80. package/dist/types/src/ui/icon_config.d.ts.map +1 -1
  81. package/dist/types/src/ui/initialize_block.d.ts +19 -2
  82. package/dist/types/src/ui/initialize_block.d.ts.map +1 -1
  83. package/dist/types/src/ui/ui.d.ts +2 -2
  84. package/dist/types/src/ui/ui.d.ts.map +1 -1
  85. package/dist/types/src/ui/use_loadable.d.ts +2 -2
  86. package/dist/types/src/ui/use_records.d.ts +11 -1
  87. package/dist/types/src/ui/use_records.d.ts.map +1 -1
  88. package/dist/types/src/unstable_testing_utils.d.ts +13 -0
  89. package/dist/types/src/unstable_testing_utils.d.ts.map +1 -0
  90. package/dist/types/test/airtable_interface_mocks/linked_records.d.ts.map +1 -1
  91. package/dist/types/test/airtable_interface_mocks/mock_airtable_interface_internal.d.ts +32 -1
  92. package/dist/types/test/airtable_interface_mocks/mock_airtable_interface_internal.d.ts.map +1 -1
  93. package/dist/types/test/airtable_interface_mocks/project_tracker.d.ts.map +1 -1
  94. package/dist/types/test/ui/expand_record.test.d.ts +2 -0
  95. package/dist/types/test/ui/expand_record.test.d.ts.map +1 -0
  96. package/dist/types/test/ui/expand_record_list.test.d.ts +2 -0
  97. package/dist/types/test/ui/expand_record_list.test.d.ts.map +1 -0
  98. package/dist/types/test/ui/expand_record_picker_async.test.d.ts +2 -0
  99. package/dist/types/test/ui/expand_record_picker_async.test.d.ts.map +1 -0
  100. package/index.d.ts +4 -2
  101. package/package.json +4 -4
  102. package/types.d.ts +3 -0
  103. package/unstable_testing_utils.d.ts +1 -0
  104. package/unstable_testing_utils.js +1 -0
  105. package/dist/cjs/testing/inject_mock_airtable_interface.js +0 -63
  106. package/dist/cjs/testing/mock_airtable_interface_external.js +0 -741
  107. package/dist/cjs/testing/test_driver.js +0 -260
  108. package/dist/cjs/types/test_mutations.js +0 -32
  109. package/dist/cjs/unstable_testing.js +0 -17
  110. package/dist/types/src/testing/inject_mock_airtable_interface.d.ts +0 -2
  111. package/dist/types/src/testing/inject_mock_airtable_interface.d.ts.map +0 -1
  112. package/dist/types/src/testing/mock_airtable_interface_external.d.ts +0 -107
  113. package/dist/types/src/testing/mock_airtable_interface_external.d.ts.map +0 -1
  114. package/dist/types/src/testing/test_driver.d.ts +0 -90
  115. package/dist/types/src/testing/test_driver.d.ts.map +0 -1
  116. package/dist/types/src/types/test_mutations.d.ts +0 -27
  117. package/dist/types/src/types/test_mutations.d.ts.map +0 -1
  118. package/dist/types/src/unstable_testing.d.ts +0 -3
  119. package/dist/types/src/unstable_testing.d.ts.map +0 -1
  120. package/dist/types/test/testing/mock_airtable_interface_external.test.d.ts +0 -2
  121. package/dist/types/test/testing/mock_airtable_interface_external.test.d.ts.map +0 -1
  122. package/dist/types/test/testing/test_driver.test.d.ts +0 -2
  123. package/dist/types/test/testing/test_driver.test.d.ts.map +0 -1
  124. package/unstable_testing.d.ts +0 -1
  125. package/unstable_testing.js +0 -1
package/CHANGELOG.md CHANGED
@@ -9,10 +9,39 @@ Not every commit needs to result in a change to this file (e.g. docs and chore c
9
9
  commit that affects the code in a way that consumers might care about should include edits to the
10
10
  'Unreleased' section though. Breaking changes should be prefixed with `**BREAKING:**`.
11
11
 
12
- ## [Unreleased](https://github.com/airtable/blocks/compare/@airtable/blocks@1.3.0...HEAD)
12
+ ## [Unreleased](https://github.com/airtable/blocks/compare/@airtable/blocks@1.5.1...HEAD)
13
13
 
14
14
  No changes.
15
15
 
16
+ ## [1.5.1](https://github.com/airtable/blocks/compare/@airtable/blocks@1.5.0...@airtable/blocks@1.5.1) - 2021-03-04
17
+
18
+ No changes.
19
+
20
+ ## [1.5.0](https://github.com/airtable/blocks/compare/@airtable/blocks@1.4.1...@airtable/blocks@1.5.0) - 2021-02-25
21
+
22
+ - Add type exports for `Cursor` & `Session` to `@airtable/blocks/models`.
23
+ - Add type exports for `GlobalConfig`, `Watchable`, & `Viewport` to `@airtable/blocks/types`.
24
+ - Add `boltList`, `boltListMicro`, `contacts`, `contactsMicro`, `megaphone`, `megaphoneMicro`,
25
+ `shareWithBolt` and `shareWithBoltMicro` icons.
26
+ - Increase spacing between `label` and `description` nodes in `FormField`.
27
+ - Support creating (but not updating) `MULTIPLE_RECORD_LINKS` fields using
28
+ `table.createFieldAsync`.
29
+ - Add `isCancelButtonDisabled` and `isConfirmButtonDisabled` props to `ConfirmationDialog`.
30
+ - Add `config` property to `Field`, which is a new `FieldConfig` discriminated union type that
31
+ provides easier access to field options.
32
+ - Improve type definitions for `getHexForColor` and `getRgbForColor`.
33
+
34
+ ## [1.4.1](https://github.com/airtable/blocks/compare/@airtable/blocks@1.4.0...@airtable/blocks@1.4.1) - 2021-01-21
35
+
36
+ No changes.
37
+
38
+ ## [1.4.0](https://github.com/airtable/blocks/compare/@airtable/blocks@1.3.0...@airtable/blocks@1.4.0) - 2021-01-19
39
+
40
+ - **DEPRECATED:** importing the Base's Cursor instance from the main entrypoint, e.g.
41
+ `import {cursor} from '@airtable/blocks';`. Use the `useCursor` React Hook instead.
42
+ - **DEPRECATED:** importing the Base's Session instance from the main entrypoint, e.g.
43
+ `import {session} from '@airtable/blocks';`. Use the `useSession` React Hook instead.
44
+
16
45
  ## [1.3.0](https://github.com/airtable/blocks/compare/@airtable/blocks@1.2.5...@airtable/blocks@1.3.0) - 2021-01-07
17
46
 
18
47
  - Fix crash when deleting views.
package/dist/cjs/index.js CHANGED
@@ -8,7 +8,7 @@ Object.defineProperty(exports, "__esModule", {
8
8
  value: true
9
9
  });
10
10
  exports.__reset = __reset;
11
- exports.unstable_fetchAsync = exports.viewport = exports.undoRedo = exports.settingsButton = exports.session = exports.runInfo = exports.reload = exports.installationId = exports.globalConfig = exports.cursor = exports.base = exports.__sdk = void 0;
11
+ exports.session = exports.cursor = exports.unstable_fetchAsync = exports.viewport = exports.undoRedo = exports.settingsButton = exports.runInfo = exports.reload = exports.installationId = exports.globalConfig = exports.base = exports.__sdk = void 0;
12
12
 
13
13
  var _perform_record_action = require("./perform_record_action");
14
14
 
@@ -20,8 +20,6 @@ var _sdk2 = _interopRequireDefault(require("./sdk"));
20
20
 
21
21
  var _create_aggregators = require("./models/create_aggregators");
22
22
 
23
- var _expand_record_picker_async = require("./ui/expand_record_picker_async");
24
-
25
23
  var _initialize_block = require("./ui/initialize_block");
26
24
 
27
25
  /** @internal */
@@ -30,8 +28,6 @@ var __sdk;
30
28
  exports.__sdk = __sdk;
31
29
  var base;
32
30
  exports.base = base;
33
- var cursor;
34
- exports.cursor = cursor;
35
31
  var globalConfig;
36
32
  exports.globalConfig = globalConfig;
37
33
  var installationId;
@@ -40,16 +36,42 @@ var reload;
40
36
  exports.reload = reload;
41
37
  var runInfo;
42
38
  exports.runInfo = runInfo;
43
- var session;
44
- exports.session = session;
45
39
  var settingsButton;
46
40
  exports.settingsButton = settingsButton;
47
41
  var undoRedo;
48
42
  exports.undoRedo = undoRedo;
49
43
  var viewport;
50
44
  exports.viewport = viewport;
51
- var unstable_fetchAsync;
45
+ var unstable_fetchAsync; // The `cursor` binding is declared on the following line solely as a signal to
46
+ // the TypeScript compiler. The exported value is actually controlled by the
47
+ // subsequent CommonJS module property descriptor.
48
+
52
49
  exports.unstable_fetchAsync = unstable_fetchAsync;
50
+ var cursor;
51
+ exports.cursor = cursor;
52
+ Object.defineProperty(module.exports, 'cursor', {
53
+ enumerable: true,
54
+
55
+ get() {
56
+ (0, _warning.default)('`import {cursor} from "@airtable/blocks"` is deprecated. Use `import {useCursor} from "@airtable/blocks/ui"` instead.');
57
+ return __sdk.cursor;
58
+ }
59
+
60
+ }); // The `session` binding is declared on the following line solely as a signal
61
+ // to the TypeScript compiler. The exported value is actually controlled by the
62
+ // subsequent CommonJS module property descriptor.
63
+
64
+ var session;
65
+ exports.session = session;
66
+ Object.defineProperty(module.exports, 'session', {
67
+ enumerable: true,
68
+
69
+ get() {
70
+ (0, _warning.default)('`import {session} from "@airtable/blocks"` is deprecated. Use `import {useSession} from "@airtable/blocks/ui"` instead.');
71
+ return __sdk.session;
72
+ }
73
+
74
+ });
53
75
  Object.defineProperty(module.exports, 'UI', {
54
76
  enumerable: true,
55
77
 
@@ -74,12 +96,10 @@ function __reset() {
74
96
  exports.__sdk = __sdk = new _sdk2.default((0, _airtable_interface.default)());
75
97
  var _sdk = __sdk;
76
98
  exports.base = base = _sdk.base;
77
- exports.cursor = cursor = _sdk.cursor;
78
99
  exports.globalConfig = globalConfig = _sdk.globalConfig;
79
100
  exports.installationId = installationId = _sdk.installationId;
80
101
  exports.reload = reload = _sdk.reload;
81
102
  exports.runInfo = runInfo = _sdk.runInfo;
82
- exports.session = session = _sdk.session;
83
103
  exports.settingsButton = settingsButton = _sdk.settingsButton;
84
104
  exports.undoRedo = undoRedo = _sdk.undoRedo;
85
105
  exports.viewport = viewport = _sdk.viewport;
@@ -89,7 +109,6 @@ function __reset() {
89
109
  // the module dependency graph.
90
110
  (0, _create_aggregators.__injectSdkIntoCreateAggregators)(__sdk);
91
111
  (0, _perform_record_action.__injectSdkIntoPerformRecordAction)(__sdk);
92
- (0, _expand_record_picker_async.__injectSdkIntoExpandRecordPickerAsync)(__sdk);
93
112
  (0, _initialize_block.__injectSdkIntoInitializeBlock)(__sdk);
94
113
  (0, _warning.__injectSdkIntoWarning)(__sdk);
95
114
  }
@@ -9,6 +9,7 @@ var _error_utils = require("../error_utils");
9
9
 
10
10
  var AIRTABLE_INTERFACE_VERSION = 0;
11
11
  var airtableInterface = null;
12
+ var missingAirtableInterfaceErrorMessage = ['Error: App environment misconfigured', '\n\n', 'Airtable Apps can only run in the presence of an Airtable Base. If you ', 'are trying to run your App with a Base hosted on airtable.com, then be ', 'sure you are using the Airtable CLI to serve your code and accessing it ', 'through a Custom App installed inside a Base on airtable.com.', '\n\n', 'If you are trying to run automated tests for your App, then make sure ', 'you have loaded the `@airtable/testing-library` module *before* the ', '`@airtable/blocks` module.'].join('');
12
13
  /** @hidden */
13
14
 
14
15
  function getAirtableInterface() {
@@ -16,7 +17,7 @@ function getAirtableInterface() {
16
17
 
17
18
  if (!airtableInterface) {
18
19
  if (!getAirtableInterfaceAtVersion) {
19
- throw (0, _error_utils.spawnError)('@airtable/blocks can only run inside the block frame');
20
+ throw (0, _error_utils.spawnError)(missingAirtableInterfaceErrorMessage);
20
21
  }
21
22
 
22
23
  airtableInterface = getAirtableInterfaceAtVersion(AIRTABLE_INTERFACE_VERSION);
@@ -81,12 +81,10 @@ var WatchableCursorKeys = Object.freeze({
81
81
  * {@link useLoadable} to access them.
82
82
  *
83
83
  * ```js
84
- * import {cursor} from '@airtable/blocks';
85
- * import {useWatchable} from '@airtable/blocks/ui';
84
+ * import {useCursor, useWatchable} from '@airtable/blocks/ui';
86
85
  *
87
86
  * function ActiveTableAndView() {
88
- * // re-render whenever the active table or view changes
89
- * useWatchable(cursor, ['activeTableId', 'activeViewId']);
87
+ * const cursor = useCursor();
90
88
  *
91
89
  * return (
92
90
  * <div>
@@ -98,10 +96,10 @@ var WatchableCursorKeys = Object.freeze({
98
96
  * ```
99
97
  *
100
98
  * ```js
101
- * import {cursor} from '@airtable/blocks';
102
- * import {useLoadable, useWatchable} from '@airtable/blocks/ui';
99
+ * import {useCursor, useLoadable, useWatchable} from '@airtable/blocks/ui';
103
100
  *
104
101
  * function SelectedRecordAndFieldIds() {
102
+ * const cursor = useCursor();
105
103
  * // load selected records and fields
106
104
  * useLoadable(cursor);
107
105
  *
@@ -444,6 +444,30 @@ function (_AbstractModel) {
444
444
 
445
445
  return options ? (0, _private_utils.cloneDeep)(options) : null;
446
446
  }
447
+ /**
448
+ * The type and options of the field to make type narrowing `FieldOptions` easier.
449
+ *
450
+ * @see {@link FieldConfig}
451
+ * @example
452
+ * const fieldConfig = field.config;
453
+ * if (fieldConfig.type === FieldType.SINGLE_SELECT) {
454
+ * return fieldConfig.options.choices;
455
+ * } else if (fieldConfig.type === FieldType.MULTIPLE_LOOKUP_VALUES && fieldConfig.options.isValid) {
456
+ * if (fieldConfig.options.result.type === FieldType.SINGLE_SELECT) {
457
+ * return fieldConfig.options.result.options.choices;
458
+ * }
459
+ * }
460
+ * return DEFAULT_CHOICES;
461
+ */
462
+
463
+ }, {
464
+ key: "config",
465
+ get: function get() {
466
+ return {
467
+ type: this.type,
468
+ options: this.options
469
+ };
470
+ }
447
471
  }, {
448
472
  key: "isComputed",
449
473
  get: function get() {
@@ -0,0 +1,475 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
5
+ require("core-js/modules/es.symbol");
6
+
7
+ require("core-js/modules/es.symbol.description");
8
+
9
+ require("core-js/modules/es.array.concat");
10
+
11
+ require("core-js/modules/es.array.iterator");
12
+
13
+ require("core-js/modules/es.array.map");
14
+
15
+ require("core-js/modules/es.array.slice");
16
+
17
+ require("core-js/modules/es.object.to-string");
18
+
19
+ require("core-js/modules/es.promise");
20
+
21
+ require("core-js/modules/web.dom-collections.iterator");
22
+
23
+ Object.defineProperty(exports, "__esModule", {
24
+ value: true
25
+ });
26
+ exports.default = void 0;
27
+
28
+ var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
29
+
30
+ require("regenerator-runtime/runtime");
31
+
32
+ var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
33
+
34
+ var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
35
+
36
+ var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
37
+
38
+ var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized"));
39
+
40
+ var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
41
+
42
+ var _get2 = _interopRequireDefault(require("@babel/runtime/helpers/get"));
43
+
44
+ var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
45
+
46
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
47
+
48
+ var _error_utils = require("../error_utils");
49
+
50
+ var _record_query_result = _interopRequireDefault(require("./record_query_result"));
51
+
52
+ var _object_pool = _interopRequireDefault(require("./object_pool"));
53
+
54
+ /** @module @airtable/blocks/models: RecordQueryResult */
55
+
56
+ /** */
57
+
58
+ /**
59
+ * Represents a group of records returned from a group query. See {@link RecordQueryResult} for main
60
+ * documentation.
61
+ *
62
+ * Do not instantiate. You can get instances of this class by calling
63
+ * `recordQueryResult.groups`.
64
+ *
65
+ * @docsPath models/query results/GroupedRecordQueryResult
66
+ * @hidden
67
+ */
68
+ var GroupedRecordQueryResult =
69
+ /*#__PURE__*/
70
+ function (_RecordQueryResult) {
71
+ (0, _inherits2.default)(GroupedRecordQueryResult, _RecordQueryResult);
72
+
73
+ /** @internal */
74
+
75
+ /** @internal */
76
+
77
+ /** @internal */
78
+
79
+ /**
80
+ * This includes groupLevel for all children & parent grouped layers, the getter
81
+ * returns only the groupLevels for this layer.
82
+ *
83
+ * @internal
84
+ */
85
+ // This is the ordered list of groups.
86
+
87
+ /** @internal */
88
+ // lazily generated set of record ids
89
+
90
+ /** @internal */
91
+ // lazily generated ordered array of recordIds
92
+
93
+ /** @internal */
94
+
95
+ /** @internal */
96
+ function GroupedRecordQueryResult(parentQueryResult, groupData, groupLevel, normalizedOpts, sdk) {
97
+ var _this;
98
+
99
+ (0, _classCallCheck2.default)(this, GroupedRecordQueryResult);
100
+ _this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(GroupedRecordQueryResult).call(this, sdk, normalizedOpts));
101
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "_parentQueryResult", void 0);
102
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "_groupData", void 0);
103
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "_groupLevels", void 0);
104
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "_orderedChildrenGroups", void 0);
105
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "_recordIdsSet", null);
106
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "_orderedRecordIds", null);
107
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "__groupedRecordQueryResultPool", void 0);
108
+ _this.__groupedRecordQueryResultPool = new _object_pool.default(GroupedRecordQueryResult);
109
+ _this._parentQueryResult = parentQueryResult;
110
+ _this._groupData = groupData;
111
+ _this._groupLevels = groupLevel;
112
+
113
+ var groupLevelDataSlicedForChildren = _this._groupLevels.slice(1);
114
+
115
+ _this._orderedChildrenGroups = groupData.groups ? groupData.groups.map(singleGroupData => {
116
+ var group = _this.__groupedRecordQueryResultPool.getObjectForReuse((0, _assertThisInitialized2.default)(_this), singleGroupData, groupLevelDataSlicedForChildren, normalizedOpts, sdk); // Don't await the loading, let others check isDataLoaded.
117
+ // (it doesn't take any time anyway). Loading also strong retains.
118
+
119
+
120
+ group.loadDataAsync();
121
+ return group;
122
+ }) : null;
123
+ return _this;
124
+ }
125
+ /**
126
+ * Gets children groups of this group (if any exist)
127
+ */
128
+
129
+
130
+ (0, _createClass2.default)(GroupedRecordQueryResult, [{
131
+ key: "_computeRecordIds",
132
+
133
+ /**
134
+ * Recursively gets all recordIds in the children groups, keeping recordIds in group order
135
+ *
136
+ * @internal
137
+ */
138
+ value: function _computeRecordIds() {
139
+ // If we are a leaf node, return the raw recordIds
140
+ if (!this.groups) {
141
+ var _this$_data$groupData;
142
+
143
+ // Typescript can't infer if groups is empty visibleRecordIds must be populated
144
+ // but the extra safety isn't bad. (istanbul also can't ignore just the ??)
145
+ // istanbul ignore next
146
+ return (_this$_data$groupData = this._data.groupData.visibleRecordIds) !== null && _this$_data$groupData !== void 0 ? _this$_data$groupData : [];
147
+ } // Otherwise build the recordId's from children groups
148
+
149
+
150
+ var recordIds = [];
151
+ var _iteratorNormalCompletion = true;
152
+ var _didIteratorError = false;
153
+ var _iteratorError = undefined;
154
+
155
+ try {
156
+ for (var _iterator = this.groups[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
157
+ var group = _step.value;
158
+ recordIds.push(...group.recordIds);
159
+ }
160
+ } catch (err) {
161
+ _didIteratorError = true;
162
+ _iteratorError = err;
163
+ } finally {
164
+ try {
165
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
166
+ _iterator.return();
167
+ }
168
+ } finally {
169
+ if (_didIteratorError) {
170
+ throw _iteratorError;
171
+ }
172
+ }
173
+ }
174
+
175
+ return recordIds;
176
+ }
177
+ /**
178
+ * Anytime the recordIds to return could have changed, we clear this so that
179
+ * the next time the user requests recordIds it recomputes
180
+ *
181
+ * @internal
182
+ */
183
+
184
+ }, {
185
+ key: "_invalidateComputedRecordIds",
186
+ value: function _invalidateComputedRecordIds() {
187
+ this._orderedRecordIds = null;
188
+ }
189
+ /**
190
+ * Ordered array of all the record ids inside this group, in group order.
191
+ * This returns all recordIds of all children groups (in grouped order).
192
+ * Watchable.
193
+ */
194
+
195
+ }, {
196
+ key: "watch",
197
+
198
+ /** @inheritdoc */
199
+ value: function watch(keys, callback, context) {
200
+ // TODO (SeanKeenan): This provides events even if they occur outside of this group
201
+ // This is an issue that needs to be fixed before this API is made public
202
+ var validKeys = this._parentQueryResult.watch(keys, callback, context);
203
+
204
+ return validKeys;
205
+ }
206
+ /** @inheritdoc */
207
+
208
+ }, {
209
+ key: "unwatch",
210
+ value: function unwatch(keys, callback, context) {
211
+ return this._parentQueryResult.unwatch(keys, callback, context);
212
+ }
213
+ /** @inheritdoc */
214
+
215
+ }, {
216
+ key: "loadDataAsync",
217
+ value: function loadDataAsync() {
218
+ return _regenerator.default.async(function loadDataAsync$(_context) {
219
+ while (1) {
220
+ switch (_context.prev = _context.next) {
221
+ case 0:
222
+ _context.next = 2;
223
+ return _regenerator.default.awrap((0, _get2.default)((0, _getPrototypeOf2.default)(GroupedRecordQueryResult.prototype), "loadDataAsync", this).call(this));
224
+
225
+ case 2:
226
+ case "end":
227
+ return _context.stop();
228
+ }
229
+ }
230
+ }, null, this);
231
+ }
232
+ /** @internal */
233
+
234
+ }, {
235
+ key: "_getChangedKeysOnLoad",
236
+ value: function _getChangedKeysOnLoad() {
237
+ return this._parentQueryResult._getChangedKeysOnLoad();
238
+ }
239
+ /** @internal */
240
+
241
+ }, {
242
+ key: "_loadDataAsync",
243
+ value: function _loadDataAsync() {
244
+ return _regenerator.default.async(function _loadDataAsync$(_context2) {
245
+ while (1) {
246
+ switch (_context2.prev = _context2.next) {
247
+ case 0:
248
+ this._parentQueryResult.__groupedRecordQueryResultPool.registerObjectForReuseStrong(this); // Ensure we invalidate our memoized computed recordIds whenever a relevant hook changes
249
+ // TODO: (SeanKeenan) At the moment this should never be relevant, because groups are recreated
250
+ // anytime the groups change - but this is how it should work once groups persist AND
251
+ // watching recordIds only changes if records in this group change.
252
+ // In the meantime this does ensure that a deleted GroupedRecordQuery with stale recordIds
253
+ // doesn't return the cached array.
254
+
255
+
256
+ this.watch(['recordIds', 'groups', 'groupLevels'], this._invalidateComputedRecordIds, this);
257
+ this.watch(['recordIds'], this._invalidateRecordIdsSet, this);
258
+ return _context2.abrupt("return", this._getChangedKeysOnLoad());
259
+
260
+ case 4:
261
+ case "end":
262
+ return _context2.stop();
263
+ }
264
+ }
265
+ }, null, this);
266
+ }
267
+ /** @internal */
268
+
269
+ }, {
270
+ key: "_unloadData",
271
+ value: function _unloadData() {
272
+ // Ensure we invalidate our memoized computed recordIds whenever a relevant hook changes
273
+ this.unwatch(['recordIds', 'groups', 'groupLevels'], this._invalidateComputedRecordIds, this);
274
+ this.unwatch(['recordIds'], this._invalidateRecordIdsSet, this); // Invalidate both of the caches, as this object can no longer be accessed
275
+
276
+ this._invalidateComputedRecordIds();
277
+
278
+ this._invalidateRecordIdsSet();
279
+
280
+ this._unloadChildrenGroupsIfNeeded();
281
+
282
+ this._parentQueryResult.__groupedRecordQueryResultPool.unregisterObjectForReuseStrong(this);
283
+ }
284
+ /** @internal */
285
+
286
+ }, {
287
+ key: "_unloadChildrenGroupsIfNeeded",
288
+
289
+ /** @internal */
290
+ value: function _unloadChildrenGroupsIfNeeded() {
291
+ if (this._orderedChildrenGroups) {
292
+ var _iteratorNormalCompletion2 = true;
293
+ var _didIteratorError2 = false;
294
+ var _iteratorError2 = undefined;
295
+
296
+ try {
297
+ for (var _iterator2 = this._orderedChildrenGroups[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
298
+ var group = _step2.value;
299
+ group.unloadData();
300
+ }
301
+ } catch (err) {
302
+ _didIteratorError2 = true;
303
+ _iteratorError2 = err;
304
+ } finally {
305
+ try {
306
+ if (!_iteratorNormalCompletion2 && _iterator2.return != null) {
307
+ _iterator2.return();
308
+ }
309
+ } finally {
310
+ if (_didIteratorError2) {
311
+ throw _iteratorError2;
312
+ }
313
+ }
314
+ }
315
+ }
316
+ }
317
+ /** @internal */
318
+
319
+ }, {
320
+ key: "_invalidateRecordIdsSet",
321
+ value: function _invalidateRecordIdsSet() {
322
+ this._recordIdsSet = null;
323
+ }
324
+ /** @internal */
325
+
326
+ }, {
327
+ key: "_getOrGenerateRecordIdsSet",
328
+ value: function _getOrGenerateRecordIdsSet() {
329
+ // TODO (SeanKeenan): this logic is duplicated in tableOrViewQueryResult
330
+ if (!this._recordIdsSet) {
331
+ var recordIdsSet = {};
332
+ var _iteratorNormalCompletion3 = true;
333
+ var _didIteratorError3 = false;
334
+ var _iteratorError3 = undefined;
335
+
336
+ try {
337
+ for (var _iterator3 = this.recordIds[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
338
+ var recordId = _step3.value;
339
+ recordIdsSet[recordId] = true;
340
+ }
341
+ } catch (err) {
342
+ _didIteratorError3 = true;
343
+ _iteratorError3 = err;
344
+ } finally {
345
+ try {
346
+ if (!_iteratorNormalCompletion3 && _iterator3.return != null) {
347
+ _iterator3.return();
348
+ }
349
+ } finally {
350
+ if (_didIteratorError3) {
351
+ throw _iteratorError3;
352
+ }
353
+ }
354
+ }
355
+
356
+ this._recordIdsSet = recordIdsSet;
357
+ }
358
+
359
+ return this._recordIdsSet;
360
+ }
361
+ }, {
362
+ key: "groups",
363
+ get: function get() {
364
+ return this._orderedChildrenGroups;
365
+ }
366
+ /** @internal */
367
+
368
+ }, {
369
+ key: "groupLevel",
370
+ get: function get() {
371
+ return this._data.groupLevels[0];
372
+ }
373
+ /**
374
+ * Gets the fieldId that this group is grouped by
375
+ */
376
+
377
+ }, {
378
+ key: "fieldId",
379
+ get: function get() {
380
+ return this.groupLevel.fieldId;
381
+ }
382
+ /**
383
+ * Gets the field that this group is grouped by
384
+ */
385
+
386
+ }, {
387
+ key: "field",
388
+ get: function get() {
389
+ return this.parentTable.getFieldById(this.fieldId);
390
+ } // TODO (SeanKeenan) This is needed because we can't always iterate down and find
391
+ // a record, it's possible to have "empty groups".
392
+ // getValue() {
393
+ // }
394
+ // TODO (SeanKeenan)
395
+ // getValueAsString() {
396
+ // }
397
+
398
+ /**
399
+ * @internal (since we may not be able to return parent model instances in the immutable models world)
400
+ * The table that records in this RecordQueryResult are part of
401
+ */
402
+
403
+ }, {
404
+ key: "parentTable",
405
+ get: function get() {
406
+ return this._parentQueryResult.parentTable;
407
+ }
408
+ }, {
409
+ key: "recordIds",
410
+ get: function get() {
411
+ (0, _error_utils.invariant)(this.isDataLoaded, 'GroupedRecordQueryResult data is not loaded');
412
+
413
+ if (this._orderedRecordIds === null) {
414
+ this._orderedRecordIds = this._computeRecordIds();
415
+ }
416
+
417
+ return this._orderedRecordIds;
418
+ }
419
+ /**
420
+ * The fields that were used to create the parent RecordQueryResult that created this GroupedRecordQueryResult.
421
+ * This is separate from the field/fieldId property - which is the field this grouping is based upon.
422
+ * Null if fields were not specified, which means the RecordQueryResult
423
+ * will load all fields in the table.
424
+ */
425
+
426
+ }, {
427
+ key: "fields",
428
+ get: function get() {
429
+ (0, _error_utils.invariant)(this.isDataLoaded, 'GroupedRecordQueryResult data is not loaded');
430
+ return this._parentQueryResult.fields;
431
+ }
432
+ }, {
433
+ key: "__poolKey",
434
+ get: function get() {
435
+ // TODO (SeanKeenan) We don't have an actual groupId, but while id is unique; this should have id removed
436
+ return "".concat(this._serializedOpts, "::").concat(this.id);
437
+ }
438
+ /**
439
+ * This model doesn't actually load data, but it does use the `_data`
440
+ * property so that checks for model deletion behave appropriately.
441
+ *
442
+ * This is considered deleted if the parent query result has been deleted.
443
+ *
444
+ * We return groupData, instead of precomputing all children groups because
445
+ * we perform the computation+caching lazily on request
446
+ *
447
+ * @internal
448
+ */
449
+
450
+ }, {
451
+ key: "_dataOrNullIfDeleted",
452
+ get: function get() {
453
+ if (this._parentQueryResult._dataOrNullIfDeleted === null) {
454
+ return null;
455
+ }
456
+
457
+ return {
458
+ groupData: this._groupData,
459
+ groupLevels: this._groupLevels
460
+ };
461
+ }
462
+ /** @inheritdoc */
463
+
464
+ }, {
465
+ key: "isDataLoaded",
466
+ get: function get() {
467
+ return this._parentQueryResult.isDataLoaded;
468
+ }
469
+ }]);
470
+ return GroupedRecordQueryResult;
471
+ }(_record_query_result.default);
472
+
473
+ (0, _defineProperty2.default)(GroupedRecordQueryResult, "_className", 'GroupedRecordQueryResult');
474
+ var _default = GroupedRecordQueryResult;
475
+ exports.default = _default;