UNPKG

@scenemesh/entity-engine

Version:

一个“元数据驱动 + 组件适配 + 动态关系 + 视图管线”式的实体引擎。以 **Model + View + FieldType + SuiteAdapter + DataSource** 为五大支点,统一 CRUD / 查询 / 引用管理 / 视图渲染 / 扩展注册,支持在运行期无侵入拼装出 **表单、网格、主从、看板、仪表盘、流程/树形视图** 等多形态界面。

510 lines (406 loc) 19.7 kB
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }"use client"; var _chunkW3GG22TSjs = require('./chunk-W3GG22TS.js'); // src/core/types/session.types.ts var EntitySession = class { constructor(sessionId, userInfo, update = () => { }) { this.sessionId = sessionId; this.userInfo = userInfo; this.update = update; } isAuthenticated() { return !!this.userInfo; } }; // src/components/renderers/view-inspector/index.tsx var _react = require('react'); var React = _interopRequireWildcard(_react); var _modals = require('@mantine/modals'); var _reactjsonview = require('@uiw/react-json-view'); var _reactjsonview2 = _interopRequireDefault(_reactjsonview); var _core = require('@mantine/core'); var _lucidereact = require('lucide-react'); // src/lib/hooks/utils/use-async/use-async.ts // src/lib/hooks/utils/use-async-effect/use-async-effect.ts function useAsyncEffect(effect, deps) { const abortRef = _react.useRef.call(void 0, null); _react.useEffect.call(void 0, () => { abortRef.current = new AbortController(); return () => { _optionalChain([abortRef, 'access', _ => _.current, 'optionalAccess', _2 => _2.abort, 'call', _3 => _3()]); }; }, []); _react.useEffect.call(void 0, () => { let canceled = false; let result; const load = async () => { const signal = abortRef.current.signal; if (canceled || signal.aborted) { return; } result = await effect(signal); }; queueMicrotask(load); return () => { canceled = true; if (result) { result(); } }; }, deps); } // src/lib/hooks/utils/use-async/use-async.ts function useAsync(func, deps) { const [{ state, data, error }, setState] = _react.useState.call(void 0, {}); useAsyncEffect(async () => { setState((draft) => ({ ...draft, state: "loading" })); try { const result = await func(); setState({ state: "hasData", data: result }); } catch (e) { setState((draft) => ({ ...draft, state: "hasError", error: e })); } }, deps); return { state: _nullishCoalesce(state, () => ( "loading")), data, error }; } function useAsyncWithCache(func, deps) { const [internalState, setInternalState] = _react.useState.call(void 0, { state: "loading" }); const deferredResult = _react.useDeferredValue.call(void 0, internalState); const [loadingState, setLoadingState] = _react.useState.call(void 0, false); useAsyncEffect(async () => { setLoadingState(true); try { const result = await func(); setInternalState({ state: "hasData", data: result, error: void 0 }); } catch (e) { setInternalState({ state: "hasError", data: void 0, error: e }); } finally { setLoadingState(false); } }, deps); return { state: loadingState ? "loading" : _nullishCoalesce(deferredResult.state, () => ( "loading")), data: deferredResult.data, error: deferredResult.error }; } // src/services/api/trpc/react.tsx var _superjson = require('superjson'); var _superjson2 = _interopRequireDefault(_superjson); var _reactquery = require('@trpc/react-query'); var _client = require('@trpc/client'); var _reactquery3 = require('@tanstack/react-query'); // src/services/api/trpc/query-client.ts var createQueryClient = () => new (0, _reactquery3.QueryClient)({ defaultOptions: { queries: { // With SSR, we usually want to set some default staleTime // above 0 to avoid refetching immediately on the client staleTime: 30 * 1e3 }, dehydrate: { serializeData: _superjson2.default.serialize, shouldDehydrateQuery: (query) => _reactquery3.defaultShouldDehydrateQuery.call(void 0, query) || query.state.status === "pending" }, hydrate: { deserializeData: _superjson2.default.deserialize } } }); // src/services/api/trpc/react.tsx var _jsxruntime = require('react/jsx-runtime'); var clientQueryClientSingleton = void 0; var getQueryClient = () => { if (typeof window === "undefined") { return createQueryClient(); } _nullishCoalesce(clientQueryClientSingleton, () => ( (clientQueryClientSingleton = createQueryClient()))); return clientQueryClientSingleton; }; var api = _reactquery.createTRPCReact.call(void 0, ); function TRPCReactProvider(props) { const engine = _chunkW3GG22TSjs.useEntityEngine.call(void 0, ); const queryClient = getQueryClient(); const [trpcClient] = React.useState( () => api.createClient({ links: [ _client.loggerLink.call(void 0, { enabled: (op) => false // process.env.NODE_ENV === 'development' || // (op.direction === 'down' && op.result instanceof Error), }), _client.httpBatchStreamLink.call(void 0, { transformer: _superjson2.default, url: engine.settings.getUrl("/trpc"), ///api/ee/trpc headers: () => { const headers = new Headers(); headers.set("x-trpc-source", "nextjs-react"); return headers; } }) ] }) ); return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _reactquery3.QueryClientProvider, { client: queryClient, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, api.Provider, { client: trpcClient, queryClient, children: props.children }) }); } // src/core/engine/engine.initializer.ts var EngineInitializer = class { constructor(args) { this._config = args.config; this._suiteAdapters = args.suiteAdapters; this._renderers = args.renderers; this._fieldTypers = args.fieldTypers; this._settings = args.settings; this._modules = args.modules; this._sessionProvider = args.sessionProvider; } async init(engine) { if (this._config) { const { models, views } = this._config; if (models.length > 0) { for (const model of models) { engine.metaRegistry.registerModel(model); } } if (views.length > 0) { for (const view of views) { engine.metaRegistry.registerView(view); } } } if (this._suiteAdapters && this._suiteAdapters.length > 0) { for (const adapter of this._suiteAdapters) { engine.componentRegistry.registerAdapter(adapter); } } if (this._renderers && this._renderers.length > 0) { for (const renderer of this._renderers) { engine.componentRegistry.registerRenderer(renderer); } } if (this._fieldTypers && this._fieldTypers.length > 0) { for (const typer of this._fieldTypers) { engine.fieldTyperRegistry.registerFieldTyper(typer); } } if (this._modules && this._modules.length > 0) { for (const mod of this._modules) { await engine.moduleRegistry.registerModule(mod, true); } } if (this._sessionProvider) { engine.sessionManager.setProvider(this._sessionProvider); } if (this._settings) { engine.settings.setBaseUrl(this._settings.baseUrl || ""); engine.settings.setEndpoint( this._settings.endpoint || process.env.EE_SERVICE_ROOT_PATH || "/api/ee" ); engine.settings.authenticationEnabled = this._settings.authenticationEnabled || false; } console.log( `Entity Engine initialized with models(${_optionalChain([this, 'access', _4 => _4._config, 'optionalAccess', _5 => _5.models, 'access', _6 => _6.length]) || 0}) and views(${_optionalChain([this, 'access', _7 => _7._config, 'optionalAccess', _8 => _8.views, 'access', _9 => _9.length]) || 0})` ); } }; // src/uikit/provider/entity-engine-provider-factory.tsx function createEntityEngineProvider(config) { process.env.EE_SERVICE_ROOT_PATH = _optionalChain([config, 'access', _10 => _10.settings, 'optionalAccess', _11 => _11.endpoint]) || "/api/ee"; const initializer = new EngineInitializer({ config: config.config, suiteAdapters: config.suiteAdapters, renderers: config.renderers, fieldTypers: config.fieldTypers, modules: config.modules, settings: config.settings }); const ConfiguredProvider = ({ children }) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkW3GG22TSjs.EntitySuiteAdapterProvider, { adapter: config.suiteAdapter || { suiteName: "build-in", suiteVersion: "1.0.0" }, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkW3GG22TSjs.EntityEngineProvider, { initializer, loading: config.loading, router: config.router, permissionGuard: config.permissionGuard, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkW3GG22TSjs.EntityEngineThemeProvider, { theme: config.theme, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, TRPCReactProvider, { children }) }) } ) } ); ConfiguredProvider.displayName = "EntityEngineProvider(Configured)"; return ConfiguredProvider; } // src/uikit/surface/empty-symbol-comp.tsx function EmptySymbol() { return null; } // src/uikit/consumer/entity-object-consumer.tsx function EntityObjectsConsumer(props) { const { modelName, query, withReference, objectsRenderer, onError, loading } = props; const engine = _chunkW3GG22TSjs.useEntityEngine.call(void 0, ); const model = engine.metaRegistry.getModel(modelName); if (!model) { return null; } const datasource = engine.datasourceFactory.getDataSource(); const dsHook = _chunkW3GG22TSjs.toDataSourceHook.call(void 0, datasource); const { data, loading: isLoading, error } = dsHook.useFindMany({ modelName, query, withAllReferences: withReference || false }); if (isLoading || !data) { return loading || /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { children: "Loading..." }); } if (error) { if (onError) { return onError(error); } return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { color: "red" }, children: [ "Error: ", error.message ] }); } return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _jsxruntime.Fragment, { children: objectsRenderer(data.count, data.data) }); } function EntityObjectConsumer(props) { const { modelName, objectId, withReference, objectRenderer, onError, loading } = props; const engine = _chunkW3GG22TSjs.useEntityEngine.call(void 0, ); const datasource = engine.datasourceFactory.getDataSource(); const dsHook = _chunkW3GG22TSjs.toDataSourceHook.call(void 0, datasource); const { data, error, state } = useAsync(async () => { if (withReference) { return await datasource.findOneWithReferences({ modelName, id: objectId, includeFieldNames: void 0 }); } else { return await datasource.findOne({ modelName, id: objectId }); } }, [objectId, withReference]); if (state === "loading" || !data) { return loading || /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { children: "Loading..." }); } if (error) { if (onError) { return onError(error); } return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { color: "red" }, children: [ "Error: ", error.message ] }); } return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _jsxruntime.Fragment, { children: objectRenderer(data) }); } // src/components/renderers/view-inspector/index.tsx var EntityViewInspector = { name: "buildin-view-inspector", slotName: "view-inspector", disabled: false, renderer: (props) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, EntityViewInspectorComp, { ...props }) }; function EntityViewInspectorComp(props) { const { model, viewData } = props; const handleAction = () => { _modals.modals.open({ title: "\u89C6\u56FE\u914D\u7F6E\u6570\u636E", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, InnerEntityViewInspectorComp, { ...props, model, viewData }) }), size: "80%", centered: true, closeOnClickOutside: true, closeOnEscape: true, onClose: () => { console.log("Settings modal closed"); } }); }; return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _core.ActionIcon, { variant: "subtle", "aria-label": "Settings", onClick: handleAction, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Settings2Icon, { size: 14, strokeWidth: 2 }) }); } function InnerEntityViewInspectorComp(props) { const { model, viewData, ...otherProps } = props; const [tab, setTab] = React.default.useState("model"); const engine = _chunkW3GG22TSjs.useEntityEngine.call(void 0, ); const handleTabChange = (value) => { setTab(value || "model"); }; return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _core.Tabs, { value: tab, variant: "outline", color: "blue", radius: "md", onChange: handleTabChange, children: [ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _core.Tabs.List, { children: [ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _core.Tabs.Tab, { value: "model", leftSection: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.ViewIcon, { size: 14, strokeWidth: 2 }), children: "\u6A21\u578B\u914D\u7F6E" }), /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _core.Tabs.Tab, { value: "view", leftSection: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.DatabaseIcon, { size: 14, strokeWidth: 2 }), children: "\u89C6\u56FE\u914D\u7F6E" }), /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _core.Tabs.Tab, { value: "other", leftSection: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Settings2Icon, { size: 14, strokeWidth: 2 }), children: "\u5176\u4ED6\u6570\u636E" }) ] }), /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _core.Tabs.Panel, { value: "model", pt: "xs", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _reactjsonview2.default, { value: JSON.parse( JSON.stringify(model, (key, value) => { if (typeof key === "string" && key.startsWith("_metaRegistry")) { return void 0; } return value; }) ) } ) }), /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _core.Tabs.Panel, { value: "view", pt: "xs", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _reactjsonview2.default, { value: JSON.parse( JSON.stringify(viewData, (key, value) => { if (typeof key === "string" && key.startsWith("_metaRegistry")) { return void 0; } return value; }) ) } ) }), /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _core.Tabs.Panel, { value: "other", pt: "xs", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _reactjsonview2.default, { value: JSON.parse( JSON.stringify(otherProps, (key, value) => { if (typeof key === "string" && key.startsWith("_metaRegistry")) { return void 0; } return value; }) ) } ) }) ] }); } // src/types/data.types.ts var QueryOperator = /* @__PURE__ */ ((QueryOperator2) => { QueryOperator2["NONE"] = "none"; QueryOperator2["EQ"] = "eq"; QueryOperator2["NE"] = "ne"; QueryOperator2["GT"] = "gt"; QueryOperator2["GTE"] = "gte"; QueryOperator2["LT"] = "lt"; QueryOperator2["LTE"] = "lte"; QueryOperator2["CONTAINS"] = "contains"; QueryOperator2["STARTS_WITH"] = "startsWith"; QueryOperator2["ENDS_WITH"] = "endsWith"; QueryOperator2["IN"] = "in"; QueryOperator2["NOT_IN"] = "notIn"; QueryOperator2["IS_NULL"] = "isNull"; QueryOperator2["IS_NOT_NULL"] = "isNotNull"; QueryOperator2["BETWEEN"] = "between"; return QueryOperator2; })(QueryOperator || {}); exports.BuildinModule = _chunkW3GG22TSjs.BuildinModule; exports.EmptySymbol = EmptySymbol; exports.EntityActionRegistry = _chunkW3GG22TSjs.EntityActionRegistry; exports.EntityComponentRegistry = _chunkW3GG22TSjs.EntityComponentRegistry; exports.EntityDataSourceFactory = _chunkW3GG22TSjs.EntityDataSourceFactory; exports.EntityEngine = _chunkW3GG22TSjs.EntityEngine; exports.EntityEngineProvider = _chunkW3GG22TSjs.EntityEngineProvider; exports.EntityEngineThemeProvider = _chunkW3GG22TSjs.EntityEngineThemeProvider; exports.EntityEventRegistry = _chunkW3GG22TSjs.EntityEventRegistry; exports.EntityFieldDelegate = _chunkW3GG22TSjs.EntityFieldDelegate; exports.EntityMetaRegistry = _chunkW3GG22TSjs.EntityMetaRegistry; exports.EntityModelDelegate = _chunkW3GG22TSjs.EntityModelDelegate; exports.EntityNamedRenderer = _chunkW3GG22TSjs.EntityNamedRenderer; exports.EntityObjectConsumer = EntityObjectConsumer; exports.EntityObjectsConsumer = EntityObjectsConsumer; exports.EntityPermissionGuard = _chunkW3GG22TSjs.EntityPermissionGuard; exports.EntitySession = EntitySession; exports.EntitySessionManager = _chunkW3GG22TSjs.EntitySessionManager; exports.EntitySuiteAdapterProvider = _chunkW3GG22TSjs.EntitySuiteAdapterProvider; exports.EntityView = _chunkW3GG22TSjs.EntityView; exports.EntityViewContainer = _chunkW3GG22TSjs.EntityViewContainer; exports.EntityViewDelegate = _chunkW3GG22TSjs.EntityViewDelegate; exports.EntityViewFieldDelegate = _chunkW3GG22TSjs.EntityViewFieldDelegate; exports.EntityViewInspector = EntityViewInspector; exports.EntityWidget = _chunkW3GG22TSjs.EntityWidget; exports.EntityWidgetRenderer = _chunkW3GG22TSjs.EntityWidgetRenderer; exports.ModelFieldTyperRegistry = _chunkW3GG22TSjs.ModelFieldTyperRegistry; exports.QueryOperator = QueryOperator; exports.TRPCEntityObjectDataSource = _chunkW3GG22TSjs.TRPCEntityObjectDataSource; exports.ViewContainerProvider = _chunkW3GG22TSjs.ViewContainerProvider; exports.createEntityEngineProvider = createEntityEngineProvider; exports.entityEngineDefaultTheme = _chunkW3GG22TSjs.entityEngineDefaultTheme; exports.getEntityEngine = _chunkW3GG22TSjs.getEntityEngine; exports.toDataSourceHook = _chunkW3GG22TSjs.toDataSourceHook; exports.useAsync = useAsync; exports.useAsyncEffect = useAsyncEffect; exports.useAsyncWithCache = useAsyncWithCache; exports.useContainerRouter = _chunkW3GG22TSjs.useContainerRouter; exports.useEntityEngine = _chunkW3GG22TSjs.useEntityEngine; exports.useEntityEngineRouter = _chunkW3GG22TSjs.useEntityEngineRouter; exports.useEntityEngineTheme = _chunkW3GG22TSjs.useEntityEngineTheme; exports.useEntityPermissionGuard = _chunkW3GG22TSjs.useEntityPermissionGuard; exports.useEntitySession = _chunkW3GG22TSjs.useEntitySession; exports.useEntitySuiteAdapter = _chunkW3GG22TSjs.useEntitySuiteAdapter; exports.useMasterDetailViewContainer = _chunkW3GG22TSjs.useMasterDetailViewContainer; //# sourceMappingURL=index.js.map