react-antd-admin-panel
Version:
Modern TypeScript-first React admin panel builder with Ant Design 6
1 lines • 7.72 kB
Source Map (JSON)
{"version":3,"file":"Loader-md4nGsvL.cjs","sources":["../src/http/Loader.ts"],"sourcesContent":["import { Get } from './Get';\nimport { Post } from './Post';\n\nexport interface LoaderData<T = any> {\n [key: string]: T;\n}\n\nexport interface LoaderHooks {\n onBeforeLoad?: () => void | Promise<void>;\n onLoad?: (data: LoaderData) => void | Promise<void>;\n onAfterLoad?: (data: LoaderData) => void | Promise<void>;\n onError?: (error: Error) => void | Promise<void>;\n}\n\nexport interface LoaderRequest<T = any> {\n key: string;\n request: Get<T> | Post<any, T>;\n required?: boolean;\n condition?: (data: LoaderData) => boolean;\n}\n\n/**\n * Loader - Data pre-fetching orchestrator for page lifecycle\n * Manages multiple HTTP requests with dependencies and conditions\n * \n * @example\n * const loader = new Loader()\n * .add('user', new Get().target('/api/user'))\n * .add('posts', new Get().target('/api/posts'), { \n * condition: (data) => data.user?.isAdmin \n * })\n * .onLoad((data) => console.log('Loaded:', data))\n * .execute();\n */\nexport class Loader {\n private _requests: LoaderRequest[] = [];\n private _hooks: LoaderHooks = {};\n private _parallel: boolean = true;\n private _abortOnError: boolean = false;\n\n /**\n * Add a request to the loader\n */\n add<T = any>(\n key: string, \n request: Get<T> | Post<any, T>, \n options?: { required?: boolean; condition?: (data: LoaderData) => boolean }\n ): this {\n this._requests.push({\n key,\n request,\n required: options?.required ?? false,\n condition: options?.condition,\n });\n return this;\n }\n\n /**\n * Set whether requests execute in parallel (default) or sequentially\n */\n parallel(value: boolean = true): this {\n this._parallel = value;\n return this;\n }\n\n /**\n * Set whether to abort on first error (default: false)\n */\n abortOnError(value: boolean = true): this {\n this._abortOnError = value;\n return this;\n }\n\n /**\n * Hook called before any requests are made\n */\n onBeforeLoad(callback: () => void | Promise<void>): this {\n this._hooks.onBeforeLoad = callback;\n return this;\n }\n\n /**\n * Hook called after all requests complete successfully\n */\n onLoad(callback: (data: LoaderData) => void | Promise<void>): this {\n this._hooks.onLoad = callback;\n return this;\n }\n\n /**\n * Hook called after onLoad (useful for side effects)\n */\n onAfterLoad(callback: (data: LoaderData) => void | Promise<void>): this {\n this._hooks.onAfterLoad = callback;\n return this;\n }\n\n /**\n * Hook called if any request fails\n */\n onError(callback: (error: Error) => void | Promise<void>): this {\n this._hooks.onError = callback;\n return this;\n }\n\n /**\n * Execute all requests with lifecycle management\n */\n async execute(): Promise<LoaderData> {\n const data: LoaderData = {};\n\n try {\n // Before load hook\n if (this._hooks.onBeforeLoad) {\n await this._hooks.onBeforeLoad();\n }\n\n if (this._parallel) {\n // Execute all requests in parallel\n await this._executeParallel(data);\n } else {\n // Execute requests sequentially (allows conditions to check previous results)\n await this._executeSequential(data);\n }\n\n // On load hook\n if (this._hooks.onLoad) {\n await this._hooks.onLoad(data);\n }\n\n // After load hook\n if (this._hooks.onAfterLoad) {\n await this._hooks.onAfterLoad(data);\n }\n\n return data;\n } catch (error) {\n // Error hook\n if (this._hooks.onError) {\n await this._hooks.onError(error as Error);\n }\n throw error;\n }\n }\n\n /**\n * Execute requests in parallel\n */\n private async _executeParallel(data: LoaderData): Promise<void> {\n const promises = this._requests.map(async (req) => {\n // Check condition\n if (req.condition && !req.condition(data)) {\n return;\n }\n\n try {\n const result = await req.request.execute();\n data[req.key] = result;\n } catch (error) {\n if (req.required || this._abortOnError) {\n throw error;\n }\n // Non-required request failed, continue\n data[req.key] = null;\n }\n });\n\n await Promise.all(promises);\n }\n\n /**\n * Execute requests sequentially (allows conditions to depend on previous results)\n */\n private async _executeSequential(data: LoaderData): Promise<void> {\n for (const req of this._requests) {\n // Check condition based on already-loaded data\n if (req.condition && !req.condition(data)) {\n continue;\n }\n\n try {\n const result = await req.request.execute();\n data[req.key] = result;\n } catch (error) {\n if (req.required || this._abortOnError) {\n throw error;\n }\n // Non-required request failed, continue\n data[req.key] = null;\n }\n }\n }\n\n /**\n * Create a loader from a configuration object\n */\n static from(config: { \n requests: LoaderRequest[]; \n hooks?: LoaderHooks; \n parallel?: boolean;\n abortOnError?: boolean;\n }): Loader {\n const loader = new Loader();\n loader._requests = config.requests;\n loader._hooks = config.hooks || {};\n loader._parallel = config.parallel ?? true;\n loader._abortOnError = config.abortOnError ?? false;\n return loader;\n }\n}\n"],"names":[],"mappings":"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"}