mirror of
https://github.com/MrUnknownDE/VRCX.git
synced 2026-05-06 22:46:06 +02:00
refactor queryRequest
This commit is contained in:
+16
-81
@@ -42,21 +42,11 @@ const registry = Object.freeze({
|
|||||||
policy: entityQueryPolicies.group,
|
policy: entityQueryPolicies.group,
|
||||||
queryFn: (params) => groupRequest.getGroup(params)
|
queryFn: (params) => groupRequest.getGroup(params)
|
||||||
},
|
},
|
||||||
groupPosts: {
|
|
||||||
key: (params) => queryKeys.groupPosts(params),
|
|
||||||
policy: entityQueryPolicies.groupCollection,
|
|
||||||
queryFn: (params) => groupRequest.getGroupPosts(params)
|
|
||||||
},
|
|
||||||
groupMember: {
|
groupMember: {
|
||||||
key: (params) => queryKeys.groupMember(params),
|
key: (params) => queryKeys.groupMember(params),
|
||||||
policy: entityQueryPolicies.groupCollection,
|
policy: entityQueryPolicies.groupCollection,
|
||||||
queryFn: (params) => groupRequest.getGroupMember(params)
|
queryFn: (params) => groupRequest.getGroupMember(params)
|
||||||
},
|
},
|
||||||
groupMembers: {
|
|
||||||
key: (params) => queryKeys.groupMembers(params),
|
|
||||||
policy: entityQueryPolicies.groupCollection,
|
|
||||||
queryFn: (params) => groupRequest.getGroupMembers(params)
|
|
||||||
},
|
|
||||||
groupGallery: {
|
groupGallery: {
|
||||||
key: (params) => queryKeys.groupGallery(params),
|
key: (params) => queryKeys.groupGallery(params),
|
||||||
policy: entityQueryPolicies.groupCollection,
|
policy: entityQueryPolicies.groupCollection,
|
||||||
@@ -67,21 +57,6 @@ const registry = Object.freeze({
|
|||||||
policy: entityQueryPolicies.groupCollection,
|
policy: entityQueryPolicies.groupCollection,
|
||||||
queryFn: (params) => groupRequest.getGroupCalendar(params.groupId)
|
queryFn: (params) => groupRequest.getGroupCalendar(params.groupId)
|
||||||
},
|
},
|
||||||
groupCalendars: {
|
|
||||||
key: (params) => queryKeys.groupCalendars(params),
|
|
||||||
policy: entityQueryPolicies.groupCalendarCollection,
|
|
||||||
queryFn: (params) => groupRequest.getGroupCalendars(params)
|
|
||||||
},
|
|
||||||
followingGroupCalendars: {
|
|
||||||
key: (params) => queryKeys.followingGroupCalendars(params),
|
|
||||||
policy: entityQueryPolicies.groupFollowingCalendarCollection,
|
|
||||||
queryFn: (params) => groupRequest.getFollowingGroupCalendars(params)
|
|
||||||
},
|
|
||||||
featuredGroupCalendars: {
|
|
||||||
key: (params) => queryKeys.featuredGroupCalendars(params),
|
|
||||||
policy: entityQueryPolicies.groupFeaturedCalendarCollection,
|
|
||||||
queryFn: (params) => groupRequest.getFeaturedGroupCalendars(params)
|
|
||||||
},
|
|
||||||
groupCalendarEvent: {
|
groupCalendarEvent: {
|
||||||
key: (params) => queryKeys.groupCalendarEvent(params),
|
key: (params) => queryKeys.groupCalendarEvent(params),
|
||||||
policy: entityQueryPolicies.groupCalendarEvent,
|
policy: entityQueryPolicies.groupCalendarEvent,
|
||||||
@@ -92,71 +67,16 @@ const registry = Object.freeze({
|
|||||||
policy: entityQueryPolicies.avatarGallery,
|
policy: entityQueryPolicies.avatarGallery,
|
||||||
queryFn: (params) => avatarRequest.getAvatarGallery(params.avatarId)
|
queryFn: (params) => avatarRequest.getAvatarGallery(params.avatarId)
|
||||||
},
|
},
|
||||||
friends: {
|
|
||||||
key: (params) => queryKeys.friends(params),
|
|
||||||
policy: entityQueryPolicies.friendList,
|
|
||||||
queryFn: (params) => friendRequest.getFriends(params)
|
|
||||||
},
|
|
||||||
favoriteLimits: {
|
favoriteLimits: {
|
||||||
key: () => queryKeys.favoriteLimits(),
|
key: () => queryKeys.favoriteLimits(),
|
||||||
policy: entityQueryPolicies.favoriteCollection,
|
policy: entityQueryPolicies.favoriteLimits,
|
||||||
queryFn: () => favoriteRequest.getFavoriteLimits()
|
queryFn: () => favoriteRequest.getFavoriteLimits()
|
||||||
},
|
},
|
||||||
favorites: {
|
|
||||||
key: (params) => queryKeys.favorites(params),
|
|
||||||
policy: entityQueryPolicies.favoriteCollection,
|
|
||||||
queryFn: (params) => favoriteRequest.getFavorites(params)
|
|
||||||
},
|
|
||||||
favoriteGroups: {
|
|
||||||
key: (params) => queryKeys.favoriteGroups(params),
|
|
||||||
policy: entityQueryPolicies.favoriteCollection,
|
|
||||||
queryFn: (params) => favoriteRequest.getFavoriteGroups(params)
|
|
||||||
},
|
|
||||||
favoriteWorlds: {
|
|
||||||
key: (params) => queryKeys.favoriteWorlds(params),
|
|
||||||
policy: entityQueryPolicies.favoriteCollection,
|
|
||||||
queryFn: (params) => favoriteRequest.getFavoriteWorlds(params)
|
|
||||||
},
|
|
||||||
favoriteAvatars: {
|
|
||||||
key: (params) => queryKeys.favoriteAvatars(params),
|
|
||||||
policy: entityQueryPolicies.favoriteCollection,
|
|
||||||
queryFn: (params) => favoriteRequest.getFavoriteAvatars(params)
|
|
||||||
},
|
|
||||||
galleryFiles: {
|
|
||||||
key: (params) => queryKeys.galleryFiles(params),
|
|
||||||
policy: entityQueryPolicies.galleryCollection,
|
|
||||||
queryFn: (params) => vrcPlusIconRequest.getFileList(params)
|
|
||||||
},
|
|
||||||
prints: {
|
|
||||||
key: (params) => queryKeys.prints(params),
|
|
||||||
policy: entityQueryPolicies.galleryCollection,
|
|
||||||
queryFn: (params) => vrcPlusImageRequest.getPrints(params)
|
|
||||||
},
|
|
||||||
print: {
|
|
||||||
key: (params) => queryKeys.print(params.printId),
|
|
||||||
policy: entityQueryPolicies.galleryCollection,
|
|
||||||
queryFn: (params) => vrcPlusImageRequest.getPrint(params)
|
|
||||||
},
|
|
||||||
userInventoryItem: {
|
userInventoryItem: {
|
||||||
key: (params) => queryKeys.userInventoryItem(params),
|
key: (params) => queryKeys.userInventoryItem(params),
|
||||||
policy: entityQueryPolicies.inventoryCollection,
|
policy: entityQueryPolicies.inventoryCollection,
|
||||||
queryFn: (params) => inventoryRequest.getUserInventoryItem(params)
|
queryFn: (params) => inventoryRequest.getUserInventoryItem(params)
|
||||||
},
|
},
|
||||||
inventoryItem: {
|
|
||||||
key: (params) => queryKeys.inventoryItem(params.inventoryId),
|
|
||||||
policy: entityQueryPolicies.inventoryObject,
|
|
||||||
queryFn: (params) => inventoryRequest.getInventoryItem(params)
|
|
||||||
},
|
|
||||||
inventoryItems: {
|
|
||||||
key: (params) => queryKeys.inventoryItems(params),
|
|
||||||
policy: entityQueryPolicies.inventoryCollection,
|
|
||||||
queryFn: (params) => inventoryRequest.getInventoryItems(params)
|
|
||||||
},
|
|
||||||
inventoryTemplate: {
|
|
||||||
key: (params) => queryKeys.inventoryTemplate(params.inventoryTemplateId),
|
|
||||||
policy: entityQueryPolicies.inventoryObject,
|
|
||||||
queryFn: (params) => inventoryRequest.getInventoryTemplate(params)
|
|
||||||
},
|
|
||||||
fileAnalysis: {
|
fileAnalysis: {
|
||||||
key: (params) => queryKeys.fileAnalysis(params),
|
key: (params) => queryKeys.fileAnalysis(params),
|
||||||
policy: entityQueryPolicies.fileAnalysis,
|
policy: entityQueryPolicies.fileAnalysis,
|
||||||
@@ -181,6 +101,21 @@ const registry = Object.freeze({
|
|||||||
key: (params) => queryKeys.file(params.fileId),
|
key: (params) => queryKeys.file(params.fileId),
|
||||||
policy: entityQueryPolicies.fileObject,
|
policy: entityQueryPolicies.fileObject,
|
||||||
queryFn: (params) => miscRequest.getFile(params)
|
queryFn: (params) => miscRequest.getFile(params)
|
||||||
|
},
|
||||||
|
avatarStyles: {
|
||||||
|
key: () => queryKeys.avatarStyles(),
|
||||||
|
policy: entityQueryPolicies.avatarStyles,
|
||||||
|
queryFn: () => avatarRequest.getAvailableAvatarStyles()
|
||||||
|
},
|
||||||
|
representedGroup: {
|
||||||
|
key: (params) => queryKeys.representedGroup(params.userId),
|
||||||
|
policy: entityQueryPolicies.representedGroup,
|
||||||
|
queryFn: (params) => groupRequest.getRepresentedGroup(params)
|
||||||
|
},
|
||||||
|
vrchatCredits: {
|
||||||
|
key: () => queryKeys.vrchatCredits(),
|
||||||
|
policy: entityQueryPolicies.vrchatCredits,
|
||||||
|
queryFn: () => miscRequest.getVRChatCredits()
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -90,8 +90,8 @@
|
|||||||
import { watch } from 'vue';
|
import { watch } from 'vue';
|
||||||
|
|
||||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../../ui/select';
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../../ui/select';
|
||||||
|
import { avatarRequest, queryRequest } from '../../../api';
|
||||||
import { arraysMatch } from '../../../shared/utils';
|
import { arraysMatch } from '../../../shared/utils';
|
||||||
import { avatarRequest } from '../../../api';
|
|
||||||
import { useAvatarStore } from '../../../stores';
|
import { useAvatarStore } from '../../../stores';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@@ -133,7 +133,7 @@
|
|||||||
*/
|
*/
|
||||||
async function getAvatarStyles() {
|
async function getAvatarStyles() {
|
||||||
try {
|
try {
|
||||||
const ref = await avatarRequest.getAvailableAvatarStyles();
|
const ref = await queryRequest.fetch('avatarStyles');
|
||||||
const styles = [];
|
const styles = [];
|
||||||
const stylesMap = new Map();
|
const stylesMap = new Map();
|
||||||
for (const style of ref.json) {
|
for (const style of ref.json) {
|
||||||
|
|||||||
@@ -408,6 +408,7 @@
|
|||||||
} from '../../../shared/utils';
|
} from '../../../shared/utils';
|
||||||
import { useGalleryStore, useGroupStore, useModalStore, useUserStore } from '../../../stores';
|
import { useGalleryStore, useGroupStore, useModalStore, useUserStore } from '../../../stores';
|
||||||
import { groupRequest, queryRequest } from '../../../api';
|
import { groupRequest, queryRequest } from '../../../api';
|
||||||
|
import { queryKeys, refetchActiveEntityQuery } from '../../../queries';
|
||||||
import { Badge } from '../../ui/badge';
|
import { Badge } from '../../ui/badge';
|
||||||
import { formatJsonVars } from '../../../shared/utils/base/ui';
|
import { formatJsonVars } from '../../../shared/utils/base/ui';
|
||||||
|
|
||||||
@@ -497,8 +498,6 @@
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param groupId
|
* @param groupId
|
||||||
@@ -536,6 +535,7 @@
|
|||||||
});
|
});
|
||||||
getGroupDialogGroup(groupId);
|
getGroupDialogGroup(groupId);
|
||||||
}
|
}
|
||||||
|
refetchActiveEntityQuery(queryKeys.representedGroup(currentUser.value.id));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -604,8 +604,6 @@
|
|||||||
* @param gallery
|
* @param gallery
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param id
|
* @param id
|
||||||
|
|||||||
@@ -76,7 +76,7 @@
|
|||||||
import DeprecationAlert from '@/components/DeprecationAlert.vue';
|
import DeprecationAlert from '@/components/DeprecationAlert.vue';
|
||||||
|
|
||||||
import { useFavoriteStore, useUserStore, useWorldStore } from '../../../stores';
|
import { useFavoriteStore, useUserStore, useWorldStore } from '../../../stores';
|
||||||
import { queryRequest } from '../../../api';
|
import { favoriteRequest } from '../../../api';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
@@ -121,7 +121,7 @@
|
|||||||
favoriteWorldsTab.value = '0';
|
favoriteWorldsTab.value = '0';
|
||||||
userDialog.value.userFavoriteWorlds = [];
|
userDialog.value.userFavoriteWorlds = [];
|
||||||
const worldLists = [];
|
const worldLists = [];
|
||||||
const groupArgs = await queryRequest.fetch('favoriteGroups', {
|
const groupArgs = await favoriteRequest.getFavoriteGroups({
|
||||||
ownerId: userId,
|
ownerId: userId,
|
||||||
n: 100,
|
n: 100,
|
||||||
offset: 0
|
offset: 0
|
||||||
@@ -145,7 +145,7 @@
|
|||||||
tag: list.name
|
tag: list.name
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
const args = await queryRequest.fetch('favoriteWorlds', params);
|
const args = await favoriteRequest.getFavoriteWorlds(params);
|
||||||
handleFavoriteWorldList(args);
|
handleFavoriteWorldList(args);
|
||||||
return [list.displayName, list.visibility, args.json];
|
return [list.displayName, list.visibility, args.json];
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|||||||
@@ -475,7 +475,6 @@
|
|||||||
import { storeToRefs } from 'pinia';
|
import { storeToRefs } from 'pinia';
|
||||||
import { toast } from 'vue-sonner';
|
import { toast } from 'vue-sonner';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import InstanceActionBar from '../../InstanceActionBar.vue';
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
copyToClipboard,
|
copyToClipboard,
|
||||||
@@ -502,7 +501,9 @@
|
|||||||
useUserStore,
|
useUserStore,
|
||||||
useWorldStore
|
useWorldStore
|
||||||
} from '../../../stores';
|
} from '../../../stores';
|
||||||
import { miscRequest, userRequest } from '../../../api';
|
import { queryRequest, userRequest } from '../../../api';
|
||||||
|
|
||||||
|
import InstanceActionBar from '../../InstanceActionBar.vue';
|
||||||
|
|
||||||
const EditNoteAndMemoDialog = defineAsyncComponent(() => import('./EditNoteAndMemoDialog.vue'));
|
const EditNoteAndMemoDialog = defineAsyncComponent(() => import('./EditNoteAndMemoDialog.vue'));
|
||||||
|
|
||||||
@@ -681,7 +682,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
function getVRChatCredits() {
|
function getVRChatCredits() {
|
||||||
miscRequest.getVRChatCredits().then((args) => (vrchatCredit.value = args.json?.balance));
|
queryRequest.fetch('vrchatCredits').then((args) => (vrchatCredit.value = args.json?.balance));
|
||||||
}
|
}
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
|
|||||||
@@ -25,11 +25,7 @@ vi.mock('../../../../api', () => ({
|
|||||||
sendPlayerModeration: vi.fn(),
|
sendPlayerModeration: vi.fn(),
|
||||||
deletePlayerModeration: vi.fn()
|
deletePlayerModeration: vi.fn()
|
||||||
},
|
},
|
||||||
worldRequest: {
|
worldRequest: {}
|
||||||
getCachedWorld: vi.fn(() =>
|
|
||||||
Promise.resolve({ ref: { name: 'TestWorld' } })
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
vi.mock('../../../../shared/utils', () => ({
|
vi.mock('../../../../shared/utils', () => ({
|
||||||
|
|||||||
@@ -3,25 +3,6 @@ import { describe, expect, test } from 'vitest';
|
|||||||
import { queryKeys } from '../keys';
|
import { queryKeys } from '../keys';
|
||||||
|
|
||||||
describe('query key shapes', () => {
|
describe('query key shapes', () => {
|
||||||
test('favorite world keys include owner and tag dimensions', () => {
|
|
||||||
const a = queryKeys.favoriteWorlds({
|
|
||||||
n: 100,
|
|
||||||
offset: 0,
|
|
||||||
ownerId: 'usr_1',
|
|
||||||
userId: 'usr_1',
|
|
||||||
tag: 'worlds1'
|
|
||||||
});
|
|
||||||
const b = queryKeys.favoriteWorlds({
|
|
||||||
n: 100,
|
|
||||||
offset: 0,
|
|
||||||
ownerId: 'usr_2',
|
|
||||||
userId: 'usr_2',
|
|
||||||
tag: 'worlds1'
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(a).not.toEqual(b);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('world list keys include query option discriminator', () => {
|
test('world list keys include query option discriminator', () => {
|
||||||
const base = {
|
const base = {
|
||||||
userId: 'usr_me',
|
userId: 'usr_me',
|
||||||
@@ -42,22 +23,119 @@ describe('query key shapes', () => {
|
|||||||
expect(defaultKey).not.toEqual(featuredKey);
|
expect(defaultKey).not.toEqual(featuredKey);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('group member list keys include sort and role dimensions', () => {
|
test('groupCalendarEvent key includes groupId and eventId', () => {
|
||||||
const everyone = queryKeys.groupMembers({
|
const a = queryKeys.groupCalendarEvent({
|
||||||
groupId: 'grp_1',
|
groupId: 'grp_1',
|
||||||
n: 100,
|
eventId: 'evt_1'
|
||||||
offset: 0,
|
|
||||||
sort: 'joinedAt:desc',
|
|
||||||
roleId: ''
|
|
||||||
});
|
});
|
||||||
const roleScoped = queryKeys.groupMembers({
|
const b = queryKeys.groupCalendarEvent({
|
||||||
groupId: 'grp_1',
|
groupId: 'grp_1',
|
||||||
n: 100,
|
eventId: 'evt_2'
|
||||||
offset: 0,
|
|
||||||
sort: 'joinedAt:desc',
|
|
||||||
roleId: 'grol_1'
|
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(everyone).not.toEqual(roleScoped);
|
expect(a).not.toEqual(b);
|
||||||
|
expect(a).toEqual(['group', 'grp_1', 'calendarEvent', 'evt_1']);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('userInventoryItem key scopes by both userId and inventoryId', () => {
|
||||||
|
const a = queryKeys.userInventoryItem({
|
||||||
|
inventoryId: 'inv_1',
|
||||||
|
userId: 'usr_1'
|
||||||
|
});
|
||||||
|
const b = queryKeys.userInventoryItem({
|
||||||
|
inventoryId: 'inv_1',
|
||||||
|
userId: 'usr_2'
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(a).not.toEqual(b);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('mutualCounts key is unique per userId', () => {
|
||||||
|
const a = queryKeys.mutualCounts('usr_1');
|
||||||
|
const b = queryKeys.mutualCounts('usr_2');
|
||||||
|
|
||||||
|
expect(a).not.toEqual(b);
|
||||||
|
expect(a).toEqual(['user', 'usr_1', 'mutualCounts']);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('representedGroup key is unique per userId', () => {
|
||||||
|
const a = queryKeys.representedGroup('usr_1');
|
||||||
|
const b = queryKeys.representedGroup('usr_2');
|
||||||
|
|
||||||
|
expect(a).not.toEqual(b);
|
||||||
|
expect(a).toEqual(['user', 'usr_1', 'representedGroup']);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('avatarStyles returns a stable singleton key', () => {
|
||||||
|
expect(queryKeys.avatarStyles()).toEqual(['avatar', 'styles']);
|
||||||
|
expect(queryKeys.avatarStyles()).toEqual(queryKeys.avatarStyles());
|
||||||
|
});
|
||||||
|
|
||||||
|
test('vrchatCredits returns a stable singleton key', () => {
|
||||||
|
expect(queryKeys.vrchatCredits()).toEqual(['credits']);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('visits returns a stable singleton key', () => {
|
||||||
|
expect(queryKeys.visits()).toEqual(['visits']);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('favoriteLimits returns a stable singleton key', () => {
|
||||||
|
expect(queryKeys.favoriteLimits()).toEqual(['favorite', 'limits']);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('groupMember key includes both groupId and userId', () => {
|
||||||
|
const key = queryKeys.groupMember({
|
||||||
|
groupId: 'grp_1',
|
||||||
|
userId: 'usr_1'
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(key).toEqual(['group', 'grp_1', 'member', 'usr_1']);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('group key differentiates includeRoles flag', () => {
|
||||||
|
const withRoles = queryKeys.group('grp_1', true);
|
||||||
|
const withoutRoles = queryKeys.group('grp_1', false);
|
||||||
|
|
||||||
|
expect(withRoles).not.toEqual(withoutRoles);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('worldPersistData key scopes by worldId', () => {
|
||||||
|
const a = queryKeys.worldPersistData('wrld_1');
|
||||||
|
const b = queryKeys.worldPersistData('wrld_2');
|
||||||
|
|
||||||
|
expect(a).not.toEqual(b);
|
||||||
|
expect(a).toEqual(['world', 'wrld_1', 'persistData']);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('fileAnalysis key differentiates version and variant', () => {
|
||||||
|
const a = queryKeys.fileAnalysis({
|
||||||
|
fileId: 'file_1',
|
||||||
|
version: 1,
|
||||||
|
variant: 'default'
|
||||||
|
});
|
||||||
|
const b = queryKeys.fileAnalysis({
|
||||||
|
fileId: 'file_1',
|
||||||
|
version: 2,
|
||||||
|
variant: 'default'
|
||||||
|
});
|
||||||
|
const c = queryKeys.fileAnalysis({
|
||||||
|
fileId: 'file_1',
|
||||||
|
version: 1,
|
||||||
|
variant: 'hd'
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(a).not.toEqual(b);
|
||||||
|
expect(a).not.toEqual(c);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('worldsByUser key coerces numeric params consistently', () => {
|
||||||
|
const a = queryKeys.worldsByUser({
|
||||||
|
userId: 'usr_1',
|
||||||
|
n: '50',
|
||||||
|
offset: '0'
|
||||||
|
});
|
||||||
|
const b = queryKeys.worldsByUser({ userId: 'usr_1', n: 50, offset: 0 });
|
||||||
|
|
||||||
|
expect(a).toEqual(b);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,12 +1,9 @@
|
|||||||
import { describe, expect, test } from 'vitest';
|
import { describe, expect, test } from 'vitest';
|
||||||
|
|
||||||
import {
|
import { entityQueryPolicies, toQueryOptions } from '../policies';
|
||||||
entityQueryPolicies,
|
|
||||||
toQueryOptions
|
|
||||||
} from '../policies';
|
|
||||||
|
|
||||||
describe('query policy configuration', () => {
|
describe('query policy configuration', () => {
|
||||||
test('matches the finalized cache strategy', () => {
|
test('core entity policies have correct stale/gc times', () => {
|
||||||
expect(entityQueryPolicies.user).toMatchObject({
|
expect(entityQueryPolicies.user).toMatchObject({
|
||||||
staleTime: 20000,
|
staleTime: 20000,
|
||||||
gcTime: 90000,
|
gcTime: 90000,
|
||||||
@@ -34,64 +31,37 @@ describe('query policy configuration', () => {
|
|||||||
retry: 1,
|
retry: 1,
|
||||||
refetchOnWindowFocus: false
|
refetchOnWindowFocus: false
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('group sub-resource policies', () => {
|
||||||
expect(entityQueryPolicies.groupCollection).toMatchObject({
|
expect(entityQueryPolicies.groupCollection).toMatchObject({
|
||||||
staleTime: 60000,
|
staleTime: 60000,
|
||||||
gcTime: 300000,
|
gcTime: 300000,
|
||||||
retry: 1,
|
retry: 1,
|
||||||
refetchOnWindowFocus: false
|
refetchOnWindowFocus: false
|
||||||
});
|
});
|
||||||
expect(entityQueryPolicies.groupCalendarCollection).toMatchObject({
|
|
||||||
staleTime: 120000,
|
|
||||||
gcTime: 600000,
|
|
||||||
retry: 1,
|
|
||||||
refetchOnWindowFocus: false
|
|
||||||
});
|
|
||||||
expect(
|
|
||||||
entityQueryPolicies.groupFollowingCalendarCollection
|
|
||||||
).toMatchObject({
|
|
||||||
staleTime: 60000,
|
|
||||||
gcTime: 300000,
|
|
||||||
retry: 1,
|
|
||||||
refetchOnWindowFocus: false
|
|
||||||
});
|
|
||||||
expect(entityQueryPolicies.groupFeaturedCalendarCollection).toMatchObject({
|
|
||||||
staleTime: 300000,
|
|
||||||
gcTime: 900000,
|
|
||||||
retry: 1,
|
|
||||||
refetchOnWindowFocus: false
|
|
||||||
});
|
|
||||||
expect(entityQueryPolicies.groupCalendarEvent).toMatchObject({
|
expect(entityQueryPolicies.groupCalendarEvent).toMatchObject({
|
||||||
staleTime: 120000,
|
staleTime: 120000,
|
||||||
gcTime: 600000,
|
gcTime: 600000,
|
||||||
retry: 1,
|
retry: 1,
|
||||||
refetchOnWindowFocus: false
|
refetchOnWindowFocus: false
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('world collection policy', () => {
|
||||||
expect(entityQueryPolicies.worldCollection).toMatchObject({
|
expect(entityQueryPolicies.worldCollection).toMatchObject({
|
||||||
staleTime: 60000,
|
staleTime: 60000,
|
||||||
gcTime: 300000,
|
gcTime: 300000,
|
||||||
retry: 1,
|
retry: 1,
|
||||||
refetchOnWindowFocus: false
|
refetchOnWindowFocus: false
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
expect(entityQueryPolicies.friendList).toMatchObject({
|
test('favorite and inventory policies', () => {
|
||||||
staleTime: 20000,
|
expect(entityQueryPolicies.favoriteLimits).toMatchObject({
|
||||||
gcTime: 90000,
|
staleTime: 600000,
|
||||||
retry: 1,
|
gcTime: 1800000,
|
||||||
refetchOnWindowFocus: false
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(entityQueryPolicies.favoriteCollection).toMatchObject({
|
|
||||||
staleTime: 60000,
|
|
||||||
gcTime: 300000,
|
|
||||||
retry: 1,
|
|
||||||
refetchOnWindowFocus: false
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(entityQueryPolicies.galleryCollection).toMatchObject({
|
|
||||||
staleTime: 60000,
|
|
||||||
gcTime: 300000,
|
|
||||||
retry: 1,
|
retry: 1,
|
||||||
refetchOnWindowFocus: false
|
refetchOnWindowFocus: false
|
||||||
});
|
});
|
||||||
@@ -102,42 +72,28 @@ describe('query policy configuration', () => {
|
|||||||
retry: 1,
|
retry: 1,
|
||||||
refetchOnWindowFocus: false
|
refetchOnWindowFocus: false
|
||||||
});
|
});
|
||||||
expect(entityQueryPolicies.inventoryObject).toMatchObject({
|
});
|
||||||
staleTime: 60000,
|
|
||||||
gcTime: 300000,
|
test('avatar gallery policy has shorter staleTime than avatar entity', () => {
|
||||||
retry: 1,
|
|
||||||
refetchOnWindowFocus: false
|
|
||||||
});
|
|
||||||
expect(entityQueryPolicies.avatarGallery).toMatchObject({
|
expect(entityQueryPolicies.avatarGallery).toMatchObject({
|
||||||
staleTime: 30000,
|
staleTime: 30000,
|
||||||
gcTime: 120000,
|
gcTime: 120000,
|
||||||
retry: 1,
|
retry: 1,
|
||||||
refetchOnWindowFocus: false
|
refetchOnWindowFocus: false
|
||||||
});
|
});
|
||||||
|
|
||||||
|
expect(entityQueryPolicies.avatarGallery.staleTime).toBeLessThan(
|
||||||
|
entityQueryPolicies.avatar.staleTime
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('file-related policies', () => {
|
||||||
expect(entityQueryPolicies.fileAnalysis).toMatchObject({
|
expect(entityQueryPolicies.fileAnalysis).toMatchObject({
|
||||||
staleTime: 120000,
|
staleTime: 120000,
|
||||||
gcTime: 600000,
|
gcTime: 600000,
|
||||||
retry: 1,
|
retry: 1,
|
||||||
refetchOnWindowFocus: false
|
refetchOnWindowFocus: false
|
||||||
});
|
});
|
||||||
expect(entityQueryPolicies.worldPersistData).toMatchObject({
|
|
||||||
staleTime: 120000,
|
|
||||||
gcTime: 600000,
|
|
||||||
retry: 1,
|
|
||||||
refetchOnWindowFocus: false
|
|
||||||
});
|
|
||||||
expect(entityQueryPolicies.mutualCounts).toMatchObject({
|
|
||||||
staleTime: 120000,
|
|
||||||
gcTime: 600000,
|
|
||||||
retry: 1,
|
|
||||||
refetchOnWindowFocus: false
|
|
||||||
});
|
|
||||||
expect(entityQueryPolicies.visits).toMatchObject({
|
|
||||||
staleTime: 300000,
|
|
||||||
gcTime: 900000,
|
|
||||||
retry: 1,
|
|
||||||
refetchOnWindowFocus: false
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(entityQueryPolicies.fileObject).toMatchObject({
|
expect(entityQueryPolicies.fileObject).toMatchObject({
|
||||||
staleTime: 60000,
|
staleTime: 60000,
|
||||||
@@ -147,6 +103,63 @@ describe('query policy configuration', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('world persist data policy', () => {
|
||||||
|
expect(entityQueryPolicies.worldPersistData).toMatchObject({
|
||||||
|
staleTime: 120000,
|
||||||
|
gcTime: 600000,
|
||||||
|
retry: 1,
|
||||||
|
refetchOnWindowFocus: false
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('user relation policies (mutualCounts, representedGroup)', () => {
|
||||||
|
expect(entityQueryPolicies.mutualCounts).toMatchObject({
|
||||||
|
staleTime: 120000,
|
||||||
|
gcTime: 600000,
|
||||||
|
retry: 1,
|
||||||
|
refetchOnWindowFocus: false
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(entityQueryPolicies.representedGroup).toMatchObject({
|
||||||
|
staleTime: 60000,
|
||||||
|
gcTime: 300000,
|
||||||
|
retry: 1,
|
||||||
|
refetchOnWindowFocus: false
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('visits policy has longer staleTime for slow-changing data', () => {
|
||||||
|
expect(entityQueryPolicies.visits).toMatchObject({
|
||||||
|
staleTime: 300000,
|
||||||
|
gcTime: 900000,
|
||||||
|
retry: 1,
|
||||||
|
refetchOnWindowFocus: false
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('avatarStyles policy has very long staleTime for static config data', () => {
|
||||||
|
expect(entityQueryPolicies.avatarStyles).toMatchObject({
|
||||||
|
staleTime: 600000,
|
||||||
|
gcTime: 3600000,
|
||||||
|
retry: 1,
|
||||||
|
refetchOnWindowFocus: false
|
||||||
|
});
|
||||||
|
|
||||||
|
// Should outlive visits (which is already long-lived)
|
||||||
|
expect(entityQueryPolicies.avatarStyles.staleTime).toBeGreaterThan(
|
||||||
|
entityQueryPolicies.visits.staleTime
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('vrchatCredits policy has moderate staleTime for balance data', () => {
|
||||||
|
expect(entityQueryPolicies.vrchatCredits).toMatchObject({
|
||||||
|
staleTime: 120000,
|
||||||
|
gcTime: 600000,
|
||||||
|
retry: 1,
|
||||||
|
refetchOnWindowFocus: false
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
test('normalizes policy values to query options', () => {
|
test('normalizes policy values to query options', () => {
|
||||||
const options = toQueryOptions(entityQueryPolicies.group);
|
const options = toQueryOptions(entityQueryPolicies.group);
|
||||||
|
|
||||||
@@ -157,4 +170,34 @@ describe('query policy configuration', () => {
|
|||||||
refetchOnWindowFocus: false
|
refetchOnWindowFocus: false
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('toQueryOptions returns only the four query option fields', () => {
|
||||||
|
const options = toQueryOptions(entityQueryPolicies.user);
|
||||||
|
const keys = Object.keys(options);
|
||||||
|
|
||||||
|
expect(keys).toEqual([
|
||||||
|
'staleTime',
|
||||||
|
'gcTime',
|
||||||
|
'retry',
|
||||||
|
'refetchOnWindowFocus'
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('all policies are frozen and immutable', () => {
|
||||||
|
for (const [, policy] of Object.entries(entityQueryPolicies)) {
|
||||||
|
expect(Object.isFrozen(policy)).toBe(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test('all policies have refetchOnWindowFocus disabled', () => {
|
||||||
|
for (const policy of Object.values(entityQueryPolicies)) {
|
||||||
|
expect(policy.refetchOnWindowFocus).toBe(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test('gcTime is always greater than staleTime for all policies', () => {
|
||||||
|
for (const [, policy] of Object.entries(entityQueryPolicies)) {
|
||||||
|
expect(policy.gcTime).toBeGreaterThan(policy.staleTime);
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
+4
-152
@@ -7,38 +7,12 @@ export const queryKeys = Object.freeze({
|
|||||||
groupId,
|
groupId,
|
||||||
Boolean(includeRoles)
|
Boolean(includeRoles)
|
||||||
],
|
],
|
||||||
groupPosts: ({ groupId, n = 100, offset = 0 } = {}) => [
|
|
||||||
'group',
|
|
||||||
groupId,
|
|
||||||
'posts',
|
|
||||||
{
|
|
||||||
n: Number(n),
|
|
||||||
offset: Number(offset)
|
|
||||||
}
|
|
||||||
],
|
|
||||||
groupMember: ({ groupId, userId } = {}) => [
|
groupMember: ({ groupId, userId } = {}) => [
|
||||||
'group',
|
'group',
|
||||||
groupId,
|
groupId,
|
||||||
'member',
|
'member',
|
||||||
userId
|
userId
|
||||||
],
|
],
|
||||||
groupMembers: ({
|
|
||||||
groupId,
|
|
||||||
n = 100,
|
|
||||||
offset = 0,
|
|
||||||
sort = '',
|
|
||||||
roleId = ''
|
|
||||||
} = {}) => [
|
|
||||||
'group',
|
|
||||||
groupId,
|
|
||||||
'members',
|
|
||||||
{
|
|
||||||
n: Number(n),
|
|
||||||
offset: Number(offset),
|
|
||||||
sort: String(sort || ''),
|
|
||||||
roleId: String(roleId || '')
|
|
||||||
}
|
|
||||||
],
|
|
||||||
groupGallery: ({ groupId, galleryId, n = 100, offset = 0 } = {}) => [
|
groupGallery: ({ groupId, galleryId, n = 100, offset = 0 } = {}) => [
|
||||||
'group',
|
'group',
|
||||||
groupId,
|
groupId,
|
||||||
@@ -50,35 +24,6 @@ export const queryKeys = Object.freeze({
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
groupCalendar: (groupId) => ['group', groupId, 'calendar'],
|
groupCalendar: (groupId) => ['group', groupId, 'calendar'],
|
||||||
groupCalendars: ({ n = 100, offset = 0, date = '' } = {}) => [
|
|
||||||
'group',
|
|
||||||
'calendar',
|
|
||||||
{
|
|
||||||
n: Number(n),
|
|
||||||
offset: Number(offset),
|
|
||||||
date: String(date || '')
|
|
||||||
}
|
|
||||||
],
|
|
||||||
followingGroupCalendars: ({ n = 100, offset = 0, date = '' } = {}) => [
|
|
||||||
'group',
|
|
||||||
'calendar',
|
|
||||||
'following',
|
|
||||||
{
|
|
||||||
n: Number(n),
|
|
||||||
offset: Number(offset),
|
|
||||||
date: String(date || '')
|
|
||||||
}
|
|
||||||
],
|
|
||||||
featuredGroupCalendars: ({ n = 100, offset = 0, date = '' } = {}) => [
|
|
||||||
'group',
|
|
||||||
'calendar',
|
|
||||||
'featured',
|
|
||||||
{
|
|
||||||
n: Number(n),
|
|
||||||
offset: Number(offset),
|
|
||||||
date: String(date || '')
|
|
||||||
}
|
|
||||||
],
|
|
||||||
groupCalendarEvent: ({ groupId, eventId } = {}) => [
|
groupCalendarEvent: ({ groupId, eventId } = {}) => [
|
||||||
'group',
|
'group',
|
||||||
groupId,
|
groupId,
|
||||||
@@ -109,109 +54,13 @@ export const queryKeys = Object.freeze({
|
|||||||
option: String(option || '')
|
option: String(option || '')
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
friends: ({ offline = false, n = 50, offset = 0 } = {}) => [
|
|
||||||
'friends',
|
|
||||||
{
|
|
||||||
offline: Boolean(offline),
|
|
||||||
n: Number(n),
|
|
||||||
offset: Number(offset)
|
|
||||||
}
|
|
||||||
],
|
|
||||||
favoriteLimits: () => ['favorite', 'limits'],
|
favoriteLimits: () => ['favorite', 'limits'],
|
||||||
favorites: ({ n = 300, offset = 0 } = {}) => [
|
|
||||||
'favorite',
|
|
||||||
'items',
|
|
||||||
{
|
|
||||||
n: Number(n),
|
|
||||||
offset: Number(offset)
|
|
||||||
}
|
|
||||||
],
|
|
||||||
favoriteGroups: ({ n = 50, offset = 0, type = '' } = {}) => [
|
|
||||||
'favorite',
|
|
||||||
'groups',
|
|
||||||
{
|
|
||||||
n: Number(n),
|
|
||||||
offset: Number(offset),
|
|
||||||
type: String(type || '')
|
|
||||||
}
|
|
||||||
],
|
|
||||||
favoriteWorlds: ({
|
|
||||||
n = 300,
|
|
||||||
offset = 0,
|
|
||||||
ownerId = '',
|
|
||||||
userId = '',
|
|
||||||
tag = ''
|
|
||||||
} = {}) => [
|
|
||||||
'favorite',
|
|
||||||
'worlds',
|
|
||||||
{
|
|
||||||
n: Number(n),
|
|
||||||
offset: Number(offset),
|
|
||||||
ownerId: String(ownerId || ''),
|
|
||||||
userId: String(userId || ''),
|
|
||||||
tag: String(tag || '')
|
|
||||||
}
|
|
||||||
],
|
|
||||||
favoriteAvatars: ({
|
|
||||||
n = 300,
|
|
||||||
offset = 0,
|
|
||||||
tag = '',
|
|
||||||
ownerId = '',
|
|
||||||
userId = ''
|
|
||||||
} = {}) => [
|
|
||||||
'favorite',
|
|
||||||
'avatars',
|
|
||||||
{
|
|
||||||
n: Number(n),
|
|
||||||
offset: Number(offset),
|
|
||||||
tag: String(tag || ''),
|
|
||||||
ownerId: String(ownerId || ''),
|
|
||||||
userId: String(userId || '')
|
|
||||||
}
|
|
||||||
],
|
|
||||||
galleryFiles: ({ tag = '', n = 100 } = {}) => [
|
|
||||||
'gallery',
|
|
||||||
'files',
|
|
||||||
{
|
|
||||||
tag: String(tag || ''),
|
|
||||||
n: Number(n)
|
|
||||||
}
|
|
||||||
],
|
|
||||||
prints: ({ n = 100 } = {}) => [
|
|
||||||
'gallery',
|
|
||||||
'prints',
|
|
||||||
{
|
|
||||||
n: Number(n)
|
|
||||||
}
|
|
||||||
],
|
|
||||||
print: (printId) => ['gallery', 'print', printId],
|
|
||||||
inventoryItems: ({
|
|
||||||
n = 100,
|
|
||||||
offset = 0,
|
|
||||||
order = 'newest',
|
|
||||||
types = ''
|
|
||||||
} = {}) => [
|
|
||||||
'inventory',
|
|
||||||
'items',
|
|
||||||
{
|
|
||||||
n: Number(n),
|
|
||||||
offset: Number(offset),
|
|
||||||
order: String(order || 'newest'),
|
|
||||||
types: String(types || '')
|
|
||||||
}
|
|
||||||
],
|
|
||||||
userInventoryItem: ({ inventoryId, userId }) => [
|
userInventoryItem: ({ inventoryId, userId }) => [
|
||||||
'inventory',
|
'inventory',
|
||||||
'item',
|
'item',
|
||||||
userId,
|
userId,
|
||||||
inventoryId
|
inventoryId
|
||||||
],
|
],
|
||||||
inventoryItem: (inventoryId) => ['inventory', 'item', inventoryId],
|
|
||||||
inventoryTemplate: (inventoryTemplateId) => [
|
|
||||||
'inventory',
|
|
||||||
'template',
|
|
||||||
inventoryTemplateId
|
|
||||||
],
|
|
||||||
fileAnalysis: ({ fileId, version, variant } = {}) => [
|
fileAnalysis: ({ fileId, version, variant } = {}) => [
|
||||||
'analysis',
|
'analysis',
|
||||||
fileId,
|
fileId,
|
||||||
@@ -221,5 +70,8 @@ export const queryKeys = Object.freeze({
|
|||||||
worldPersistData: (worldId) => ['world', worldId, 'persistData'],
|
worldPersistData: (worldId) => ['world', worldId, 'persistData'],
|
||||||
mutualCounts: (userId) => ['user', userId, 'mutualCounts'],
|
mutualCounts: (userId) => ['user', userId, 'mutualCounts'],
|
||||||
visits: () => ['visits'],
|
visits: () => ['visits'],
|
||||||
file: (fileId) => ['file', fileId]
|
file: (fileId) => ['file', fileId],
|
||||||
|
avatarStyles: () => ['avatar', 'styles'],
|
||||||
|
representedGroup: (userId) => ['user', userId, 'representedGroup'],
|
||||||
|
vrchatCredits: () => ['credits']
|
||||||
});
|
});
|
||||||
|
|||||||
+21
-39
@@ -31,24 +31,6 @@ export const entityQueryPolicies = Object.freeze({
|
|||||||
retry: 1,
|
retry: 1,
|
||||||
refetchOnWindowFocus: false
|
refetchOnWindowFocus: false
|
||||||
}),
|
}),
|
||||||
groupCalendarCollection: Object.freeze({
|
|
||||||
staleTime: 120 * SECOND,
|
|
||||||
gcTime: 600 * SECOND,
|
|
||||||
retry: 1,
|
|
||||||
refetchOnWindowFocus: false
|
|
||||||
}),
|
|
||||||
groupFollowingCalendarCollection: Object.freeze({
|
|
||||||
staleTime: 60 * SECOND,
|
|
||||||
gcTime: 300 * SECOND,
|
|
||||||
retry: 1,
|
|
||||||
refetchOnWindowFocus: false
|
|
||||||
}),
|
|
||||||
groupFeaturedCalendarCollection: Object.freeze({
|
|
||||||
staleTime: 300 * SECOND,
|
|
||||||
gcTime: 900 * SECOND,
|
|
||||||
retry: 1,
|
|
||||||
refetchOnWindowFocus: false
|
|
||||||
}),
|
|
||||||
groupCalendarEvent: Object.freeze({
|
groupCalendarEvent: Object.freeze({
|
||||||
staleTime: 120 * SECOND,
|
staleTime: 120 * SECOND,
|
||||||
gcTime: 600 * SECOND,
|
gcTime: 600 * SECOND,
|
||||||
@@ -61,21 +43,9 @@ export const entityQueryPolicies = Object.freeze({
|
|||||||
retry: 1,
|
retry: 1,
|
||||||
refetchOnWindowFocus: false
|
refetchOnWindowFocus: false
|
||||||
}),
|
}),
|
||||||
friendList: Object.freeze({
|
favoriteLimits: Object.freeze({
|
||||||
staleTime: 20 * SECOND,
|
staleTime: 600 * SECOND,
|
||||||
gcTime: 90 * SECOND,
|
gcTime: 1800 * SECOND,
|
||||||
retry: 1,
|
|
||||||
refetchOnWindowFocus: false
|
|
||||||
}),
|
|
||||||
favoriteCollection: Object.freeze({
|
|
||||||
staleTime: 60 * SECOND,
|
|
||||||
gcTime: 300 * SECOND,
|
|
||||||
retry: 1,
|
|
||||||
refetchOnWindowFocus: false
|
|
||||||
}),
|
|
||||||
galleryCollection: Object.freeze({
|
|
||||||
staleTime: 60 * SECOND,
|
|
||||||
gcTime: 300 * SECOND,
|
|
||||||
retry: 1,
|
retry: 1,
|
||||||
refetchOnWindowFocus: false
|
refetchOnWindowFocus: false
|
||||||
}),
|
}),
|
||||||
@@ -85,12 +55,6 @@ export const entityQueryPolicies = Object.freeze({
|
|||||||
retry: 1,
|
retry: 1,
|
||||||
refetchOnWindowFocus: false
|
refetchOnWindowFocus: false
|
||||||
}),
|
}),
|
||||||
inventoryObject: Object.freeze({
|
|
||||||
staleTime: 60 * SECOND,
|
|
||||||
gcTime: 300 * SECOND,
|
|
||||||
retry: 1,
|
|
||||||
refetchOnWindowFocus: false
|
|
||||||
}),
|
|
||||||
avatarGallery: Object.freeze({
|
avatarGallery: Object.freeze({
|
||||||
staleTime: 30 * SECOND,
|
staleTime: 30 * SECOND,
|
||||||
gcTime: 120 * SECOND,
|
gcTime: 120 * SECOND,
|
||||||
@@ -126,6 +90,24 @@ export const entityQueryPolicies = Object.freeze({
|
|||||||
gcTime: 300 * SECOND,
|
gcTime: 300 * SECOND,
|
||||||
retry: 1,
|
retry: 1,
|
||||||
refetchOnWindowFocus: false
|
refetchOnWindowFocus: false
|
||||||
|
}),
|
||||||
|
avatarStyles: Object.freeze({
|
||||||
|
staleTime: 600 * SECOND,
|
||||||
|
gcTime: 3600 * SECOND,
|
||||||
|
retry: 1,
|
||||||
|
refetchOnWindowFocus: false
|
||||||
|
}),
|
||||||
|
representedGroup: Object.freeze({
|
||||||
|
staleTime: 60 * SECOND,
|
||||||
|
gcTime: 300 * SECOND,
|
||||||
|
retry: 1,
|
||||||
|
refetchOnWindowFocus: false
|
||||||
|
}),
|
||||||
|
vrchatCredits: Object.freeze({
|
||||||
|
staleTime: 120 * SECOND,
|
||||||
|
gcTime: 600 * SECOND,
|
||||||
|
retry: 1,
|
||||||
|
refetchOnWindowFocus: false
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -600,7 +600,7 @@ export const useFavoriteStore = defineStore('Favorite', () => {
|
|||||||
}
|
}
|
||||||
isFavoriteGroupLoading.value = true;
|
isFavoriteGroupLoading.value = true;
|
||||||
processBulk({
|
processBulk({
|
||||||
fn: favoriteRequest.getCachedFavoriteGroups,
|
fn: (params) => favoriteRequest.getFavoriteGroups(params),
|
||||||
N: -1,
|
N: -1,
|
||||||
params: {
|
params: {
|
||||||
n: 50,
|
n: 50,
|
||||||
@@ -781,7 +781,7 @@ export const useFavoriteStore = defineStore('Favorite', () => {
|
|||||||
}
|
}
|
||||||
let newFavoriteSortOrder = [];
|
let newFavoriteSortOrder = [];
|
||||||
processBulk({
|
processBulk({
|
||||||
fn: (params) => queryRequest.fetch('favorites', params),
|
fn: (params) => favoriteRequest.getFavorites(params),
|
||||||
N: -1,
|
N: -1,
|
||||||
params: {
|
params: {
|
||||||
n: 300,
|
n: 300,
|
||||||
@@ -884,7 +884,7 @@ export const useFavoriteStore = defineStore('Favorite', () => {
|
|||||||
offset: 0,
|
offset: 0,
|
||||||
tag
|
tag
|
||||||
};
|
};
|
||||||
const args = await queryRequest.fetch('favoriteAvatars', params);
|
const args = await favoriteRequest.getFavoriteAvatars(params);
|
||||||
handleFavoriteAvatarList(args);
|
handleFavoriteAvatarList(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -893,8 +893,8 @@ export const useFavoriteStore = defineStore('Favorite', () => {
|
|||||||
*/
|
*/
|
||||||
function refreshFavoriteItems() {
|
function refreshFavoriteItems() {
|
||||||
const types = {
|
const types = {
|
||||||
world: [0, favoriteRequest.getCachedFavoriteWorlds],
|
world: [0, (params) => favoriteRequest.getFavoriteWorlds(params)],
|
||||||
avatar: [0, favoriteRequest.getCachedFavoriteAvatars]
|
avatar: [0, (params) => favoriteRequest.getFavoriteAvatars(params)]
|
||||||
};
|
};
|
||||||
const tags = [];
|
const tags = [];
|
||||||
for (const ref of cachedFavorites.values()) {
|
for (const ref of cachedFavorites.values()) {
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import {
|
|||||||
isRealInstance,
|
isRealInstance,
|
||||||
migrateMemos
|
migrateMemos
|
||||||
} from '../shared/utils';
|
} from '../shared/utils';
|
||||||
import { friendRequest, queryRequest, userRequest } from '../api';
|
import { friendRequest, userRequest } from '../api';
|
||||||
import { AppDebug } from '../service/appConfig';
|
import { AppDebug } from '../service/appConfig';
|
||||||
import { createFriendPresenceCoordinator } from './coordinators/friendPresenceCoordinator';
|
import { createFriendPresenceCoordinator } from './coordinators/friendPresenceCoordinator';
|
||||||
import { createFriendRelationshipCoordinator } from './coordinators/friendRelationshipCoordinator';
|
import { createFriendRelationshipCoordinator } from './coordinators/friendRelationshipCoordinator';
|
||||||
@@ -567,7 +567,7 @@ export const useFriendStore = defineStore('Friend', () => {
|
|||||||
async function fetchPage(offset) {
|
async function fetchPage(offset) {
|
||||||
const result = await executeWithBackoff(
|
const result = await executeWithBackoff(
|
||||||
async () => {
|
async () => {
|
||||||
const { json } = await queryRequest.fetch('friends', {
|
const { json } = await friendRequest.getFriends({
|
||||||
...args,
|
...args,
|
||||||
n: PAGE_SIZE,
|
n: PAGE_SIZE,
|
||||||
offset
|
offset
|
||||||
|
|||||||
+17
-12
@@ -9,7 +9,12 @@ import {
|
|||||||
getPrintLocalDate,
|
getPrintLocalDate,
|
||||||
openExternalLink
|
openExternalLink
|
||||||
} from '../shared/utils';
|
} from '../shared/utils';
|
||||||
import { queryRequest, vrcPlusImageRequest } from '../api';
|
import {
|
||||||
|
inventoryRequest,
|
||||||
|
queryRequest,
|
||||||
|
vrcPlusIconRequest,
|
||||||
|
vrcPlusImageRequest
|
||||||
|
} from '../api';
|
||||||
import { AppDebug } from '../service/appConfig';
|
import { AppDebug } from '../service/appConfig';
|
||||||
import { handleImageUploadInput } from '../shared/utils/imageUpload';
|
import { handleImageUploadInput } from '../shared/utils/imageUpload';
|
||||||
import { router } from '../plugin/router';
|
import { router } from '../plugin/router';
|
||||||
@@ -157,8 +162,8 @@ export const useGalleryStore = defineStore('Gallery', () => {
|
|||||||
n: 100,
|
n: 100,
|
||||||
tag: 'gallery'
|
tag: 'gallery'
|
||||||
};
|
};
|
||||||
queryRequest
|
vrcPlusIconRequest
|
||||||
.fetch('galleryFiles', params)
|
.getFileList(params)
|
||||||
.then((args) => handleFilesList(args))
|
.then((args) => handleFilesList(args))
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error('Error fetching gallery files:', error);
|
console.error('Error fetching gallery files:', error);
|
||||||
@@ -177,8 +182,8 @@ export const useGalleryStore = defineStore('Gallery', () => {
|
|||||||
n: 100,
|
n: 100,
|
||||||
tag: 'icon'
|
tag: 'icon'
|
||||||
};
|
};
|
||||||
queryRequest
|
vrcPlusIconRequest
|
||||||
.fetch('galleryFiles', params)
|
.getFileList(params)
|
||||||
.then((args) => handleFilesList(args))
|
.then((args) => handleFilesList(args))
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error('Error fetching VRC Plus icons:', error);
|
console.error('Error fetching VRC Plus icons:', error);
|
||||||
@@ -229,8 +234,8 @@ export const useGalleryStore = defineStore('Gallery', () => {
|
|||||||
n: 100,
|
n: 100,
|
||||||
tag: 'sticker'
|
tag: 'sticker'
|
||||||
};
|
};
|
||||||
queryRequest
|
vrcPlusIconRequest
|
||||||
.fetch('galleryFiles', params)
|
.getFileList(params)
|
||||||
.then((args) => handleFilesList(args))
|
.then((args) => handleFilesList(args))
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error('Error fetching stickers:', error);
|
console.error('Error fetching stickers:', error);
|
||||||
@@ -304,7 +309,7 @@ export const useGalleryStore = defineStore('Gallery', () => {
|
|||||||
n: 100
|
n: 100
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
const args = await queryRequest.fetch('prints', params);
|
const args = await vrcPlusImageRequest.getPrints(params);
|
||||||
args.json.sort((a, b) => {
|
args.json.sort((a, b) => {
|
||||||
return (
|
return (
|
||||||
new Date(b.timestamp).getTime() -
|
new Date(b.timestamp).getTime() -
|
||||||
@@ -349,7 +354,7 @@ export const useGalleryStore = defineStore('Gallery', () => {
|
|||||||
* @param printId
|
* @param printId
|
||||||
*/
|
*/
|
||||||
async function trySavePrintToFile(printId) {
|
async function trySavePrintToFile(printId) {
|
||||||
const args = await queryRequest.fetch('print', { printId });
|
const args = await vrcPlusImageRequest.getPrint({ printId });
|
||||||
const imageUrl = args.json?.files?.image;
|
const imageUrl = args.json?.files?.image;
|
||||||
if (!imageUrl) {
|
if (!imageUrl) {
|
||||||
console.error('Print image URL is missing', args);
|
console.error('Print image URL is missing', args);
|
||||||
@@ -402,8 +407,8 @@ export const useGalleryStore = defineStore('Gallery', () => {
|
|||||||
n: 100,
|
n: 100,
|
||||||
tag: 'emoji'
|
tag: 'emoji'
|
||||||
};
|
};
|
||||||
queryRequest
|
vrcPlusIconRequest
|
||||||
.fetch('galleryFiles', params)
|
.getFileList(params)
|
||||||
.then((args) => handleFilesList(args))
|
.then((args) => handleFilesList(args))
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error('Error fetching emojis:', error);
|
console.error('Error fetching emojis:', error);
|
||||||
@@ -428,7 +433,7 @@ export const useGalleryStore = defineStore('Gallery', () => {
|
|||||||
try {
|
try {
|
||||||
for (let i = 0; i < 100; i++) {
|
for (let i = 0; i < 100; i++) {
|
||||||
params.offset = i * params.n;
|
params.offset = i * params.n;
|
||||||
const args = await queryRequest.fetch('inventoryItems', params);
|
const args = await inventoryRequest.getInventoryItems(params);
|
||||||
for (const item of args.json.data) {
|
for (const item of args.json.data) {
|
||||||
advancedSettingsStore.currentUserInventory.set(
|
advancedSettingsStore.currentUserInventory.set(
|
||||||
item.id,
|
item.id,
|
||||||
|
|||||||
+1
-1
@@ -417,7 +417,7 @@ export const useGroupStore = defineStore('Group', () => {
|
|||||||
let total = Infinity;
|
let total = Infinity;
|
||||||
let pages = 0;
|
let pages = 0;
|
||||||
do {
|
do {
|
||||||
const args = await queryRequest.fetch('groupPosts', {
|
const args = await groupRequest.getGroupPosts({
|
||||||
groupId: params.groupId,
|
groupId: params.groupId,
|
||||||
n,
|
n,
|
||||||
offset
|
offset
|
||||||
|
|||||||
+2
-2
@@ -868,8 +868,8 @@ export const useUserStore = defineStore('User', () => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
groupRequest
|
queryRequest
|
||||||
.getRepresentedGroup({ userId })
|
.fetch('representedGroup', { userId })
|
||||||
.then((args1) => {
|
.then((args1) => {
|
||||||
groupStore.handleGroupRepresented(args1);
|
groupStore.handleGroupRepresented(args1);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -48,7 +48,9 @@ const mocks = vi.hoisted(() => ({
|
|||||||
localFriendFavorites: { value: {} }
|
localFriendFavorites: { value: {} }
|
||||||
},
|
},
|
||||||
locationStore: {
|
locationStore: {
|
||||||
lastLocation: { value: { location: 'wrld_home:123', friendList: new Map() } },
|
lastLocation: {
|
||||||
|
value: { location: 'wrld_home:123', friendList: new Map() }
|
||||||
|
},
|
||||||
lastLocationDestination: { value: '' }
|
lastLocationDestination: { value: '' }
|
||||||
},
|
},
|
||||||
gameStore: {
|
gameStore: {
|
||||||
@@ -62,9 +64,7 @@ const mocks = vi.hoisted(() => ({
|
|||||||
sendRequestInvite: vi.fn().mockResolvedValue({}),
|
sendRequestInvite: vi.fn().mockResolvedValue({}),
|
||||||
sendInvite: vi.fn().mockResolvedValue({})
|
sendInvite: vi.fn().mockResolvedValue({})
|
||||||
},
|
},
|
||||||
worldRequest: {
|
worldRequest: {},
|
||||||
getCachedWorld: vi.fn().mockResolvedValue({ ref: { name: 'World' } })
|
|
||||||
},
|
|
||||||
instanceRequest: {
|
instanceRequest: {
|
||||||
selfInvite: vi.fn().mockResolvedValue({})
|
selfInvite: vi.fn().mockResolvedValue({})
|
||||||
},
|
},
|
||||||
@@ -162,7 +162,8 @@ vi.mock('../../../../components/ui/context-menu', () => ({
|
|||||||
ContextMenuItem: {
|
ContextMenuItem: {
|
||||||
emits: ['click'],
|
emits: ['click'],
|
||||||
props: ['disabled'],
|
props: ['disabled'],
|
||||||
template: '<button :disabled="disabled" @click="$emit(\'click\')"><slot /></button>'
|
template:
|
||||||
|
'<button :disabled="disabled" @click="$emit(\'click\')"><slot /></button>'
|
||||||
},
|
},
|
||||||
ContextMenuSeparator: { template: '<hr />' },
|
ContextMenuSeparator: { template: '<hr />' },
|
||||||
ContextMenuSub: { template: '<div><slot /></div>' },
|
ContextMenuSub: { template: '<div><slot /></div>' },
|
||||||
@@ -277,7 +278,10 @@ describe('FriendsSidebar.vue', () => {
|
|||||||
test('renders same-instance section when grouping is enabled', async () => {
|
test('renders same-instance section when grouping is enabled', async () => {
|
||||||
mocks.appearanceStore.isSidebarGroupByInstance.value = true;
|
mocks.appearanceStore.isSidebarGroupByInstance.value = true;
|
||||||
mocks.friendStore.friendsInSameInstance.value = [
|
mocks.friendStore.friendsInSameInstance.value = [
|
||||||
[makeFriend('usr_a', 'wrld_same:1'), makeFriend('usr_b', 'wrld_same:1')]
|
[
|
||||||
|
makeFriend('usr_a', 'wrld_same:1'),
|
||||||
|
makeFriend('usr_b', 'wrld_same:1')
|
||||||
|
]
|
||||||
];
|
];
|
||||||
|
|
||||||
const wrapper = mount(FriendsSidebar);
|
const wrapper = mount(FriendsSidebar);
|
||||||
|
|||||||
@@ -106,8 +106,8 @@
|
|||||||
|
|
||||||
import { formatDateFilter, getGroupName, replaceBioSymbols } from '../../../shared/utils';
|
import { formatDateFilter, getGroupName, replaceBioSymbols } from '../../../shared/utils';
|
||||||
import { Switch } from '../../../components/ui/switch';
|
import { Switch } from '../../../components/ui/switch';
|
||||||
|
import { groupRequest } from '../../../api';
|
||||||
import { processBulk } from '../../../service/request';
|
import { processBulk } from '../../../service/request';
|
||||||
import { queryRequest } from '../../../api';
|
|
||||||
import { useGroupStore } from '../../../stores';
|
import { useGroupStore } from '../../../stores';
|
||||||
|
|
||||||
import GroupCalendarEventCard from '../components/GroupCalendarEventCard.vue';
|
import GroupCalendarEventCard from '../components/GroupCalendarEventCard.vue';
|
||||||
@@ -355,7 +355,7 @@
|
|||||||
calendar.value = [];
|
calendar.value = [];
|
||||||
try {
|
try {
|
||||||
await processBulk({
|
await processBulk({
|
||||||
fn: (bulkParams) => queryRequest.fetch('groupCalendars', bulkParams),
|
fn: (bulkParams) => groupRequest.getGroupCalendars(bulkParams),
|
||||||
N: -1,
|
N: -1,
|
||||||
params: {
|
params: {
|
||||||
n: 100,
|
n: 100,
|
||||||
@@ -384,7 +384,7 @@
|
|||||||
followingCalendar.value = [];
|
followingCalendar.value = [];
|
||||||
try {
|
try {
|
||||||
await processBulk({
|
await processBulk({
|
||||||
fn: (bulkParams) => queryRequest.fetch('followingGroupCalendars', bulkParams),
|
fn: (bulkParams) => groupRequest.getFollowingGroupCalendars(bulkParams),
|
||||||
N: -1,
|
N: -1,
|
||||||
params: {
|
params: {
|
||||||
n: 100,
|
n: 100,
|
||||||
@@ -411,7 +411,7 @@
|
|||||||
featuredCalendar.value = [];
|
featuredCalendar.value = [];
|
||||||
try {
|
try {
|
||||||
await processBulk({
|
await processBulk({
|
||||||
fn: (bulkParams) => queryRequest.fetch('featuredGroupCalendars', bulkParams),
|
fn: (bulkParams) => groupRequest.getFeaturedGroupCalendars(bulkParams),
|
||||||
N: -1,
|
N: -1,
|
||||||
params: {
|
params: {
|
||||||
n: 100,
|
n: 100,
|
||||||
|
|||||||
Reference in New Issue
Block a user