amplifyquery 2.0.3 → 2.0.5
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/README.md +1 -4
- package/dist/config.d.ts +1 -2
- package/dist/config.js +1 -2
- package/dist/service.js +40 -210
- package/dist/singleton.js +7 -9
- package/dist/types.d.ts +1 -11
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -166,10 +166,7 @@ const {
|
|
|
166
166
|
isLoading: isSettingsLoading,
|
|
167
167
|
update: upsertSettings, // creates if missing
|
|
168
168
|
refresh: refreshSettings,
|
|
169
|
-
} = UserSettingsService.
|
|
170
|
-
|
|
171
|
-
// Legacy alias (deprecated)
|
|
172
|
-
// UserSettingsService.useCurrentHook()
|
|
169
|
+
} = UserSettingsService.useSingletonHook();
|
|
173
170
|
```
|
|
174
171
|
|
|
175
172
|
### 4. Data Fetching and Saving
|
package/dist/config.d.ts
CHANGED
|
@@ -42,8 +42,7 @@ export declare function resetConfig(): void;
|
|
|
42
42
|
/**
|
|
43
43
|
* Enable/disable singleton auto-create behavior for singleton hooks.
|
|
44
44
|
*
|
|
45
|
-
* - **New**: `
|
|
46
|
-
* - **Legacy**: `useCurrentHook()` (deprecated alias)
|
|
45
|
+
* - **New**: `useSingletonHook()` (recommended)
|
|
47
46
|
*/
|
|
48
47
|
export declare function setSingletonAutoCreate(config: {
|
|
49
48
|
enabled?: boolean;
|
package/dist/config.js
CHANGED
|
@@ -93,8 +93,7 @@ function resetConfig() {
|
|
|
93
93
|
/**
|
|
94
94
|
* Enable/disable singleton auto-create behavior for singleton hooks.
|
|
95
95
|
*
|
|
96
|
-
* - **New**: `
|
|
97
|
-
* - **Legacy**: `useCurrentHook()` (deprecated alias)
|
|
96
|
+
* - **New**: `useSingletonHook()` (recommended)
|
|
98
97
|
*/
|
|
99
98
|
function setSingletonAutoCreate(config) {
|
|
100
99
|
globalConfig.singletonAutoCreate = {
|
package/dist/service.js
CHANGED
|
@@ -68,40 +68,14 @@ function areItemArraysEquivalentById(a, b) {
|
|
|
68
68
|
function getOwnerByAuthMode(authMode) {
|
|
69
69
|
return __awaiter(this, void 0, void 0, function* () {
|
|
70
70
|
let owner = "";
|
|
71
|
-
let ownerCandidates = [];
|
|
72
71
|
// Set owner value only in userPool auth mode
|
|
73
72
|
if (authMode === "userPool") {
|
|
74
73
|
try {
|
|
75
74
|
const { username, userId } = yield (0, auth_1.getCurrentUser)();
|
|
76
|
-
//
|
|
77
|
-
//
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
// This prevents a common bug where some records are written with `sub` (userId)
|
|
81
|
-
// while the owner secondary index is queried with `username`, or vice versa,
|
|
82
|
-
// causing refetch to "lose" most items and overwrite cache with a partial list.
|
|
83
|
-
const canonicalUsername = typeof username === "string" ? username : "";
|
|
84
|
-
const canonicalSub = typeof userId === "string" ? userId : "";
|
|
85
|
-
const legacyOwner = canonicalSub && canonicalUsername && canonicalUsername !== canonicalSub
|
|
86
|
-
? `${canonicalSub}::${canonicalUsername}`
|
|
87
|
-
: "";
|
|
88
|
-
// Preferred owner value for create/update payloads.
|
|
89
|
-
owner = canonicalUsername || canonicalSub;
|
|
90
|
-
// Preferred owner candidates for list-by-owner queries.
|
|
91
|
-
// If username is available, ONLY use username-based owner to keep list results consistent.
|
|
92
|
-
// If username is missing for some reason, fall back to sub to avoid total failure.
|
|
93
|
-
const candidates = canonicalUsername
|
|
94
|
-
? [canonicalUsername, legacyOwner]
|
|
95
|
-
: [canonicalSub];
|
|
96
|
-
ownerCandidates = Array.from(new Set(candidates.filter((v) => typeof v === "string" && v.length > 0)));
|
|
97
|
-
// Debug: surface the actual Cognito identifiers in dev logs
|
|
98
|
-
(0, config_1.debugLog)(`🍬 Auth identity resolved`, {
|
|
99
|
-
authMode,
|
|
100
|
-
username,
|
|
101
|
-
userId,
|
|
102
|
-
owner,
|
|
103
|
-
ownerCandidates,
|
|
104
|
-
});
|
|
75
|
+
// Keep behavior consistent with old-AmplifyQuery:
|
|
76
|
+
// owner = `${userId}::${username}`
|
|
77
|
+
owner = `${userId}::${username}`;
|
|
78
|
+
(0, config_1.debugLog)(`🍬 Auth identity resolved`, { authMode, username, userId, owner });
|
|
105
79
|
}
|
|
106
80
|
catch (error) {
|
|
107
81
|
console.error("Error getting user authentication info:", error);
|
|
@@ -111,7 +85,6 @@ function getOwnerByAuthMode(authMode) {
|
|
|
111
85
|
// Return with auth mode parameters
|
|
112
86
|
return {
|
|
113
87
|
owner,
|
|
114
|
-
ownerCandidates,
|
|
115
88
|
authModeParams: { authMode },
|
|
116
89
|
};
|
|
117
90
|
});
|
|
@@ -306,8 +279,8 @@ function createAmplifyService(modelName, defaultAuthMode) {
|
|
|
306
279
|
}
|
|
307
280
|
// Determine auth mode (use provided option if available)
|
|
308
281
|
const authMode = (options === null || options === void 0 ? void 0 : options.authMode) || currentAuthMode;
|
|
309
|
-
// Get
|
|
310
|
-
const {
|
|
282
|
+
// Get parameters based on auth mode
|
|
283
|
+
const { authModeParams } = yield getOwnerByAuthMode(authMode);
|
|
311
284
|
const dataWithoutOwner = utils_1.Utils.removeOwnerField(data, "create");
|
|
312
285
|
const cleanedData = {};
|
|
313
286
|
Object.entries(dataWithoutOwner).forEach(([key, value]) => {
|
|
@@ -358,8 +331,11 @@ function createAmplifyService(modelName, defaultAuthMode) {
|
|
|
358
331
|
});
|
|
359
332
|
}
|
|
360
333
|
}
|
|
361
|
-
else if (queryKey.length
|
|
362
|
-
// Regular list query (
|
|
334
|
+
else if (queryKey.length < 3 && queryKey[1] !== "currentId") {
|
|
335
|
+
// Regular list query (old-AmplifyQuery behavior: update all short list keys)
|
|
336
|
+
// - [Model]
|
|
337
|
+
// - [Model, ...] (length 2)
|
|
338
|
+
// But avoid internal singleton keys like ["User","currentId"].
|
|
363
339
|
const data = query_1.queryClient.getQueryData(queryKey);
|
|
364
340
|
if (data) {
|
|
365
341
|
previousDataMap.set(queryKey, data);
|
|
@@ -373,21 +349,7 @@ function createAmplifyService(modelName, defaultAuthMode) {
|
|
|
373
349
|
try {
|
|
374
350
|
// Attempt API call - apply auth mode
|
|
375
351
|
(0, config_1.debugLog)(`🍬 ${modelName} creation attempt [Auth: ${authMode}]:`, newItem.id);
|
|
376
|
-
|
|
377
|
-
// but retry without it if the model doesn't define it.
|
|
378
|
-
const createPayload = owner ? Object.assign(Object.assign({}, newItem), { owner }) : newItem;
|
|
379
|
-
let createdItem = null;
|
|
380
|
-
try {
|
|
381
|
-
({ data: createdItem } = yield (0, client_1.getClient)().models[modelName].create(createPayload, authModeParams));
|
|
382
|
-
}
|
|
383
|
-
catch (e) {
|
|
384
|
-
if (owner && isOwnerNotInSchemaError(e)) {
|
|
385
|
-
({ data: createdItem } = yield (0, client_1.getClient)().models[modelName].create(newItem, authModeParams));
|
|
386
|
-
}
|
|
387
|
-
else {
|
|
388
|
-
throw e;
|
|
389
|
-
}
|
|
390
|
-
}
|
|
352
|
+
const { data: createdItem } = yield (0, client_1.getClient)().models[modelName].create(newItem, authModeParams);
|
|
391
353
|
if (createdItem) {
|
|
392
354
|
// Update cache on API success
|
|
393
355
|
query_1.queryClient.setQueryData(singleItemQueryKey, createdItem);
|
|
@@ -436,8 +398,8 @@ function createAmplifyService(modelName, defaultAuthMode) {
|
|
|
436
398
|
}
|
|
437
399
|
// Determine auth mode (use provided option if available)
|
|
438
400
|
const authMode = (options === null || options === void 0 ? void 0 : options.authMode) || currentAuthMode;
|
|
439
|
-
// Get
|
|
440
|
-
const {
|
|
401
|
+
// Get parameters based on auth mode
|
|
402
|
+
const { authModeParams } = yield getOwnerByAuthMode(authMode);
|
|
441
403
|
const preparedItems = dataList
|
|
442
404
|
.map((data) => {
|
|
443
405
|
if (!data)
|
|
@@ -489,8 +451,9 @@ function createAmplifyService(modelName, defaultAuthMode) {
|
|
|
489
451
|
return oldItems; // No change if no items match relation ID
|
|
490
452
|
});
|
|
491
453
|
}
|
|
492
|
-
else if (queryKey.length
|
|
493
|
-
// Regular list query - add all items (
|
|
454
|
+
else if (queryKey.length < 3 && queryKey[1] !== "currentId") {
|
|
455
|
+
// Regular list query - add all items (old-AmplifyQuery behavior)
|
|
456
|
+
// Avoid internal singleton keys like ["User","currentId"].
|
|
494
457
|
query_1.queryClient.setQueryData(queryKey, (oldData) => {
|
|
495
458
|
const oldItems = Array.isArray(oldData) ? oldData : [];
|
|
496
459
|
return [...oldItems, ...preparedItems];
|
|
@@ -508,20 +471,7 @@ function createAmplifyService(modelName, defaultAuthMode) {
|
|
|
508
471
|
// Parallel API calls - apply auth mode
|
|
509
472
|
const createPromises = preparedItems.map((newItem) => __awaiter(this, void 0, void 0, function* () {
|
|
510
473
|
try {
|
|
511
|
-
const
|
|
512
|
-
? Object.assign(Object.assign({}, newItem), { owner }) : newItem;
|
|
513
|
-
let createdItem = null;
|
|
514
|
-
try {
|
|
515
|
-
({ data: createdItem } = yield (0, client_1.getClient)().models[modelName].create(createPayload, authModeParams));
|
|
516
|
-
}
|
|
517
|
-
catch (e) {
|
|
518
|
-
if (owner && isOwnerNotInSchemaError(e)) {
|
|
519
|
-
({ data: createdItem } = yield (0, client_1.getClient)().models[modelName].create(newItem, authModeParams));
|
|
520
|
-
}
|
|
521
|
-
else {
|
|
522
|
-
throw e;
|
|
523
|
-
}
|
|
524
|
-
}
|
|
474
|
+
const { data: createdItem } = yield (0, client_1.getClient)().models[modelName].create(newItem, authModeParams);
|
|
525
475
|
// Update individual item cache on API success
|
|
526
476
|
if (createdItem) {
|
|
527
477
|
const itemId = createdItem === null || createdItem === void 0 ? void 0 : createdItem.id;
|
|
@@ -649,7 +599,7 @@ function createAmplifyService(modelName, defaultAuthMode) {
|
|
|
649
599
|
}),
|
|
650
600
|
// Batch get items
|
|
651
601
|
list: (...args_1) => __awaiter(this, [...args_1], void 0, function* (options = { filter: undefined, forceRefresh: false, throwOnError: false }) {
|
|
652
|
-
var _a, _b, _c, _d
|
|
602
|
+
var _a, _b, _c, _d;
|
|
653
603
|
try {
|
|
654
604
|
// Determine query key
|
|
655
605
|
const queryKey = options.filter
|
|
@@ -669,63 +619,21 @@ function createAmplifyService(modelName, defaultAuthMode) {
|
|
|
669
619
|
// Determine auth mode (use provided option if available)
|
|
670
620
|
const authMode = (options === null || options === void 0 ? void 0 : options.authMode) || currentAuthMode;
|
|
671
621
|
// Get owner and parameters based on auth mode
|
|
672
|
-
const { owner,
|
|
622
|
+
const { owner, authModeParams } = yield getOwnerByAuthMode(authMode);
|
|
673
623
|
// Get owner-based query name from global config
|
|
674
624
|
const ownerQueryName = (0, config_1.getOwnerQueryName)(modelName);
|
|
675
625
|
// Try query call
|
|
676
626
|
try {
|
|
677
627
|
(0, config_1.debugLog)(`🍬 ${modelName} list API call`, queryKey, `by ${ownerQueryName}`, `[Auth: ${authMode}]`);
|
|
678
628
|
if ((0, config_1.isDebugEnabled)()) {
|
|
679
|
-
// Debug: Check if model and query exist
|
|
680
629
|
const client = (0, client_1.getClient)();
|
|
681
630
|
(0, config_1.debugLog)(`🍬 Debug - client.models exists:`, !!client.models);
|
|
682
631
|
(0, config_1.debugLog)(`🍬 Debug - client.models[${modelName}] exists:`, !!client.models[modelName]);
|
|
683
632
|
(0, config_1.debugLog)(`🍬 Debug - client.models[${modelName}][${ownerQueryName}] exists:`, !!((_a = client.models[modelName]) === null || _a === void 0 ? void 0 : _a[ownerQueryName]));
|
|
684
633
|
(0, config_1.debugLog)(`🍬 Debug - Available methods for ${modelName}:`, Object.keys(client.models[modelName] || {}));
|
|
685
634
|
}
|
|
686
|
-
|
|
687
|
-
const
|
|
688
|
-
// Execute owner query (try multiple owner candidates)
|
|
689
|
-
const ownersToTry = Array.isArray(ownerCandidates) && ownerCandidates.length > 0
|
|
690
|
-
? ownerCandidates
|
|
691
|
-
: owner
|
|
692
|
-
? [owner]
|
|
693
|
-
: [];
|
|
694
|
-
if (!(model === null || model === void 0 ? void 0 : model[ownerQueryName]) || ownersToTry.length === 0) {
|
|
695
|
-
throw new Error(`owner query not available or owner missing: ${modelName}.${ownerQueryName}`);
|
|
696
|
-
}
|
|
697
|
-
let result = null;
|
|
698
|
-
let usedOwner = null;
|
|
699
|
-
for (const candidateOwner of ownersToTry) {
|
|
700
|
-
(0, config_1.debugLog)(`🍬 ${modelName} list owner-query attempt`, `[${ownerQueryName}]`, { owner: candidateOwner, authMode });
|
|
701
|
-
// Generated secondary index query typically expects { owner } only.
|
|
702
|
-
const { data } = yield model[ownerQueryName]({ owner: candidateOwner }, authModeParams);
|
|
703
|
-
const items = ((data === null || data === void 0 ? void 0 : data.items) || (data === null || data === void 0 ? void 0 : data.data) || data || []).filter((item) => item !== null);
|
|
704
|
-
if (items.length > 0) {
|
|
705
|
-
result = data;
|
|
706
|
-
usedOwner = candidateOwner;
|
|
707
|
-
break;
|
|
708
|
-
}
|
|
709
|
-
// If empty, try next candidate (legacy owner format)
|
|
710
|
-
}
|
|
711
|
-
// If owner-query returns empty for all candidates, fall back to default list().
|
|
712
|
-
// This prevents "data disappears on refetch" when the project stores owner using
|
|
713
|
-
// a different identity claim than expected (e.g., username vs sub) OR when the
|
|
714
|
-
// owner secondary index exists but doesn't match stored owner values.
|
|
715
|
-
if (!result) {
|
|
716
|
-
(0, config_1.debugWarn)(`🍬 ${modelName} list: owner-query returned 0 items for all candidates, falling back to model.list()`, { ownersToTry, authMode });
|
|
717
|
-
const { data: fallback } = yield model.list({}, authModeParams);
|
|
718
|
-
const fallbackItems = ((fallback === null || fallback === void 0 ? void 0 : fallback.items) ||
|
|
719
|
-
(fallback === null || fallback === void 0 ? void 0 : fallback.data) ||
|
|
720
|
-
fallback ||
|
|
721
|
-
[]).filter((item) => item !== null);
|
|
722
|
-
// Use the same shape below by setting `result` to array-ish
|
|
723
|
-
result = fallbackItems;
|
|
724
|
-
usedOwner = null;
|
|
725
|
-
}
|
|
726
|
-
if (usedOwner && usedOwner !== ownersToTry[0]) {
|
|
727
|
-
(0, config_1.debugWarn)(`🍬 ${modelName} list: owner-query returned results only for legacy owner format`, { tried: ownersToTry, usedOwner });
|
|
728
|
-
}
|
|
635
|
+
// Execute owner query (old-AmplifyQuery behavior)
|
|
636
|
+
const { data: result } = yield (0, client_1.getClient)().models[modelName][ownerQueryName]({ owner, authMode }, authModeParams);
|
|
729
637
|
// Extract result data + filter null values
|
|
730
638
|
const items = ((result === null || result === void 0 ? void 0 : result.items) || (result === null || result === void 0 ? void 0 : result.data) || result || []).filter((item) => item !== null);
|
|
731
639
|
// Apply filter (if client-side filtering needed)
|
|
@@ -773,11 +681,9 @@ function createAmplifyService(modelName, defaultAuthMode) {
|
|
|
773
681
|
}
|
|
774
682
|
catch (error) {
|
|
775
683
|
// Check if the error is because the owner query doesn't exist
|
|
776
|
-
if (((
|
|
777
|
-
((
|
|
778
|
-
((
|
|
779
|
-
((_f = error === null || error === void 0 ? void 0 : error.message) === null || _f === void 0 ? void 0 : _f.includes("owner query not available")) ||
|
|
780
|
-
((_g = error === null || error === void 0 ? void 0 : error.message) === null || _g === void 0 ? void 0 : _g.includes("owner missing"))) {
|
|
684
|
+
if (((_b = error === null || error === void 0 ? void 0 : error.message) === null || _b === void 0 ? void 0 : _b.includes("not found")) ||
|
|
685
|
+
((_c = error === null || error === void 0 ? void 0 : error.message) === null || _c === void 0 ? void 0 : _c.includes("is not a function")) ||
|
|
686
|
+
((_d = error === null || error === void 0 ? void 0 : error.message) === null || _d === void 0 ? void 0 : _d.includes("is undefined"))) {
|
|
781
687
|
console.warn(`🍬 ${ownerQueryName} query not found. Trying default list query...`);
|
|
782
688
|
// Try default list query if owner query not found
|
|
783
689
|
const { data: result } = yield (0, client_1.getClient)().models[modelName].list({}, authModeParams);
|
|
@@ -1155,13 +1061,14 @@ function createAmplifyService(modelName, defaultAuthMode) {
|
|
|
1155
1061
|
// Determine auth mode (use provided options if available)
|
|
1156
1062
|
const authMode = (options === null || options === void 0 ? void 0 : options.authMode) || currentAuthMode;
|
|
1157
1063
|
// Get owner and parameters based on auth mode
|
|
1158
|
-
const { owner,
|
|
1159
|
-
// Add owner value to queries requiring owner field when userPool auth
|
|
1160
|
-
// IMPORTANT: many projects store owner as `cognito:username`, not `sub`.
|
|
1161
|
-
// If this is an owner-based index query, try multiple owner candidates to
|
|
1162
|
-
// avoid returning empty results and accidentally clearing UI state on refetch.
|
|
1163
|
-
const isOwnerQuery = authMode === "userPool" && queryName.toLowerCase().includes("owner");
|
|
1064
|
+
const { owner, authModeParams } = yield getOwnerByAuthMode(authMode);
|
|
1065
|
+
// Add owner value to queries requiring owner field when userPool auth
|
|
1164
1066
|
const enhancedArgs = Object.assign({}, args);
|
|
1067
|
+
if (owner &&
|
|
1068
|
+
authMode === "userPool" &&
|
|
1069
|
+
queryName.toLowerCase().includes("owner")) {
|
|
1070
|
+
enhancedArgs.owner = owner;
|
|
1071
|
+
}
|
|
1165
1072
|
// Detect relational query (if fields like dailyId, userId exist)
|
|
1166
1073
|
const relationField = Object.keys(enhancedArgs).find((key) => key.endsWith("Id"));
|
|
1167
1074
|
const isRelationalQuery = !!relationField;
|
|
@@ -1197,40 +1104,8 @@ function createAmplifyService(modelName, defaultAuthMode) {
|
|
|
1197
1104
|
if (!((_a = (0, client_1.getClient)().models[modelName]) === null || _a === void 0 ? void 0 : _a[queryName])) {
|
|
1198
1105
|
throw new Error(`🍬 Query ${queryName} does not exist.`);
|
|
1199
1106
|
}
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
let result = null;
|
|
1203
|
-
if (isOwnerQuery) {
|
|
1204
|
-
const candidates = [
|
|
1205
|
-
// If caller explicitly passed owner, try that first
|
|
1206
|
-
typeof (args === null || args === void 0 ? void 0 : args.owner) === "string" ? args.owner : "",
|
|
1207
|
-
...(Array.isArray(ownerCandidates) ? ownerCandidates : []),
|
|
1208
|
-
typeof owner === "string" ? owner : "",
|
|
1209
|
-
].filter((v) => typeof v === "string" && v.length > 0);
|
|
1210
|
-
const ownersToTry = Array.from(new Set(candidates));
|
|
1211
|
-
if (ownersToTry.length === 0) {
|
|
1212
|
-
throw new Error(`🍬 owner is missing for ${modelName}.${queryName}`);
|
|
1213
|
-
}
|
|
1214
|
-
for (const candidateOwner of ownersToTry) {
|
|
1215
|
-
const nextArgs = Object.assign(Object.assign({}, enhancedArgs), { owner: candidateOwner });
|
|
1216
|
-
const { data } = yield model[queryName](nextArgs, authModeParams);
|
|
1217
|
-
const items = ((data === null || data === void 0 ? void 0 : data.items) || (data === null || data === void 0 ? void 0 : data.data) || data || []).filter((item) => item !== null);
|
|
1218
|
-
if (items.length > 0) {
|
|
1219
|
-
result = data;
|
|
1220
|
-
if (candidateOwner !== ownersToTry[0]) {
|
|
1221
|
-
(0, config_1.debugWarn)(`🍬 ${modelName} ${queryName}: returned results only for non-primary owner candidate`, { tried: ownersToTry, usedOwner: candidateOwner });
|
|
1222
|
-
}
|
|
1223
|
-
break;
|
|
1224
|
-
}
|
|
1225
|
-
}
|
|
1226
|
-
// If still empty, return empty list (do not throw unless requested)
|
|
1227
|
-
if (!result) {
|
|
1228
|
-
result = [];
|
|
1229
|
-
}
|
|
1230
|
-
}
|
|
1231
|
-
else {
|
|
1232
|
-
({ data: result } = yield model[queryName](enhancedArgs, authModeParams));
|
|
1233
|
-
}
|
|
1107
|
+
// Execute index query - apply auth mode
|
|
1108
|
+
const { data: result } = yield (0, client_1.getClient)().models[modelName][queryName](enhancedArgs, authModeParams);
|
|
1234
1109
|
// Extract result data
|
|
1235
1110
|
const items = (result === null || result === void 0 ? void 0 : result.items) || (result === null || result === void 0 ? void 0 : result.data) || result || [];
|
|
1236
1111
|
(0, config_1.debugLog)(`🍬 ${modelName} ${queryName} result:`, items.length, "items");
|
|
@@ -1301,7 +1176,7 @@ function createAmplifyService(modelName, defaultAuthMode) {
|
|
|
1301
1176
|
},
|
|
1302
1177
|
// React Hook returning method - Reimplemented based on TanStack Query
|
|
1303
1178
|
useHook: (options) => {
|
|
1304
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o
|
|
1179
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
|
|
1305
1180
|
const hookQueryClient = (0, react_query_1.useQueryClient)();
|
|
1306
1181
|
// Determine query key
|
|
1307
1182
|
const queryKey = (0, react_1.useMemo)(() => {
|
|
@@ -1590,57 +1465,12 @@ function createAmplifyService(modelName, defaultAuthMode) {
|
|
|
1590
1465
|
}), [service, refetch] // refetch dependency added
|
|
1591
1466
|
);
|
|
1592
1467
|
const refresh = (0, react_1.useCallback)((refreshOptions) => __awaiter(this, void 0, void 0, function* () {
|
|
1593
|
-
var _a;
|
|
1594
1468
|
(0, config_1.debugLog)(`🍬 ${modelName} useHook refresh called`, queryKey);
|
|
1595
|
-
//
|
|
1596
|
-
//
|
|
1597
|
-
const
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
// If filter is provided and different from current filter, we'd need a new query key.
|
|
1601
|
-
// For now, we ignore refreshOptions.filter and refresh the current hook query only.
|
|
1602
|
-
if (refreshOptions === null || refreshOptions === void 0 ? void 0 : refreshOptions.filter) {
|
|
1603
|
-
console.warn(`🍬 ${modelName} useHook refresh: refreshOptions.filter is currently ignored (queryKey is fixed per hook instance).`);
|
|
1604
|
-
}
|
|
1605
|
-
let newData = [];
|
|
1606
|
-
if (options === null || options === void 0 ? void 0 : options.customList) {
|
|
1607
|
-
newData = yield service.customList(options.customList.queryName, options.customList.args, { forceRefresh: true, throwOnError: true });
|
|
1608
|
-
}
|
|
1609
|
-
else if ((_a = options === null || options === void 0 ? void 0 : options.initialFetchOptions) === null || _a === void 0 ? void 0 : _a.filter) {
|
|
1610
|
-
newData = yield service.list({
|
|
1611
|
-
filter: options.initialFetchOptions.filter,
|
|
1612
|
-
forceRefresh: true,
|
|
1613
|
-
throwOnError: true,
|
|
1614
|
-
});
|
|
1615
|
-
}
|
|
1616
|
-
else {
|
|
1617
|
-
newData = yield service.list({
|
|
1618
|
-
forceRefresh: true,
|
|
1619
|
-
throwOnError: true,
|
|
1620
|
-
});
|
|
1621
|
-
}
|
|
1622
|
-
(0, config_1.debugLog)(`🍬 ${modelName} useHook refresh - server refresh result:`, (newData === null || newData === void 0 ? void 0 : newData.length) || 0, "items");
|
|
1623
|
-
// Keep hook cache in sync with hook's queryKey.
|
|
1624
|
-
hookQueryClient.setQueryData(queryKey, newData);
|
|
1625
|
-
return newData || [];
|
|
1626
|
-
}
|
|
1627
|
-
catch (e) {
|
|
1628
|
-
console.error(`🍬 ${modelName} useHook refresh error:`, e);
|
|
1629
|
-
// On error, restore previous data if available (prevents list flashing empty)
|
|
1630
|
-
if (currentData && currentData.length > 0) {
|
|
1631
|
-
hookQueryClient.setQueryData(queryKey, currentData);
|
|
1632
|
-
return currentData;
|
|
1633
|
-
}
|
|
1634
|
-
return [];
|
|
1635
|
-
}
|
|
1636
|
-
}), [
|
|
1637
|
-
modelName,
|
|
1638
|
-
queryKey,
|
|
1639
|
-
hookQueryClient,
|
|
1640
|
-
service,
|
|
1641
|
-
options === null || options === void 0 ? void 0 : options.customList,
|
|
1642
|
-
(_p = options === null || options === void 0 ? void 0 : options.initialFetchOptions) === null || _p === void 0 ? void 0 : _p.filter,
|
|
1643
|
-
]);
|
|
1469
|
+
// Keep behavior consistent with old-AmplifyQuery:
|
|
1470
|
+
// refresh == refetch() (same queryFn as initial load)
|
|
1471
|
+
const { data } = yield refetch({ throwOnError: true });
|
|
1472
|
+
return data || [];
|
|
1473
|
+
}), [refetch, queryKey, modelName]);
|
|
1644
1474
|
const customListFn = (0, react_1.useCallback)((queryName, args, options) => __awaiter(this, void 0, void 0, function* () {
|
|
1645
1475
|
try {
|
|
1646
1476
|
const result = yield service.customList(queryName, args, options);
|
package/dist/singleton.js
CHANGED
|
@@ -102,7 +102,7 @@ function createSingletonService(baseService, getModelId) {
|
|
|
102
102
|
}
|
|
103
103
|
}),
|
|
104
104
|
// React hook to manage the current singleton item
|
|
105
|
-
|
|
105
|
+
useSingletonHook: (options) => {
|
|
106
106
|
const { data: currentId, isLoading: isIdLoading, error: idError, refetch: refetchId, } = (0, react_query_1.useQuery)({
|
|
107
107
|
queryKey: [modelName, "currentId"],
|
|
108
108
|
queryFn: () => __awaiter(this, void 0, void 0, function* () {
|
|
@@ -118,7 +118,7 @@ function createSingletonService(baseService, getModelId) {
|
|
|
118
118
|
refetchOnWindowFocus: false,
|
|
119
119
|
});
|
|
120
120
|
const idForItemHook = currentId !== null && currentId !== void 0 ? currentId : "";
|
|
121
|
-
(0, config_2.debugLog)(`🍬 ${modelName}
|
|
121
|
+
(0, config_2.debugLog)(`🍬 ${modelName} useSingletonHook currentId`, {
|
|
122
122
|
currentId,
|
|
123
123
|
idForItemHook,
|
|
124
124
|
});
|
|
@@ -134,7 +134,7 @@ function createSingletonService(baseService, getModelId) {
|
|
|
134
134
|
const isLoading = isIdLoading || core.isLoading;
|
|
135
135
|
const error = idError || core.error || null;
|
|
136
136
|
(0, react_1.useEffect)(() => {
|
|
137
|
-
(0, config_2.debugLog)(`🍬 ${modelName}
|
|
137
|
+
(0, config_2.debugLog)(`🍬 ${modelName} useSingletonHook effect check`, {
|
|
138
138
|
currentId,
|
|
139
139
|
isLoading,
|
|
140
140
|
autoCreateEnabled,
|
|
@@ -158,18 +158,18 @@ function createSingletonService(baseService, getModelId) {
|
|
|
158
158
|
// Best-effort: create { id } if missing.
|
|
159
159
|
void (() => __awaiter(this, void 0, void 0, function* () {
|
|
160
160
|
try {
|
|
161
|
-
(0, config_2.debugWarn)(`🍬 ${modelName}
|
|
161
|
+
(0, config_2.debugWarn)(`🍬 ${modelName} useSingletonHook auto-create starting`, {
|
|
162
162
|
currentId,
|
|
163
163
|
});
|
|
164
164
|
yield singletonService.upsertCurrent({});
|
|
165
165
|
yield singletonService.getCurrent({ forceRefresh: true });
|
|
166
|
-
(0, config_2.debugLog)(`🍬 ${modelName}
|
|
166
|
+
(0, config_2.debugLog)(`🍬 ${modelName} useSingletonHook auto-create done`, {
|
|
167
167
|
currentId,
|
|
168
168
|
});
|
|
169
169
|
}
|
|
170
170
|
catch (e) {
|
|
171
171
|
attemptedAutoCreateForIdRef.current = null; // allow retry later
|
|
172
|
-
(0, config_2.debugWarn)(`🍬 ${modelName}
|
|
172
|
+
(0, config_2.debugWarn)(`🍬 ${modelName} useSingletonHook auto-create failed:`, e);
|
|
173
173
|
}
|
|
174
174
|
}))();
|
|
175
175
|
}, [currentId, isLoading, item, modelName, autoCreateEnabled, error]);
|
|
@@ -200,9 +200,7 @@ function createSingletonService(baseService, getModelId) {
|
|
|
200
200
|
}
|
|
201
201
|
});
|
|
202
202
|
return { item, isLoading, error, refresh, update, delete: remove };
|
|
203
|
-
}
|
|
204
|
-
// Backward-compatible alias
|
|
205
|
-
useCurrentHook: (options) => singletonService.useSigletoneHook(options) });
|
|
203
|
+
} });
|
|
206
204
|
return singletonService;
|
|
207
205
|
}
|
|
208
206
|
/**
|
package/dist/types.d.ts
CHANGED
|
@@ -121,7 +121,7 @@ export interface SingletonAmplifyService<T> extends AmplifyDataService<T> {
|
|
|
121
121
|
}) => Promise<T | null>;
|
|
122
122
|
updateCurrent: (data: Partial<T>) => Promise<T | null>;
|
|
123
123
|
upsertCurrent: (data: Partial<T>) => Promise<T | null>;
|
|
124
|
-
|
|
124
|
+
useSingletonHook: (options?: {
|
|
125
125
|
/**
|
|
126
126
|
* When true (default), if the singleton item does not exist it will be created.
|
|
127
127
|
* You can set false to disable auto-create for this hook call.
|
|
@@ -132,16 +132,6 @@ export interface SingletonAmplifyService<T> extends AmplifyDataService<T> {
|
|
|
132
132
|
observeOptions?: Record<string, any>;
|
|
133
133
|
};
|
|
134
134
|
}) => ItemHook<T>;
|
|
135
|
-
/**
|
|
136
|
-
* @deprecated Use useSigletoneHook() instead.
|
|
137
|
-
*/
|
|
138
|
-
useCurrentHook: (options?: {
|
|
139
|
-
autoCreate?: boolean;
|
|
140
|
-
realtime?: {
|
|
141
|
-
enabled?: boolean;
|
|
142
|
-
observeOptions?: Record<string, any>;
|
|
143
|
-
};
|
|
144
|
-
}) => ItemHook<T>;
|
|
145
135
|
}
|
|
146
136
|
export interface BaseModel {
|
|
147
137
|
id: string;
|