ember-data-model-fragments 7.0.1 → 7.0.3
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/.release-plan.json +4 -4
- package/CHANGELOG.md +22 -0
- package/addon/attributes/array.js +3 -0
- package/addon/attributes/fragment-array.js +3 -0
- package/addon/attributes/fragment-owner.js +10 -1
- package/addon/attributes/fragment.js +4 -0
- package/addon/cache/fragment-state-manager.js +7 -5
- package/addon/fragment.js +7 -0
- package/package.json +1 -1
package/.release-plan.json
CHANGED
|
@@ -2,17 +2,17 @@
|
|
|
2
2
|
"solution": {
|
|
3
3
|
"ember-data-model-fragments": {
|
|
4
4
|
"impact": "patch",
|
|
5
|
-
"oldVersion": "7.0.
|
|
6
|
-
"newVersion": "7.0.
|
|
5
|
+
"oldVersion": "7.0.2",
|
|
6
|
+
"newVersion": "7.0.3",
|
|
7
7
|
"tagName": "latest",
|
|
8
8
|
"constraints": [
|
|
9
9
|
{
|
|
10
10
|
"impact": "patch",
|
|
11
|
-
"reason": "Appears in changelog section :
|
|
11
|
+
"reason": "Appears in changelog section :bug: Bug Fix"
|
|
12
12
|
}
|
|
13
13
|
],
|
|
14
14
|
"pkgJSONPath": "./package.json"
|
|
15
15
|
}
|
|
16
16
|
},
|
|
17
|
-
"description": "## Release (2026-02-
|
|
17
|
+
"description": "## Release (2026-02-27)\n\n* ember-data-model-fragments 7.0.3 (patch)\n\n#### :bug: Bug Fix\n* `ember-data-model-fragments`\n * [#514](https://github.com/adopted-ember-addons/ember-data-model-fragments/pull/514) Guard fragment access on destroyed/unloaded records ([@deanmarano](https://github.com/deanmarano))\n\n#### Committers: 1\n- Dean Marano ([@deanmarano](https://github.com/deanmarano))\n"
|
|
18
18
|
}
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## Release (2026-02-27)
|
|
4
|
+
|
|
5
|
+
* ember-data-model-fragments 7.0.3 (patch)
|
|
6
|
+
|
|
7
|
+
#### :bug: Bug Fix
|
|
8
|
+
* `ember-data-model-fragments`
|
|
9
|
+
* [#514](https://github.com/adopted-ember-addons/ember-data-model-fragments/pull/514) Guard fragment access on destroyed/unloaded records ([@deanmarano](https://github.com/deanmarano))
|
|
10
|
+
|
|
11
|
+
#### Committers: 1
|
|
12
|
+
- Dean Marano ([@deanmarano](https://github.com/deanmarano))
|
|
13
|
+
|
|
14
|
+
## Release (2026-02-11)
|
|
15
|
+
|
|
16
|
+
* ember-data-model-fragments 7.0.2 (patch)
|
|
17
|
+
|
|
18
|
+
#### :bug: Bug Fix
|
|
19
|
+
* `ember-data-model-fragments`
|
|
20
|
+
* [#512](https://github.com/adopted-ember-addons/ember-data-model-fragments/pull/512) Prevent newly created fragments from being marked deleted after save ([@deanmarano](https://github.com/deanmarano))
|
|
21
|
+
|
|
22
|
+
#### Committers: 1
|
|
23
|
+
- Dean Marano ([@deanmarano](https://github.com/deanmarano))
|
|
24
|
+
|
|
3
25
|
## Release (2026-02-06)
|
|
4
26
|
|
|
5
27
|
* ember-data-model-fragments 7.0.1 (patch)
|
|
@@ -55,6 +55,9 @@ export default function array(type, options) {
|
|
|
55
55
|
// eslint-disable-next-line ember/require-computed-property-dependencies
|
|
56
56
|
return computed({
|
|
57
57
|
get(key) {
|
|
58
|
+
if (this.isDestroying || this.isDestroyed) {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
58
61
|
const identifier = recordIdentifierFor(this);
|
|
59
62
|
const cache = this.store.cache;
|
|
60
63
|
if (cache.getFragment(identifier, key) === null) {
|
|
@@ -64,6 +64,9 @@ export default function fragmentArray(type, options) {
|
|
|
64
64
|
// eslint-disable-next-line ember/require-computed-property-dependencies
|
|
65
65
|
return computed({
|
|
66
66
|
get(key) {
|
|
67
|
+
if (this.isDestroying || this.isDestroyed) {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
67
70
|
const identifier = recordIdentifierFor(this);
|
|
68
71
|
const cache = this.store.cache;
|
|
69
72
|
if (cache.getFragment(identifier, key) === null) {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { assert } from '@ember/debug';
|
|
2
2
|
import { computed } from '@ember/object';
|
|
3
|
+
import { isDestroying, isDestroyed } from '@ember/destroyable';
|
|
3
4
|
import { isFragment } from '../fragment';
|
|
4
5
|
import { recordIdentifierFor } from '@ember-data/store';
|
|
5
6
|
|
|
@@ -27,7 +28,15 @@ import { recordIdentifierFor } from '@ember-data/store';
|
|
|
27
28
|
@return {Attribute}
|
|
28
29
|
*/
|
|
29
30
|
export default function fragmentOwner() {
|
|
30
|
-
|
|
31
|
+
// No dependent keys: the value is invalidated via notifyPropertyChange in
|
|
32
|
+
// setFragmentOwner(). Omitting dependent keys also avoids Ember's
|
|
33
|
+
// "Attempted to access the computed ... on a destroyed object" assertion
|
|
34
|
+
// when a fragment is torn down.
|
|
35
|
+
// eslint-disable-next-line ember/require-computed-property-dependencies
|
|
36
|
+
return computed(function () {
|
|
37
|
+
if (isDestroying(this) || isDestroyed(this)) {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
31
40
|
assert(
|
|
32
41
|
'Fragment owner properties can only be used on fragments.',
|
|
33
42
|
isFragment(this),
|
|
@@ -60,8 +60,12 @@ export default function fragment(type, options) {
|
|
|
60
60
|
options,
|
|
61
61
|
};
|
|
62
62
|
|
|
63
|
+
// eslint-disable-next-line ember/require-computed-property-dependencies -- isDestroying/isDestroyed are guards, not dependencies
|
|
63
64
|
return computed('store.{_instanceCache,cache}', {
|
|
64
65
|
get(key) {
|
|
66
|
+
if (this.isDestroying || this.isDestroyed) {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
65
69
|
const identifier = recordIdentifierFor(this);
|
|
66
70
|
const cache = this.store.cache;
|
|
67
71
|
const fragmentIdentifier = cache.getFragment(identifier, key);
|
|
@@ -1161,14 +1161,16 @@ export default class FragmentStateManager {
|
|
|
1161
1161
|
}
|
|
1162
1162
|
}
|
|
1163
1163
|
|
|
1164
|
+
// Upsert the committed values as new canonical state BEFORE rollback.
|
|
1165
|
+
// This clears isNew on the inner cache, which prevents rollbackAttrs
|
|
1166
|
+
// from incorrectly setting isDeleted=true for newly created fragments.
|
|
1167
|
+
// (rollbackAttrs treats isNew records as "discard new record" and marks
|
|
1168
|
+
// them deleted, but here we want to transition them to saved state.)
|
|
1169
|
+
innerCache.upsert(identifier, { attributes: commitAttrs }, false);
|
|
1170
|
+
|
|
1164
1171
|
// Rollback the inner cache to clear dirty/in-flight tracking
|
|
1165
1172
|
innerCache.rollbackAttrs(identifier);
|
|
1166
1173
|
|
|
1167
|
-
// Push the committed values as the new canonical state
|
|
1168
|
-
if (Object.keys(commitAttrs).length > 0) {
|
|
1169
|
-
innerCache.upsert(identifier, { attributes: commitAttrs }, false);
|
|
1170
|
-
}
|
|
1171
|
-
|
|
1172
1174
|
// Re-apply any new dirty changes made during in-flight
|
|
1173
1175
|
for (const [key, value] of Object.entries(newDirtyAttrs)) {
|
|
1174
1176
|
innerCache.setAttr(identifier, key, value);
|
package/addon/fragment.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { get, computed } from '@ember/object';
|
|
2
2
|
import Ember from 'ember';
|
|
3
|
+
import { isDestroying, isDestroyed } from '@ember/destroyable';
|
|
3
4
|
// DS.Model gets munged to add fragment support, which must be included first
|
|
4
5
|
import { Model } from './ext';
|
|
5
6
|
import { copy } from './util/copy';
|
|
@@ -115,6 +116,9 @@ const Fragment = Model.extend(Ember.Comparable, {
|
|
|
115
116
|
},
|
|
116
117
|
|
|
117
118
|
toStringExtension() {
|
|
119
|
+
if (isDestroying(this) || isDestroyed(this)) {
|
|
120
|
+
return '';
|
|
121
|
+
}
|
|
118
122
|
const identifier = recordIdentifierFor(this);
|
|
119
123
|
const owner = this.store.cache.getFragmentOwner(identifier);
|
|
120
124
|
return owner ? `owner(${owner.ownerIdentifier?.id})` : '';
|
|
@@ -125,6 +129,9 @@ const Fragment = Model.extend(Ember.Comparable, {
|
|
|
125
129
|
ember-data 4.12+ doesn't call toStringExtension in Model.toString().
|
|
126
130
|
*/
|
|
127
131
|
toString() {
|
|
132
|
+
if (isDestroying(this) || isDestroyed(this)) {
|
|
133
|
+
return `<fragment(destroyed)>`;
|
|
134
|
+
}
|
|
128
135
|
const identifier = recordIdentifierFor(this);
|
|
129
136
|
const extension = this.toStringExtension();
|
|
130
137
|
const extensionStr = extension ? `:${extension}` : '';
|