@blocklet/pages-kit 0.4.16-beta.20250305-2 → 0.4.16-beta.20250309-3

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.
@@ -1,7 +1,17 @@
1
1
  "use strict";
2
- window.esmsInitOptions = {
3
- // Enable Shim Mode
4
- shimMode: true,
5
- // Enable polyfill features.
6
- polyfillEnable: ['css-modules', 'json-modules', 'wasm-modules', 'source-phase'],
7
- };
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.injectESModulesShimsOptions = injectESModulesShimsOptions;
4
+ function injectESModulesShimsOptions() {
5
+ // if already initialized, return
6
+ if (window.esmsInitOptions) {
7
+ return;
8
+ }
9
+ window.esmsInitOptions = {
10
+ shimMode: true,
11
+ polyfillEnable: ['css-modules', 'json-modules', 'wasm-modules', 'source-phase'],
12
+ skip: ['crypto-browserify', 'crypto'],
13
+ mapOverrides: true,
14
+ };
15
+ }
16
+ // enable es-module-shims
17
+ injectESModulesShimsOptions();
@@ -22,15 +22,6 @@ var __importStar = (this && this.__importStar) || function (mod) {
22
22
  __setModuleDefault(result, mod);
23
23
  return result;
24
24
  };
25
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
26
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
27
- return new (P || (P = Promise))(function (resolve, reject) {
28
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
29
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
30
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
31
- step((generator = generator.apply(thisArg, _arguments || [])).next());
32
- });
33
- };
34
25
  var __importDefault = (this && this.__importDefault) || function (mod) {
35
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
36
27
  };
@@ -40,7 +31,6 @@ require("es-module-shims");
40
31
  const react_1 = __importDefault(require("react"));
41
32
  const ufo_1 = require("ufo");
42
33
  const arcblockUx = __importStar(require("../builtin/arcblock/ux"));
43
- const aiRuntime = __importStar(require("../builtin/async/ai-runtime"));
44
34
  const imagePreview = __importStar(require("../builtin/async/image-preview"));
45
35
  const reactMarkdown = __importStar(require("../builtin/async/react-markdown"));
46
36
  const reactScrollToBottom = __importStar(require("../builtin/async/react-scroll-to-bottom"));
@@ -65,14 +55,20 @@ const zustand = __importStar(require("../builtin/zustand"));
65
55
  const zustandMiddlewareImmer = __importStar(require("../builtin/zustand/middleware/immer"));
66
56
  const CustomComponentRenderer_1 = __importDefault(require("../components/CustomComponentRenderer"));
67
57
  const builtin_1 = require("../types/builtin");
58
+ const builtin_module_transformer_1 = require("./typescript/builtin-module-transformer");
68
59
  // Initialize ES Module Shims before any imports
