refactor queryRequest

This commit is contained in:
pa
2026-03-09 23:59:19 +09:00
parent 8f802ecf28
commit 21489fb717
17 changed files with 312 additions and 418 deletions

View File

@@ -42,21 +42,11 @@ const registry = Object.freeze({
policy: entityQueryPolicies.group,
queryFn: (params) => groupRequest.getGroup(params)
},
groupPosts: {
key: (params) => queryKeys.groupPosts(params),
policy: entityQueryPolicies.groupCollection,
queryFn: (params) => groupRequest.getGroupPosts(params)
},
groupMember: {
key: (params) => queryKeys.groupMember(params),
policy: entityQueryPolicies.groupCollection,
queryFn: (params) => groupRequest.getGroupMember(params)
},
groupMembers: {
key: (params) => queryKeys.groupMembers(params),
policy: entityQueryPolicies.groupCollection,
queryFn: (params) => groupRequest.getGroupMembers(params)
},
groupGallery: {
key: (params) => queryKeys.groupGallery(params),
policy: entityQueryPolicies.groupCollection,
@@ -67,21 +57,6 @@ const registry = Object.freeze({
policy: entityQueryPolicies.groupCollection,
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: {
key: (params) => queryKeys.groupCalendarEvent(params),
policy: entityQueryPolicies.groupCalendarEvent,
@@ -92,71 +67,16 @@ const registry = Object.freeze({
policy: entityQueryPolicies.avatarGallery,
queryFn: (params) => avatarRequest.getAvatarGallery(params.avatarId)
},
friends: {
key: (params) => queryKeys.friends(params),
policy: entityQueryPolicies.friendList,
queryFn: (params) => friendRequest.getFriends(params)
},
favoriteLimits: {
key: () => queryKeys.favoriteLimits(),
policy: entityQueryPolicies.favoriteCollection,
policy: entityQueryPolicies.favoriteLimits,
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: {
key: (params) => queryKeys.userInventoryItem(params),
policy: entityQueryPolicies.inventoryCollection,
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: {
key: (params) => queryKeys.fileAnalysis(params),
policy: entityQueryPolicies.fileAnalysis,
@@ -181,6 +101,21 @@ const registry = Object.freeze({
key: (params) => queryKeys.file(params.fileId),
policy: entityQueryPolicies.fileObject,
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()
}
});

View File

@@ -90,8 +90,8 @@
import { watch } from 'vue';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../../ui/select';
import { avatarRequest, queryRequest } from '../../../api';
import { arraysMatch } from '../../../shared/utils';
import { avatarRequest } from '../../../api';
import { useAvatarStore } from '../../../stores';
const props = defineProps({
@@ -133,7 +133,7 @@
*/
async function getAvatarStyles() {
try {
const ref = await avatarRequest.getAvailableAvatarStyles();
const ref = await queryRequest.fetch('avatarStyles');
const styles = [];
const stylesMap = new Map();
for (const style of ref.json) {

View File

@@ -408,6 +408,7 @@
} from '../../../shared/utils';
import { useGalleryStore, useGroupStore, useModalStore, useUserStore } from '../../../stores';
import { groupRequest, queryRequest } from '../../../api';
import { queryKeys, refetchActiveEntityQuery } from '../../../queries';
import { Badge } from '../../ui/badge';
import { formatJsonVars } from '../../../shared/utils/base/ui';
@@ -497,8 +498,6 @@
}
);
/**
*
* @param groupId
@@ -536,6 +535,7 @@
});
getGroupDialogGroup(groupId);
}
refetchActiveEntityQuery(queryKeys.representedGroup(currentUser.value.id));
});
}
@@ -604,8 +604,6 @@
* @param gallery
*/
/**
*
* @param id

View File

@@ -76,7 +76,7 @@
import DeprecationAlert from '@/components/DeprecationAlert.vue';
import { useFavoriteStore, useUserStore, useWorldStore } from '../../../stores';
import { queryRequest } from '../../../api';
import { favoriteRequest } from '../../../api';
const { t } = useI18n();
@@ -121,7 +121,7 @@
favoriteWorldsTab.value = '0';
userDialog.value.userFavoriteWorlds = [];
const worldLists = [];
const groupArgs = await queryRequest.fetch('favoriteGroups', {
const groupArgs = await favoriteRequest.getFavoriteGroups({
ownerId: userId,
n: 100,
offset: 0
@@ -145,7 +145,7 @@
tag: list.name
};
try {
const args = await queryRequest.fetch('favoriteWorlds', params);
const args = await favoriteRequest.getFavoriteWorlds(params);
handleFavoriteWorldList(args);
return [list.displayName, list.visibility, args.json];
} catch (err) {

View File

@@ -475,7 +475,6 @@
import { storeToRefs } from 'pinia';
import { toast } from 'vue-sonner';
import { useI18n } from 'vue-i18n';
import InstanceActionBar from '../../InstanceActionBar.vue';
import {
copyToClipboard,
@@ -502,7 +501,9 @@
useUserStore,
useWorldStore
} from '../../../stores';
import { miscRequest, userRequest } from '../../../api';
import { queryRequest, userRequest } from '../../../api';
import InstanceActionBar from '../../InstanceActionBar.vue';
const EditNoteAndMemoDialog = defineAsyncComponent(() => import('./EditNoteAndMemoDialog.vue'));
@@ -681,7 +682,7 @@
*
*/
function getVRChatCredits() {
miscRequest.getVRChatCredits().then((args) => (vrchatCredit.value = args.json?.balance));
queryRequest.fetch('vrchatCredits').then((args) => (vrchatCredit.value = args.json?.balance));
}
defineExpose({

View File

@@ -25,11 +25,7 @@ vi.mock('../../../../api', () => ({
sendPlayerModeration: vi.fn(),
deletePlayerModeration: vi.fn()
},
worldRequest: {
getCachedWorld: vi.fn(() =>
Promise.resolve({ ref: { name: 'TestWorld' } })
)
}
worldRequest: {}
}));
vi.mock('../../../../shared/utils', () => ({

View File

@@ -3,25 +3,6 @@ import { describe, expect, test } from 'vitest';
import { queryKeys } from '../keys';
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', () => {
const base = {
userId: 'usr_me',
@@ -42,22 +23,119 @@ describe('query key shapes', () => {
expect(defaultKey).not.toEqual(featuredKey);
});
test('group member list keys include sort and role dimensions', () => {
const everyone = queryKeys.groupMembers({
test('groupCalendarEvent key includes groupId and eventId', () => {
const a = queryKeys.groupCalendarEvent({
groupId: 'grp_1',
n: 100,
offset: 0,
sort: 'joinedAt:desc',
roleId: ''
eventId: 'evt_1'
});
const roleScoped = queryKeys.groupMembers({
const b = queryKeys.groupCalendarEvent({
groupId: 'grp_1',
n: 100,
offset: 0,
sort: 'joinedAt:desc',
roleId: 'grol_1'
eventId: 'evt_2'
});
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);
});
});

View File

@@ -1,12 +1,9 @@
import { describe, expect, test } from 'vitest';
import {
entityQueryPolicies,
toQueryOptions
} from '../policies';
import { entityQueryPolicies, toQueryOptions } from '../policies';
describe('query policy configuration', () => {
test('matches the finalized cache strategy', () => {
test('core entity policies have correct stale/gc times', () => {
expect(entityQueryPolicies.user).toMatchObject({
staleTime: 20000,
gcTime: 90000,
@@ -34,64 +31,37 @@ describe('query policy configuration', () => {
retry: 1,
refetchOnWindowFocus: false
});
});
test('group sub-resource policies', () => {
expect(entityQueryPolicies.groupCollection).toMatchObject({
staleTime: 60000,
gcTime: 300000,
retry: 1,
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({
staleTime: 120000,
gcTime: 600000,
retry: 1,
refetchOnWindowFocus: false
});
});
test('world collection policy', () => {
expect(entityQueryPolicies.worldCollection).toMatchObject({
staleTime: 60000,
gcTime: 300000,
retry: 1,
refetchOnWindowFocus: false
});
});
expect(entityQueryPolicies.friendList).toMatchObject({
staleTime: 20000,
gcTime: 90000,
retry: 1,
refetchOnWindowFocus: false
});
expect(entityQueryPolicies.favoriteCollection).toMatchObject({
staleTime: 60000,
gcTime: 300000,
retry: 1,
refetchOnWindowFocus: false
});
expect(entityQueryPolicies.galleryCollection).toMatchObject({
staleTime: 60000,
gcTime: 300000,
test('favorite and inventory policies', () => {
expect(entityQueryPolicies.favoriteLimits).toMatchObject({
staleTime: 600000,
gcTime: 1800000,
retry: 1,
refetchOnWindowFocus: false
});
@@ -102,42 +72,28 @@ describe('query policy configuration', () => {
retry: 1,
refetchOnWindowFocus: false
});
expect(entityQueryPolicies.inventoryObject).toMatchObject({
staleTime: 60000,
gcTime: 300000,
retry: 1,
refetchOnWindowFocus: false
});
});
test('avatar gallery policy has shorter staleTime than avatar entity', () => {
expect(entityQueryPolicies.avatarGallery).toMatchObject({
staleTime: 30000,
gcTime: 120000,
retry: 1,
refetchOnWindowFocus: false
});
expect(entityQueryPolicies.avatarGallery.staleTime).toBeLessThan(
entityQueryPolicies.avatar.staleTime
);
});
test('file-related policies', () => {
expect(entityQueryPolicies.fileAnalysis).toMatchObject({
staleTime: 120000,
gcTime: 600000,
retry: 1,
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({
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', () => {
const options = toQueryOptions(entityQueryPolicies.group);
@@ -157,4 +170,34 @@ describe('query policy configuration', () => {
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);
}
});
});

View File

@@ -7,38 +7,12 @@ export const queryKeys = Object.freeze({
groupId,
Boolean(includeRoles)
],
groupPosts: ({ groupId, n = 100, offset = 0 } = {}) => [
'group',
groupId,
'posts',
{
n: Number(n),
offset: Number(offset)
}
],
groupMember: ({ groupId, userId } = {}) => [
'group',
groupId,
'member',
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 } = {}) => [
'group',
groupId,
@@ -50,35 +24,6 @@ export const queryKeys = Object.freeze({
}
],
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 } = {}) => [
'group',
groupId,
@@ -109,109 +54,13 @@ export const queryKeys = Object.freeze({
option: String(option || '')
}
],
friends: ({ offline = false, n = 50, offset = 0 } = {}) => [
'friends',
{
offline: Boolean(offline),
n: Number(n),
offset: Number(offset)
}
],
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 }) => [
'inventory',
'item',
userId,
inventoryId
],
inventoryItem: (inventoryId) => ['inventory', 'item', inventoryId],
inventoryTemplate: (inventoryTemplateId) => [
'inventory',
'template',
inventoryTemplateId
],
fileAnalysis: ({ fileId, version, variant } = {}) => [
'analysis',
fileId,
@@ -221,5 +70,8 @@ export const queryKeys = Object.freeze({
worldPersistData: (worldId) => ['world', worldId, 'persistData'],
mutualCounts: (userId) => ['user', userId, 'mutualCounts'],
visits: () => ['visits'],
file: (fileId) => ['file', fileId]
file: (fileId) => ['file', fileId],
avatarStyles: () => ['avatar', 'styles'],
representedGroup: (userId) => ['user', userId, 'representedGroup'],
vrchatCredits: () => ['credits']
});

View File

@@ -31,24 +31,6 @@ export const entityQueryPolicies = Object.freeze({
retry: 1,
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({
staleTime: 120 * SECOND,
gcTime: 600 * SECOND,
@@ -61,21 +43,9 @@ export const entityQueryPolicies = Object.freeze({
retry: 1,
refetchOnWindowFocus: false
}),
friendList: Object.freeze({
staleTime: 20 * SECOND,
gcTime: 90 * 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,
favoriteLimits: Object.freeze({
staleTime: 600 * SECOND,
gcTime: 1800 * SECOND,
retry: 1,
refetchOnWindowFocus: false
}),
@@ -85,12 +55,6 @@ export const entityQueryPolicies = Object.freeze({
retry: 1,
refetchOnWindowFocus: false
}),
inventoryObject: Object.freeze({
staleTime: 60 * SECOND,
gcTime: 300 * SECOND,
retry: 1,
refetchOnWindowFocus: false
}),
avatarGallery: Object.freeze({
staleTime: 30 * SECOND,
gcTime: 120 * SECOND,
@@ -126,6 +90,24 @@ export const entityQueryPolicies = Object.freeze({
gcTime: 300 * SECOND,
retry: 1,
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
})
});

View File

@@ -600,7 +600,7 @@ export const useFavoriteStore = defineStore('Favorite', () => {
}
isFavoriteGroupLoading.value = true;
processBulk({
fn: favoriteRequest.getCachedFavoriteGroups,
fn: (params) => favoriteRequest.getFavoriteGroups(params),
N: -1,
params: {
n: 50,
@@ -781,7 +781,7 @@ export const useFavoriteStore = defineStore('Favorite', () => {
}
let newFavoriteSortOrder = [];
processBulk({
fn: (params) => queryRequest.fetch('favorites', params),
fn: (params) => favoriteRequest.getFavorites(params),
N: -1,
params: {
n: 300,
@@ -884,7 +884,7 @@ export const useFavoriteStore = defineStore('Favorite', () => {
offset: 0,
tag
};
const args = await queryRequest.fetch('favoriteAvatars', params);
const args = await favoriteRequest.getFavoriteAvatars(params);
handleFavoriteAvatarList(args);
}
@@ -893,8 +893,8 @@ export const useFavoriteStore = defineStore('Favorite', () => {
*/
function refreshFavoriteItems() {
const types = {
world: [0, favoriteRequest.getCachedFavoriteWorlds],
avatar: [0, favoriteRequest.getCachedFavoriteAvatars]
world: [0, (params) => favoriteRequest.getFavoriteWorlds(params)],
avatar: [0, (params) => favoriteRequest.getFavoriteAvatars(params)]
};
const tags = [];
for (const ref of cachedFavorites.values()) {

View File

@@ -16,7 +16,7 @@ import {
isRealInstance,
migrateMemos
} from '../shared/utils';
import { friendRequest, queryRequest, userRequest } from '../api';
import { friendRequest, userRequest } from '../api';
import { AppDebug } from '../service/appConfig';
import { createFriendPresenceCoordinator } from './coordinators/friendPresenceCoordinator';
import { createFriendRelationshipCoordinator } from './coordinators/friendRelationshipCoordinator';
@@ -567,7 +567,7 @@ export const useFriendStore = defineStore('Friend', () => {
async function fetchPage(offset) {
const result = await executeWithBackoff(
async () => {
const { json } = await queryRequest.fetch('friends', {
const { json } = await friendRequest.getFriends({
...args,
n: PAGE_SIZE,
offset

View File

@@ -9,7 +9,12 @@ import {
getPrintLocalDate,
openExternalLink
} from '../shared/utils';
import { queryRequest, vrcPlusImageRequest } from '../api';
import {
inventoryRequest,
queryRequest,
vrcPlusIconRequest,
vrcPlusImageRequest
} from '../api';
import { AppDebug } from '../service/appConfig';
import { handleImageUploadInput } from '../shared/utils/imageUpload';
import { router } from '../plugin/router';
@@ -157,8 +162,8 @@ export const useGalleryStore = defineStore('Gallery', () => {
n: 100,
tag: 'gallery'
};
queryRequest
.fetch('galleryFiles', params)
vrcPlusIconRequest
.getFileList(params)
.then((args) => handleFilesList(args))
.catch((error) => {
console.error('Error fetching gallery files:', error);
@@ -177,8 +182,8 @@ export const useGalleryStore = defineStore('Gallery', () => {
n: 100,
tag: 'icon'
};
queryRequest
.fetch('galleryFiles', params)
vrcPlusIconRequest
.getFileList(params)
.then((args) => handleFilesList(args))
.catch((error) => {
console.error('Error fetching VRC Plus icons:', error);
@@ -229,8 +234,8 @@ export const useGalleryStore = defineStore('Gallery', () => {
n: 100,
tag: 'sticker'
};
queryRequest
.fetch('galleryFiles', params)
vrcPlusIconRequest
.getFileList(params)
.then((args) => handleFilesList(args))
.catch((error) => {
console.error('Error fetching stickers:', error);
@@ -304,7 +309,7 @@ export const useGalleryStore = defineStore('Gallery', () => {
n: 100
};
try {
const args = await queryRequest.fetch('prints', params);
const args = await vrcPlusImageRequest.getPrints(params);
args.json.sort((a, b) => {
return (
new Date(b.timestamp).getTime() -
@@ -349,7 +354,7 @@ export const useGalleryStore = defineStore('Gallery', () => {
* @param printId
*/
async function trySavePrintToFile(printId) {
const args = await queryRequest.fetch('print', { printId });
const args = await vrcPlusImageRequest.getPrint({ printId });
const imageUrl = args.json?.files?.image;
if (!imageUrl) {
console.error('Print image URL is missing', args);
@@ -402,8 +407,8 @@ export const useGalleryStore = defineStore('Gallery', () => {
n: 100,
tag: 'emoji'
};
queryRequest
.fetch('galleryFiles', params)
vrcPlusIconRequest
.getFileList(params)
.then((args) => handleFilesList(args))
.catch((error) => {
console.error('Error fetching emojis:', error);
@@ -428,7 +433,7 @@ export const useGalleryStore = defineStore('Gallery', () => {
try {
for (let i = 0; i < 100; i++) {
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) {
advancedSettingsStore.currentUserInventory.set(
item.id,

View File

@@ -417,7 +417,7 @@ export const useGroupStore = defineStore('Group', () => {
let total = Infinity;
let pages = 0;
do {
const args = await queryRequest.fetch('groupPosts', {
const args = await groupRequest.getGroupPosts({
groupId: params.groupId,
n,
offset

View File

@@ -868,8 +868,8 @@ export const useUserStore = defineStore('User', () => {
}
});
}
groupRequest
.getRepresentedGroup({ userId })
queryRequest
.fetch('representedGroup', { userId })
.then((args1) => {
groupStore.handleGroupRepresented(args1);
});

View File

@@ -48,7 +48,9 @@ const mocks = vi.hoisted(() => ({
localFriendFavorites: { value: {} }
},
locationStore: {
lastLocation: { value: { location: 'wrld_home:123', friendList: new Map() } },
lastLocation: {
value: { location: 'wrld_home:123', friendList: new Map() }
},
lastLocationDestination: { value: '' }
},
gameStore: {
@@ -62,9 +64,7 @@ const mocks = vi.hoisted(() => ({
sendRequestInvite: vi.fn().mockResolvedValue({}),
sendInvite: vi.fn().mockResolvedValue({})
},
worldRequest: {
getCachedWorld: vi.fn().mockResolvedValue({ ref: { name: 'World' } })
},
worldRequest: {},
instanceRequest: {
selfInvite: vi.fn().mockResolvedValue({})
},
@@ -162,7 +162,8 @@ vi.mock('../../../../components/ui/context-menu', () => ({
ContextMenuItem: {
emits: ['click'],
props: ['disabled'],
template: '<button :disabled="disabled" @click="$emit(\'click\')"><slot /></button>'
template:
'<button :disabled="disabled" @click="$emit(\'click\')"><slot /></button>'
},
ContextMenuSeparator: { template: '<hr />' },
ContextMenuSub: { template: '<div><slot /></div>' },
@@ -277,7 +278,10 @@ describe('FriendsSidebar.vue', () => {
test('renders same-instance section when grouping is enabled', async () => {
mocks.appearanceStore.isSidebarGroupByInstance.value = true;
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);

View File

@@ -106,8 +106,8 @@
import { formatDateFilter, getGroupName, replaceBioSymbols } from '../../../shared/utils';
import { Switch } from '../../../components/ui/switch';
import { groupRequest } from '../../../api';
import { processBulk } from '../../../service/request';
import { queryRequest } from '../../../api';
import { useGroupStore } from '../../../stores';
import GroupCalendarEventCard from '../components/GroupCalendarEventCard.vue';
@@ -355,7 +355,7 @@
calendar.value = [];
try {
await processBulk({
fn: (bulkParams) => queryRequest.fetch('groupCalendars', bulkParams),
fn: (bulkParams) => groupRequest.getGroupCalendars(bulkParams),
N: -1,
params: {
n: 100,
@@ -384,7 +384,7 @@
followingCalendar.value = [];
try {
await processBulk({
fn: (bulkParams) => queryRequest.fetch('followingGroupCalendars', bulkParams),
fn: (bulkParams) => groupRequest.getFollowingGroupCalendars(bulkParams),
N: -1,
params: {
n: 100,
@@ -411,7 +411,7 @@
featuredCalendar.value = [];
try {
await processBulk({
fn: (bulkParams) => queryRequest.fetch('featuredGroupCalendars', bulkParams),
fn: (bulkParams) => groupRequest.getFeaturedGroupCalendars(bulkParams),
N: -1,
params: {
n: 100,