@ember-data/store 4.2.0-beta.0 → 4.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/addon/-private/identifiers/cache.ts +3 -16
  2. package/addon/-private/identifiers/is-stable-identifier.ts +2 -2
  3. package/addon/-private/index.ts +1 -3
  4. package/addon/-private/system/core-store.ts +192 -958
  5. package/addon/-private/system/ds-model-store.ts +20 -111
  6. package/addon/-private/system/fetch-manager.ts +11 -5
  7. package/addon/-private/system/model/internal-model.ts +92 -345
  8. package/addon/-private/system/model/shim-model-class.ts +15 -16
  9. package/addon/-private/system/model/states.js +2 -14
  10. package/addon/-private/system/record-array-manager.js +21 -70
  11. package/addon/-private/system/record-arrays/adapter-populated-record-array.js +1 -20
  12. package/addon/-private/system/record-arrays/record-array.js +1 -8
  13. package/addon/-private/system/record-data-for.ts +10 -8
  14. package/addon/-private/system/record-notification-manager.ts +11 -10
  15. package/addon/-private/system/references/belongs-to.ts +32 -67
  16. package/addon/-private/system/references/has-many.ts +21 -41
  17. package/addon/-private/system/references/record.ts +15 -27
  18. package/addon/-private/system/references/reference.ts +4 -11
  19. package/addon/-private/system/schema-definition-service.ts +2 -2
  20. package/addon/-private/system/snapshot.ts +28 -48
  21. package/addon/-private/system/store/finders.js +2 -96
  22. package/addon/-private/system/store/internal-model-factory.ts +34 -28
  23. package/addon/-private/system/store/record-data-store-wrapper.ts +28 -36
  24. package/addon/-private/system/weak-cache.ts +125 -0
  25. package/addon/-private/ts-interfaces/fetch-manager.ts +4 -0
  26. package/addon/-private/ts-interfaces/identifier.ts +2 -2
  27. package/addon/-private/ts-interfaces/minimum-adapter-interface.ts +0 -1
  28. package/addon/-private/ts-interfaces/schema-definition-service.ts +2 -2
  29. package/package.json +16 -16
  30. package/addon/-private/system/deprecated-evented.js +0 -92
@@ -1,9 +1,7 @@
1
- import { CUSTOM_MODEL_CLASS } from '@ember-data/canary-features';
2
1
  import type { RelationshipDefinition } from '@ember-data/model/-private/system/relationships/relationship-meta';
3
2
  import { HAS_RECORD_DATA_PACKAGE } from '@ember-data/private-build-infra';
4
3
 
5
4
  import type { IdentifierCache } from '../../identifiers/cache';
6
- import { identifierCacheFor } from '../../identifiers/cache';
7
5
  import type { StableRecordIdentifier } from '../../ts-interfaces/identifier';
8
6
  import type { RecordData } from '../../ts-interfaces/record-data';
