@ember-data/store 4.9.0-alpha.6 → 4.9.0-beta.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.
- package/LICENSE.md +3 -1
- package/addon/-private/caches/identifier-cache.ts +9 -7
- package/addon/-private/caches/instance-cache.ts +18 -13
- package/addon/-private/legacy-model-support/schema-definition-service.ts +32 -24
- package/addon/-private/managers/record-array-manager.ts +8 -9
- package/addon/-private/managers/record-data-store-wrapper.ts +17 -13
- package/addon/-private/managers/record-notification-manager.ts +5 -3
- package/addon/-private/network/fetch-manager.ts +2 -2
- package/addon/-private/network/snapshot.ts +2 -2
- package/addon/-private/proxies/promise-proxies.ts +35 -7
- package/addon/-private/record-arrays/identifier-array.ts +13 -10
- package/addon/-private/store-service.ts +43 -38
- package/index.js +1 -1
- package/package.json +36 -44
- package/addon/-debug/index.js +0 -69
- package/config/environment.js +0 -5
package/LICENSE.md
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
The MIT License (MIT)
|
|
2
2
|
|
|
3
|
-
Copyright (
|
|
3
|
+
Copyright (C) 2017-2022 Ember.js contributors
|
|
4
|
+
Portions Copyright (C) 2011-2017 Tilde, Inc. and contributors.
|
|
5
|
+
Portions Copyright (C) 2011 LivingSocial Inc.
|
|
4
6
|
|
|
5
7
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
6
8
|
|
|
@@ -266,14 +266,16 @@ export class IdentifierCache {
|
|
|
266
266
|
// one level up
|
|
267
267
|
keyOptions.lid.set(identifier.lid, identifier);
|
|
268
268
|
|
|
269
|
-
if (LOG_IDENTIFIERS
|
|
270
|
-
|
|
271
|
-
console.log(`Identifiers: generated ${String(identifier)} for`, resource);
|
|
272
|
-
if (resource[DEBUG_IDENTIFIER_BUCKET]) {
|
|
269
|
+
if (LOG_IDENTIFIERS) {
|
|
270
|
+
if (shouldGenerate) {
|
|
273
271
|
// eslint-disable-next-line no-console
|
|
274
|
-
console.
|
|
275
|
-
|
|
276
|
-
|
|
272
|
+
console.log(`Identifiers: generated ${String(identifier)} for`, resource);
|
|
273
|
+
if (resource[DEBUG_IDENTIFIER_BUCKET]) {
|
|
274
|
+
// eslint-disable-next-line no-console
|
|
275
|
+
console.trace(
|
|
276
|
+
`[WARNING] Identifiers: generated a new identifier from a previously used identifier. This is likely a bug.`
|
|
277
|
+
);
|
|
278
|
+
}
|
|
277
279
|
}
|
|
278
280
|
}
|
|
279
281
|
}
|
|
@@ -84,8 +84,10 @@ export function recordIdentifierFor(record: RecordInstance): StableRecordIdentif
|
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
export function setRecordIdentifier(record: RecordInstance, identifier: StableRecordIdentifier): void {
|
|
87
|
-
if (DEBUG
|
|
88
|
-
|
|
87
|
+
if (DEBUG) {
|
|
88
|
+
if (RecordCache.has(record) && RecordCache.get(record) !== identifier) {
|
|
89
|
+
throw new Error(`${String(record)} was already assigned an identifier`);
|
|
90
|
+
}
|
|
89
91
|
}
|
|
90
92
|
|
|
91
93
|
/*
|
|
@@ -260,8 +262,8 @@ export class InstanceCache {
|
|
|
260
262
|
getRecordData(identifier: StableRecordIdentifier): RecordData {
|
|
261
263
|
let recordData = this.__instances.recordData.get(identifier);
|
|
262
264
|
|
|
263
|
-
if (
|
|
264
|
-
if (
|
|
265
|
+
if (DEPRECATE_V1CACHE_STORE_APIS) {
|
|
266
|
+
if (!recordData && this.store.createRecordDataFor.length > 2) {
|
|
265
267
|
deprecate(
|
|
266
268
|
`Store.createRecordDataFor(<type>, <id>, <lid>, <storeWrapper>) has been deprecated in favor of Store.createRecordDataFor(<identifier>, <storeWrapper>)`,
|
|
267
269
|
false,
|
|
@@ -285,19 +287,22 @@ export class InstanceCache {
|
|
|
285
287
|
recordData = this.__cacheManager =
|
|
286
288
|
this.__cacheManager || new NonSingletonRecordDataManager(this.store, recordDataInstance, identifier);
|
|
287
289
|
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
if (!recordData) {
|
|
294
|
+
let recordDataInstance = this.store.createRecordDataFor(identifier, this._storeWrapper);
|
|
295
|
+
if (DEPRECATE_V1_RECORD_DATA) {
|
|
296
|
+
recordData = new NonSingletonRecordDataManager(this.store, recordDataInstance, identifier);
|
|
288
297
|
} else {
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
recordData
|
|
298
|
+
if (DEBUG) {
|
|
299
|
+
recordData = this.__cacheManager = this.__cacheManager || new SingletonRecordDataManager();
|
|
300
|
+
(recordData as SingletonRecordDataManager)._addRecordData(identifier, recordDataInstance as RecordData);
|
|
292
301
|
} else {
|
|
293
|
-
|
|
294
|
-
recordData = this.__cacheManager = this.__cacheManager || new SingletonRecordDataManager();
|
|
295
|
-
(recordData as SingletonRecordDataManager)._addRecordData(identifier, recordDataInstance as RecordData);
|
|
296
|
-
} else {
|
|
297
|
-
recordData = recordDataInstance as RecordData;
|
|
298
|
-
}
|
|
302
|
+
recordData = recordDataInstance as RecordData;
|
|
299
303
|
}
|
|
300
304
|
}
|
|
305
|
+
|
|
301
306
|
setRecordDataFor(identifier, recordData);
|
|
302
307
|
|
|
303
308
|
this.__instances.recordData.set(identifier, recordData);
|
|
@@ -39,18 +39,22 @@ export class DSModelSchemaDefinitionService {
|
|
|
39
39
|
// Following the existing RD implementation
|
|
40
40
|
attributesDefinitionFor(identifier: RecordIdentifier | { type: string }): AttributesSchema {
|
|
41
41
|
let modelName, attributes;
|
|
42
|
-
if (DEPRECATE_STRING_ARG_SCHEMAS
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
42
|
+
if (DEPRECATE_STRING_ARG_SCHEMAS) {
|
|
43
|
+
if (typeof identifier === 'string') {
|
|
44
|
+
deprecate(
|
|
45
|
+
`attributesDefinitionFor expects either a record identifier or an argument of shape { type: string }, received a string.`,
|
|
46
|
+
false,
|
|
47
|
+
{
|
|
48
|
+
id: 'ember-data:deprecate-string-arg-schemas',
|
|
49
|
+
for: 'ember-data',
|
|
50
|
+
until: '5.0',
|
|
51
|
+
since: { enabled: '4.5', available: '4.5' },
|
|
52
|
+
}
|
|
53
|
+
);
|
|
54
|
+
modelName = identifier;
|
|
55
|
+
} else {
|
|
56
|
+
modelName = identifier.type;
|
|
57
|
+
}
|
|
54
58
|
} else {
|
|
55
59
|
modelName = identifier.type;
|
|
56
60
|
}
|
|
@@ -72,18 +76,22 @@ export class DSModelSchemaDefinitionService {
|
|
|
72
76
|
// Following the existing RD implementation
|
|
73
77
|
relationshipsDefinitionFor(identifier: RecordIdentifier | { type: string }): RelationshipsSchema {
|
|
74
78
|
let modelName, relationships;
|
|
75
|
-
if (DEPRECATE_STRING_ARG_SCHEMAS
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
79
|
+
if (DEPRECATE_STRING_ARG_SCHEMAS) {
|
|
80
|
+
if (typeof identifier === 'string') {
|
|
81
|
+
deprecate(
|
|
82
|
+
`relationshipsDefinitionFor expects either a record identifier or an argument of shape { type: string }, received a string.`,
|
|
83
|
+
false,
|
|
84
|
+
{
|
|
85
|
+
id: 'ember-data:deprecate-string-arg-schemas',
|
|
86
|
+
for: 'ember-data',
|
|
87
|
+
until: '5.0',
|
|
88
|
+
since: { enabled: '4.5', available: '4.5' },
|
|
89
|
+
}
|
|
90
|
+
);
|
|
91
|
+
modelName = identifier;
|
|
92
|
+
} else {
|
|
93
|
+
modelName = identifier.type;
|
|
94
|
+
}
|
|
87
95
|
} else {
|
|
88
96
|
modelName = identifier.type;
|
|
89
97
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
@module @ember-data/store
|
|
3
3
|
*/
|
|
4
|
+
import { addToTransaction } from '@ember-data/tracking/-private';
|
|
4
5
|
import type { CollectionResourceDocument } from '@ember-data/types/q/ember-data-json-api';
|
|
5
6
|
import type { StableRecordIdentifier } from '@ember-data/types/q/identifier';
|
|
6
7
|
import type { Dict } from '@ember-data/types/q/utils';
|
|
@@ -60,7 +61,7 @@ export function fastPush<T>(target: T[], source: T[]) {
|
|
|
60
61
|
let newLength = source.length;
|
|
61
62
|
while (newLength - startLength > SLICE_BATCH_SIZE) {
|
|
62
63
|
// eslint-disable-next-line prefer-spread
|
|
63
|
-
target.push.apply(target, source.slice(startLength, SLICE_BATCH_SIZE));
|
|
64
|
+
target.push.apply(target, source.slice(startLength, startLength + SLICE_BATCH_SIZE));
|
|
64
65
|
startLength += SLICE_BATCH_SIZE;
|
|
65
66
|
}
|
|
66
67
|
// eslint-disable-next-line prefer-spread
|
|
@@ -167,14 +168,16 @@ class RecordArrayManager {
|
|
|
167
168
|
return array;
|
|
168
169
|
}
|
|
169
170
|
|
|
170
|
-
dirtyArray(array: IdentifierArray): void {
|
|
171
|
+
dirtyArray(array: IdentifierArray, delta: number): void {
|
|
171
172
|
if (array === FAKE_ARR) {
|
|
172
173
|
return;
|
|
173
174
|
}
|
|
174
175
|
let tag = array[IDENTIFIER_ARRAY_TAG];
|
|
175
176
|
if (!tag.shouldReset) {
|
|
176
177
|
tag.shouldReset = true;
|
|
177
|
-
tag
|
|
178
|
+
addToTransaction(tag);
|
|
179
|
+
} else if (delta > 0 && tag.t) {
|
|
180
|
+
addToTransaction(tag);
|
|
178
181
|
}
|
|
179
182
|
}
|
|
180
183
|
|
|
@@ -257,9 +260,7 @@ class RecordArrayManager {
|
|
|
257
260
|
} else {
|
|
258
261
|
changes.set(identifier, 'add');
|
|
259
262
|
|
|
260
|
-
|
|
261
|
-
this.dirtyArray(array);
|
|
262
|
-
}
|
|
263
|
+
this.dirtyArray(array, changes.size);
|
|
263
264
|
}
|
|
264
265
|
});
|
|
265
266
|
}
|
|
@@ -275,9 +276,7 @@ class RecordArrayManager {
|
|
|
275
276
|
} else {
|
|
276
277
|
changes.set(identifier, 'del');
|
|
277
278
|
|
|
278
|
-
|
|
279
|
-
this.dirtyArray(array);
|
|
280
|
-
}
|
|
279
|
+
this.dirtyArray(array, changes.size);
|
|
281
280
|
}
|
|
282
281
|
});
|
|
283
282
|
}
|
|
@@ -297,19 +297,23 @@ class LegacyWrapper implements LegacyRecordDataStoreWrapper {
|
|
|
297
297
|
disconnectRecord(type: StableRecordIdentifier): void;
|
|
298
298
|
disconnectRecord(type: string | StableRecordIdentifier, id?: string | null, lid?: string | null): void {
|
|
299
299
|
let identifier: StableRecordIdentifier;
|
|
300
|
-
if (DEPRECATE_V1CACHE_STORE_APIS
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
300
|
+
if (DEPRECATE_V1CACHE_STORE_APIS) {
|
|
301
|
+
if (typeof type === 'string') {
|
|
302
|
+
deprecate(
|
|
303
|
+
`StoreWrapper.disconnectRecord(<type>) has been deprecated in favor of StoreWrapper.disconnectRecord(<identifier>)`,
|
|
304
|
+
false,
|
|
305
|
+
{
|
|
306
|
+
id: 'ember-data:deprecate-v1cache-store-apis',
|
|
307
|
+
for: 'ember-data',
|
|
308
|
+
until: '5.0',
|
|
309
|
+
since: { enabled: '4.7', available: '4.7' },
|
|
310
|
+
}
|
|
311
|
+
);
|
|
312
|
+
let resource = constructResource(type, id, lid) as RecordIdentifier;
|
|
313
|
+
identifier = this.identifierCache.peekRecordIdentifier(resource)!;
|
|
314
|
+
} else {
|
|
315
|
+
identifier = type as StableRecordIdentifier;
|
|
316
|
+
}
|
|
313
317
|
} else {
|
|
314
318
|
identifier = type as StableRecordIdentifier;
|
|
315
319
|
}
|
|
@@ -24,9 +24,11 @@ export interface NotificationCallback {
|
|
|
24
24
|
// TODO this isn't importable anyway, remove and use a map on the manager?
|
|
25
25
|
export function unsubscribe(token: UnsubscribeToken) {
|
|
26
26
|
let identifier = Tokens.get(token);
|
|
27
|
-
if (LOG_NOTIFICATIONS
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
if (LOG_NOTIFICATIONS) {
|
|
28
|
+
if (!identifier) {
|
|
29
|
+
// eslint-disable-next-line no-console
|
|
30
|
+
console.log('Passed unknown unsubscribe token to unsubscribe', identifier);
|
|
31
|
+
}
|
|
30
32
|
}
|
|
31
33
|
if (identifier) {
|
|
32
34
|
Tokens.delete(token);
|
|
@@ -5,7 +5,7 @@ import { assert, deprecate, warn } from '@ember/debug';
|
|
|
5
5
|
import { _backburner as emberBackburner } from '@ember/runloop';
|
|
6
6
|
import { DEBUG } from '@glimmer/env';
|
|
7
7
|
|
|
8
|
-
import { importSync } from '@embroider/macros';
|
|
8
|
+
import { importSync, isDevelopingApp } from '@embroider/macros';
|
|
9
9
|
import { default as RSVP, resolve } from 'rsvp';
|
|
10
10
|
|
|
11
11
|
import { HAS_RECORD_DATA_PACKAGE } from '@ember-data/private-build-infra';
|
|
@@ -147,7 +147,7 @@ export default class FetchManager {
|
|
|
147
147
|
|
|
148
148
|
scheduleFetch(identifier: StableExistingRecordIdentifier, options: FindOptions): Promise<StableRecordIdentifier> {
|
|
149
149
|
// TODO Probably the store should pass in the query object
|
|
150
|
-
let shouldTrace =
|
|
150
|
+
let shouldTrace = isDevelopingApp() && this._store.generateStackTracesForTrackedRequests;
|
|
151
151
|
|
|
152
152
|
let query: FindRecordQuery = {
|
|
153
153
|
op: 'findRecord',
|
|
@@ -7,8 +7,8 @@ import { importSync } from '@embroider/macros';
|
|
|
7
7
|
|
|
8
8
|
import { HAS_RECORD_DATA_PACKAGE } from '@ember-data/private-build-infra';
|
|
9
9
|
import { DEPRECATE_SNAPSHOT_MODEL_CLASS_ACCESS } from '@ember-data/private-build-infra/deprecations';
|
|
10
|
-
import type BelongsToRelationship from '@ember-data/record-data
|
|
11
|
-
import type ManyRelationship from '@ember-data/record-data
|
|
10
|
+
import type BelongsToRelationship from '@ember-data/record-data/-private/relationships/state/belongs-to';
|
|
11
|
+
import type ManyRelationship from '@ember-data/record-data/-private/relationships/state/has-many';
|
|
12
12
|
import type { StableRecordIdentifier } from '@ember-data/types/q/identifier';
|
|
13
13
|
import type { OptionsHash } from '@ember-data/types/q/minimum-serializer-interface';
|
|
14
14
|
import type { ChangedAttributesHash } from '@ember-data/types/q/record-data';
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { deprecate } from '@ember/debug';
|
|
2
|
+
import { get } from '@ember/object';
|
|
2
3
|
import type ComputedProperty from '@ember/object/computed';
|
|
3
4
|
import { reads } from '@ember/object/computed';
|
|
5
|
+
import { DEBUG } from '@glimmer/env';
|
|
4
6
|
|
|
5
7
|
import { resolve } from 'rsvp';
|
|
6
8
|
|
|
@@ -105,6 +107,7 @@ function _promiseArray<I, T extends EmberArrayLike<I>>(promise: Promise<T>, labe
|
|
|
105
107
|
|
|
106
108
|
// constructor is accessed in some internals but not including it in the copyright for the deprecation
|
|
107
109
|
const ALLOWABLE_METHODS = ['constructor', 'then', 'catch', 'finally'];
|
|
110
|
+
const ALLOWABLE_PROPS = ['__ec_yieldable__', '__ec_cancel__'];
|
|
108
111
|
const PROXIED_ARRAY_PROPS = [
|
|
109
112
|
'length',
|
|
110
113
|
'[]',
|
|
@@ -123,11 +126,17 @@ const PROXIED_OBJECT_PROPS = ['content', 'isPending', 'isSettled', 'isRejected',
|
|
|
123
126
|
|
|
124
127
|
export function promiseArray<I, T extends EmberArrayLike<I>>(promise: Promise<T>): PromiseArray<I, T> {
|
|
125
128
|
const promiseObjectProxy: PromiseArray<I, T> = _promiseArray(promise);
|
|
129
|
+
if (!DEBUG) {
|
|
130
|
+
return promiseObjectProxy;
|
|
131
|
+
}
|
|
126
132
|
const handler = {
|
|
127
|
-
get(target: object, prop: string, receiver
|
|
133
|
+
get(target: object, prop: string, receiver: object): unknown {
|
|
128
134
|
if (typeof prop === 'symbol') {
|
|
129
135
|
return Reflect.get(target, prop, receiver);
|
|
130
136
|
}
|
|
137
|
+
if (ALLOWABLE_PROPS.includes(prop)) {
|
|
138
|
+
return receiver[prop];
|
|
139
|
+
}
|
|
131
140
|
if (!ALLOWABLE_METHODS.includes(prop)) {
|
|
132
141
|
deprecate(
|
|
133
142
|
`Accessing ${prop} on this PromiseArray is deprecated. The return type is being changed from PromiseArray to a Promise. The only available methods to access on this promise are .then, .catch and .finally`,
|
|
@@ -160,13 +169,30 @@ export function promiseArray<I, T extends EmberArrayLike<I>>(promise: Promise<T>
|
|
|
160
169
|
return new Proxy(promiseObjectProxy, handler);
|
|
161
170
|
}
|
|
162
171
|
|
|
172
|
+
const ProxySymbolString = String(Symbol.for('PROXY_CONTENT'));
|
|
173
|
+
|
|
163
174
|
export function promiseObject<T>(promise: Promise<T>): PromiseObjectProxy<T> {
|
|
164
175
|
const promiseObjectProxy: PromiseObjectProxy<T> = _promiseObject(promise);
|
|
176
|
+
if (!DEBUG) {
|
|
177
|
+
return promiseObjectProxy;
|
|
178
|
+
}
|
|
165
179
|
const handler = {
|
|
166
|
-
get(target: object, prop: string, receiver
|
|
180
|
+
get(target: object, prop: string, receiver: object): unknown {
|
|
167
181
|
if (typeof prop === 'symbol') {
|
|
182
|
+
if (String(prop) === ProxySymbolString) {
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
168
185
|
return Reflect.get(target, prop, receiver);
|
|
169
186
|
}
|
|
187
|
+
|
|
188
|
+
if (prop === 'constructor') {
|
|
189
|
+
return target.constructor;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
if (ALLOWABLE_PROPS.includes(prop)) {
|
|
193
|
+
return receiver[prop];
|
|
194
|
+
}
|
|
195
|
+
|
|
170
196
|
if (!ALLOWABLE_METHODS.includes(prop)) {
|
|
171
197
|
deprecate(
|
|
172
198
|
`Accessing ${prop} on this PromiseObject is deprecated. The return type is being changed from PromiseObject to a Promise. The only available methods to access on this promise are .then, .catch and .finally`,
|
|
@@ -181,15 +207,17 @@ export function promiseObject<T>(promise: Promise<T>): PromiseObjectProxy<T> {
|
|
|
181
207
|
},
|
|
182
208
|
}
|
|
183
209
|
);
|
|
210
|
+
} else {
|
|
211
|
+
return (target[prop] as () => unknown).bind(target);
|
|
184
212
|
}
|
|
185
213
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
return value.bind(target);
|
|
214
|
+
if (PROXIED_OBJECT_PROPS.includes(prop)) {
|
|
215
|
+
return target[prop];
|
|
189
216
|
}
|
|
190
217
|
|
|
191
|
-
|
|
192
|
-
|
|
218
|
+
const value: unknown = get(target, prop);
|
|
219
|
+
if (value && typeof value === 'function' && typeof value.bind === 'function') {
|
|
220
|
+
return value.bind(receiver);
|
|
193
221
|
}
|
|
194
222
|
|
|
195
223
|
return undefined;
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
DEPRECATE_PROMISE_PROXIES,
|
|
16
16
|
DEPRECATE_SNAPSHOT_MODEL_CLASS_ACCESS,
|
|
17
17
|
} from '@ember-data/private-build-infra/deprecations';
|
|
18
|
+
import { addToTransaction, subscribe } from '@ember-data/tracking/-private';
|
|
18
19
|
import { Links, PaginationLinks } from '@ember-data/types/q/ember-data-json-api';
|
|
19
20
|
import type { StableRecordIdentifier } from '@ember-data/types/q/identifier';
|
|
20
21
|
import type { RecordInstance } from '@ember-data/types/q/record-instance';
|
|
@@ -76,6 +77,7 @@ function convertToInt(prop: KeyType): number | null {
|
|
|
76
77
|
class Tag {
|
|
77
78
|
@tracked ref = null;
|
|
78
79
|
shouldReset: boolean = false;
|
|
80
|
+
t = false;
|
|
79
81
|
}
|
|
80
82
|
|
|
81
83
|
type ProxiedMethod = (...args: unknown[]) => unknown;
|
|
@@ -219,27 +221,28 @@ class IdentifierArray {
|
|
|
219
221
|
let index = convertToInt(prop);
|
|
220
222
|
if (_TAG.shouldReset && (index !== null || SYNC_PROPS.has(prop) || isArrayGetter(prop))) {
|
|
221
223
|
options.manager._syncArray(receiver as unknown as IdentifierArray);
|
|
224
|
+
_TAG.t = false;
|
|
222
225
|
_TAG.shouldReset = false;
|
|
223
226
|
}
|
|
224
227
|
|
|
225
228
|
if (index !== null) {
|
|
226
229
|
const identifier = target[index];
|
|
227
230
|
if (!transaction) {
|
|
228
|
-
_TAG
|
|
231
|
+
subscribe(_TAG);
|
|
229
232
|
}
|
|
230
233
|
return identifier && store._instanceCache.getRecord(identifier);
|
|
231
234
|
}
|
|
232
235
|
|
|
233
|
-
if (prop === 'meta') return _TAG
|
|
234
|
-
if (prop === 'links') return _TAG
|
|
235
|
-
if (prop === '[]') return _TAG
|
|
236
|
+
if (prop === 'meta') return subscribe(_TAG), PrivateState.meta;
|
|
237
|
+
if (prop === 'links') return subscribe(_TAG), PrivateState.links;
|
|
238
|
+
if (prop === '[]') return subscribe(_TAG), receiver;
|
|
236
239
|
|
|
237
240
|
if (isArrayGetter(prop)) {
|
|
238
241
|
let fn = boundFns.get(prop);
|
|
239
242
|
|
|
240
243
|
if (fn === undefined) {
|
|
241
244
|
fn = function () {
|
|
242
|
-
_TAG
|
|
245
|
+
subscribe(_TAG);
|
|
243
246
|
// array functions must run through Reflect to work properly
|
|
244
247
|
// binding via other means will not work.
|
|
245
248
|
transaction = true;
|
|
@@ -270,7 +273,7 @@ class IdentifierArray {
|
|
|
270
273
|
transaction = true;
|
|
271
274
|
let result = Reflect.apply(target[prop] as ProxiedMethod, receiver, args) as unknown;
|
|
272
275
|
self[MUTATE]!(prop as string, args, result);
|
|
273
|
-
_TAG
|
|
276
|
+
addToTransaction(_TAG);
|
|
274
277
|
// TODO handle cache updates
|
|
275
278
|
transaction = false;
|
|
276
279
|
return result;
|
|
@@ -300,7 +303,7 @@ class IdentifierArray {
|
|
|
300
303
|
|
|
301
304
|
if (typeof outcome === 'function') {
|
|
302
305
|
fn = function () {
|
|
303
|
-
_TAG
|
|
306
|
+
subscribe(_TAG);
|
|
304
307
|
// array functions must run through Reflect to work properly
|
|
305
308
|
// binding via other means will not work.
|
|
306
309
|
return Reflect.apply(outcome as ProxiedMethod, receiver, arguments) as unknown;
|
|
@@ -310,7 +313,7 @@ class IdentifierArray {
|
|
|
310
313
|
return fn;
|
|
311
314
|
}
|
|
312
315
|
|
|
313
|
-
return _TAG
|
|
316
|
+
return subscribe(_TAG), outcome;
|
|
314
317
|
}
|
|
315
318
|
|
|
316
319
|
return target[prop];
|
|
@@ -320,7 +323,7 @@ class IdentifierArray {
|
|
|
320
323
|
if (prop === 'length') {
|
|
321
324
|
if (!transaction && value === 0) {
|
|
322
325
|
transaction = true;
|
|
323
|
-
_TAG
|
|
326
|
+
addToTransaction(_TAG);
|
|
324
327
|
Reflect.set(target, prop, value);
|
|
325
328
|
self[MUTATE]!('length 0', []);
|
|
326
329
|
transaction = false;
|
|
@@ -359,7 +362,7 @@ class IdentifierArray {
|
|
|
359
362
|
(target as unknown as Record<KeyType, unknown>)[index] = newIdentifier;
|
|
360
363
|
if (!transaction) {
|
|
361
364
|
self[MUTATE]!('replace cell', [index, original, newIdentifier]);
|
|
362
|
-
_TAG
|
|
365
|
+
addToTransaction(_TAG);
|
|
363
366
|
}
|
|
364
367
|
|
|
365
368
|
return true;
|
|
@@ -73,6 +73,7 @@ import promiseRecord from './utils/promise-record';
|
|
|
73
73
|
|
|
74
74
|
export { storeFor };
|
|
75
75
|
|
|
76
|
+
// hello world
|
|
76
77
|
type RecordDataConstruct = typeof RecordDataClass;
|
|
77
78
|
let _RecordData: RecordDataConstruct | undefined;
|
|
78
79
|
|
|
@@ -2397,30 +2398,32 @@ class Store extends Service {
|
|
|
2397
2398
|
// a cycle we can't easily fix (or clearly pin point) at present.
|
|
2398
2399
|
//
|
|
2399
2400
|
// it can be reproduced in partner tests by running
|
|
2400
|
-
// node ./scripts/packages-for-commit.js &&
|
|
2401
|
+
// node ./scripts/packages-for-commit.js && pnpm test-external:ember-observer
|
|
2401
2402
|
if (_RecordData === undefined) {
|
|
2402
2403
|
_RecordData = (
|
|
2403
2404
|
importSync('@ember-data/record-data/-private') as typeof import('@ember-data/record-data/-private')
|
|
2404
2405
|
).RecordData;
|
|
2405
2406
|
}
|
|
2406
2407
|
|
|
2407
|
-
if (DEPRECATE_V1CACHE_STORE_APIS
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2408
|
+
if (DEPRECATE_V1CACHE_STORE_APIS) {
|
|
2409
|
+
if (arguments.length === 4) {
|
|
2410
|
+
deprecate(
|
|
2411
|
+
`Store.createRecordDataFor(<type>, <id>, <lid>, <storeWrapper>) has been deprecated in favor of Store.createRecordDataFor(<identifier>, <storeWrapper>)`,
|
|
2412
|
+
false,
|
|
2413
|
+
{
|
|
2414
|
+
id: 'ember-data:deprecate-v1cache-store-apis',
|
|
2415
|
+
for: 'ember-data',
|
|
2416
|
+
until: '5.0',
|
|
2417
|
+
since: { enabled: '4.7', available: '4.7' },
|
|
2418
|
+
}
|
|
2419
|
+
);
|
|
2420
|
+
identifier = this.identifierCache.getOrCreateRecordIdentifier({
|
|
2421
|
+
type: arguments[0],
|
|
2422
|
+
id: arguments[1],
|
|
2423
|
+
lid: arguments[2],
|
|
2424
|
+
});
|
|
2425
|
+
storeWrapper = arguments[3];
|
|
2426
|
+
}
|
|
2424
2427
|
}
|
|
2425
2428
|
|
|
2426
2429
|
this.__private_singleton_recordData = this.__private_singleton_recordData || new _RecordData(storeWrapper);
|
|
@@ -2850,26 +2853,28 @@ function extractIdentifierFromRecord(
|
|
|
2850
2853
|
}
|
|
2851
2854
|
const extract = isForV1 ? recordDataFor : recordIdentifierFor;
|
|
2852
2855
|
|
|
2853
|
-
if (DEPRECATE_PROMISE_PROXIES
|
|
2854
|
-
|
|
2855
|
-
|
|
2856
|
-
|
|
2857
|
-
|
|
2858
|
-
|
|
2859
|
-
|
|
2860
|
-
|
|
2861
|
-
|
|
2862
|
-
|
|
2863
|
-
|
|
2864
|
-
|
|
2865
|
-
|
|
2866
|
-
|
|
2867
|
-
|
|
2868
|
-
|
|
2869
|
-
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
2856
|
+
if (DEPRECATE_PROMISE_PROXIES) {
|
|
2857
|
+
if (isPromiseRecord(recordOrPromiseRecord)) {
|
|
2858
|
+
let content = recordOrPromiseRecord.content;
|
|
2859
|
+
assert(
|
|
2860
|
+
'You passed in a promise that did not originate from an EmberData relationship. You can only pass promises that come from a belongsTo or hasMany relationship to the get call.',
|
|
2861
|
+
content !== undefined
|
|
2862
|
+
);
|
|
2863
|
+
deprecate(
|
|
2864
|
+
`You passed in a PromiseProxy to a Relationship API that now expects a resolved value. await the value before setting it.`,
|
|
2865
|
+
false,
|
|
2866
|
+
{
|
|
2867
|
+
id: 'ember-data:deprecate-promise-proxies',
|
|
2868
|
+
until: '5.0',
|
|
2869
|
+
since: {
|
|
2870
|
+
enabled: '4.7',
|
|
2871
|
+
available: '4.7',
|
|
2872
|
+
},
|
|
2873
|
+
for: 'ember-data',
|
|
2874
|
+
}
|
|
2875
|
+
);
|
|
2876
|
+
return content ? extract(content) : null;
|
|
2877
|
+
}
|
|
2873
2878
|
}
|
|
2874
2879
|
|
|
2875
2880
|
return extract(recordOrPromiseRecord);
|
package/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ember-data/store",
|
|
3
|
-
"version": "4.9.0-
|
|
3
|
+
"version": "4.9.0-beta.0",
|
|
4
4
|
"description": "The core of EmberData. Provides the Store service which coordinates the cache with the network and presentation layers.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ember-addon"
|
|
@@ -13,57 +13,49 @@
|
|
|
13
13
|
"license": "MIT",
|
|
14
14
|
"author": "",
|
|
15
15
|
"directories": {},
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
"
|
|
16
|
+
"peerDependencies": {
|
|
17
|
+
"@ember-data/model": "workspace:4.9.0-alpha.6",
|
|
18
|
+
"@ember-data/record-data": "workspace:4.9.0-alpha.6",
|
|
19
|
+
"@ember-data/tracking": "workspace:4.9.0-alpha.6",
|
|
20
|
+
"@ember/string": "^3.0.0",
|
|
21
|
+
"@glimmer/tracking": "^1.1.2"
|
|
22
|
+
},
|
|
23
|
+
"peerDependenciesMeta": {
|
|
24
|
+
"@ember-data/record-data": {
|
|
25
|
+
"optional": true
|
|
26
|
+
},
|
|
27
|
+
"@ember-data/model": {
|
|
28
|
+
"optional": true
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"dependenciesMeta": {
|
|
32
|
+
"@ember-data/canary-features": {
|
|
33
|
+
"injected": true
|
|
34
|
+
},
|
|
35
|
+
"@ember-data/private-build-infra": {
|
|
36
|
+
"injected": true
|
|
37
|
+
}
|
|
19
38
|
},
|
|
20
39
|
"dependencies": {
|
|
21
|
-
"@ember-data/canary-features": "4.9.0-
|
|
22
|
-
"@ember-data/private-build-infra": "4.9.0-
|
|
23
|
-
"@
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"ember-
|
|
27
|
-
"ember-cached-decorator-polyfill": "^0.1.4",
|
|
28
|
-
"ember-cli-babel": "^7.26.11",
|
|
29
|
-
"ember-cli-path-utils": "^1.0.0",
|
|
30
|
-
"ember-cli-typescript": "^5.1.1"
|
|
40
|
+
"@ember-data/canary-features": "workspace:4.9.0-beta.0",
|
|
41
|
+
"@ember-data/private-build-infra": "workspace:4.9.0-beta.0",
|
|
42
|
+
"@embroider/macros": "^1.9.0",
|
|
43
|
+
"ember-auto-import": "^2.4.3",
|
|
44
|
+
"ember-cached-decorator-polyfill": "^1.0.1",
|
|
45
|
+
"ember-cli-babel": "^7.26.11"
|
|
31
46
|
},
|
|
32
47
|
"devDependencies": {
|
|
33
|
-
"@
|
|
34
|
-
"@
|
|
35
|
-
"
|
|
36
|
-
"@types/ember": "^4.0.1",
|
|
37
|
-
"@types/rsvp": "^4.0.4",
|
|
38
|
-
"broccoli-asset-rev": "^3.0.0",
|
|
39
|
-
"ember-cli": "~4.7.0",
|
|
40
|
-
"ember-cli-dependency-checker": "^3.3.1",
|
|
41
|
-
"ember-cli-htmlbars": "^6.1.1",
|
|
42
|
-
"ember-cli-inject-live-reload": "^2.1.0",
|
|
43
|
-
"ember-cli-sri": "^2.1.1",
|
|
44
|
-
"ember-cli-terser": "~4.0.2",
|
|
45
|
-
"ember-disable-prototype-extensions": "^1.1.3",
|
|
46
|
-
"ember-export-application-global": "^2.0.1",
|
|
47
|
-
"ember-load-initializers": "^2.1.2",
|
|
48
|
-
"ember-maybe-import-regenerator": "^1.0.0",
|
|
49
|
-
"ember-qunit": "^5.1.5",
|
|
50
|
-
"ember-resolver": "^8.0.3",
|
|
51
|
-
"ember-source": "~4.7.0",
|
|
52
|
-
"ember-source-channel-url": "^3.0.0",
|
|
53
|
-
"ember-try": "^2.0.0",
|
|
54
|
-
"loader.js": "^4.7.0",
|
|
55
|
-
"qunit": "^2.19.1",
|
|
56
|
-
"qunit-dom": "^2.0.0",
|
|
48
|
+
"@babel/core": "^7.19.6",
|
|
49
|
+
"@glimmer/component": "^1.1.2",
|
|
50
|
+
"ember-source": "~4.8.0",
|
|
57
51
|
"webpack": "^5.74.0"
|
|
58
52
|
},
|
|
59
53
|
"engines": {
|
|
60
54
|
"node": "^14.8.0 || 16.* || >= 18.*"
|
|
61
55
|
},
|
|
62
|
-
"ember-addon": {
|
|
63
|
-
"configPath": "tests/dummy/config"
|
|
64
|
-
},
|
|
56
|
+
"ember-addon": {},
|
|
65
57
|
"volta": {
|
|
66
|
-
"
|
|
67
|
-
|
|
68
|
-
|
|
58
|
+
"extends": "../../package.json"
|
|
59
|
+
},
|
|
60
|
+
"packageManager": "pnpm@7.14.1"
|
|
69
61
|
}
|
package/addon/-debug/index.js
DELETED
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
import { assert } from '@ember/debug';
|
|
2
|
-
import { DEBUG } from '@glimmer/env';
|
|
3
|
-
|
|
4
|
-
import { DEPRECATE_NON_EXPLICIT_POLYMORPHISM } from '@ember-data/private-build-infra/deprecations';
|
|
5
|
-
|
|
6
|
-
/*
|
|
7
|
-
Assert that `addedRecord` has a valid type so it can be added to the
|
|
8
|
-
relationship of the `record`.
|
|
9
|
-
|
|
10
|
-
The assert basically checks if the `addedRecord` can be added to the
|
|
11
|
-
relationship (specified via `relationshipMeta`) of the `record`.
|
|
12
|
-
|
|
13
|
-
This utility should only be used internally, as both record parameters must
|
|
14
|
-
be stable record identifiers and the `relationshipMeta` needs to be the meta
|
|
15
|
-
information about the relationship, retrieved via
|
|
16
|
-
`record.relationshipFor(key)`.
|
|
17
|
-
*/
|
|
18
|
-
let assertPolymorphicType;
|
|
19
|
-
|
|
20
|
-
if (DEBUG) {
|
|
21
|
-
let checkPolymorphic = function checkPolymorphic(modelClass, addedModelClass) {
|
|
22
|
-
if (modelClass.__isMixin) {
|
|
23
|
-
return (
|
|
24
|
-
modelClass.__mixin.detect(addedModelClass.PrototypeMixin) ||
|
|
25
|
-
// handle native class extension e.g. `class Post extends Model.extend(Commentable) {}`
|
|
26
|
-
modelClass.__mixin.detect(Object.getPrototypeOf(addedModelClass).PrototypeMixin)
|
|
27
|
-
);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
return addedModelClass.prototype instanceof modelClass || modelClass.detect(addedModelClass);
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
assertPolymorphicType = function assertPolymorphicType(parentIdentifier, parentDefinition, addedIdentifier, store) {
|
|
34
|
-
let asserted = false;
|
|
35
|
-
|
|
36
|
-
if (parentDefinition.inverseIsImplicit) {
|
|
37
|
-
return;
|
|
38
|
-
}
|
|
39
|
-
if (parentDefinition.isPolymorphic) {
|
|
40
|
-
let meta = store.getSchemaDefinitionService().relationshipsDefinitionFor(addedIdentifier)[
|
|
41
|
-
parentDefinition.inverseKey
|
|
42
|
-
];
|
|
43
|
-
if (meta?.options?.as) {
|
|
44
|
-
asserted = true;
|
|
45
|
-
assert(
|
|
46
|
-
`The schema for the relationship '${parentDefinition.inverseKey}' on '${addedIdentifier.type}' type does not implement '${parentDefinition.type}' and thus cannot be assigned to the '${parentDefinition.key}' relationship in '${parentIdentifier.type}'. The definition should specify 'as: "${parentDefinition.type}"' in options.`,
|
|
47
|
-
meta.options.as === parentDefinition.type
|
|
48
|
-
);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
if (DEPRECATE_NON_EXPLICIT_POLYMORPHISM && !asserted) {
|
|
53
|
-
store = store._store ? store._store : store; // allow usage with storeWrapper
|
|
54
|
-
let addedModelName = addedIdentifier.type;
|
|
55
|
-
let parentModelName = parentIdentifier.type;
|
|
56
|
-
let key = parentDefinition.key;
|
|
57
|
-
let relationshipModelName = parentDefinition.type;
|
|
58
|
-
let relationshipClass = store.modelFor(relationshipModelName);
|
|
59
|
-
let addedClass = store.modelFor(addedModelName);
|
|
60
|
-
|
|
61
|
-
let assertionMessage = `The '${addedModelName}' type does not implement '${relationshipModelName}' and thus cannot be assigned to the '${key}' relationship in '${parentModelName}'. Make it a descendant of '${relationshipModelName}' or use a mixin of the same name.`;
|
|
62
|
-
let isPolymorphic = checkPolymorphic(relationshipClass, addedClass);
|
|
63
|
-
|
|
64
|
-
assert(assertionMessage, isPolymorphic);
|
|
65
|
-
}
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
export { assertPolymorphicType };
|