@lark-apaas/client-toolkit 1.1.14-alpha.devServer.1 → 1.1.14-dataloom-test.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/components/AppContainer/IframeBridge.js +3 -3
- package/lib/components/AppContainer/PageHoc.js +2 -2
- package/lib/components/AppContainer/utils/listenHot.js +9 -7
- package/lib/components/User/UserDisplay.d.ts +6 -1
- package/lib/components/User/UserDisplay.js +80 -29
- package/lib/components/User/UserSelect.d.ts +7 -3
- package/lib/components/User/UserSelect.js +134 -5
- package/lib/components/User/UserWithAvatar.js +6 -1
- package/lib/logger/intercept-global-error.js +4 -63
- package/lib/logger/log-types.d.ts +13 -4
- package/lib/logger/log-types.js +5 -2
- package/lib/logger/selected-logs.js +51 -5
- package/lib/types/iframe-events.d.ts +1 -8
- package/lib/utils/postMessage.d.ts +1 -2
- package/lib/utils/postMessage.js +2 -7
- package/package.json +2 -2
|
@@ -3,7 +3,7 @@ import { useCallback, useEffect, useMemo, useRef } from "react";
|
|
|
3
3
|
import { useLocation, useNavigate } from "react-router-dom";
|
|
4
4
|
import { connectToParent } from "penpal";
|
|
5
5
|
import { useUpdatingRef } from "../../hooks/useUpdatingRef.js";
|
|
6
|
-
import {
|
|
6
|
+
import { postMessage } from "../../utils/postMessage.js";
|
|
7
7
|
import { getPreviewParentOrigin } from "../../utils/getParentOrigin.js";
|
|
8
8
|
import { childApi } from "./utils/childApi.js";
|
|
9
9
|
import "./utils/listenHot.js";
|
|
@@ -17,7 +17,7 @@ function isRouteMessageType(type) {
|
|
|
17
17
|
return Object.values(IframeBridge_RouteMessageType).includes(type);
|
|
18
18
|
}
|
|
19
19
|
async function connectParent() {
|
|
20
|
-
|
|
20
|
+
postMessage({
|
|
21
21
|
type: 'PreviewReady',
|
|
22
22
|
data: {}
|
|
23
23
|
});
|
|
@@ -61,7 +61,7 @@ function IframeBridge() {
|
|
|
61
61
|
isActive.current = false;
|
|
62
62
|
return;
|
|
63
63
|
}
|
|
64
|
-
|
|
64
|
+
postMessage({
|
|
65
65
|
type: 'ChildLocationChange',
|
|
66
66
|
data: location
|
|
67
67
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Fragment, jsx } from "react/jsx-runtime";
|
|
2
2
|
import { useEffect } from "react";
|
|
3
3
|
import { snapdom } from "@zumer/snapdom";
|
|
4
|
-
import {
|
|
4
|
+
import { postMessage } from "../../utils/postMessage.js";
|
|
5
5
|
function PageHoc(props) {
|
|
6
6
|
const { children } = props;
|
|
7
7
|
useEffect(()=>{
|
|
@@ -17,7 +17,7 @@ function PageHoc(props) {
|
|
|
17
17
|
backgroundColor: '#ffffff'
|
|
18
18
|
}).then(async (res)=>{
|
|
19
19
|
const imgEle = await res.toPng();
|
|
20
|
-
|
|
20
|
+
postMessage({
|
|
21
21
|
type: 'PageScreenshot',
|
|
22
22
|
data: imgEle.src
|
|
23
23
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import sockjs_client from "sockjs-client";
|
|
2
|
-
import {
|
|
2
|
+
import { postMessage } from "../../../utils/postMessage.js";
|
|
3
3
|
import { getWsPath } from "../../../utils/utils.js";
|
|
4
4
|
let hotInited = false;
|
|
5
5
|
function handleDevServerMessage(msg) {
|
|
@@ -8,14 +8,14 @@ function handleDevServerMessage(msg) {
|
|
|
8
8
|
hotInited = true;
|
|
9
9
|
return;
|
|
10
10
|
}
|
|
11
|
-
|
|
11
|
+
postMessage({
|
|
12
12
|
type: 'HmrMessage',
|
|
13
13
|
msg: {
|
|
14
14
|
type: 'hot'
|
|
15
15
|
},
|
|
16
16
|
data: null
|
|
17
17
|
});
|
|
18
|
-
} else if ('errors' === msg.type)
|
|
18
|
+
} else if ('errors' === msg.type) postMessage({
|
|
19
19
|
type: 'HmrMessage',
|
|
20
20
|
msg: {
|
|
21
21
|
type: 'errors',
|
|
@@ -25,7 +25,8 @@ function handleDevServerMessage(msg) {
|
|
|
25
25
|
});
|
|
26
26
|
else if ('hmr-timing' === msg.type) {
|
|
27
27
|
const { duration, fileCount, fileTotalSize } = msg.data;
|
|
28
|
-
|
|
28
|
+
const slardar = window['KSlardarWeb'];
|
|
29
|
+
if (slardar && 'function' == typeof slardar) slardar('sendEvent', {
|
|
29
30
|
name: 'runTiming',
|
|
30
31
|
metrics: {
|
|
31
32
|
duration
|
|
@@ -36,19 +37,20 @@ function handleDevServerMessage(msg) {
|
|
|
36
37
|
fileTotalSize
|
|
37
38
|
}
|
|
38
39
|
});
|
|
40
|
+
else console.warn('hmr listen function not found');
|
|
39
41
|
}
|
|
40
42
|
}
|
|
41
43
|
function connectDevServer() {
|
|
42
44
|
const sockUrl = getWsPath();
|
|
43
45
|
const sock = new sockjs_client(sockUrl);
|
|
44
|
-
sock.onopen = ()=>console.log(
|
|
46
|
+
sock.onopen = ()=>console.log("✅ connect DevServer SockJS");
|
|
45
47
|
sock.onmessage = (event)=>{
|
|
46
48
|
try {
|
|
47
49
|
const msg = JSON.parse(event.data);
|
|
48
|
-
console.log(
|
|
50
|
+
console.log("hmr 消息:", msg);
|
|
49
51
|
handleDevServerMessage(msg);
|
|
50
52
|
} catch (err) {
|
|
51
|
-
console.error(
|
|
53
|
+
console.error("解析 hmr 消息失败:", event.data);
|
|
52
54
|
}
|
|
53
55
|
};
|
|
54
56
|
return sock;
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import type { IUserProfile } from '../../apis/udt-types';
|
|
3
3
|
export interface UserDisplayProps {
|
|
4
|
-
|
|
4
|
+
/**
|
|
5
|
+
* 支持传入完整的用户资料(IUserProfile)/ 列表(IUserProfile[])
|
|
6
|
+
* 或仅传入用户 ID(string)/ 列表(string[])。
|
|
7
|
+
* 当传入 user_id 或 user_id[] 时组件会自动拉取用户资料并渲染。
|
|
8
|
+
*/
|
|
9
|
+
users: IUserProfile | IUserProfile[] | string | string[];
|
|
5
10
|
size?: 'small' | 'medium' | 'large';
|
|
6
11
|
className?: string;
|
|
7
12
|
style?: React.CSSProperties;
|
|
@@ -6,38 +6,82 @@ import { UserProfile } from "./UserProfile/index.js";
|
|
|
6
6
|
import { UserWithAvatar } from "./UserWithAvatar.js";
|
|
7
7
|
import { Popover, PopoverContent, PopoverTrigger } from "../ui/popover.js";
|
|
8
8
|
const UserDisplay = ({ users, size, className, style, showLabel = true })=>{
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
const normalizedIds = useMemo(()=>{
|
|
10
|
+
if (!users) return [];
|
|
11
|
+
if (Array.isArray(users)) {
|
|
12
|
+
if (0 === users.length) return [];
|
|
13
|
+
const first = users[0];
|
|
14
|
+
const isStringArray = 'string' == typeof first;
|
|
15
|
+
return isStringArray ? users.filter(Boolean).map((id)=>String(id)) : users.map((u)=>String(u.user_id)).filter(Boolean);
|
|
16
|
+
}
|
|
17
|
+
return 'string' == typeof users ? [
|
|
18
|
+
String(users)
|
|
19
|
+
] : [
|
|
20
|
+
String(users.user_id)
|
|
21
|
+
].filter(Boolean);
|
|
22
|
+
}, [
|
|
23
|
+
users
|
|
24
|
+
]);
|
|
25
|
+
const inputProfilesMap = useMemo(()=>{
|
|
26
|
+
const map = new Map();
|
|
27
|
+
if (!users) return map;
|
|
28
|
+
if (Array.isArray(users)) {
|
|
29
|
+
const first = users[0];
|
|
30
|
+
const isStringArray = 'string' == typeof first;
|
|
31
|
+
if (!isStringArray) {
|
|
32
|
+
for (const u of users)if (u?.user_id) map.set(String(u.user_id), {
|
|
33
|
+
user_id: String(u.user_id),
|
|
34
|
+
name: u?.name ?? '',
|
|
35
|
+
avatar: u?.avatar ?? '',
|
|
36
|
+
email: u?.email ?? '',
|
|
37
|
+
status: u?.status ?? 1
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
} else if ('string' != typeof users) {
|
|
41
|
+
const u = users;
|
|
42
|
+
if (u?.user_id) map.set(String(u.user_id), {
|
|
43
|
+
user_id: String(u.user_id),
|
|
44
|
+
name: u?.name ?? '',
|
|
45
|
+
avatar: u?.avatar ?? '',
|
|
46
|
+
email: u?.email ?? '',
|
|
47
|
+
status: u?.status ?? 1
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
return map;
|
|
51
|
+
}, [
|
|
12
52
|
users
|
|
13
53
|
]);
|
|
14
|
-
const [resolvedUsers, setResolvedUsers] = useState(
|
|
54
|
+
const [resolvedUsers, setResolvedUsers] = useState(()=>normalizedIds.map((id)=>inputProfilesMap.get(id) ?? {
|
|
55
|
+
user_id: id,
|
|
56
|
+
name: '',
|
|
57
|
+
avatar: '',
|
|
58
|
+
email: '',
|
|
59
|
+
status: 1
|
|
60
|
+
}));
|
|
15
61
|
const [loadingProfiles, setLoadingProfiles] = useState(false);
|
|
16
62
|
useEffect(()=>{
|
|
17
63
|
let isCancelled = false;
|
|
18
|
-
if (!
|
|
64
|
+
if (!normalizedIds.length) {
|
|
19
65
|
setResolvedUsers([]);
|
|
20
66
|
setLoadingProfiles(false);
|
|
21
67
|
return ()=>{
|
|
22
68
|
isCancelled = true;
|
|
23
69
|
};
|
|
24
70
|
}
|
|
25
|
-
const usersNeedingDetails = normalizedUsers.filter((user)=>!user?.name?.trim());
|
|
26
|
-
if (!usersNeedingDetails.length) {
|
|
27
|
-
setResolvedUsers(normalizedUsers);
|
|
28
|
-
setLoadingProfiles(false);
|
|
29
|
-
return ()=>{
|
|
30
|
-
isCancelled = true;
|
|
31
|
-
};
|
|
32
|
-
}
|
|
33
71
|
const fetchProfiles = async ()=>{
|
|
34
72
|
try {
|
|
35
73
|
setLoadingProfiles(true);
|
|
36
74
|
const dataloom = await getDataloom();
|
|
37
75
|
if (!dataloom) throw new Error('dataloom client is unavailable');
|
|
38
|
-
const ids =
|
|
76
|
+
const ids = normalizedIds.map((id)=>Number(id)).filter((id)=>Number.isFinite(id));
|
|
39
77
|
if (!ids.length) {
|
|
40
|
-
setResolvedUsers(
|
|
78
|
+
setResolvedUsers(normalizedIds.map((id)=>inputProfilesMap.get(id) ?? {
|
|
79
|
+
user_id: id,
|
|
80
|
+
name: '',
|
|
81
|
+
avatar: '',
|
|
82
|
+
email: '',
|
|
83
|
+
status: 1
|
|
84
|
+
}));
|
|
41
85
|
setLoadingProfiles(false);
|
|
42
86
|
return;
|
|
43
87
|
}
|
|
@@ -51,28 +95,35 @@ const UserDisplay = ({ users, size, className, style, showLabel = true })=>{
|
|
|
51
95
|
user_id: id,
|
|
52
96
|
name: profile?.name ?? '',
|
|
53
97
|
avatar: profile?.avatar ?? '',
|
|
54
|
-
email: profile?.email,
|
|
55
|
-
status: profile?.status
|
|
56
|
-
...profile
|
|
98
|
+
email: profile?.email ?? '',
|
|
99
|
+
status: profile?.status ?? 1
|
|
57
100
|
});
|
|
58
101
|
});
|
|
59
|
-
const mergedUsers =
|
|
60
|
-
const id = String(user.user_id);
|
|
102
|
+
const mergedUsers = normalizedIds.map((id)=>{
|
|
61
103
|
const fetched = fetchedMap.get(id);
|
|
62
|
-
|
|
104
|
+
const given = inputProfilesMap.get(id);
|
|
105
|
+
const name = given?.name?.trim() ? given.name : fetched?.name ?? '';
|
|
106
|
+
const avatar = given?.avatar || fetched?.avatar || '';
|
|
107
|
+
const email = given?.email || fetched?.email || '';
|
|
108
|
+
const status = given?.status ?? fetched?.status ?? 1;
|
|
63
109
|
return {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
status: user.status ?? fetched.status
|
|
110
|
+
user_id: id,
|
|
111
|
+
name,
|
|
112
|
+
avatar,
|
|
113
|
+
email,
|
|
114
|
+
status
|
|
70
115
|
};
|
|
71
116
|
});
|
|
72
117
|
if (!isCancelled) setResolvedUsers(mergedUsers);
|
|
73
118
|
} catch (error) {
|
|
74
119
|
console.error('Failed to resolve user profiles:', error);
|
|
75
|
-
if (!isCancelled) setResolvedUsers(
|
|
120
|
+
if (!isCancelled) setResolvedUsers(normalizedIds.map((id)=>inputProfilesMap.get(id) ?? {
|
|
121
|
+
user_id: id,
|
|
122
|
+
name: '',
|
|
123
|
+
avatar: '',
|
|
124
|
+
email: '',
|
|
125
|
+
status: 1
|
|
126
|
+
}));
|
|
76
127
|
} finally{
|
|
77
128
|
if (!isCancelled) setLoadingProfiles(false);
|
|
78
129
|
}
|
|
@@ -82,7 +133,7 @@ const UserDisplay = ({ users, size, className, style, showLabel = true })=>{
|
|
|
82
133
|
isCancelled = true;
|
|
83
134
|
};
|
|
84
135
|
}, [
|
|
85
|
-
|
|
136
|
+
normalizedIds
|
|
86
137
|
]);
|
|
87
138
|
if (!resolvedUsers.length || loadingProfiles) return null;
|
|
88
139
|
return /*#__PURE__*/ jsx("div", {
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { IUserProfile } from '../../apis/udt-types';
|
|
3
3
|
export interface UserSelectProps {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
/**
|
|
5
|
+
* 支持传入完整的用户资料(IUserProfile)/ 列表(IUserProfile[])
|
|
6
|
+
* 或仅传入用户 ID(string)/ 列表(string[])。
|
|
7
|
+
*/
|
|
8
|
+
value?: IUserProfile | IUserProfile[] | string | string[];
|
|
9
|
+
onChange?: (value: IUserProfile | IUserProfile[] | undefined) => void;
|
|
10
|
+
defaultValue?: IUserProfile | IUserProfile[] | string | string[];
|
|
7
11
|
mode?: 'single' | 'multiple';
|
|
8
12
|
placeholder?: string;
|
|
9
13
|
fetchUsers?: (keyword: string) => Promise<IUserProfile[]>;
|
|
@@ -3,6 +3,127 @@ import react from "react";
|
|
|
3
3
|
import { getDataloom } from "../../integrations/dataloom.js";
|
|
4
4
|
import { UserSelectUI } from "./UserSelectUI/index.js";
|
|
5
5
|
const UserSelect = ({ mode = 'single', defaultValue, value, onChange, placeholder, fetchUsers })=>{
|
|
6
|
+
const normalizedIds = react.useMemo(()=>{
|
|
7
|
+
const src = value ?? defaultValue;
|
|
8
|
+
if (!src) return [];
|
|
9
|
+
if (Array.isArray(src)) {
|
|
10
|
+
if (0 === src.length) return [];
|
|
11
|
+
const first = src[0];
|
|
12
|
+
const isStringArray = 'string' == typeof first;
|
|
13
|
+
return isStringArray ? src.filter(Boolean).map((id)=>String(id)) : src.map((u)=>String(u.user_id)).filter(Boolean);
|
|
14
|
+
}
|
|
15
|
+
return 'string' == typeof src ? [
|
|
16
|
+
String(src)
|
|
17
|
+
] : [
|
|
18
|
+
String(src.user_id)
|
|
19
|
+
].filter(Boolean);
|
|
20
|
+
}, [
|
|
21
|
+
value,
|
|
22
|
+
defaultValue
|
|
23
|
+
]);
|
|
24
|
+
const inputProfilesMap = react.useMemo(()=>{
|
|
25
|
+
const map = new Map();
|
|
26
|
+
const src = value ?? defaultValue;
|
|
27
|
+
if (!src) return map;
|
|
28
|
+
if (Array.isArray(src)) {
|
|
29
|
+
const first = src[0];
|
|
30
|
+
const isStringArray = 'string' == typeof first;
|
|
31
|
+
if (!isStringArray) {
|
|
32
|
+
for (const u of src)if (u?.user_id) map.set(String(u.user_id), {
|
|
33
|
+
user_id: String(u.user_id),
|
|
34
|
+
name: u?.name ?? '',
|
|
35
|
+
avatar: u?.avatar ?? '',
|
|
36
|
+
email: u?.email ?? '',
|
|
37
|
+
status: u?.status ?? 1
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
} else if ('string' != typeof src) {
|
|
41
|
+
const u = src;
|
|
42
|
+
if (u?.user_id) map.set(String(u.user_id), {
|
|
43
|
+
user_id: String(u.user_id),
|
|
44
|
+
name: u?.name ?? '',
|
|
45
|
+
avatar: u?.avatar ?? '',
|
|
46
|
+
email: u?.email ?? '',
|
|
47
|
+
status: u?.status ?? 1
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
return map;
|
|
51
|
+
}, [
|
|
52
|
+
value,
|
|
53
|
+
defaultValue
|
|
54
|
+
]);
|
|
55
|
+
const [uiValue, setUiValue] = react.useState(()=>{
|
|
56
|
+
if (!normalizedIds.length) return;
|
|
57
|
+
const profiles = normalizedIds.map((id)=>inputProfilesMap.get(id) ?? {
|
|
58
|
+
user_id: id,
|
|
59
|
+
name: '',
|
|
60
|
+
avatar: '',
|
|
61
|
+
email: '',
|
|
62
|
+
status: 1
|
|
63
|
+
});
|
|
64
|
+
return 'single' === mode ? profiles[0] : profiles;
|
|
65
|
+
});
|
|
66
|
+
react.useEffect(()=>{
|
|
67
|
+
if (!normalizedIds.length) return void setUiValue(void 0);
|
|
68
|
+
const fetchProfiles = async ()=>{
|
|
69
|
+
try {
|
|
70
|
+
const ids = normalizedIds.map((id)=>Number(id)).filter((id)=>Number.isFinite(id));
|
|
71
|
+
if (!ids.length) {
|
|
72
|
+
const profiles = normalizedIds.map((id)=>inputProfilesMap.get(id) ?? {
|
|
73
|
+
user_id: id,
|
|
74
|
+
name: '',
|
|
75
|
+
avatar: '',
|
|
76
|
+
email: '',
|
|
77
|
+
status: 1
|
|
78
|
+
});
|
|
79
|
+
setUiValue('single' === mode ? profiles[0] : profiles);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
const dataloom = await getDataloom();
|
|
83
|
+
const response = await dataloom.service.user.getByIds(ids);
|
|
84
|
+
const fetchedList = Array.isArray(response?.data) ? response?.data : Array.isArray(response?.data?.user_list) ? response?.data?.user_list : [];
|
|
85
|
+
const fetchedMap = new Map();
|
|
86
|
+
fetchedList.forEach((profile)=>{
|
|
87
|
+
const id = String(profile?.user_id ?? '');
|
|
88
|
+
if (!id) return;
|
|
89
|
+
fetchedMap.set(id, {
|
|
90
|
+
user_id: id,
|
|
91
|
+
name: profile?.name ?? '',
|
|
92
|
+
avatar: profile?.avatar ?? '',
|
|
93
|
+
email: profile?.email ?? '',
|
|
94
|
+
status: profile?.status ?? 1
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
const merged = normalizedIds.map((id)=>{
|
|
98
|
+
const fetched = fetchedMap.get(id);
|
|
99
|
+
const given = inputProfilesMap.get(id);
|
|
100
|
+
return {
|
|
101
|
+
user_id: id,
|
|
102
|
+
name: given?.name?.trim() ? given.name : fetched?.name ?? '',
|
|
103
|
+
avatar: given?.avatar || fetched?.avatar || '',
|
|
104
|
+
email: given?.email || fetched?.email || '',
|
|
105
|
+
status: given?.status ?? fetched?.status ?? 1
|
|
106
|
+
};
|
|
107
|
+
});
|
|
108
|
+
setUiValue('single' === mode ? merged[0] : merged);
|
|
109
|
+
} catch (error) {
|
|
110
|
+
console.error('Failed to resolve select value profiles:', error);
|
|
111
|
+
const profiles = normalizedIds.map((id)=>inputProfilesMap.get(id) ?? {
|
|
112
|
+
user_id: id,
|
|
113
|
+
name: '',
|
|
114
|
+
avatar: '',
|
|
115
|
+
email: '',
|
|
116
|
+
status: 1
|
|
117
|
+
});
|
|
118
|
+
setUiValue('single' === mode ? profiles[0] : profiles);
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
fetchProfiles();
|
|
122
|
+
}, [
|
|
123
|
+
normalizedIds,
|
|
124
|
+
inputProfilesMap,
|
|
125
|
+
mode
|
|
126
|
+
]);
|
|
6
127
|
const fetchUsersImpl = react.useCallback(async (search)=>{
|
|
7
128
|
if (fetchUsers) return fetchUsers(search);
|
|
8
129
|
try {
|
|
@@ -30,15 +151,23 @@ const UserSelect = ({ mode = 'single', defaultValue, value, onChange, placeholde
|
|
|
30
151
|
return /*#__PURE__*/ jsx("div", {
|
|
31
152
|
className: "user-select-container",
|
|
32
153
|
children: /*#__PURE__*/ jsx(UserSelectUI, {
|
|
33
|
-
defaultValue:
|
|
154
|
+
defaultValue: void 0,
|
|
34
155
|
mode: selectMode,
|
|
35
156
|
onSearch: fetchUsersImpl,
|
|
36
157
|
allowClear: true,
|
|
37
158
|
placeholder: placeholder,
|
|
38
|
-
value:
|
|
39
|
-
onChange: (
|
|
40
|
-
if (
|
|
41
|
-
|
|
159
|
+
value: uiValue,
|
|
160
|
+
onChange: (next)=>{
|
|
161
|
+
if (!onChange) return;
|
|
162
|
+
if ('multiple' === selectMode) {
|
|
163
|
+
const arr = Array.isArray(next) ? next ?? [] : next ? [
|
|
164
|
+
next
|
|
165
|
+
] : [];
|
|
166
|
+
onChange(arr);
|
|
167
|
+
} else {
|
|
168
|
+
const single = Array.isArray(next) ? next[0] ?? void 0 : next ?? void 0;
|
|
169
|
+
onChange(single);
|
|
170
|
+
}
|
|
42
171
|
}
|
|
43
172
|
})
|
|
44
173
|
});
|
|
@@ -18,6 +18,11 @@ const sizeClassMap = {
|
|
|
18
18
|
medium: 'py-0.5 pl-0.5 pr-2 max-w-[172px]',
|
|
19
19
|
large: 'py-1 pl-1 pr-2.5 max-w-[196px]'
|
|
20
20
|
};
|
|
21
|
+
const sizeClassMapWithoutLabel = {
|
|
22
|
+
small: 'py-0.5 px-0.5 max-w-[148px]',
|
|
23
|
+
medium: 'py-0.5 px-0.5 max-w-[172px]',
|
|
24
|
+
large: 'py-1 px-1 max-w-[196px]'
|
|
25
|
+
};
|
|
21
26
|
const textVariantMap = {
|
|
22
27
|
small: 'text-[12px] leading-[16px]',
|
|
23
28
|
medium: 'text-[14px] leading-[20px]',
|
|
@@ -32,7 +37,7 @@ function UserWithAvatar({ data, size = 'medium', mode = 'tag', className, showLa
|
|
|
32
37
|
'large'
|
|
33
38
|
].includes(size) ? size : 'medium';
|
|
34
39
|
return /*#__PURE__*/ jsxs("div", {
|
|
35
|
-
className: clsxWithTw('flex min-w-0 items-center gap-1 rounded-full', sizeClassMap[formatSize], {
|
|
40
|
+
className: clsxWithTw('flex min-w-0 items-center gap-1 rounded-full', showLabel ? sizeClassMap[formatSize] : sizeClassMapWithoutLabel[formatSize], {
|
|
36
41
|
'bg-muted': 'tag' === mode
|
|
37
42
|
}, className),
|
|
38
43
|
children: [
|
|
@@ -1,64 +1,5 @@
|
|
|
1
|
-
import { submitPostMessage, submitSlardarEvent } from "../utils/postMessage.js";
|
|
2
1
|
import { levelSchema } from "./log-types.js";
|
|
3
2
|
import { logger } from "./logger.js";
|
|
4
|
-
let devServerDisconnectInfo = null;
|
|
5
|
-
let retryCount = 0;
|
|
6
|
-
function processDevServerLog(log) {
|
|
7
|
-
if (!log) return;
|
|
8
|
-
if (log.includes('webpack-dev-server') && log.includes('Disconnected')) {
|
|
9
|
-
const time = Date.now();
|
|
10
|
-
devServerDisconnectInfo = {
|
|
11
|
-
time
|
|
12
|
-
};
|
|
13
|
-
submitSlardarEvent({
|
|
14
|
-
name: 'sandbox-devServer',
|
|
15
|
-
categories: {
|
|
16
|
-
type: 'disconnected',
|
|
17
|
-
time
|
|
18
|
-
}
|
|
19
|
-
});
|
|
20
|
-
submitPostMessage({
|
|
21
|
-
type: 'DevServerMessage',
|
|
22
|
-
data: {
|
|
23
|
-
type: 'devServer-status',
|
|
24
|
-
status: 'disconnected'
|
|
25
|
-
}
|
|
26
|
-
});
|
|
27
|
-
return;
|
|
28
|
-
}
|
|
29
|
-
if (!devServerDisconnectInfo) return;
|
|
30
|
-
if (log.includes('webpack-dev-server') && log.includes('Trying to reconnect')) {
|
|
31
|
-
if (retryCount) submitSlardarEvent({
|
|
32
|
-
name: 'sandbox-devServer',
|
|
33
|
-
categories: {
|
|
34
|
-
type: 'reconnect-failed',
|
|
35
|
-
retryCount: retryCount + 1
|
|
36
|
-
}
|
|
37
|
-
});
|
|
38
|
-
retryCount++;
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
41
|
-
if (log.includes('HMR') || log.includes('App updated') || log.includes('App hot update')) {
|
|
42
|
-
submitPostMessage({
|
|
43
|
-
type: 'DevServerMessage',
|
|
44
|
-
data: {
|
|
45
|
-
type: 'devServer-status',
|
|
46
|
-
status: 'connected'
|
|
47
|
-
}
|
|
48
|
-
});
|
|
49
|
-
const startTime = devServerDisconnectInfo.time;
|
|
50
|
-
const duration = Date.now() - startTime;
|
|
51
|
-
devServerDisconnectInfo = null;
|
|
52
|
-
submitSlardarEvent({
|
|
53
|
-
name: 'sandbox-devServer',
|
|
54
|
-
categories: {
|
|
55
|
-
type: 'devServer-reconnected',
|
|
56
|
-
startTime,
|
|
57
|
-
duration
|
|
58
|
-
}
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
3
|
function interceptErrors() {
|
|
63
4
|
window.addEventListener('error', (event)=>{
|
|
64
5
|
logger.error(event.error);
|
|
@@ -76,14 +17,14 @@ function interceptErrors() {
|
|
|
76
17
|
const originalMethod = window.console[method];
|
|
77
18
|
window.console[method] = (...args)=>{
|
|
78
19
|
originalMethod(...args);
|
|
20
|
+
const level = 'log' === method ? 'info' : method;
|
|
79
21
|
const log = args[0];
|
|
80
|
-
if ('string' == typeof log)
|
|
81
|
-
if ('string' == typeof log && log.startsWith('[Dataloom]') && levelSchema.safeParse(method).success) {
|
|
22
|
+
if ('string' == typeof log && log.startsWith('[Dataloom]') && levelSchema.safeParse(level).success) {
|
|
82
23
|
logger.log({
|
|
83
|
-
level:
|
|
24
|
+
level: level,
|
|
84
25
|
args
|
|
85
26
|
});
|
|
86
|
-
|
|
27
|
+
postMessage({
|
|
87
28
|
type: 'Console',
|
|
88
29
|
method,
|
|
89
30
|
data: args
|
|
@@ -28,10 +28,10 @@ export declare const logStackFrameSchema: z.ZodObject<{
|
|
|
28
28
|
}, z.core.$strip>;
|
|
29
29
|
export declare const levelSchema: z.ZodEnum<{
|
|
30
30
|
success: "success";
|
|
31
|
+
debug: "debug";
|
|
31
32
|
info: "info";
|
|
32
33
|
warn: "warn";
|
|
33
34
|
error: "error";
|
|
34
|
-
debug: "debug";
|
|
35
35
|
}>;
|
|
36
36
|
export declare const logMeta: z.ZodObject<{
|
|
37
37
|
stacktrace: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
@@ -45,15 +45,18 @@ export declare const logMeta: z.ZodObject<{
|
|
|
45
45
|
noStacktrace: z.ZodOptional<z.ZodBoolean>;
|
|
46
46
|
repairMessage: z.ZodOptional<z.ZodString>;
|
|
47
47
|
type: z.ZodOptional<z.ZodString>;
|
|
48
|
+
isDuplicate: z.ZodOptional<z.ZodBoolean>;
|
|
49
|
+
duplicateCount: z.ZodOptional<z.ZodNumber>;
|
|
50
|
+
duplicateOfId: z.ZodOptional<z.ZodString>;
|
|
48
51
|
}, z.core.$strip>;
|
|
49
52
|
export declare const selectedLogSchema: z.ZodObject<{
|
|
50
53
|
type: z.ZodLiteral<"typedLogV2">;
|
|
51
54
|
level: z.ZodEnum<{
|
|
52
55
|
success: "success";
|
|
56
|
+
debug: "debug";
|
|
53
57
|
info: "info";
|
|
54
58
|
warn: "warn";
|
|
55
59
|
error: "error";
|
|
56
|
-
debug: "debug";
|
|
57
60
|
}>;
|
|
58
61
|
id: z.ZodString;
|
|
59
62
|
args: z.ZodArray<z.ZodUnknown>;
|
|
@@ -69,16 +72,19 @@ export declare const selectedLogSchema: z.ZodObject<{
|
|
|
69
72
|
noStacktrace: z.ZodOptional<z.ZodBoolean>;
|
|
70
73
|
repairMessage: z.ZodOptional<z.ZodString>;
|
|
71
74
|
type: z.ZodOptional<z.ZodString>;
|
|
75
|
+
isDuplicate: z.ZodOptional<z.ZodBoolean>;
|
|
76
|
+
duplicateCount: z.ZodOptional<z.ZodNumber>;
|
|
77
|
+
duplicateOfId: z.ZodOptional<z.ZodString>;
|
|
72
78
|
}, z.core.$strip>;
|
|
73
79
|
}, z.core.$strip>;
|
|
74
|
-
export type LogLevel =
|
|
80
|
+
export type LogLevel = z.infer<typeof levelSchema>;
|
|
75
81
|
export declare const logWithMetaSchema: z.ZodObject<{
|
|
76
82
|
level: z.ZodEnum<{
|
|
77
83
|
success: "success";
|
|
84
|
+
debug: "debug";
|
|
78
85
|
info: "info";
|
|
79
86
|
warn: "warn";
|
|
80
87
|
error: "error";
|
|
81
|
-
debug: "debug";
|
|
82
88
|
}>;
|
|
83
89
|
args: z.ZodArray<z.ZodUnknown>;
|
|
84
90
|
meta: z.ZodOptional<z.ZodObject<{
|
|
@@ -93,6 +99,9 @@ export declare const logWithMetaSchema: z.ZodObject<{
|
|
|
93
99
|
noStacktrace: z.ZodOptional<z.ZodBoolean>;
|
|
94
100
|
repairMessage: z.ZodOptional<z.ZodString>;
|
|
95
101
|
type: z.ZodOptional<z.ZodString>;
|
|
102
|
+
isDuplicate: z.ZodOptional<z.ZodBoolean>;
|
|
103
|
+
duplicateCount: z.ZodOptional<z.ZodNumber>;
|
|
104
|
+
duplicateOfId: z.ZodOptional<z.ZodString>;
|
|
96
105
|
}, z.core.$strip>>;
|
|
97
106
|
}, z.core.$strip>;
|
|
98
107
|
export type LogStackFrame = z.infer<typeof logStackFrameSchema>;
|
package/lib/logger/log-types.js
CHANGED
|
@@ -27,10 +27,10 @@ const logStackFrameSchema = zod.object({
|
|
|
27
27
|
columnNumber: zod.number()
|
|
28
28
|
});
|
|
29
29
|
const levelSchema = zod["enum"]([
|
|
30
|
+
'debug',
|
|
30
31
|
'info',
|
|
31
32
|
'warn',
|
|
32
33
|
'error',
|
|
33
|
-
'debug',
|
|
34
34
|
'success'
|
|
35
35
|
]);
|
|
36
36
|
const logMeta = zod.object({
|
|
@@ -39,7 +39,10 @@ const logMeta = zod.object({
|
|
|
39
39
|
skipFrame: zod.optional(zod.number()),
|
|
40
40
|
noStacktrace: zod.optional(zod.boolean()),
|
|
41
41
|
repairMessage: zod.optional(zod.string()),
|
|
42
|
-
type: zod.optional(zod.string())
|
|
42
|
+
type: zod.optional(zod.string()),
|
|
43
|
+
isDuplicate: zod.optional(zod.boolean()),
|
|
44
|
+
duplicateCount: zod.optional(zod.number()),
|
|
45
|
+
duplicateOfId: zod.optional(zod.string())
|
|
43
46
|
});
|
|
44
47
|
const selectedLogSchema = zod.object({
|
|
45
48
|
type: zod.literal('typedLogV2'),
|
|
@@ -40,7 +40,17 @@ async function sendSelectedLog(logWithoutID) {
|
|
|
40
40
|
if (!log.meta.stacktrace) try {
|
|
41
41
|
const stacktrace = await stacktrace_js.fromError(error);
|
|
42
42
|
log.meta.stacktrace = mapStacktrace(stacktrace);
|
|
43
|
-
} catch (e) {
|
|
43
|
+
} catch (e) {
|
|
44
|
+
if (window.parent !== window) try {
|
|
45
|
+
window.parent.postMessage({
|
|
46
|
+
type: 'STACKTRACE_PARSE_ERROR',
|
|
47
|
+
payload: {
|
|
48
|
+
error: e instanceof Error ? e.message : String(e),
|
|
49
|
+
context: 'StackTrace.fromError'
|
|
50
|
+
}
|
|
51
|
+
}, '*');
|
|
52
|
+
} catch (postError) {}
|
|
53
|
+
}
|
|
44
54
|
newParts.push(newError.message, newError);
|
|
45
55
|
} else newParts.push(log.args[i]);
|
|
46
56
|
log.args = newParts;
|
|
@@ -49,11 +59,46 @@ async function sendSelectedLog(logWithoutID) {
|
|
|
49
59
|
const firstFrameIndex = frames.findIndex((frame)=>!frame.fileName.includes('node_modules/@lark-apaas/client-toolkit/lib/logger'));
|
|
50
60
|
frames = -1 === firstFrameIndex ? [] : frames.slice(firstFrameIndex);
|
|
51
61
|
log.meta.stacktrace = frames;
|
|
52
|
-
} catch (e) {
|
|
62
|
+
} catch (e) {
|
|
63
|
+
if (window.parent !== window) try {
|
|
64
|
+
window.parent.postMessage({
|
|
65
|
+
type: 'STACKTRACE_PARSE_ERROR',
|
|
66
|
+
payload: {
|
|
67
|
+
error: e instanceof Error ? e.message : String(e),
|
|
68
|
+
context: 'getStacktrace'
|
|
69
|
+
}
|
|
70
|
+
}, '*');
|
|
71
|
+
} catch (postError) {}
|
|
72
|
+
}
|
|
53
73
|
if (void 0 === log.meta.skipFrame) log.meta.skipFrame = 2;
|
|
54
74
|
const logJSON = JSON.stringify(log);
|
|
55
|
-
|
|
56
|
-
|
|
75
|
+
const logForDedup = {
|
|
76
|
+
...log
|
|
77
|
+
};
|
|
78
|
+
delete logForDedup.id;
|
|
79
|
+
const logContentForDedup = JSON.stringify(logForDedup);
|
|
80
|
+
if (lastLogInfo && lastLogInfo.content === logContentForDedup) {
|
|
81
|
+
lastLogInfo.count++;
|
|
82
|
+
log.meta.isDuplicate = true;
|
|
83
|
+
log.meta.duplicateCount = lastLogInfo.count;
|
|
84
|
+
log.meta.duplicateOfId = lastLogInfo.id;
|
|
85
|
+
const updatedLogJSON = JSON.stringify(log);
|
|
86
|
+
try {
|
|
87
|
+
batchLogInfo('info', updatedLogJSON);
|
|
88
|
+
} catch (e) {}
|
|
89
|
+
if (window.parent !== window) try {
|
|
90
|
+
window.parent.postMessage({
|
|
91
|
+
type: 'SELECTED_LOG',
|
|
92
|
+
payload: updatedLogJSON
|
|
93
|
+
}, '*');
|
|
94
|
+
} catch (e) {}
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
lastLogInfo = {
|
|
98
|
+
content: logContentForDedup,
|
|
99
|
+
id: log.id,
|
|
100
|
+
count: 1
|
|
101
|
+
};
|
|
57
102
|
try {
|
|
58
103
|
batchLogInfo('info', logJSON);
|
|
59
104
|
} catch (e) {}
|
|
@@ -70,6 +115,7 @@ async function getStacktrace() {
|
|
|
70
115
|
const frames = mapStacktrace(stacktrace);
|
|
71
116
|
return frames;
|
|
72
117
|
}
|
|
118
|
+
let lastLogInfo = null;
|
|
73
119
|
async function sendTypedLogV2(logWithMeta) {
|
|
74
120
|
sendSelectedLog({
|
|
75
121
|
type: 'typedLogV2',
|
|
@@ -84,7 +130,7 @@ const typedLogInterceptor = (logger)=>({
|
|
|
84
130
|
logger.debug(message, ...args);
|
|
85
131
|
} catch (e) {}
|
|
86
132
|
sendTypedLogV2({
|
|
87
|
-
level: '
|
|
133
|
+
level: 'info',
|
|
88
134
|
args: [
|
|
89
135
|
message,
|
|
90
136
|
...args
|
|
@@ -38,14 +38,7 @@ export interface HmrMessage extends IframeMessage<Record<string, never>> {
|
|
|
38
38
|
data?: any;
|
|
39
39
|
};
|
|
40
40
|
}
|
|
41
|
-
|
|
42
|
-
export interface DevServerMessage extends IframeMessage<{
|
|
43
|
-
type: 'devServer-status';
|
|
44
|
-
status: 'connected' | 'disconnected';
|
|
45
|
-
}> {
|
|
46
|
-
type: 'DevServerMessage';
|
|
47
|
-
}
|
|
48
|
-
export type OutgoingMessage = PreviewReadyMessage | HmrMessage | ConsoleMessage | ChildLocationChangeMessage | CreatePageMessage | RenderErrorMessage | RenderErrorRepairMessage | PageScreenshotMessage | DevServerMessage | UpdateRoutesMessage;
|
|
41
|
+
export type OutgoingMessage = PreviewReadyMessage | HmrMessage | ConsoleMessage | ChildLocationChangeMessage | CreatePageMessage | RenderErrorMessage | RenderErrorRepairMessage | PageScreenshotMessage | UpdateRoutesMessage;
|
|
49
42
|
export interface GetRoutesMessage extends IframeMessage<Record<string, never>> {
|
|
50
43
|
type: 'GetRoutes';
|
|
51
44
|
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { IncomingMessage, OutgoingMessage } from '../types/iframe-events';
|
|
2
|
-
export declare function
|
|
3
|
-
export declare function submitSlardarEvent(event: any): void;
|
|
2
|
+
export declare function postMessage<T extends OutgoingMessage>(message: T, targetOrigin?: string): void;
|
|
4
3
|
export declare function isOutgoingMessage<T extends OutgoingMessage['type']>(msg: OutgoingMessage, type: T): msg is Extract<OutgoingMessage, {
|
|
5
4
|
type: T;
|
|
6
5
|
}>;
|
package/lib/utils/postMessage.js
CHANGED
|
@@ -1,20 +1,15 @@
|
|
|
1
1
|
import { getPreviewParentOrigin } from "./getParentOrigin.js";
|
|
2
|
-
function
|
|
2
|
+
function postMessage(message, targetOrigin) {
|
|
3
3
|
try {
|
|
4
4
|
window.parent.postMessage(message, targetOrigin ?? getPreviewParentOrigin());
|
|
5
5
|
} catch (e) {
|
|
6
6
|
console.error('postMessage error', e);
|
|
7
7
|
}
|
|
8
8
|
}
|
|
9
|
-
function submitSlardarEvent(event) {
|
|
10
|
-
const slardar = window['KSlardarWeb'];
|
|
11
|
-
if (slardar && 'function' == typeof slardar) slardar('sendEvent', event);
|
|
12
|
-
else console.warn('hmr listen function not found');
|
|
13
|
-
}
|
|
14
9
|
function isOutgoingMessage(msg, type) {
|
|
15
10
|
return msg.type === type;
|
|
16
11
|
}
|
|
17
12
|
function isIncomingMessage(msg, type) {
|
|
18
13
|
return msg.type === type;
|
|
19
14
|
}
|
|
20
|
-
export { isIncomingMessage, isOutgoingMessage,
|
|
15
|
+
export { isIncomingMessage, isOutgoingMessage, postMessage };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lark-apaas/client-toolkit",
|
|
3
|
-
"version": "1.1.14-
|
|
3
|
+
"version": "1.1.14-dataloom-test.1",
|
|
4
4
|
"types": "./lib/index.d.ts",
|
|
5
5
|
"main": "./lib/index.js",
|
|
6
6
|
"files": [
|
|
@@ -75,7 +75,7 @@
|
|
|
75
75
|
"dependencies": {
|
|
76
76
|
"@ant-design/colors": "^7.2.1",
|
|
77
77
|
"@ant-design/cssinjs": "^1.24.0",
|
|
78
|
-
"@data-loom/js": "
|
|
78
|
+
"@data-loom/js": "0.4.1-alpha.2",
|
|
79
79
|
"@lark-apaas/miaoda-inspector": "^1.0.2",
|
|
80
80
|
"@radix-ui/react-avatar": "^1.1.10",
|
|
81
81
|
"@radix-ui/react-popover": "^1.1.15",
|