@lobehub/lobehub 2.0.0-next.59 → 2.0.0-next.60
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/CHANGELOG.md +25 -0
- package/changelog/v1.json +9 -0
- package/package.json +1 -3
- package/src/app/[variants]/(main)/chat/components/conversation/features/ChatMinimap/index.tsx +4 -2
- package/src/services/__tests__/upload.test.ts +92 -82
- package/src/services/upload.ts +4 -33
- package/src/services/file/ClientS3/index.test.ts +0 -115
- package/src/services/file/ClientS3/index.ts +0 -59
- package/src/store/middleware/createHyperStorage/index.test.ts +0 -341
- package/src/store/middleware/createHyperStorage/index.ts +0 -126
- package/src/store/middleware/createHyperStorage/indexedDB.test.ts +0 -64
- package/src/store/middleware/createHyperStorage/indexedDB.ts +0 -26
- package/src/store/middleware/createHyperStorage/keyMapper.ts +0 -57
- package/src/store/middleware/createHyperStorage/localStorage.ts +0 -18
- package/src/store/middleware/createHyperStorage/type.ts +0 -25
- package/src/store/middleware/createHyperStorage/urlStorage.test.ts +0 -84
- package/src/store/middleware/createHyperStorage/urlStorage.ts +0 -81
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
2
|
-
|
|
3
|
-
import { creatUrlStorage } from './urlStorage';
|
|
4
|
-
|
|
5
|
-
// Mock global location and history objects
|
|
6
|
-
const mockLocation = {
|
|
7
|
-
hash: '',
|
|
8
|
-
search: '',
|
|
9
|
-
};
|
|
10
|
-
const mockHistory = {
|
|
11
|
-
replaceState: vi.fn(),
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
global.location = mockLocation as Location;
|
|
15
|
-
global.history = mockHistory as any as History;
|
|
16
|
-
|
|
17
|
-
describe('creatUrlStorage', () => {
|
|
18
|
-
beforeEach(() => {
|
|
19
|
-
// Reset all mocks and location properties before each test
|
|
20
|
-
vi.resetAllMocks();
|
|
21
|
-
mockLocation.hash = '';
|
|
22
|
-
mockLocation.search = '';
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
it('getItem should return the correct state from URL hash', () => {
|
|
26
|
-
mockLocation.hash = '#key1=value1&key2=value2';
|
|
27
|
-
const storage = creatUrlStorage('hash');
|
|
28
|
-
const result = storage.getItem();
|
|
29
|
-
|
|
30
|
-
expect(result).toEqual({ state: { key1: 'value1', key2: 'value2' } });
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
it('getItem should return the correct state from URL search', () => {
|
|
34
|
-
mockLocation.search = '?key1=value1&key2=value2';
|
|
35
|
-
const storage = creatUrlStorage('search');
|
|
36
|
-
const result = storage.getItem();
|
|
37
|
-
|
|
38
|
-
expect(result).toEqual({ state: { key1: 'value1', key2: 'value2' } });
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
it('getItem should return undefined if no state in URL', () => {
|
|
42
|
-
const storage = creatUrlStorage('hash');
|
|
43
|
-
const result = storage.getItem();
|
|
44
|
-
|
|
45
|
-
expect(result).toBeUndefined();
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
it('removeItem should remove a specific key from URL hash', () => {
|
|
49
|
-
mockLocation.hash = '#key1=value1&key2=value2';
|
|
50
|
-
const storage = creatUrlStorage('hash');
|
|
51
|
-
storage.removeItem('key1');
|
|
52
|
-
|
|
53
|
-
expect(location.hash).toEqual('key2=value2');
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
it('removeItem should remove a specific key from URL search', () => {
|
|
57
|
-
mockLocation.search = '?key1=value1&key2=value2';
|
|
58
|
-
const storage = creatUrlStorage('search');
|
|
59
|
-
storage.removeItem('key1');
|
|
60
|
-
|
|
61
|
-
expect(mockHistory.replaceState).toHaveBeenCalledWith({}, '', '?key2=value2');
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
it('setItem should set state in URL hash', () => {
|
|
65
|
-
const storage = creatUrlStorage('hash');
|
|
66
|
-
storage.setItem('state', { key1: 'value1', key2: 'value2', key3: 1, key4: false });
|
|
67
|
-
|
|
68
|
-
expect(location.hash).toEqual('key1=value1&key2=value2&key3=1&key4=0');
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
it('setItem should set state in URL search', () => {
|
|
72
|
-
const storage = creatUrlStorage('search');
|
|
73
|
-
storage.setItem('state', { key1: 'value1', key2: 'value2' });
|
|
74
|
-
|
|
75
|
-
expect(mockHistory.replaceState).toHaveBeenCalledWith({}, '', '?key1=value1&key2=value2');
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
it('setItem should handle non-string values by JSON stringifying them', () => {
|
|
79
|
-
const storage = creatUrlStorage('hash');
|
|
80
|
-
storage.setItem('state', { key1: { nested: 'value' }, key2: 123, key4: {} });
|
|
81
|
-
|
|
82
|
-
expect(location.hash).toEqual(`key1=%7B%22nested%22%3A%22value%22%7D&key2=123`);
|
|
83
|
-
});
|
|
84
|
-
});
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import { isEmpty } from 'lodash-es';
|
|
2
|
-
import { StorageValue } from 'zustand/middleware';
|
|
3
|
-
|
|
4
|
-
interface UrlSearchHelper {
|
|
5
|
-
getUrlSearch: () => string;
|
|
6
|
-
setUrlSearch: (params: URLSearchParams) => void;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
const createUrlSearch = (mode: 'search' | 'hash' = 'hash'): UrlSearchHelper => {
|
|
10
|
-
if (mode === 'hash')
|
|
11
|
-
return {
|
|
12
|
-
getUrlSearch: () => location.hash.slice(1),
|
|
13
|
-
setUrlSearch: (params: URLSearchParams) => (location.hash = params.toString()),
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
return {
|
|
17
|
-
getUrlSearch: () => location.search.slice(1),
|
|
18
|
-
setUrlSearch: (params: URLSearchParams) => {
|
|
19
|
-
if (params.size === 0) return;
|
|
20
|
-
|
|
21
|
-
history.replaceState({}, '', '?' + params.toString());
|
|
22
|
-
},
|
|
23
|
-
};
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
export const creatUrlStorage = <State extends object>(mode: 'hash' | 'search' = 'hash') => {
|
|
27
|
-
const { setUrlSearch, getUrlSearch } = createUrlSearch(mode);
|
|
28
|
-
|
|
29
|
-
return {
|
|
30
|
-
getItem: <T extends State>(): StorageValue<T> | undefined => {
|
|
31
|
-
const searchParameters = new URLSearchParams(getUrlSearch());
|
|
32
|
-
|
|
33
|
-
if (searchParameters.size === 0) return undefined;
|
|
34
|
-
|
|
35
|
-
const state = Object.fromEntries(searchParameters.entries()) as T;
|
|
36
|
-
|
|
37
|
-
return { state };
|
|
38
|
-
},
|
|
39
|
-
removeItem: (key?: string) => {
|
|
40
|
-
const searchParameters = new URLSearchParams(getUrlSearch());
|
|
41
|
-
if (key) searchParameters.delete(key);
|
|
42
|
-
|
|
43
|
-
setUrlSearch(searchParameters);
|
|
44
|
-
},
|
|
45
|
-
setItem: <T extends State>(name: string, state: T) => {
|
|
46
|
-
const searchParameters = new URLSearchParams(getUrlSearch());
|
|
47
|
-
|
|
48
|
-
for (const [urlKey, v] of Object.entries(state)) {
|
|
49
|
-
switch (typeof v) {
|
|
50
|
-
case 'boolean': {
|
|
51
|
-
searchParameters.set(urlKey, (v ? 1 : 0).toString());
|
|
52
|
-
break;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
case 'bigint':
|
|
56
|
-
case 'number': {
|
|
57
|
-
searchParameters.set(urlKey, v.toString());
|
|
58
|
-
break;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
case 'string': {
|
|
62
|
-
searchParameters.set(urlKey, v);
|
|
63
|
-
break;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
case 'object': {
|
|
67
|
-
if (isEmpty(v)) {
|
|
68
|
-
searchParameters.delete(urlKey);
|
|
69
|
-
continue;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
searchParameters.set(urlKey, JSON.stringify(v));
|
|
73
|
-
break;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
setUrlSearch(searchParameters);
|
|
79
|
-
},
|
|
80
|
-
};
|
|
81
|
-
};
|