9
7
  import type {
@@ -45,7 +43,7 @@ export default class RecordDataStoreWrapper implements StoreWrapper {
45
43
  }
46
44
 
47
45
  get identifierCache(): IdentifierCache {
48
- return identifierCacheFor(this._store);
46
+ return this._store.identifierCache;
49
47
  }
50
48
 
51
49
  _scheduleNotification(identifier: StableRecordIdentifier, key: string, kind: 'belongsTo' | 'hasMany') {
@@ -71,7 +69,7 @@ export default class RecordDataStoreWrapper implements StoreWrapper {
71
69
  notifyErrorsChange(type: string, id: string | null, lid: string): void;
72
70
  notifyErrorsChange(type: string, id: string | null, lid: string | null): void {
73
71
  const resource = constructResource(type, id, lid);
74
- const identifier = identifierCacheFor(this._store).getOrCreateRecordIdentifier(resource);
72
+ const identifier = this.identifierCache.getOrCreateRecordIdentifier(resource);
75
73
 
76
74
  let internalModel = internalModelFactoryFor(this._store).peek(identifier);
77
75
 
@@ -105,11 +103,11 @@ export default class RecordDataStoreWrapper implements StoreWrapper {
105
103
  }
106
104
 
107
105
  attributesDefinitionFor(type: string): AttributesSchema {
108
- return this._store._attributesDefinitionFor(type);
106
+ return this._store._attributesDefinitionFor({ type });
109
107
  }
110
108
 
111
109
  relationshipsDefinitionFor(type: string): RelationshipsSchema {
112
- return this._store._relationshipsDefinitionFor(type);
110
+ return this._store._relationshipsDefinitionFor({ type });
113
111
  }
114
112
 
115
113
  inverseForRelationship(type: string, key: string): string | null {
@@ -118,16 +116,13 @@ export default class RecordDataStoreWrapper implements StoreWrapper {
118
116
  if (!definition) {
119
117
  return null;
120
118
  }
121
- if (CUSTOM_MODEL_CLASS) {
122
- if (metaIsRelationshipDefinition(definition)) {
123
- return definition._inverseKey(this._store, modelClass);
124
- } else if (definition.options && definition.options.inverse !== undefined) {
125
- return definition.options.inverse;
126
- } else {
127
- return null;
128
- }
119
+
120
+ if (metaIsRelationshipDefinition(definition)) {
121
+ return definition._inverseKey(this._store, modelClass);
122
+ } else if (definition.options && definition.options.inverse !== undefined) {
123
+ return definition.options.inverse;
129
124
  } else {
130
- return (definition as RelationshipDefinition)._inverseKey(this._store, modelClass);
125
+ return null;
131
126
  }
132
127
  }
133
128
 
@@ -137,21 +132,18 @@ export default class RecordDataStoreWrapper implements StoreWrapper {
137
132
  if (!definition) {
138
133
  return false;
139
134
  }
140
- if (CUSTOM_MODEL_CLASS) {
141
- if (definition.options && definition.options.inverse === null) {
142
- return false;
143
- }
144
- if ((definition as unknown as { inverseIsAsync?: boolean }).inverseIsAsync !== undefined) {
145
- // TODO do we need to amend the RFC for this prop?
146
- // else we should add it to the TS interface and document.
147
- return !!(definition as unknown as { inverseIsAsync: boolean }).inverseIsAsync;
148
- } else if (metaIsRelationshipDefinition(definition)) {
149
- return definition._inverseIsAsync(this._store, modelClass);
150
- } else {
151
- return false;
152
- }
135
+
136
+ if (definition.options && definition.options.inverse === null) {
137
+ return false;
138
+ }
139
+ if ((definition as unknown as { inverseIsAsync?: boolean }).inverseIsAsync !== undefined) {
140
+ // TODO do we need to amend the RFC for this prop?
141
+ // else we should add it to the TS interface and document.
142
+ return !!(definition as unknown as { inverseIsAsync: boolean }).inverseIsAsync;
143
+ } else if (metaIsRelationshipDefinition(definition)) {
144
+ return definition._inverseIsAsync(this._store, modelClass);
153
145
  } else {
154
- return (definition as RelationshipDefinition)._inverseIsAsync(this._store, modelClass);
146
+ return false;
155
147
  }
156
148
  }
157
149
 
@@ -159,7 +151,7 @@ export default class RecordDataStoreWrapper implements StoreWrapper {
159
151
  notifyPropertyChange(type: string, id: string, lid: string | null | undefined, key: string): void;
160
152
  notifyPropertyChange(type: string, id: string | null, lid: string | null | undefined, key: string): void {
161
153
  const resource = constructResource(type, id, lid);
162
- const identifier = identifierCacheFor(this._store).getOrCreateRecordIdentifier(resource);
154
+ const identifier = this.identifierCache.getOrCreateRecordIdentifier(resource);
163
155
  let internalModel = internalModelFactoryFor(this._store).peek(identifier);
164
156
 
165
157
  if (internalModel) {
@@ -171,7 +163,7 @@ export default class RecordDataStoreWrapper implements StoreWrapper {
171
163
  notifyHasManyChange(type: string, id: string, lid: string | null | undefined, key: string): void;
172
164
  notifyHasManyChange(type: string, id: string | null, lid: string | null | undefined, key: string): void {
173
165
  const resource = constructResource(type, id, lid);
174
- const identifier = identifierCacheFor(this._store).getOrCreateRecordIdentifier(resource);
166
+ const identifier = this.identifierCache.getOrCreateRecordIdentifier(resource);
175
167
  this._scheduleNotification(identifier, key, 'hasMany');
176
168
  }
177
169
 
@@ -179,7 +171,7 @@ export default class RecordDataStoreWrapper implements StoreWrapper {
179
171
  notifyBelongsToChange(type: string, id: string, lid: string | null | undefined, key: string): void;
180
172
  notifyBelongsToChange(type: string, id: string | null, lid: string | null | undefined, key: string): void {
181
173
  const resource = constructResource(type, id, lid);
182
- const identifier = identifierCacheFor(this._store).getOrCreateRecordIdentifier(resource);
174
+ const identifier = this.identifierCache.getOrCreateRecordIdentifier(resource);
183
175
 
184
176
  this._scheduleNotification(identifier, key, 'belongsTo');
185
177
  }
@@ -188,7 +180,7 @@ export default class RecordDataStoreWrapper implements StoreWrapper {
188
180
  notifyStateChange(type: string, id: string | null, lid: string, key?: string): void;
189
181
  notifyStateChange(type: string, id: string | null, lid: string | null, key?: string): void {
190
182
  const resource = constructResource(type, id, lid);
191
- const identifier = identifierCacheFor(this._store).getOrCreateRecordIdentifier(resource);
183
+ const identifier = this.identifierCache.getOrCreateRecordIdentifier(resource);
192
184
  let internalModel = internalModelFactoryFor(this._store).peek(identifier);
193
185
 
194
186
  if (internalModel) {
@@ -207,7 +199,7 @@ export default class RecordDataStoreWrapper implements StoreWrapper {
207
199
  identifier = { type };
208
200
  } else {
209
201
  const resource = constructResource(type, id, lid);
210
- identifier = identifierCacheFor(this._store).getOrCreateRecordIdentifier(resource);
202
+ identifier = this.identifierCache.getOrCreateRecordIdentifier(resource);
211
203
  }
212
204
 
213
205
  return this._store.recordDataFor(identifier, isCreate);
@@ -221,7 +213,7 @@ export default class RecordDataStoreWrapper implements StoreWrapper {
221
213
  isRecordInUse(type: string, id: string, lid?: string | null): boolean;
222
214
  isRecordInUse(type: string, id: string | null, lid?: string | null): boolean {
223
215
  const resource = constructResource(type, id, lid);
224
- const identifier = identifierCacheFor(this._store).getOrCreateRecordIdentifier(resource);
216
+ const identifier = this.identifierCache.getOrCreateRecordIdentifier(resource);
225
217
  const internalModel = internalModelFactoryFor(this._store).peek(identifier);
226
218
 
227
219
  if (!internalModel) {
@@ -236,7 +228,7 @@ export default class RecordDataStoreWrapper implements StoreWrapper {
236
228
  disconnectRecord(type: string, id: string, lid?: string | null): void;
237
229
  disconnectRecord(type: string, id: string | null, lid?: string | null): void {
238
230
  const resource = constructResource(type, id, lid);
239
- const identifier = identifierCacheFor(this._store).getOrCreateRecordIdentifier(resource);
231
+ const identifier = this.identifierCache.getOrCreateRecordIdentifier(resource);
240
232
  if (HAS_RECORD_DATA_PACKAGE) {
241
233
  let graph = peekGraph(this);
242
234
  if (graph) {
@@ -0,0 +1,125 @@
1
+ import { DEBUG } from '@glimmer/env';
2
+
3
+ import { DEBUG_IDENTIFIER_BUCKET } from '../ts-interfaces/identifier';
4
+
5
+ /*
6
+ DEBUG only fields. Keeping this in a separate interface
7
+ which Typescript then merges with the class definition allow us to
8
+ have a DEBUG only property without paying the cost of that field being
9
+ present and initialized (usually to void 0) in production.
10
+ */
11
+ interface WeakCache<K extends object, V> extends WeakMap<K, V> {
12
+ _symbol: Symbol;
13
+ _fieldName: string;
14
+ _expectMsg?: (key: K) => string;
15
+ /*
16
+ The default Typescript Signature for WeakMap expects obj: K and
17
+ returns a boolean. This behavior isn't useful in our common case
18
+ where we want to use `has` to narrow by determining whether a
19
+ particular object is a key.
20
+
21
+ For instance, we use WeakMap key check to determine in some cases
22
+ whether an object given to us by a user is a RecordIdentifier or
23
+ a Record.
24
+ */
25
+ has(obj: unknown): obj is K;
26
+
27
+ /*
28
+ This is an exception to the interface being used for
29
+ DEBUG ony fields. In this case, only a few WeakCache's
30
+ will utilize the lookup behavior, so paying the cost in
31
+ the constructor signature / field initialization seemed
32
+ off.
33
+ */
34
+ _generator?: (key: K) => V;
35
+ }
36
+
37
+ /**
38
+ * @class WeakCache
39
+ * @extends WeakMap
40
+ * @internal
41
+ */
42
+ class WeakCache<K extends object, V> extends WeakMap<K, V> {
43
+ constructor(_fieldName: string) {
44
+ super();
45
+ if (DEBUG) {
46
+ this._fieldName = _fieldName;
47
+ this._symbol = Symbol.for(_fieldName);
48
+ }
49
+ }
50
+
51
+ /**
52
+ * Retrieve the value for a key from the WeakCache with the expectation
53
+ * that the key exists. Throws the error generated by _expectMsg in DEBUG if
54
+ * that key does not exist.
55
+ *
56
+ * @method getWithError
57
+ * @param obj
58
+ * @internal
59
+ */
60
+ getWithError(obj: K): V {
61
+ let v = this.get(obj);
62
+
63
+ if (DEBUG && v === undefined) {
64
+ throw new Error(this._expectMsg!(obj));
65
+ }
66
+
67
+ return v as V;
68
+ }
69
+
70
+ /**
71
+ * Retrieve the value for a key from the WeakCache, or generate one
72
+ * using the configured _generator method if no value is yet present.
73
+ *
74
+ * @method lookup
75
+ * @param obj
76
+ * @internal
77
+ */
78
+ lookup(obj: K): V {
79
+ let v = super.get(obj);
80
+
81
+ if (v === undefined) {
82
+ v = this._generator!(obj);
83
+ super.set(obj, v);
84
+
85
+ if (DEBUG) {
86
+ if (obj[DEBUG_IDENTIFIER_BUCKET] && this._fieldName !== 'identifier-proxy-target') {
87
+ const target: K = obj[Symbol.for('identifier-proxy-target') as unknown as string] as K;
88
+ target[this._symbol as unknown as string] = v;
89
+ } else {
90
+ obj[this._symbol as unknown as string] = v;
91
+ }
92
+ }
93
+ }
94
+
95
+ return v;
96
+ }
97
+ }
98
+
99
+ class DebugWeakCache<K extends object, V> extends WeakCache<K, V> {
100
+ set(obj: K, value: V): this {
101
+ if (DEBUG && super.has(obj)) {
102
+ throw new Error(`${Object.prototype.toString.call(obj)} was already assigned a value for ${this._fieldName}`);
103
+ }
104
+ if (DEBUG) {
105
+ if (obj[DEBUG_IDENTIFIER_BUCKET] && this._fieldName !== 'identifier-proxy-target') {
106
+ const target: K = obj[Symbol.for('identifier-proxy-target') as unknown as string] as K;
107
+ target[this._symbol as unknown as string] = value;
108
+ // TODO the Proxy check here is entirely for ember-m3
109
+ // as it's attribute access tests fail since the symbol
110
+ // is an unexpected key received by it's proxies.
111
+ // we should address this upstream.
112
+ } else if (obj.constructor?.toString?.() !== 'MegamorphicModel') {
113
+ try {
114
+ obj[this._symbol as unknown as string] = value;
115
+ } catch {
116
+ // some keys are proxies that can't accept symbol values
117
+ // for instance records from ember-m3
118
+ }
119
+ }
120
+ }
121
+ return super.set(obj, value);
122
+ }
123
+ }
124
+ export type { DebugWeakCache };
125
+ export default DEBUG ? DebugWeakCache : WeakCache;
@@ -1,7 +1,11 @@
1
+ import type { Dict } from '@ember-data/store/-private/ts-interfaces/utils';
2
+
1
3
  import type { RecordIdentifier } from './identifier';
2
4
 
3
5
  export interface Operation {
4
6
  op: string;
7
+ options: Dict<unknown> | undefined;
8
+ recordIdentifier: RecordIdentifier;
5
9
  }
6
10
 
7
11
  export interface FindRecordQuery extends Operation {
@@ -113,7 +113,7 @@ export type StableRecordIdentifier = StableExistingRecordIdentifier | StableNewR
113
113
 
114
114
  /**
115
115
  Configures how unique identifier lid strings are generated by @ember-data/store.
116
-
116
+
117
117
  This configuration MUST occur prior to the store instance being created.
118
118
 
119
119
  Takes a method which can expect to receive various data as its first argument
@@ -231,7 +231,7 @@ export type ForgetMethod = (identifier: StableIdentifier | StableRecordIdentifie
231
231
  ```js
232
232
  import { setIdentifierResetMethod } from '@ember-data/store';
233
233
  ```
234
-
234
+
235
235
  Takes a method which can expect to be called when the parent application is destroyed.
236
236
 
237
237
  If you have properly used a WeakMap to encapsulate the state of your customization
@@ -1,4 +1,3 @@
1
- /* eslint-disable no-restricted-globals */
2
1
  // the above eslint rule checks return types. This is an interface
3
2
  // and we intend Promise whether it is Native or polyfilled is of
4
3
  // no consequence.
@@ -7,6 +7,6 @@ import type { AttributesSchema, RelationshipsSchema } from './record-data-schema
7
7
 
8
8
  export interface SchemaDefinitionService {
9
9
  doesTypeExist(modelName: string): boolean;
10
- attributesDefinitionFor(identifier: RecordIdentifier | string): AttributesSchema;
11
- relationshipsDefinitionFor(identifier: RecordIdentifier | string): RelationshipsSchema;
10
+ attributesDefinitionFor(identifier: RecordIdentifier | { type: string }): AttributesSchema;
11
+ relationshipsDefinitionFor(identifier: RecordIdentifier | { type: string }): RelationshipsSchema;
12
12
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ember-data/store",
3
- "version": "4.2.0-beta.0",
3
+ "version": "4.3.0",
4
4
  "description": "The default blueprint for ember-cli addons.",
5
5
  "keywords": [
6
6
  "ember-addon"
@@ -17,41 +17,41 @@
17
17
  "start": "ember serve"
18
18
  },
19
19
  "dependencies": {
20
- "@ember-data/canary-features": "4.2.0-beta.0",
21
- "@ember-data/private-build-infra": "4.2.0-beta.0",
20
+ "@ember-data/canary-features": "4.3.0",
21
+ "@ember-data/private-build-infra": "4.3.0",
22
22
  "@ember/string": "^3.0.0",
23
23
  "@glimmer/tracking": "^1.0.4",
24
24
  "ember-auto-import": "^2.2.4",
25
25
  "ember-cached-decorator-polyfill": "^0.1.4",
26
- "ember-cli-babel": "^7.26.6",
26
+ "ember-cli-babel": "^7.26.11",
27
27
  "ember-cli-path-utils": "^1.0.0",
28
- "ember-cli-typescript": "^4.1.0"
28
+ "ember-cli-typescript": "^5.0.0"
29
29
  },
30
30
  "devDependencies": {
31
- "@ember-data/unpublished-test-infra": "4.2.0-beta.0",
31
+ "@ember-data/unpublished-test-infra": "4.3.0",
32
32
  "@ember/optional-features": "^2.0.0",
33
33
  "@ember/test-helpers": "^2.6.0",
34
- "@types/ember": "^3.16.5",
35
- "@types/rsvp": "^4.0.3",
34
+ "@types/ember": "^4.0.0",
35
+ "@types/rsvp": "^4.0.4",
36
36
  "broccoli-asset-rev": "^3.0.0",
37
- "ember-cli": "~3.26.1",
37
+ "ember-cli": "~4.1.1",
38
38
  "ember-cli-dependency-checker": "^3.2.0",
39
- "ember-cli-htmlbars": "^5.1.2",
39
+ "ember-cli-htmlbars": "^6.0.1",
40
40
  "ember-cli-inject-live-reload": "^2.0.2",
41
41
  "ember-cli-sri": "^2.1.1",
42
42
  "ember-cli-terser": "~4.0.1",
43
43
  "ember-disable-prototype-extensions": "^1.1.3",
44
44
  "ember-export-application-global": "^2.0.1",
45
45
  "ember-load-initializers": "^2.1.1",
46
- "ember-maybe-import-regenerator": "^0.1.6",
46
+ "ember-maybe-import-regenerator": "^1.0.0",
47
47
  "ember-qunit": "^5.1.5",
48
- "ember-resolver": "^8.0.0",
49
- "ember-source": "~3.28.6",
48
+ "ember-resolver": "^8.0.3",
49
+ "ember-source": "~4.3.0",
50
50
  "ember-source-channel-url": "^3.0.0",
51
- "ember-try": "^1.4.0",
51
+ "ember-try": "^2.0.0",
52
52
  "loader.js": "^4.7.0",
53
- "qunit": "^2.15.0",
54
- "qunit-dom": "^1.6.0",
53
+ "qunit": "^2.17.0",
54
+ "qunit-dom": "^2.0.0",
55
55
  "webpack": "^5.37.1"
56
56
  },
57
57
  "engines": {
@@ -1,92 +0,0 @@
1
- import { deprecate } from '@ember/debug';
2
- import Evented from '@ember/object/evented';
3
- import Mixin from '@ember/object/mixin';
4
- import { DEBUG } from '@glimmer/env';
5
-
6
- import { DEPRECATE_EVENTED_API_USAGE } from '@ember-data/private-build-infra/deprecations';
7
-
8
- /**
9
- @module @ember-data/store
10
- */
11
-
12
- let INSTANCE_DEPRECATIONS;
13
- let lookupDeprecations;
14
- let DeprecatedEvented;
15
-
16
- if (DEBUG) {
17
- INSTANCE_DEPRECATIONS = new WeakMap();
18
-
19
- lookupDeprecations = function lookupInstanceDrecations(instance) {
20
- let deprecations = INSTANCE_DEPRECATIONS.get(instance);
21
-
22
- if (!deprecations) {
23
- deprecations = {};
24
- INSTANCE_DEPRECATIONS.set(instance, deprecations);
25
- }
26
-
27
- return deprecations;
28
- };
29
-
30
- /**
31
- * `DeprecatedEvented` is a mixin that proxies to the `Ember.Evented`
32
- * mixin while logging deprecations. It is used by classes that were previously instrumented with
33
- * Evented whose evented APIs are now deprecated.
34
- *
35
- * @class DeprecatedEvented
36
- * @private
37
- * @uses Ember.Evented
38
- */
39
- DeprecatedEvented = Mixin.create(Evented, {
40
- _has(name) {
41
- return Evented.mixins[0].properties.has.call(this, name);
42
- },
43
-
44
- _on() {
45
- return Evented.mixins[0].properties.on.call(this, ...arguments);
46
- },
47
-
48
- _deprecateEvented(eventName) {
49
- let deprecations = lookupDeprecations(this);
50
- const _deprecationData = this._getDeprecatedEventedInfo ? `on ${this._getDeprecatedEventedInfo()}` : '';
51
- const deprecationMessage = _deprecationData ? `Called ${eventName} ${_deprecationData}` : eventName;
52
- deprecate(deprecationMessage, deprecations[eventName], {
53
- id: 'ember-data:evented-api-usage',
54
- until: '4.0',
55
- url: 'https://deprecations.emberjs.com/ember-data/v3.x/#deprecatingrecordlifecycleeventmethods',
56
- for: '@ember-data/model',
57
- since: {
58
- available: '3.12',
59
- enabled: '3.12',
60
- },
61
- });
62
- deprecations[eventName] = true;
63
- },
64
-
65
- has(name) {
66
- this._deprecateEvented(name);
67
- return this._super(...arguments);
68
- },
69
-
70
- off(name, target, method) {
71
- this._deprecateEvented(name);
72
- return this._super(...arguments);
73
- },
74
-
75
- on(name, target, method) {
76
- this._deprecateEvented(name);
77
- return this._super(...arguments);
78
- },
79
-
80
- one(name, target, method) {
81
- this._deprecateEvented(name);
82
- return this._super(...arguments);
83
- },
84
-
85
- trigger(name) {
86
- this._deprecateEvented(name);
87
- return this._super(...arguments);
88
- },
89
- });
90
- }
91
-
92
- export default DEPRECATE_EVENTED_API_USAGE ? (DEBUG ? DeprecatedEvented : Evented) : {};