@iamjulianacosta/mobx-data 1.0.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.
- package/LICENSE +21 -0
- package/README.md +366 -0
- package/dist/CacheHandler-BTU_rYkv.js +208 -0
- package/dist/CacheHandler-BTU_rYkv.js.map +1 -0
- package/dist/CacheHandler-CXgY9IJo.cjs +2 -0
- package/dist/CacheHandler-CXgY9IJo.cjs.map +1 -0
- package/dist/EmbeddedRecordsMixin-CBvqNdgC.cjs +2 -0
- package/dist/EmbeddedRecordsMixin-CBvqNdgC.cjs.map +1 -0
- package/dist/EmbeddedRecordsMixin-VoHluHCT.js +261 -0
- package/dist/EmbeddedRecordsMixin-VoHluHCT.js.map +1 -0
- package/dist/JsonApiSerializer-CC5HXp4b.js +194 -0
- package/dist/JsonApiSerializer-CC5HXp4b.js.map +1 -0
- package/dist/JsonApiSerializer-CKB02AgP.cjs +2 -0
- package/dist/JsonApiSerializer-CKB02AgP.cjs.map +1 -0
- package/dist/MemoryAdapter-Bx1e7ndV.js +123 -0
- package/dist/MemoryAdapter-Bx1e7ndV.js.map +1 -0
- package/dist/MemoryAdapter-D1cTyydm.cjs +2 -0
- package/dist/MemoryAdapter-D1cTyydm.cjs.map +1 -0
- package/dist/ODataAdapter-C4IHK4BK.js +157 -0
- package/dist/ODataAdapter-C4IHK4BK.js.map +1 -0
- package/dist/ODataAdapter-DyyF1sdA.cjs +2 -0
- package/dist/ODataAdapter-DyyF1sdA.cjs.map +1 -0
- package/dist/RestAdapter-B4aRvs4m.js +355 -0
- package/dist/RestAdapter-B4aRvs4m.js.map +1 -0
- package/dist/RestAdapter-CJOwTsKK.cjs +2 -0
- package/dist/RestAdapter-CJOwTsKK.cjs.map +1 -0
- package/dist/SchemaService-DZwkFgZu.js +102 -0
- package/dist/SchemaService-DZwkFgZu.js.map +1 -0
- package/dist/SchemaService-Di_yjVzU.cjs +2 -0
- package/dist/SchemaService-Di_yjVzU.cjs.map +1 -0
- package/dist/Serializer-95gi5edy.cjs +2 -0
- package/dist/Serializer-95gi5edy.cjs.map +1 -0
- package/dist/Serializer-FxJbsZ50.js +139 -0
- package/dist/Serializer-FxJbsZ50.js.map +1 -0
- package/dist/Store-BdwMrbDi.cjs +2 -0
- package/dist/Store-BdwMrbDi.cjs.map +1 -0
- package/dist/Store-CZ7Z-Nme.js +912 -0
- package/dist/Store-CZ7Z-Nme.js.map +1 -0
- package/dist/adapter/Adapter.d.ts +146 -0
- package/dist/adapter/Adapter.d.ts.map +1 -0
- package/dist/adapter/MemoryAdapter.d.ts +44 -0
- package/dist/adapter/MemoryAdapter.d.ts.map +1 -0
- package/dist/adapter/RestAdapter.d.ts +57 -0
- package/dist/adapter/RestAdapter.d.ts.map +1 -0
- package/dist/adapter/index.cjs +2 -0
- package/dist/adapter/index.cjs.map +1 -0
- package/dist/adapter/index.d.ts +4 -0
- package/dist/adapter/index.d.ts.map +1 -0
- package/dist/adapter/index.js +8 -0
- package/dist/adapter/index.js.map +1 -0
- package/dist/date-Bj4O2W1F.js +107 -0
- package/dist/date-Bj4O2W1F.js.map +1 -0
- package/dist/date-CRCe-9gf.cjs +2 -0
- package/dist/date-CRCe-9gf.cjs.map +1 -0
- package/dist/decorators-HQ1KnRdh.cjs +2 -0
- package/dist/decorators-HQ1KnRdh.cjs.map +1 -0
- package/dist/decorators-Zr35qr6A.js +50 -0
- package/dist/decorators-Zr35qr6A.js.map +1 -0
- package/dist/index.cjs +2 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +52 -0
- package/dist/index.js.map +1 -0
- package/dist/json-api/JsonApiAdapter.d.ts +38 -0
- package/dist/json-api/JsonApiAdapter.d.ts.map +1 -0
- package/dist/json-api/JsonApiSerializer.d.ts +73 -0
- package/dist/json-api/JsonApiSerializer.d.ts.map +1 -0
- package/dist/json-api/index.cjs +2 -0
- package/dist/json-api/index.cjs.map +1 -0
- package/dist/json-api/index.d.ts +3 -0
- package/dist/json-api/index.d.ts.map +1 -0
- package/dist/json-api/index.js +6 -0
- package/dist/json-api/index.js.map +1 -0
- package/dist/model/Errors.d.ts +46 -0
- package/dist/model/Errors.d.ts.map +1 -0
- package/dist/model/Model.d.ts +226 -0
- package/dist/model/Model.d.ts.map +1 -0
- package/dist/model/Snapshot.d.ts +72 -0
- package/dist/model/Snapshot.d.ts.map +1 -0
- package/dist/model/StateMachine.d.ts +45 -0
- package/dist/model/StateMachine.d.ts.map +1 -0
- package/dist/model/index.cjs +2 -0
- package/dist/model/index.cjs.map +1 -0
- package/dist/model/index.d.ts +6 -0
- package/dist/model/index.d.ts.map +1 -0
- package/dist/model/index.js +11 -0
- package/dist/model/index.js.map +1 -0
- package/dist/model/relationships.d.ts +182 -0
- package/dist/model/relationships.d.ts.map +1 -0
- package/dist/odata/ODataAdapter.d.ts +67 -0
- package/dist/odata/ODataAdapter.d.ts.map +1 -0
- package/dist/odata/index.cjs +2 -0
- package/dist/odata/index.cjs.map +1 -0
- package/dist/odata/index.d.ts +2 -0
- package/dist/odata/index.d.ts.map +1 -0
- package/dist/odata/index.js +5 -0
- package/dist/odata/index.js.map +1 -0
- package/dist/relationships-B55LBaCW.cjs +2 -0
- package/dist/relationships-B55LBaCW.cjs.map +1 -0
- package/dist/relationships-BEXANmWg.js +821 -0
- package/dist/relationships-BEXANmWg.js.map +1 -0
- package/dist/request/CacheHandler.d.ts +50 -0
- package/dist/request/CacheHandler.d.ts.map +1 -0
- package/dist/request/FetchHandler.d.ts +41 -0
- package/dist/request/FetchHandler.d.ts.map +1 -0
- package/dist/request/RequestManager.d.ts +52 -0
- package/dist/request/RequestManager.d.ts.map +1 -0
- package/dist/request/index.cjs +2 -0
- package/dist/request/index.cjs.map +1 -0
- package/dist/request/index.d.ts +5 -0
- package/dist/request/index.d.ts.map +1 -0
- package/dist/request/index.js +7 -0
- package/dist/request/index.js.map +1 -0
- package/dist/request/types.d.ts +111 -0
- package/dist/request/types.d.ts.map +1 -0
- package/dist/schema/SchemaService.d.ts +58 -0
- package/dist/schema/SchemaService.d.ts.map +1 -0
- package/dist/schema/decorators.d.ts +50 -0
- package/dist/schema/decorators.d.ts.map +1 -0
- package/dist/schema/index.cjs +2 -0
- package/dist/schema/index.cjs.map +1 -0
- package/dist/schema/index.d.ts +4 -0
- package/dist/schema/index.d.ts.map +1 -0
- package/dist/schema/index.js +13 -0
- package/dist/schema/index.js.map +1 -0
- package/dist/schema/types.d.ts +61 -0
- package/dist/schema/types.d.ts.map +1 -0
- package/dist/serializer/EmbeddedRecordsMixin.d.ts +80 -0
- package/dist/serializer/EmbeddedRecordsMixin.d.ts.map +1 -0
- package/dist/serializer/JsonSerializer.d.ts +52 -0
- package/dist/serializer/JsonSerializer.d.ts.map +1 -0
- package/dist/serializer/RestSerializer.d.ts +43 -0
- package/dist/serializer/RestSerializer.d.ts.map +1 -0
- package/dist/serializer/Serializer.d.ts +202 -0
- package/dist/serializer/Serializer.d.ts.map +1 -0
- package/dist/serializer/index.cjs +2 -0
- package/dist/serializer/index.cjs.map +1 -0
- package/dist/serializer/index.d.ts +5 -0
- package/dist/serializer/index.d.ts.map +1 -0
- package/dist/serializer/index.js +9 -0
- package/dist/serializer/index.js.map +1 -0
- package/dist/store/IdentityMap.d.ts +53 -0
- package/dist/store/IdentityMap.d.ts.map +1 -0
- package/dist/store/RecordArray.d.ts +114 -0
- package/dist/store/RecordArray.d.ts.map +1 -0
- package/dist/store/Store.d.ts +395 -0
- package/dist/store/Store.d.ts.map +1 -0
- package/dist/store/index.cjs +2 -0
- package/dist/store/index.cjs.map +1 -0
- package/dist/store/index.d.ts +5 -0
- package/dist/store/index.d.ts.map +1 -0
- package/dist/store/index.js +8 -0
- package/dist/store/index.js.map +1 -0
- package/dist/transforms/Transform.d.ts +49 -0
- package/dist/transforms/Transform.d.ts.map +1 -0
- package/dist/transforms/boolean.d.ts +26 -0
- package/dist/transforms/boolean.d.ts.map +1 -0
- package/dist/transforms/date.d.ts +22 -0
- package/dist/transforms/date.d.ts.map +1 -0
- package/dist/transforms/index.cjs +2 -0
- package/dist/transforms/index.cjs.map +1 -0
- package/dist/transforms/index.d.ts +6 -0
- package/dist/transforms/index.d.ts.map +1 -0
- package/dist/transforms/index.js +9 -0
- package/dist/transforms/index.js.map +1 -0
- package/dist/transforms/number.d.ts +17 -0
- package/dist/transforms/number.d.ts.map +1 -0
- package/dist/transforms/string.d.ts +18 -0
- package/dist/transforms/string.d.ts.map +1 -0
- package/dist/types-C9NB2gRj.js +7 -0
- package/dist/types-C9NB2gRj.js.map +1 -0
- package/dist/types-uWOXMPWW.cjs +2 -0
- package/dist/types-uWOXMPWW.cjs.map +1 -0
- package/package.json +140 -0
- package/src/adapter/Adapter.ts +320 -0
- package/src/adapter/MemoryAdapter.ts +216 -0
- package/src/adapter/RestAdapter.ts +248 -0
- package/src/adapter/index.ts +7 -0
- package/src/index.ts +17 -0
- package/src/json-api/JsonApiAdapter.ts +93 -0
- package/src/json-api/JsonApiSerializer.ts +245 -0
- package/src/json-api/index.ts +2 -0
- package/src/model/Errors.ts +100 -0
- package/src/model/Model.ts +683 -0
- package/src/model/Snapshot.ts +162 -0
- package/src/model/StateMachine.ts +149 -0
- package/src/model/index.ts +20 -0
- package/src/model/relationships.ts +484 -0
- package/src/odata/ODataAdapter.ts +245 -0
- package/src/odata/index.ts +1 -0
- package/src/request/CacheHandler.ts +125 -0
- package/src/request/FetchHandler.ts +119 -0
- package/src/request/RequestManager.ts +112 -0
- package/src/request/index.ts +4 -0
- package/src/request/types.ts +139 -0
- package/src/schema/SchemaService.ts +161 -0
- package/src/schema/decorators.ts +162 -0
- package/src/schema/index.ts +3 -0
- package/src/schema/types.ts +66 -0
- package/src/serializer/EmbeddedRecordsMixin.ts +257 -0
- package/src/serializer/JsonSerializer.ts +173 -0
- package/src/serializer/RestSerializer.ts +138 -0
- package/src/serializer/Serializer.ts +397 -0
- package/src/serializer/index.ts +15 -0
- package/src/store/IdentityMap.ts +110 -0
- package/src/store/RecordArray.ts +210 -0
- package/src/store/Store.ts +1391 -0
- package/src/store/index.ts +11 -0
- package/src/transforms/Transform.ts +52 -0
- package/src/transforms/boolean.ts +57 -0
- package/src/transforms/date.ts +48 -0
- package/src/transforms/index.ts +5 -0
- package/src/transforms/number.ts +42 -0
- package/src/transforms/string.ts +35 -0
|
@@ -0,0 +1,821 @@
|
|
|
1
|
+
import "reflect-metadata";
|
|
2
|
+
import { makeObservable as c, action as d, computed as a, observable as h, runInAction as l } from "mobx";
|
|
3
|
+
import { A as S, R as v } from "./types-C9NB2gRj.js";
|
|
4
|
+
import { injectable as b } from "tsyringe";
|
|
5
|
+
var R = Object.getOwnPropertyDescriptor, w = (o, t, e, i) => {
|
|
6
|
+
for (var r = i > 1 ? void 0 : i ? R(t, e) : t, s = o.length - 1, n; s >= 0; s--)
|
|
7
|
+
(n = o[s]) && (r = n(r) || r);
|
|
8
|
+
return r;
|
|
9
|
+
};
|
|
10
|
+
let g = class {
|
|
11
|
+
constructor() {
|
|
12
|
+
this._errors = /* @__PURE__ */ new Map(), c(this, {
|
|
13
|
+
_errors: h.shallow,
|
|
14
|
+
isEmpty: a,
|
|
15
|
+
length: a,
|
|
16
|
+
add: d,
|
|
17
|
+
remove: d,
|
|
18
|
+
clear: d
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
/** `true` when there are no validation errors. */
|
|
22
|
+
get isEmpty() {
|
|
23
|
+
return this._errors.size === 0;
|
|
24
|
+
}
|
|
25
|
+
/** Total number of error messages across all attributes. */
|
|
26
|
+
get length() {
|
|
27
|
+
let o = 0;
|
|
28
|
+
for (const t of this._errors.values())
|
|
29
|
+
o += t.length;
|
|
30
|
+
return o;
|
|
31
|
+
}
|
|
32
|
+
/** Returns all error messages for `attribute`, or an empty array. */
|
|
33
|
+
get(o) {
|
|
34
|
+
return this._errors.get(o) ?? [];
|
|
35
|
+
}
|
|
36
|
+
/** Returns `true` when `attribute` has at least one error message. */
|
|
37
|
+
has(o) {
|
|
38
|
+
const t = this._errors.get(o);
|
|
39
|
+
return !!t && t.length > 0;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Appends one or more error messages for `attribute`.
|
|
43
|
+
* Existing messages are preserved — this is an additive operation.
|
|
44
|
+
*/
|
|
45
|
+
add(o, t) {
|
|
46
|
+
const e = Array.isArray(t) ? t : [t], r = [
|
|
47
|
+
...this._errors.get(o) ?? [],
|
|
48
|
+
...e.map((s) => ({ attribute: o, message: s }))
|
|
49
|
+
];
|
|
50
|
+
this._errors.set(o, r);
|
|
51
|
+
}
|
|
52
|
+
/** Removes all error messages for `attribute`. */
|
|
53
|
+
remove(o) {
|
|
54
|
+
this._errors.delete(o);
|
|
55
|
+
}
|
|
56
|
+
/** Removes all error messages for every attribute. */
|
|
57
|
+
clear() {
|
|
58
|
+
this._errors.clear();
|
|
59
|
+
}
|
|
60
|
+
/** Iterates `[attributeName, ErrorMessage[]]` pairs. */
|
|
61
|
+
*[Symbol.iterator]() {
|
|
62
|
+
for (const o of this._errors.entries())
|
|
63
|
+
yield o;
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
g = w([
|
|
67
|
+
b()
|
|
68
|
+
], g);
|
|
69
|
+
const A = {
|
|
70
|
+
"root.empty": {
|
|
71
|
+
loadingData: "root.loading",
|
|
72
|
+
pushedData: "root.loaded.saved"
|
|
73
|
+
},
|
|
74
|
+
"root.loading": {
|
|
75
|
+
pushedData: "root.loaded.saved",
|
|
76
|
+
becameError: "root.error"
|
|
77
|
+
},
|
|
78
|
+
"root.loaded.saved": {
|
|
79
|
+
didSetProperty: "root.loaded.updated.uncommitted",
|
|
80
|
+
deleteRecord: "root.deleted.uncommitted",
|
|
81
|
+
loadingData: "root.loading",
|
|
82
|
+
pushedData: "root.loaded.saved",
|
|
83
|
+
unloadRecord: "root.empty"
|
|
84
|
+
},
|
|
85
|
+
"root.loaded.created.uncommitted": {
|
|
86
|
+
willCommit: "root.loaded.created.inFlight",
|
|
87
|
+
rolledBack: "root.empty",
|
|
88
|
+
deleteRecord: "root.deleted.uncommitted",
|
|
89
|
+
didSetProperty: "root.loaded.created.uncommitted",
|
|
90
|
+
unloadRecord: "root.empty"
|
|
91
|
+
},
|
|
92
|
+
"root.loaded.created.inFlight": {
|
|
93
|
+
didCommit: "root.loaded.saved",
|
|
94
|
+
becameInvalid: "root.loaded.created.uncommitted",
|
|
95
|
+
becameError: "root.error"
|
|
96
|
+
},
|
|
97
|
+
"root.loaded.updated.uncommitted": {
|
|
98
|
+
willCommit: "root.loaded.updated.inFlight",
|
|
99
|
+
rolledBack: "root.loaded.saved",
|
|
100
|
+
didSetProperty: "root.loaded.updated.uncommitted",
|
|
101
|
+
deleteRecord: "root.deleted.uncommitted",
|
|
102
|
+
unloadRecord: "root.empty"
|
|
103
|
+
},
|
|
104
|
+
"root.loaded.updated.inFlight": {
|
|
105
|
+
didCommit: "root.loaded.saved",
|
|
106
|
+
becameInvalid: "root.loaded.updated.uncommitted",
|
|
107
|
+
becameError: "root.error"
|
|
108
|
+
},
|
|
109
|
+
"root.deleted.uncommitted": {
|
|
110
|
+
willCommit: "root.deleted.inFlight",
|
|
111
|
+
rolledBack: "root.loaded.saved",
|
|
112
|
+
unloadRecord: "root.empty"
|
|
113
|
+
},
|
|
114
|
+
"root.deleted.inFlight": {
|
|
115
|
+
didCommit: "root.deleted.saved",
|
|
116
|
+
becameError: "root.error"
|
|
117
|
+
},
|
|
118
|
+
"root.deleted.saved": {
|
|
119
|
+
unloadRecord: "root.empty"
|
|
120
|
+
},
|
|
121
|
+
"root.error": {
|
|
122
|
+
rolledBack: "root.loaded.saved",
|
|
123
|
+
unloadRecord: "root.empty"
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
class D {
|
|
127
|
+
constructor(t = "root.empty") {
|
|
128
|
+
this.current = t, c(this, {
|
|
129
|
+
current: h,
|
|
130
|
+
transition: d
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Applies `event` to the current state, updates `current`, and returns the
|
|
135
|
+
* new state.
|
|
136
|
+
*
|
|
137
|
+
* @throws `Error` when `event` is not permitted from the current state.
|
|
138
|
+
*/
|
|
139
|
+
transition(t) {
|
|
140
|
+
const e = A[this.current][t];
|
|
141
|
+
if (!e)
|
|
142
|
+
throw new Error(
|
|
143
|
+
`Invalid transition: event "${t}" not allowed from state "${this.current}"`
|
|
144
|
+
);
|
|
145
|
+
return this.current = e, e;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
function p(o, t) {
|
|
149
|
+
const e = [];
|
|
150
|
+
let i = o;
|
|
151
|
+
for (; i && i !== Object.prototype; )
|
|
152
|
+
e.push(i), i = Object.getPrototypeOf(i);
|
|
153
|
+
const r = /* @__PURE__ */ new Map();
|
|
154
|
+
for (const s of e.reverse()) {
|
|
155
|
+
const n = Reflect.getOwnMetadata(t, s);
|
|
156
|
+
if (n)
|
|
157
|
+
for (const [f, m] of n)
|
|
158
|
+
r.set(f, m);
|
|
159
|
+
}
|
|
160
|
+
return r;
|
|
161
|
+
}
|
|
162
|
+
class M {
|
|
163
|
+
constructor(t) {
|
|
164
|
+
this.record = t, this.id = t.id, this.modelName = t.modelName;
|
|
165
|
+
const e = t;
|
|
166
|
+
this._attributes = { ...e._data }, this._relationships = new Map(e._relationships), this._changedAttributes = t.changedAttributes();
|
|
167
|
+
const i = Object.getPrototypeOf(t);
|
|
168
|
+
this._attributeDefinitions = p(i, S), this._relationshipDefinitions = p(i, v);
|
|
169
|
+
}
|
|
170
|
+
/** Returns the snapshot-time value for an attribute key. */
|
|
171
|
+
attr(t) {
|
|
172
|
+
return this._attributes[t];
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Returns the `belongsTo` reference for `key`.
|
|
176
|
+
* When `{ id: true }` is passed, returns only the id string; otherwise
|
|
177
|
+
* returns a `BelongsToReference` `{ id, type }` object, or `null` when the
|
|
178
|
+
* relationship is empty.
|
|
179
|
+
*/
|
|
180
|
+
belongsTo(t, e) {
|
|
181
|
+
const i = this._relationships.get(t);
|
|
182
|
+
if (!i || i.data === null)
|
|
183
|
+
return null;
|
|
184
|
+
const r = i.data;
|
|
185
|
+
return e != null && e.id ? r.id : { id: r.id, type: r.type };
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Returns the `hasMany` references for `key`.
|
|
189
|
+
* When `{ ids: true }` is passed, returns a plain string array of ids;
|
|
190
|
+
* otherwise returns an array of `HasManyReference` objects.
|
|
191
|
+
*/
|
|
192
|
+
hasMany(t, e) {
|
|
193
|
+
const i = this._relationships.get(t);
|
|
194
|
+
if (!i || !Array.isArray(i.data))
|
|
195
|
+
return [];
|
|
196
|
+
const r = i.data;
|
|
197
|
+
return e != null && e.ids ? r.map((s) => s.id) : r.map((s) => ({ id: s.id, type: s.type }));
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Returns a `{ [key]: [original, current] }` map of attributes that
|
|
201
|
+
* differ from the server-received values at snapshot time.
|
|
202
|
+
*/
|
|
203
|
+
changedAttributes() {
|
|
204
|
+
return { ...this._changedAttributes };
|
|
205
|
+
}
|
|
206
|
+
/** Iterates over every attribute definition, calling `callback` for each. */
|
|
207
|
+
eachAttribute(t) {
|
|
208
|
+
for (const [e, i] of this._attributeDefinitions)
|
|
209
|
+
t(e, i);
|
|
210
|
+
}
|
|
211
|
+
/** Iterates over every relationship definition, calling `callback` for each. */
|
|
212
|
+
eachRelationship(t) {
|
|
213
|
+
for (const [e, i] of this._relationshipDefinitions)
|
|
214
|
+
t(e, i);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
const _ = Symbol("mobx-data:accessors-installed");
|
|
218
|
+
function y(o, t) {
|
|
219
|
+
const e = [];
|
|
220
|
+
let i = o;
|
|
221
|
+
for (; i && i !== Object.prototype; )
|
|
222
|
+
e.push(i), i = Object.getPrototypeOf(i);
|
|
223
|
+
const r = /* @__PURE__ */ new Map();
|
|
224
|
+
for (const s of e.reverse()) {
|
|
225
|
+
const n = Reflect.getOwnMetadata(t, s);
|
|
226
|
+
if (n)
|
|
227
|
+
for (const [f, m] of n)
|
|
228
|
+
r.set(f, m);
|
|
229
|
+
}
|
|
230
|
+
return r;
|
|
231
|
+
}
|
|
232
|
+
function C(o) {
|
|
233
|
+
const t = o.prototype;
|
|
234
|
+
if (o[_])
|
|
235
|
+
return;
|
|
236
|
+
o[_] = !0;
|
|
237
|
+
const e = y(t, S);
|
|
238
|
+
for (const [r] of e)
|
|
239
|
+
Object.defineProperty(t, r, {
|
|
240
|
+
get() {
|
|
241
|
+
return this._data[r];
|
|
242
|
+
},
|
|
243
|
+
set(s) {
|
|
244
|
+
this._setAttribute(
|
|
245
|
+
r,
|
|
246
|
+
s
|
|
247
|
+
);
|
|
248
|
+
},
|
|
249
|
+
configurable: !0,
|
|
250
|
+
enumerable: !0
|
|
251
|
+
});
|
|
252
|
+
const i = y(t, v);
|
|
253
|
+
for (const [r, s] of i)
|
|
254
|
+
Object.defineProperty(t, r, {
|
|
255
|
+
get() {
|
|
256
|
+
return this._resolveRelationship(r, s);
|
|
257
|
+
},
|
|
258
|
+
set(n) {
|
|
259
|
+
this._setRelationship(r, s, n);
|
|
260
|
+
},
|
|
261
|
+
configurable: !0,
|
|
262
|
+
enumerable: !0
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
class P {
|
|
266
|
+
constructor(t = {}) {
|
|
267
|
+
this._data = {}, this._originalData = {}, this._relationships = /* @__PURE__ */ new Map(), this._id = null, this.errors = new g();
|
|
268
|
+
const e = t;
|
|
269
|
+
C(this.constructor), this._id = e.id ?? null, this.store = e.store, this._stateMachine = new D(
|
|
270
|
+
e.__initialState ?? "root.loaded.created.uncommitted"
|
|
271
|
+
);
|
|
272
|
+
const i = e.data ? { ...e.data } : {};
|
|
273
|
+
if (this._data = i, e.__initialState === "root.loaded.saved" ? this._originalData = { ...i } : this._originalData = {}, e.relationships)
|
|
274
|
+
for (const [r, s] of Object.entries(e.relationships))
|
|
275
|
+
this._relationships.set(r, s);
|
|
276
|
+
c(this, {
|
|
277
|
+
_data: h.shallow,
|
|
278
|
+
_originalData: h.ref,
|
|
279
|
+
_relationships: h.shallow,
|
|
280
|
+
_id: h,
|
|
281
|
+
id: a,
|
|
282
|
+
currentState: a,
|
|
283
|
+
isLoading: a,
|
|
284
|
+
isLoaded: a,
|
|
285
|
+
isSaving: a,
|
|
286
|
+
isDirty: a,
|
|
287
|
+
hasDirtyAttributes: a,
|
|
288
|
+
isNew: a,
|
|
289
|
+
isDeleted: a,
|
|
290
|
+
isValid: a,
|
|
291
|
+
isError: a,
|
|
292
|
+
isEmpty: a,
|
|
293
|
+
_setAttribute: d,
|
|
294
|
+
_transitionIfClean: d,
|
|
295
|
+
_applyServerData: d,
|
|
296
|
+
_setState: d,
|
|
297
|
+
rollbackAttributes: d,
|
|
298
|
+
deleteRecord: d
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* Factory method that creates an instance in the `root.loaded.saved` state
|
|
303
|
+
* (i.e. as if freshly loaded from the server) and calls `didLoad()`.
|
|
304
|
+
*
|
|
305
|
+
* Used internally by `Store.pushResource` to avoid exposing the internal
|
|
306
|
+
* `__initialState` option.
|
|
307
|
+
*/
|
|
308
|
+
static push(t) {
|
|
309
|
+
const e = this, i = new e({
|
|
310
|
+
...t,
|
|
311
|
+
__initialState: "root.loaded.saved"
|
|
312
|
+
});
|
|
313
|
+
return i.didLoad(), i;
|
|
314
|
+
}
|
|
315
|
+
/** Server-assigned id, or `null` for new records. */
|
|
316
|
+
get id() {
|
|
317
|
+
return this._id;
|
|
318
|
+
}
|
|
319
|
+
set id(t) {
|
|
320
|
+
l(() => {
|
|
321
|
+
this._id = t;
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
/** Returns the static `modelName` from the concrete subclass constructor. */
|
|
325
|
+
get modelName() {
|
|
326
|
+
return this.constructor.modelName;
|
|
327
|
+
}
|
|
328
|
+
/** Current state-machine state string. */
|
|
329
|
+
get currentState() {
|
|
330
|
+
return this._stateMachine.current;
|
|
331
|
+
}
|
|
332
|
+
/** `true` while an adapter request to fetch this record is in flight. */
|
|
333
|
+
get isLoading() {
|
|
334
|
+
return this.currentState === "root.loading";
|
|
335
|
+
}
|
|
336
|
+
/** `true` when the record has been loaded (any `root.loaded.*` state). */
|
|
337
|
+
get isLoaded() {
|
|
338
|
+
return this.currentState.startsWith("root.loaded");
|
|
339
|
+
}
|
|
340
|
+
/** `true` while a create or update request is in flight. */
|
|
341
|
+
get isSaving() {
|
|
342
|
+
return this.currentState.endsWith(".inFlight");
|
|
343
|
+
}
|
|
344
|
+
/** `true` when the record was created locally and has never been saved. */
|
|
345
|
+
get isNew() {
|
|
346
|
+
return this.currentState.startsWith("root.loaded.created");
|
|
347
|
+
}
|
|
348
|
+
/** `true` when `deleteRecord()` has been called (regardless of server state). */
|
|
349
|
+
get isDeleted() {
|
|
350
|
+
return this.currentState.startsWith("root.deleted");
|
|
351
|
+
}
|
|
352
|
+
/** `true` when the record is in the `root.error` state. */
|
|
353
|
+
get isError() {
|
|
354
|
+
return this.currentState === "root.error";
|
|
355
|
+
}
|
|
356
|
+
/** `true` when the record is in the `root.empty` placeholder state. */
|
|
357
|
+
get isEmpty() {
|
|
358
|
+
return this.currentState === "root.empty";
|
|
359
|
+
}
|
|
360
|
+
/** `true` when any attribute differs from its last-saved value. */
|
|
361
|
+
get hasDirtyAttributes() {
|
|
362
|
+
const t = this._data, e = this._originalData;
|
|
363
|
+
for (const i of Object.keys(t))
|
|
364
|
+
if (!Object.is(t[i], e[i]))
|
|
365
|
+
return !0;
|
|
366
|
+
for (const i of Object.keys(e))
|
|
367
|
+
if (!(i in t))
|
|
368
|
+
return !0;
|
|
369
|
+
return !1;
|
|
370
|
+
}
|
|
371
|
+
/**
|
|
372
|
+
* `true` when the record needs to be saved — new, deleted (not yet
|
|
373
|
+
* confirmed), or has dirty attributes.
|
|
374
|
+
*/
|
|
375
|
+
get isDirty() {
|
|
376
|
+
return this.isNew || this.isDeleted && this.currentState !== "root.deleted.saved" ? !0 : this.hasDirtyAttributes;
|
|
377
|
+
}
|
|
378
|
+
/** `true` when `errors.isEmpty` — i.e. no validation errors are present. */
|
|
379
|
+
get isValid() {
|
|
380
|
+
return this.errors.isEmpty;
|
|
381
|
+
}
|
|
382
|
+
/**
|
|
383
|
+
* Returns a `{ [key]: [original, current] }` map of attributes that differ
|
|
384
|
+
* from the last server-received snapshot.
|
|
385
|
+
*/
|
|
386
|
+
changedAttributes() {
|
|
387
|
+
const t = {}, e = /* @__PURE__ */ new Set([
|
|
388
|
+
...Object.keys(this._data),
|
|
389
|
+
...Object.keys(this._originalData)
|
|
390
|
+
]);
|
|
391
|
+
for (const i of e) {
|
|
392
|
+
const r = this._data[i], s = this._originalData[i];
|
|
393
|
+
Object.is(r, s) || (t[i] = [s, r]);
|
|
394
|
+
}
|
|
395
|
+
return t;
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* Resets all attributes to their original server values and clears
|
|
399
|
+
* validation errors. For new records the record is transitioned to
|
|
400
|
+
* `root.empty` and unloaded from the store.
|
|
401
|
+
*/
|
|
402
|
+
rollbackAttributes() {
|
|
403
|
+
var t;
|
|
404
|
+
if (this._data = { ...this._originalData }, this.errors.clear(), this.isNew) {
|
|
405
|
+
this._setState("root.empty"), (t = this.store) != null && t.unloadRecord && this.store.unloadRecord(this);
|
|
406
|
+
return;
|
|
407
|
+
}
|
|
408
|
+
this.currentState === "root.loaded.updated.uncommitted" ? this._stateMachine.transition("rolledBack") : this.currentState === "root.deleted.uncommitted" && this._stateMachine.transition("rolledBack");
|
|
409
|
+
}
|
|
410
|
+
/**
|
|
411
|
+
* Persists the record to the server. No-ops if the record is not dirty.
|
|
412
|
+
* Delegates to `store.saveRecord`.
|
|
413
|
+
*
|
|
414
|
+
* @throws when no store is attached.
|
|
415
|
+
*/
|
|
416
|
+
async save(t = {}) {
|
|
417
|
+
var i;
|
|
418
|
+
if (!this.isDirty)
|
|
419
|
+
return this;
|
|
420
|
+
if (!((i = this.store) != null && i.saveRecord))
|
|
421
|
+
throw new Error("Cannot save: no store attached");
|
|
422
|
+
const e = this.isNew;
|
|
423
|
+
this.willSave(), this._stateMachine.transition("willCommit");
|
|
424
|
+
try {
|
|
425
|
+
return await this.store.saveRecord(this, t), (this.currentState === "root.loaded.created.inFlight" || this.currentState === "root.loaded.updated.inFlight") && l(() => {
|
|
426
|
+
this._originalData = { ...this._data }, this._stateMachine.transition("didCommit");
|
|
427
|
+
}), e ? this.didCreate() : this.didUpdate(), this.didSave(), this;
|
|
428
|
+
} catch (r) {
|
|
429
|
+
throw this.errors.isEmpty ? (this._stateMachine.transition("becameError"), this.becameError()) : (this._stateMachine.transition("becameInvalid"), this.becameInvalid()), r;
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
/**
|
|
433
|
+
* Reloads the record from the server.
|
|
434
|
+
* @throws when no store is attached.
|
|
435
|
+
*/
|
|
436
|
+
async reload() {
|
|
437
|
+
var t;
|
|
438
|
+
if (!((t = this.store) != null && t.reloadRecord))
|
|
439
|
+
throw new Error("Cannot reload: no store attached");
|
|
440
|
+
return await this.store.reloadRecord(this);
|
|
441
|
+
}
|
|
442
|
+
/**
|
|
443
|
+
* Marks the record for deletion. The record moves to
|
|
444
|
+
* `root.deleted.uncommitted` but is not yet removed from the server.
|
|
445
|
+
* Call `destroyRecord()` to also issue the DELETE request.
|
|
446
|
+
*/
|
|
447
|
+
deleteRecord() {
|
|
448
|
+
this.isNew ? this._setState("root.deleted.uncommitted") : this._stateMachine.transition("deleteRecord");
|
|
449
|
+
}
|
|
450
|
+
/**
|
|
451
|
+
* Marks the record for deletion and immediately sends a DELETE request.
|
|
452
|
+
* @throws when no store is attached.
|
|
453
|
+
*/
|
|
454
|
+
async destroyRecord() {
|
|
455
|
+
var e;
|
|
456
|
+
if (this.deleteRecord(), !((e = this.store) != null && e.deleteRecord))
|
|
457
|
+
throw new Error("Cannot destroy: no store attached");
|
|
458
|
+
this._stateMachine.transition("willCommit");
|
|
459
|
+
const t = await this.store.deleteRecord(this);
|
|
460
|
+
return this.currentState === "root.deleted.inFlight" && this._stateMachine.transition("didCommit"), this.didDelete(), t;
|
|
461
|
+
}
|
|
462
|
+
/** Removes the record from the store's identity map without a server call. */
|
|
463
|
+
unloadRecord() {
|
|
464
|
+
var t;
|
|
465
|
+
(t = this.store) != null && t.unloadRecord && this.store.unloadRecord(this);
|
|
466
|
+
}
|
|
467
|
+
/** Creates a frozen `Snapshot` of the current record state. */
|
|
468
|
+
createSnapshot() {
|
|
469
|
+
return new M(this);
|
|
470
|
+
}
|
|
471
|
+
/** Returns a plain-object representation of the current attribute data. */
|
|
472
|
+
serialize(t = {}) {
|
|
473
|
+
return { ...this._data };
|
|
474
|
+
}
|
|
475
|
+
/** Returns `{ id, ...attributes }` — used by `JSON.stringify`. */
|
|
476
|
+
toJSON() {
|
|
477
|
+
return { id: this._id, ...this._data };
|
|
478
|
+
}
|
|
479
|
+
// Lifecycle hooks — default no-ops, overridable.
|
|
480
|
+
/** Called after the record is loaded from the server. */
|
|
481
|
+
didLoad() {
|
|
482
|
+
}
|
|
483
|
+
/** Called after a new record is successfully persisted. */
|
|
484
|
+
didCreate() {
|
|
485
|
+
}
|
|
486
|
+
/** Called after an existing record is successfully updated. */
|
|
487
|
+
didUpdate() {
|
|
488
|
+
}
|
|
489
|
+
/** Called after a record is successfully deleted. */
|
|
490
|
+
didDelete() {
|
|
491
|
+
}
|
|
492
|
+
/** Called immediately before a save request is issued. */
|
|
493
|
+
willSave() {
|
|
494
|
+
}
|
|
495
|
+
/** Called after any successful save (create or update). */
|
|
496
|
+
didSave() {
|
|
497
|
+
}
|
|
498
|
+
/** Called when the server returns a 422-style validation error. */
|
|
499
|
+
becameInvalid() {
|
|
500
|
+
}
|
|
501
|
+
/** Called when the server returns a non-validation error. */
|
|
502
|
+
becameError() {
|
|
503
|
+
}
|
|
504
|
+
// --- internals ---
|
|
505
|
+
/** Called by generated attribute setters. */
|
|
506
|
+
_setAttribute(t, e) {
|
|
507
|
+
Object.is(this._data[t], e) || (this._data[t] = e, this._transitionIfClean());
|
|
508
|
+
}
|
|
509
|
+
/**
|
|
510
|
+
* Transitions to `updated.uncommitted` when the record becomes dirty, or
|
|
511
|
+
* back to `saved` when all changes are rolled back.
|
|
512
|
+
*/
|
|
513
|
+
_transitionIfClean() {
|
|
514
|
+
const t = this.hasDirtyAttributes;
|
|
515
|
+
t && this.currentState === "root.loaded.saved" ? this._stateMachine.transition("didSetProperty") : !t && this.currentState === "root.loaded.updated.uncommitted" && this._stateMachine.transition("rolledBack");
|
|
516
|
+
}
|
|
517
|
+
/** Directly sets the state machine's current state (bypasses transition validation). */
|
|
518
|
+
_setState(t) {
|
|
519
|
+
this._stateMachine.current = t;
|
|
520
|
+
}
|
|
521
|
+
/** Fires a state-machine transition event. */
|
|
522
|
+
_transition(t) {
|
|
523
|
+
this._stateMachine.transition(t);
|
|
524
|
+
}
|
|
525
|
+
/** Used by Store to apply server data after save, making record clean again. */
|
|
526
|
+
_applyServerData(t, e, i) {
|
|
527
|
+
if (t !== null && (this._id = t), this._data = { ...this._data, ...e }, this._originalData = { ...this._data }, this.errors.clear(), i)
|
|
528
|
+
for (const [r, s] of Object.entries(i))
|
|
529
|
+
this._relationships.set(r, s);
|
|
530
|
+
this.currentState === "root.loaded.created.inFlight" ? (this._stateMachine.transition("didCommit"), this.didCreate()) : this.currentState === "root.loaded.updated.inFlight" ? (this._stateMachine.transition("didCommit"), this.didUpdate()) : this.currentState === "root.deleted.inFlight" ? this._stateMachine.transition("didCommit") : this.currentState === "root.loading" && this._stateMachine.transition("pushedData"), !this.isNew && !this.isDeleted && (this.currentState === "root.loaded.updated.uncommitted" || this.currentState === "root.loaded.created.uncommitted") && this._setState("root.loaded.saved");
|
|
531
|
+
}
|
|
532
|
+
/** Relationship data (reference only). Resolution to records lives in Store. */
|
|
533
|
+
_getRelationshipRef(t) {
|
|
534
|
+
return this._relationships.get(t) ?? null;
|
|
535
|
+
}
|
|
536
|
+
/** Stores a raw relationship reference without triggering store logic. */
|
|
537
|
+
_setRelationshipRef(t, e) {
|
|
538
|
+
this._relationships.set(t, e);
|
|
539
|
+
}
|
|
540
|
+
/**
|
|
541
|
+
* Delegates relationship resolution to the store.
|
|
542
|
+
* Returns `null` when no store is attached (e.g. in unit tests).
|
|
543
|
+
*/
|
|
544
|
+
_resolveRelationship(t, e) {
|
|
545
|
+
var i;
|
|
546
|
+
return (i = this.store) != null && i.resolveRelationship ? this.store.resolveRelationship(this, t, e) : null;
|
|
547
|
+
}
|
|
548
|
+
/** Delegates relationship mutation to the store (which also handles inverse sync). */
|
|
549
|
+
_setRelationship(t, e, i) {
|
|
550
|
+
var r;
|
|
551
|
+
(r = this.store) != null && r.setRelationshipValue && this.store.setRelationshipValue(this, t, e, i);
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
class u {
|
|
555
|
+
static refData(t) {
|
|
556
|
+
return !t || !t.data ? [] : Array.isArray(t.data) ? t.data : [];
|
|
557
|
+
}
|
|
558
|
+
constructor(t) {
|
|
559
|
+
this.host = t, c(this, {
|
|
560
|
+
resolved: a,
|
|
561
|
+
length: a,
|
|
562
|
+
push: d,
|
|
563
|
+
removeObject: d
|
|
564
|
+
});
|
|
565
|
+
}
|
|
566
|
+
/**
|
|
567
|
+
* Resolves the current set of related records from the store identity map.
|
|
568
|
+
* Pending (unsaved) members appended via `push()` are appended at the end.
|
|
569
|
+
*/
|
|
570
|
+
get resolved() {
|
|
571
|
+
const t = this.host.store._getRelationshipRefFor(this.host.parent, this.host.name), e = [], i = /* @__PURE__ */ new Set();
|
|
572
|
+
for (const s of u.refData(t)) {
|
|
573
|
+
const n = this.host.store.peekRecord(s.type, s.id);
|
|
574
|
+
n && (e.push(n), i.add(n));
|
|
575
|
+
}
|
|
576
|
+
const r = this.host.store._getPendingMembers(
|
|
577
|
+
this.host.parent,
|
|
578
|
+
this.host.name
|
|
579
|
+
);
|
|
580
|
+
for (const s of r)
|
|
581
|
+
i.has(s) || e.push(s);
|
|
582
|
+
return e;
|
|
583
|
+
}
|
|
584
|
+
/** Number of related records currently in the array. */
|
|
585
|
+
get length() {
|
|
586
|
+
return this.resolved.length;
|
|
587
|
+
}
|
|
588
|
+
/** Returns the record at `index`, or `undefined`. */
|
|
589
|
+
at(t) {
|
|
590
|
+
return this.resolved[t];
|
|
591
|
+
}
|
|
592
|
+
/**
|
|
593
|
+
* Adds one or more records to the relationship.
|
|
594
|
+
* Delegates to `store._hasManyAppend` which also handles inverse tracking.
|
|
595
|
+
*/
|
|
596
|
+
push(...t) {
|
|
597
|
+
for (const e of t)
|
|
598
|
+
this.host.store._hasManyAppend(
|
|
599
|
+
this.host.parent,
|
|
600
|
+
this.host.name,
|
|
601
|
+
this.host.meta,
|
|
602
|
+
e
|
|
603
|
+
);
|
|
604
|
+
return this.length;
|
|
605
|
+
}
|
|
606
|
+
/**
|
|
607
|
+
* Removes a record from the relationship.
|
|
608
|
+
* Delegates to `store._hasManyRemove` which also handles inverse tracking.
|
|
609
|
+
*/
|
|
610
|
+
removeObject(t) {
|
|
611
|
+
this.host.store._hasManyRemove(
|
|
612
|
+
this.host.parent,
|
|
613
|
+
this.host.name,
|
|
614
|
+
this.host.meta,
|
|
615
|
+
t
|
|
616
|
+
);
|
|
617
|
+
}
|
|
618
|
+
/** Returns `true` when `record` is currently in the relationship. */
|
|
619
|
+
includes(t) {
|
|
620
|
+
return this.resolved.includes(t);
|
|
621
|
+
}
|
|
622
|
+
/** Returns a plain array snapshot of all related records. */
|
|
623
|
+
toArray() {
|
|
624
|
+
return [...this.resolved];
|
|
625
|
+
}
|
|
626
|
+
/** Maps over the related records. */
|
|
627
|
+
map(t) {
|
|
628
|
+
return this.resolved.map(t);
|
|
629
|
+
}
|
|
630
|
+
/** Filters the related records. */
|
|
631
|
+
filter(t) {
|
|
632
|
+
return this.resolved.filter(t);
|
|
633
|
+
}
|
|
634
|
+
/** Iterates over the related records. */
|
|
635
|
+
forEach(t) {
|
|
636
|
+
this.resolved.forEach(t);
|
|
637
|
+
}
|
|
638
|
+
[Symbol.iterator]() {
|
|
639
|
+
return this.resolved[Symbol.iterator]();
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
class k {
|
|
643
|
+
constructor(t) {
|
|
644
|
+
this.loadedState = "pending", this.currentValue = null, this.error = null, this.inflight = null, this.host = t, c(this, {
|
|
645
|
+
loadedState: h,
|
|
646
|
+
currentValue: h.ref,
|
|
647
|
+
error: h.ref,
|
|
648
|
+
isPending: a,
|
|
649
|
+
isFulfilled: a,
|
|
650
|
+
isRejected: a,
|
|
651
|
+
isLoaded: a,
|
|
652
|
+
isLoading: a,
|
|
653
|
+
value: a,
|
|
654
|
+
reason: a,
|
|
655
|
+
syncFromCache: d
|
|
656
|
+
}), this.syncFromCache();
|
|
657
|
+
}
|
|
658
|
+
/** Checks the store cache and transitions to `fulfilled` if the record is already loaded. */
|
|
659
|
+
syncFromCache() {
|
|
660
|
+
const t = this.host.store._getRelationshipRefFor(this.host.parent, this.host.name);
|
|
661
|
+
if (!t || !t.data || Array.isArray(t.data)) {
|
|
662
|
+
this.currentValue = null, this.loadedState = "fulfilled";
|
|
663
|
+
return;
|
|
664
|
+
}
|
|
665
|
+
const e = this.host.store.peekRecord(t.data.type, t.data.id);
|
|
666
|
+
e && (this.currentValue = e, this.loadedState = "fulfilled");
|
|
667
|
+
}
|
|
668
|
+
/** `true` while the relationship has not yet been resolved. */
|
|
669
|
+
get isPending() {
|
|
670
|
+
return this.loadedState === "pending";
|
|
671
|
+
}
|
|
672
|
+
/** `true` once the relationship has been resolved (including to `null`). */
|
|
673
|
+
get isFulfilled() {
|
|
674
|
+
return this.loadedState === "fulfilled";
|
|
675
|
+
}
|
|
676
|
+
/** `true` if the network request failed. */
|
|
677
|
+
get isRejected() {
|
|
678
|
+
return this.loadedState === "rejected";
|
|
679
|
+
}
|
|
680
|
+
/** `true` while a network request is in flight. */
|
|
681
|
+
get isLoading() {
|
|
682
|
+
return this.inflight !== null && this.isPending;
|
|
683
|
+
}
|
|
684
|
+
/** `true` once the relationship is resolved. */
|
|
685
|
+
get isLoaded() {
|
|
686
|
+
return this.loadedState === "fulfilled";
|
|
687
|
+
}
|
|
688
|
+
/** The resolved record, or `null` when the relationship is empty or not yet loaded. */
|
|
689
|
+
get value() {
|
|
690
|
+
return this.currentValue;
|
|
691
|
+
}
|
|
692
|
+
/** The rejection reason if `isRejected`. */
|
|
693
|
+
get reason() {
|
|
694
|
+
return this.error;
|
|
695
|
+
}
|
|
696
|
+
/**
|
|
697
|
+
* Ensures the related record is loaded, returning a `Promise<T | null>`.
|
|
698
|
+
* If the record is already in the store it resolves immediately.
|
|
699
|
+
* Concurrent calls share the same in-flight promise.
|
|
700
|
+
*/
|
|
701
|
+
load() {
|
|
702
|
+
if (this.syncFromCache(), this.loadedState === "fulfilled" && this.currentValue)
|
|
703
|
+
return Promise.resolve(this.currentValue);
|
|
704
|
+
if (this.inflight)
|
|
705
|
+
return this.inflight;
|
|
706
|
+
const t = this.host.store._getRelationshipRefFor(this.host.parent, this.host.name);
|
|
707
|
+
if (!t || !t.data || Array.isArray(t.data))
|
|
708
|
+
return Promise.resolve(null);
|
|
709
|
+
const { type: e, id: i } = t.data;
|
|
710
|
+
return this.inflight = this.host.store.findRecord(e, i).then(
|
|
711
|
+
(r) => (l(() => {
|
|
712
|
+
this.currentValue = r, this.loadedState = "fulfilled", this.inflight = null;
|
|
713
|
+
}), r),
|
|
714
|
+
(r) => {
|
|
715
|
+
throw l(() => {
|
|
716
|
+
this.error = r, this.loadedState = "rejected", this.inflight = null;
|
|
717
|
+
}), r;
|
|
718
|
+
}
|
|
719
|
+
), this.inflight;
|
|
720
|
+
}
|
|
721
|
+
/** Forces a fresh fetch, ignoring any cached value. */
|
|
722
|
+
reload() {
|
|
723
|
+
return this.inflight = null, this.loadedState = "pending", this.load();
|
|
724
|
+
}
|
|
725
|
+
then(t, e) {
|
|
726
|
+
return this.load().then(t, e);
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
class L {
|
|
730
|
+
constructor(t) {
|
|
731
|
+
this.loadedState = "pending", this.error = null, this.inflight = null, this.host = t, this.manyArray = new u(t), c(this, {
|
|
732
|
+
loadedState: h,
|
|
733
|
+
error: h.ref,
|
|
734
|
+
isPending: a,
|
|
735
|
+
isFulfilled: a,
|
|
736
|
+
isRejected: a,
|
|
737
|
+
isLoaded: a,
|
|
738
|
+
isLoading: a,
|
|
739
|
+
length: a,
|
|
740
|
+
syncFromCache: d
|
|
741
|
+
}), this.syncFromCache();
|
|
742
|
+
}
|
|
743
|
+
/** Transitions to `fulfilled` if all referenced records are already in the cache. */
|
|
744
|
+
syncFromCache() {
|
|
745
|
+
const t = this.host.store._getRelationshipRefFor(this.host.parent, this.host.name);
|
|
746
|
+
u.refData(t).every(
|
|
747
|
+
(r) => this.host.store.peekRecord(r.type, r.id) !== null
|
|
748
|
+
) && (this.loadedState = "fulfilled");
|
|
749
|
+
}
|
|
750
|
+
/** `true` while the relationship has not yet been resolved. */
|
|
751
|
+
get isPending() {
|
|
752
|
+
return this.loadedState === "pending";
|
|
753
|
+
}
|
|
754
|
+
/** `true` once all referenced records have been resolved. */
|
|
755
|
+
get isFulfilled() {
|
|
756
|
+
return this.loadedState === "fulfilled";
|
|
757
|
+
}
|
|
758
|
+
/** `true` if any fetch failed. */
|
|
759
|
+
get isRejected() {
|
|
760
|
+
return this.loadedState === "rejected";
|
|
761
|
+
}
|
|
762
|
+
/** `true` while a network request is in flight. */
|
|
763
|
+
get isLoading() {
|
|
764
|
+
return this.inflight !== null && this.isPending;
|
|
765
|
+
}
|
|
766
|
+
/** `true` once the relationship is resolved. */
|
|
767
|
+
get isLoaded() {
|
|
768
|
+
return this.loadedState === "fulfilled";
|
|
769
|
+
}
|
|
770
|
+
/** The underlying `ManyArray` (always available, even before `load()`). */
|
|
771
|
+
get value() {
|
|
772
|
+
return this.manyArray;
|
|
773
|
+
}
|
|
774
|
+
/** Number of records currently in the resolved array. */
|
|
775
|
+
get length() {
|
|
776
|
+
return this.manyArray.length;
|
|
777
|
+
}
|
|
778
|
+
/**
|
|
779
|
+
* Ensures all referenced records are loaded.
|
|
780
|
+
* Records already in the cache are not re-fetched.
|
|
781
|
+
* Concurrent calls share the same in-flight promise.
|
|
782
|
+
*/
|
|
783
|
+
load() {
|
|
784
|
+
if (this.syncFromCache(), this.loadedState === "fulfilled")
|
|
785
|
+
return Promise.resolve(this.manyArray);
|
|
786
|
+
if (this.inflight)
|
|
787
|
+
return this.inflight;
|
|
788
|
+
const t = this.host.store._getRelationshipRefFor(this.host.parent, this.host.name), r = u.refData(t).filter(
|
|
789
|
+
(s) => this.host.store.peekRecord(s.type, s.id) === null
|
|
790
|
+
).map(
|
|
791
|
+
(s) => this.host.store.findRecord(s.type, s.id)
|
|
792
|
+
);
|
|
793
|
+
return this.inflight = Promise.all(r).then(
|
|
794
|
+
() => (l(() => {
|
|
795
|
+
this.loadedState = "fulfilled", this.inflight = null;
|
|
796
|
+
}), this.manyArray),
|
|
797
|
+
(s) => {
|
|
798
|
+
throw l(() => {
|
|
799
|
+
this.error = s, this.loadedState = "rejected", this.inflight = null;
|
|
800
|
+
}), s;
|
|
801
|
+
}
|
|
802
|
+
), this.inflight;
|
|
803
|
+
}
|
|
804
|
+
/** Forces a fresh fetch, ignoring any cached state. */
|
|
805
|
+
reload() {
|
|
806
|
+
return this.inflight = null, this.loadedState = "pending", this.load();
|
|
807
|
+
}
|
|
808
|
+
then(t, e) {
|
|
809
|
+
return this.load().then(t, e);
|
|
810
|
+
}
|
|
811
|
+
}
|
|
812
|
+
export {
|
|
813
|
+
k as A,
|
|
814
|
+
g as E,
|
|
815
|
+
u as M,
|
|
816
|
+
M as S,
|
|
817
|
+
L as a,
|
|
818
|
+
P as b,
|
|
819
|
+
D as c
|
|
820
|
+
};
|
|
821
|
+
//# sourceMappingURL=relationships-BEXANmWg.js.map
|