69
60
  function injectGlobalComponents() {
61
+ var _a;
70
62
  const win = window || {};
71
- const importShim = win.importShim;
63
+ // if already initialized, return
64
+ if (win[builtin_1.BuiltinModulesGlobalVariableName]) {
65
+ return;
66
+ }
67
+ const enableShim = !!((_a = window === null || window === void 0 ? void 0 : window.esmsInitOptions) === null || _a === void 0 ? void 0 : _a.shimMode);
72
68
  win.React = react_1.default;
73
- // 创建模块映射
69
+ // create module map
74
70
  const modules = {
75
- react,
71
+ React: react,
76
72
  '@blocklet/pages-kit/builtin/pages-kit': { CustomComponentRenderer: CustomComponentRenderer_1.default },
77
73
  '@blocklet/pages-kit/builtin/dayjs': dayjs,
78
74
  '@blocklet/pages-kit/builtin/utils': utils,
@@ -97,55 +93,107 @@ function injectGlobalComponents() {
97
93
  '@blocklet/pages-kit/builtin/async/react-markdown': reactMarkdown,
98
94
  '@blocklet/pages-kit/builtin/async/react-syntax-highlighter': reactSyntaxHighlighter,
99
95
  '@blocklet/pages-kit/builtin/async/image-preview': imagePreview,
100
- '@blocklet/pages-kit/builtin/async/ai-runtime': aiRuntime,
96
+ '@blocklet/pages-kit/builtin/async/ai-runtime': {
97
+ get: () => Promise.resolve().then(() => __importStar(require('../builtin/async/ai-runtime'))).catch((err) => {
98
+ console.error('Failed to load AI runtime', err);
99
+ return {};
100
+ }),
101
+ },
101
102
  };
102
- // 设置全局变量
103
+ // set global variable
103
104
  win[builtin_1.BuiltinModulesGlobalVariableName] = {
104
105
  modules,
105
106
  require(module) {
106
- return __awaiter(this, void 0, void 0, function* () {
107
- var _a;
108
- // 处理内置模块
109
- const builtinModule = this.modules[module];
110
- if (builtinModule) {
111
- return builtinModule;
107
+ var _a;
108
+ // handle builtin module
109
+ const builtinModule = this.modules[module];
110
+ if (builtinModule) {
111
+ return builtinModule;
112
+ }
113
+ // handle relative path import
114
+ if ((0, builtin_module_transformer_1.isRelativeModule)(module)) {
115
+ const fileName = module.split('/').pop();
116
+ const fullUrl = (0, ufo_1.joinURL)(window.location.origin, ((_a = window === null || window === void 0 ? void 0 : window.blocklet) === null || _a === void 0 ? void 0 : _a.prefix) || '/', 'chunks', fileName);
117
+ if (enableShim) {
118
+ const mod = window.importShim(fullUrl);
119
+ return mod;
112
120
  }
113
- // 处理相对路径导入
114
- if (module.startsWith('./') || module.startsWith('../')) {
115
- const fileName = module.split('/').pop();
116
- const fullUrl = (0, ufo_1.joinURL)(window.location.origin, ((_a = window === null || window === void 0 ? void 0 : window.blocklet) === null || _a === void 0 ? void 0 : _a.prefix) || '/', 'chunks', fileName);
117
- if (importShim) {
118
- return yield importShim(fullUrl);
119
- }
120
- return yield Promise.resolve(`${fullUrl}`).then(s => __importStar(require(s)));
121
- }
122
- return null;
123
- });
121
+ const mod = Promise.resolve(`${fullUrl}`).then(s => __importStar(require(s)));
122
+ return mod;
123
+ }
124
+ return null;
124
125
  },
125
126
  };
126
- // 创建 importmap
127
+ // create importmap
127
128
  const setupImportMap = () => {
128
- // 设置 importmap 内容
129
- const imports = Object.entries(modules).reduce((acc, [modulePath, moduleContent]) => {
130
- const namedExports = Object.keys(moduleContent).filter((key) => key !== 'default');
131
- const hasDefaultExport = 'default' in moduleContent;
132
- // 创建模块代码
133
- const moduleCode = `// GENERATED FILE. DO NOT EDIT.
134
- const moduleSource = window['${builtin_1.BuiltinModulesGlobalVariableName}'].modules['${modulePath}'];
135
- ${namedExports.map((name) => `export const ${name} = moduleSource['${name}'];`).join('\n')}
136
- export default ${hasDefaultExport ? 'moduleSource.default' : 'moduleSource'};
137
- `;
138
- // 使用 base64 编码模块代码
139
- const base64Code = btoa(moduleCode);
140
- acc[modulePath] = `data:application/javascript;base64,${base64Code}`;
141
- return acc;
142
- }, {});
143
- // 添加 resolve 配置
144
- const importMap = {
145
- imports,
129
+ // 计算模块的 hash 值作为缓存版本
130
+ const calculateModulesHash = () => {
131
+ // 只提取模块路径和导出的键名用于 hash 计算
132
+ const moduleStructure = Object.entries(modules).map(([path, mod]) => ({
133
+ path,
134
+ exports: Object.keys(mod).sort(),
135
+ }));
136
+ const str = JSON.stringify(moduleStructure);
137
+ // 简单的 hash 计算方法
138
+ let hash = 0;
139
+ for (let i = 0; i < str.length; i++) {
140
+ const char = str.charCodeAt(i);
141
+ hash = hash * 2 ** 5 - hash + char;
142
+ }
143
+ return hash.toString(16);
146
144
  };
147
- if (importShim === null || importShim === void 0 ? void 0 : importShim.addImportMap) {
148
- importShim.addImportMap(importMap);
145
+ const cacheKey = 'pages-kit-import-map';
146
+ const moduleHash = calculateModulesHash();
147
+ // 获取 imports - 优先从缓存读取
148
+ const getImportsFromCache = () => {
149
+ try {
150
+ const cachedData = localStorage.getItem(cacheKey);
151
+ if (cachedData) {
152
+ const { hash, imports } = JSON.parse(cachedData);
153
+ if (hash === moduleHash) {
154
+ // eslint-disable-next-line no-console
155
+ console.log(`getImportsFromCache: ${hash}`, imports);
156
+ return imports; // 返回缓存的 imports
157
+ }
158
+ }
159
+ }
160
+ catch (e) {
161
+ console.warn('Failed to load import map from cache', e);
162
+ }
163
+ return null; // 缓存无效
164
+ };
165
+ // 尝试从缓存获取或重新计算
166
+ const imports = getImportsFromCache() ||
167
+ Object.entries(modules).reduce((acc, [modulePath, moduleContent]) => {
168
+ const namedExports = Object.keys(moduleContent).filter((key) => key !== 'default');
169
+ const hasDefaultExport = 'default' in moduleContent;
170
+ // create module code
171
+ const moduleCode = `// GENERATED FILE. DO NOT EDIT.
172
+ const moduleSource = window['${builtin_1.BuiltinModulesGlobalVariableName}'].modules['${modulePath}'];
173
+ ${namedExports.map((name) => `export const ${name} = moduleSource['${name}'];`).join('\n')}
174
+ export default ${hasDefaultExport ? 'moduleSource.default' : 'moduleSource'};
175
+ `;
176
+ // create base64 code
177
+ const base64Code = btoa(moduleCode);
178
+ acc[modulePath] = `data:application/javascript;base64,${base64Code}`;
179
+ return acc;
180
+ }, {});
181
+ // 如果是新计算的 imports,保存到缓存
182
+ if (!getImportsFromCache()) {
183
+ try {
184
+ localStorage.setItem(cacheKey, JSON.stringify({
185
+ hash: moduleHash,
186
+ imports,
187
+ }));
188
+ }
189
+ catch (e) {
190
+ console.warn('Failed to cache import map', e);
191
+ }
192
+ }
193
+ // 添加 resolve 配置
194
+ const importMap = { imports };
195
+ if (enableShim) {
196
+ window.importShim.addImportMap(importMap);
149
197
  }
150
198
  else {
151
199
  // fallback to create script tag
@@ -1,16 +1,18 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createBuiltinModuleTransformer = void 0;
3
+ exports.createBuiltinModuleTransformer = exports.isRelativeModule = void 0;
4
4
  const builtin_1 = require("../../types/builtin");
5
+ const isRelativeModule = (moduleSpecifier) => {
6
+ return moduleSpecifier.startsWith('./') || moduleSpecifier.startsWith('../');
7
+ };
8
+ exports.isRelativeModule = isRelativeModule;
5
9
  const createBuiltinModuleTransformer = (ts) => (context) => (file) => {
6
10
  const { factory } = context;
7
11
  // 统一的模块导入收集器
8
12
  const imports = [];
9
13
  // check if the module is a target module
10
14
  const isTargetModule = (moduleSpecifier) => {
11
- return (moduleSpecifier.startsWith('@blocklet/pages-kit/builtin/') ||
12
- moduleSpecifier.startsWith('./') ||
13
- moduleSpecifier.startsWith('../'));
15
+ return moduleSpecifier.startsWith('@blocklet/pages-kit/builtin/') || (0, exports.isRelativeModule)(moduleSpecifier);
14
16
  };
15
17
  // filter and collect the import statements that need to be processed
16
18
  const statements = file.statements.filter((s) => {
@@ -46,11 +48,9 @@ const createBuiltinModuleTransformer = (ts) => (context) => (file) => {
46
48
  });
47
49
  statements.unshift(...imports.flatMap((importInfo) => {
48
50
  // call inject-global-components require method
49
- const requireCall = factory.createCallExpression(factory.createPropertyAccessExpression(factory.createPropertyAccessExpression(
50
- // factory.createIdentifier('globalThis'),
51
- factory.createIdentifier('window'), factory.createIdentifier(builtin_1.BuiltinModulesGlobalVariableName)), factory.createIdentifier('require')), undefined, [factory.createStringLiteral(importInfo.moduleName)]);
52
- // create await expression to wait for the async result
53
- const mod = factory.createAwaitExpression(requireCall);
51
+ const requireCall = factory.createCallExpression(factory.createPropertyAccessExpression(factory.createIdentifier(builtin_1.BuiltinModulesGlobalVariableName), 'require'), undefined, [factory.createStringLiteral(importInfo.moduleName)]);
52
+ // create await expression if the module is ../ or ./
53
+ const mod = (0, exports.isRelativeModule)(importInfo.moduleName) ? factory.createAwaitExpression(requireCall) : requireCall;
54
54
  return [
55
55
  importInfo.name
56
56
  ? factory.createVariableStatement([], factory.createVariableDeclarationList([
@@ -0,0 +1,36 @@
1
+ var __rest = (this && this.__rest) || function (s, e) {
2
+ var t = {};
3
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
+ t[p] = s[p];
5
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
+ t[p[i]] = s[p[i]];
9
+ }
10
+ return t;
11
+ };
12
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
13
+ import { Box, Typography, Button } from '@mui/material';
14
+ export const ComponentError = (_a) => {
15
+ var { title = 'Component Failed to Load', message, componentId, componentName, blockletId, blockletTitle, showHints = false, error, resetErrorBoundary } = _a, rest = __rest(_a, ["title", "message", "componentId", "componentName", "blockletId", "blockletTitle", "showHints", "error", "resetErrorBoundary"]);
16
+ // 如果提供了error但没有message,使用error.message
17
+ const displayMessage = message || (error ? error.message : 'Unknown error');
18
+ console.warn(rest);
19
+ return (_jsxs(Box, { sx: {
20
+ p: 3,
21
+ border: '1px dashed #d32f2f',
22
+ borderRadius: 1,
23
+ bgcolor: 'rgba(211, 47, 47, 0.04)',
24
+ display: 'flex',
25
+ flexDirection: 'column',
26
+ gap: 1,
27
+ }, children: [_jsx(Typography, { variant: "subtitle1", sx: { color: '#d32f2f', fontWeight: 500 }, children: title }), _jsx(Typography, { variant: "body2", sx: { color: 'text.secondary' }, children: displayMessage }), error && error.stack && process.env.NODE_ENV !== 'production' && (_jsx(Box, { component: "pre", sx: {
28
+ mt: 2,
29
+ p: 1,
30
+ bgcolor: 'rgba(0,0,0,0.04)',
31
+ borderRadius: 1,
32
+ fontSize: '0.75rem',
33
+ overflow: 'auto',
34
+ maxHeight: '200px',
35
+ }, children: error.stack })), showHints && (_jsxs(_Fragment, { children: [_jsx(Typography, { variant: "body2", sx: { color: 'text.secondary' }, children: "Please try the following:" }), _jsxs(Box, { component: "ul", sx: { m: 0, pl: 2 }, children: [componentId && (_jsxs(Typography, { component: "li", variant: "body2", sx: { color: 'text.secondary' }, children: ["Select component", ' ', _jsx(Box, { component: "span", sx: { fontWeight: 500 }, children: componentName !== null && componentName !== void 0 ? componentName : componentId }), ' ', "in settings or create this component."] })), (blockletId || blockletTitle) && (_jsxs(Typography, { component: "li", variant: "body2", sx: { color: 'text.secondary' }, children: ["Contact administrator to install", ' ', _jsx(Box, { component: "span", sx: { fontWeight: 500 }, children: blockletTitle !== null && blockletTitle !== void 0 ? blockletTitle : blockletId }), ' ', "Blocklet"] }))] })] })), resetErrorBoundary && (_jsx(Box, { sx: { mt: 2 }, children: _jsx(Button, { variant: "outlined", color: "error", size: "small", onClick: resetErrorBoundary, children: "Try Again" }) }))] }));
36
+ };
@@ -9,12 +9,12 @@ var __rest = (this && this.__rest) || function (s, e) {
9
9
  }
10
10
  return t;
11
11
  };
12
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
13
- import { Alert, Box, Typography } from '@mui/material';
12
+ import { jsx as _jsx } from "react/jsx-runtime";
14
13
  import { ErrorBoundary } from 'react-error-boundary';
15
14
  import { RenderNestedComponent } from '../../utils/property';
16
15
  import BlockletReactComponentRenderer from './BlockletReactComponentRenderer';
17
16
  import { DevProvider, useDev } from './DevProvider';
17
+ import { ComponentError } from './ErrorComponent';
18
18
  import { useCustomComponentRenderer } from './context';
19
19
  import { useComponent } from './state';
20
20
  export * from './state';
@@ -25,14 +25,11 @@ export default function CustomComponentRenderer(_a) {
25
25
  var { dev } = _a, props = __rest(_a, ["dev"]);
26
26
  const inheritedDev = useDev();
27
27
  const BuiltinComponent = BuiltinComponents[props.componentId];
28
- return (_jsx(ErrorBoundary, { FallbackComponent: (props === null || props === void 0 ? void 0 : props.fallbackRender) || ErrorView, resetKeys: [Date.now()], children: _jsx(DevProvider, { dev: dev !== null && dev !== void 0 ? dev : inheritedDev, children: BuiltinComponent ? (_jsx(BuiltinComponent, Object.assign({}, props))) : (_jsx(ComponentRenderer, Object.assign({}, props, { instanceId: (_b = props.instanceId) !== null && _b !== void 0 ? _b : props.componentId, renderType: props.renderType }))) }) }));
28
+ return (_jsx(ErrorBoundary, { FallbackComponent: (props === null || props === void 0 ? void 0 : props.fallbackRender) || ComponentError, resetKeys: [Date.now()], children: _jsx(DevProvider, { dev: dev !== null && dev !== void 0 ? dev : inheritedDev, children: BuiltinComponent ? (_jsx(BuiltinComponent, Object.assign({}, props))) : (_jsx(ComponentRenderer, Object.assign({}, props, { instanceId: (_b = props.instanceId) !== null && _b !== void 0 ? _b : props.componentId, renderType: props.renderType }))) }) }));
29
29
  }
30
30
  const BuiltinComponents = {
31
31
  'blocklet-react-component': BlockletReactComponentRenderer,
32
32
  };
33
- function ErrorView({ error }) {
34
- return (_jsx(Box, { children: _jsx(Alert, { severity: "error", children: error.message }) }));
35
- }
36
33
  function ComponentRenderer(_a) {
37
34
  var _b;
38
35
  var { renderCount = 0, blockletId, blockletTitle, componentName, renderType = 'view' } = _a, props = __rest(_a, ["renderCount", "blockletId", "blockletTitle", "componentName", "renderType"]);
@@ -57,15 +54,7 @@ function ComponentRenderer(_a) {
57
54
  }
58
55
  // if the component is not in the dev.components, it means the component is not loaded
59
56
  if ((dev === null || dev === void 0 ? void 0 : dev.mode) === 'draft' && dev && ((_b = dev.components) === null || _b === void 0 ? void 0 : _b[props.componentId]) === undefined) {
60
- return (_jsxs(Box, { sx: {
61
- p: 3,
62
- border: '1px dashed #d32f2f',
63
- borderRadius: 1,
64
- bgcolor: 'rgba(211, 47, 47, 0.04)',
65
- display: 'flex',
66
- flexDirection: 'column',
67
- gap: 1,
68
- }, children: [_jsx(Typography, { variant: "subtitle1", sx: { color: '#d32f2f', fontWeight: 500 }, children: "Component Failed to Load" }), _jsx(Typography, { variant: "body2", sx: { color: 'text.secondary' }, children: "Please try the following:" }), _jsxs(Box, { component: "ul", sx: { m: 0, pl: 2 }, children: [_jsxs(Typography, { component: "li", variant: "body2", sx: { color: 'text.secondary' }, children: ["Select component", ' ', _jsx(Box, { component: "span", sx: { fontWeight: 500 }, children: componentName !== null && componentName !== void 0 ? componentName : props.componentId }), ' ', "in settings or create this component."] }), (blockletId || blockletTitle) && (_jsxs(Typography, { component: "li", variant: "body2", sx: { color: 'text.secondary' }, children: ["Contact administrator to install", ' ', _jsx(Box, { component: "span", sx: { fontWeight: 500 }, children: blockletTitle !== null && blockletTitle !== void 0 ? blockletTitle : blockletId }), ' ', "Blocklet"] }))] })] }));
57
+ return (_jsx(ComponentError, { componentId: props.componentId, componentName: componentName, blockletId: blockletId, blockletTitle: blockletTitle, message: "Component not found in available components", showHints: true }));
69
58
  }
70
59
  return null;
71
60
  }
@@ -20,9 +20,10 @@ var __rest = (this && this.__rest) || function (s, e) {
20
20
  };
21
21
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
22
22
  import { cx } from '@emotion/css';
23
+ import { Skeleton, Fade, Box } from '@mui/material';
23
24
  import { isEmpty } from 'lodash';
24
25
  import set from 'lodash/set';
25
- import { useDeferredValue, useEffect, useRef, useState } from 'react';
26
+ import { useDeferredValue, useEffect, useRef, useState, useMemo } from 'react';
26
27
  import { Helmet } from 'react-helmet';
27
28
  import { joinURL } from 'ufo';
28
29
  import { create } from 'zustand';
@@ -31,17 +32,109 @@ import { preloadComponents } from '../../api';
31
32
  import { PreloadComponentScriptModule } from '../../types';
32
33
  import { PreloadComponentsStateGlobalVariableName } from '../../types/preload';
33
34
  import { mergeComponent, parsePropertyValue } from '../../utils/property';
35
+ import { ComponentError } from './ErrorComponent';
34
36
  const PRELOAD_COMPONENTS_STATE = window[PreloadComponentsStateGlobalVariableName];
35
37
  let states;
36
38
  function importCustomComponent(m, { componentId }) {
39
+ // check if m is a Promise
40
+ if (m && typeof m.then === 'function') {
41
+ // handle Promise case
42
+ return (props) => {
43
+ const [loading, setLoading] = useState(true);
44
+ const [error, setError] = useState(null);
45
+ const [ResolvedComponent, setResolvedComponent] = useState(null);
46
+ // 只在组件首次加载时执行,避免重复加载
47
+ useEffect(() => {
48
+ let isMounted = true;
49
+ const loadComponent = () => __awaiter(this, void 0, void 0, function* () {
50
+ try {
51
+ const result = yield m;
52
+ if (!isMounted)
53
+ return;
54
+ if (!result) {
55
+ setError(new Error(`Component ${componentId} resolved to empty value`));
56
+ }
57
+ else {
58
+ const Component = importCustomComponent(result, { componentId });
59
+ if (Component) {
60
+ // 存储组件引用而不是渲染结果
61
+ setResolvedComponent(() => Component);
62
+ }
63
+ else {
64
+ setError(new Error(`Failed to resolve component ${componentId}`));
65
+ }
66
+ }
67
+ }
68
+ catch (err) {
69
+ if (!isMounted)
70
+ return;
71
+ console.error(`Component loading error (${componentId}):`, err);
72
+ setError(err instanceof Error ? err : new Error(String(err)));
73
+ }
74
+ finally {
75
+ if (isMounted) {
76
+ setLoading(false);
77
+ }
78
+ }
79
+ });
80
+ loadComponent();
81
+ return () => {
82
+ isMounted = false;
83
+ };
84
+ }, []); // 仅在组件挂载时执行一次
85
+ // 使用useMemo缓存渲染内容,避免不必要的重计算
86
+ const content = useMemo(() => {
87
+ if (loading) {
88
+ return (_jsx(Box, { sx: { width: '100%', p: 1 }, children: _jsx(Skeleton, { variant: "rectangular", width: "100%", height: 40, animation: "wave" }) }));
89
+ }
90
+ if (error) {
91
+ return _jsx(ComponentError, { componentId: componentId, message: error.message });
92
+ }
93
+ // 动态渲染组件,但允许props更新传递
94
+ if (ResolvedComponent) {
95
+ return _jsx(ResolvedComponent, Object.assign({}, props));
96
+ }
97
+ return null;
98
+ }, [loading, error, ResolvedComponent, props]);
99
+ return (_jsx(Fade, { in: !loading, timeout: 500, children: _jsx(Box, { children: content }) }));
100
+ };
101
+ }
102
+ // non-Promise case
103
+ // empty value check
104
+ if (!m) {
105
+ console.warn(`Component ${componentId} resolved to empty value`);
106
+ return null;
107
+ }
37
108
  let Component;
38
109
  const css = m.__PagesKit_CSS__;
39
- if (typeof m === 'function')
110
+ // smart handle component
111
+ if (typeof m === 'function') {
112
+ // the function itself may be a component
40
113
  Component = m;
41
- else if (!css)
42
- Component = m.default;
43
- else {
44
- Component = (props) => (_jsxs(_Fragment, { children: [_jsx(Helmet, { children: _jsx("style", { children: css }) }), _jsx(m.default, Object.assign({}, props, { className: cx(props.className, `CustomComponent_${componentId}`) }))] }));
114
+ }
115
+ else if (m.default) {
116
+ // has default export
117
+ if (typeof m.default === 'function') {
118
+ // default is a function may be a component
119
+ Component = m.default;
120
+ }
121
+ else {
122
+ // default is not a function, maybe a JSX element
123
+ Component = () => m.default;
124
+ }
125
+ }
126
+ else if (css) {
127
+ // has CSS but no valid component found
128
+ console.warn(`Component ${componentId} has CSS but no valid component found`);
129
+ return null;
130
+ }
131
+ // if a component is found and has CSS, wrap the component with styles
132
+ if (Component && css) {
133
+ const OriginalComponent = Component;
134
+ Component = (props) => (_jsxs(_Fragment, { children: [_jsx(Helmet, { children: _jsx("style", { children: css }) }), _jsx(OriginalComponent, Object.assign({}, props, { className: cx(props.className, `CustomComponent_${componentId}`) }))] }));
135
+ }
136
+ // keep aigneOutputValueSchema
137
+ if (Component && m.aigneOutputValueSchema) {
45
138
  Component.aigneOutputValueSchema = m.aigneOutputValueSchema;
46
139
  }
47
140
  return Component;
@@ -73,14 +166,29 @@ export const customComponentStates = () => {
73
166
  states !== null && states !== void 0 ? states : (states = create()(immer((set, get) => ({
74
167
  state: {
75
168
  config: Object.assign({}, PRELOAD_COMPONENTS_STATE === null || PRELOAD_COMPONENTS_STATE === void 0 ? void 0 : PRELOAD_COMPONENTS_STATE.config),
76
- components: Object.fromEntries(Object.entries(Object.assign({}, PRELOAD_COMPONENTS_STATE === null || PRELOAD_COMPONENTS_STATE === void 0 ? void 0 : PRELOAD_COMPONENTS_STATE.components)).map(([componentId, preload]) => {
169
+ components: Object.fromEntries(Object.entries(Object.assign({}, PRELOAD_COMPONENTS_STATE === null || PRELOAD_COMPONENTS_STATE === void 0 ? void 0 : PRELOAD_COMPONENTS_STATE.components))
170
+ .map(([componentId, preload]) => {
77
171
  let Component;
78
172
  if (preload.componentModuleGlobalVariable) {
79
173
  const m = window[preload.componentModuleGlobalVariable];
80
- Component = typeof m === 'function' ? importCustomComponent(m(), { componentId }) : undefined;
174
+ // handle the global variable
175
+ if (typeof m === 'function') {
176
+ try {
177
+ // call m() to get the component module
178
+ const modulePromiseOrObject = m();
179
+ Component = importCustomComponent(modulePromiseOrObject, { componentId });
180
+ }
181
+ catch (err) {
182
+ console.error(`Failed to initialize component ${componentId}:`, err);
183
+ }
184
+ }
185
+ else {
186
+ console.warn(`Component global variable ${preload.componentModuleGlobalVariable} is not a function`);
187
+ }
81
188
  }
82
189
  return [componentId, Object.assign(Object.assign({}, preload), { Component })];
83
- })),
190
+ })
191
+ .filter((i) => !!i)),
84
192
  instances: Object.assign({}, PRELOAD_COMPONENTS_STATE === null || PRELOAD_COMPONENTS_STATE === void 0 ? void 0 : PRELOAD_COMPONENTS_STATE.instances),
85
193
  },
86
194
  getComponent({ instanceId, componentId, locale }) {
@@ -273,7 +381,7 @@ export function transpileAndLoadScript(script) {
273
381
  before: [createBuiltinModuleTransformer(ts)],
274
382
  },
275
383
  }).outputText;
276
- // 降级到原有的处理方式
384
+ // fallback to the original handling
277
385
  const url = URL.createObjectURL(new Blob([compiled], { type: 'application/javascript' }));
278
386
  try {
279
387
  return yield import(/* @vite-ignore */ url);