@alepha/react 0.13.7 → 0.13.8
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/dist/auth/index.d.ts +102 -102
- package/dist/core/index.browser.js +22 -1
- package/dist/core/index.browser.js.map +1 -1
- package/dist/core/index.d.ts +121 -109
- package/dist/core/index.js +22 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.native.js +24 -2
- package/dist/core/index.native.js.map +1 -1
- package/dist/head/index.d.ts +17 -17
- package/dist/i18n/index.d.ts +22 -22
- package/dist/websocket/index.d.ts +19 -19
- package/package.json +20 -22
- package/src/core/contexts/AlephaProvider.tsx +41 -0
- package/src/core/index.shared.ts +1 -0
|
@@ -1,12 +1,34 @@
|
|
|
1
|
-
import { $module, AlephaError, Atom } from "alepha";
|
|
1
|
+
import { $module, Alepha, AlephaError, Atom } from "alepha";
|
|
2
2
|
import { AlephaDateTime, DateTimeProvider } from "alepha/datetime";
|
|
3
3
|
import { AlephaServerLinks, LinkProvider } from "alepha/server/links";
|
|
4
4
|
import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState } from "react";
|
|
5
|
+
import { jsx } from "react/jsx-runtime";
|
|
5
6
|
import { HttpClient } from "alepha/server";
|
|
6
7
|
|
|
7
8
|
//#region ../../src/core/contexts/AlephaContext.ts
|
|
8
9
|
const AlephaContext = createContext(void 0);
|
|
9
10
|
|
|
11
|
+
//#endregion
|
|
12
|
+
//#region ../../src/core/contexts/AlephaProvider.tsx
|
|
13
|
+
/**
|
|
14
|
+
* AlephaProvider component to initialize and provide Alepha instance to the app.
|
|
15
|
+
* This isn't recommended for apps using alepha/react/router, as Router will handle this for you.
|
|
16
|
+
*/
|
|
17
|
+
const AlephaProvider = (props) => {
|
|
18
|
+
const alepha = useMemo(() => Alepha.create(), []);
|
|
19
|
+
const [started, setStarted] = useState(false);
|
|
20
|
+
const [error, setError] = useState();
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
alepha.start().then(() => setStarted(true)).catch((err) => setError(err));
|
|
23
|
+
}, [alepha]);
|
|
24
|
+
if (error) return props.onError(error);
|
|
25
|
+
if (!started) return props.onLoading();
|
|
26
|
+
return /* @__PURE__ */ jsx(AlephaContext.Provider, {
|
|
27
|
+
value: alepha,
|
|
28
|
+
children: props.children
|
|
29
|
+
});
|
|
30
|
+
};
|
|
31
|
+
|
|
10
32
|
//#endregion
|
|
11
33
|
//#region ../../src/core/hooks/useAlepha.ts
|
|
12
34
|
/**
|
|
@@ -377,5 +399,5 @@ const AlephaReact = $module({
|
|
|
377
399
|
});
|
|
378
400
|
|
|
379
401
|
//#endregion
|
|
380
|
-
export { AlephaContext, AlephaReact, ssrSchemaLoading, useAction, useAlepha, useClient, useEvents, useInject, useSchema, useStore };
|
|
402
|
+
export { AlephaContext, AlephaProvider, AlephaReact, ssrSchemaLoading, useAction, useAlepha, useClient, useEvents, useInject, useSchema, useStore };
|
|
381
403
|
//# sourceMappingURL=index.native.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.native.js","names":["error","subs: Function[]","schema"],"sources":["../../src/core/contexts/AlephaContext.ts","../../src/core/hooks/useAlepha.ts","../../src/core/hooks/useInject.ts","../../src/core/hooks/useAction.ts","../../src/core/hooks/useClient.ts","../../src/core/hooks/useEvents.ts","../../src/core/hooks/useSchema.ts","../../src/core/hooks/useStore.ts","../../src/core/index.native.ts"],"sourcesContent":["import type { Alepha } from \"alepha\";\nimport { createContext } from \"react\";\n\nexport const AlephaContext = createContext<Alepha | undefined>(undefined);\n","import { type Alepha, AlephaError } from \"alepha\";\nimport { useContext } from \"react\";\nimport { AlephaContext } from \"../contexts/AlephaContext.ts\";\n\n/**\n * Main Alepha hook.\n *\n * It provides access to the Alepha instance within a React component.\n *\n * With Alepha, you can access the core functionalities of the framework:\n *\n * - alepha.state() for state management\n * - alepha.inject() for dependency injection\n * - alepha.events.emit() for event handling\n * etc...\n */\nexport const useAlepha = (): Alepha => {\n const alepha = useContext(AlephaContext);\n if (!alepha) {\n throw new AlephaError(\n \"Hook 'useAlepha()' must be used within an AlephaContext.Provider\",\n );\n }\n\n return alepha;\n};\n","import type { Service } from \"alepha\";\nimport { useMemo } from \"react\";\nimport { useAlepha } from \"./useAlepha.ts\";\n\n/**\n * Hook to inject a service instance.\n * It's a wrapper of `useAlepha().inject(service)` with a memoization.\n */\nexport const useInject = <T extends object>(service: Service<T>): T => {\n const alepha = useAlepha();\n return useMemo(() => alepha.inject(service), []);\n};\n","import {\n DateTimeProvider,\n type DurationLike,\n type Interval,\n type Timeout,\n} from \"alepha/datetime\";\nimport {\n type DependencyList,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport { useAlepha } from \"./useAlepha.ts\";\nimport { useInject } from \"./useInject.ts\";\nimport type { Async } from \"alepha\";\n\n/**\n * Hook for handling async actions with automatic error handling and event emission.\n *\n * By default, prevents concurrent executions - if an action is running and you call it again,\n * the second call will be ignored. Use `debounce` option to delay execution instead.\n *\n * Emits lifecycle events:\n * - `react:action:begin` - When action starts\n * - `react:action:success` - When action completes successfully\n * - `react:action:error` - When action throws an error\n * - `react:action:end` - Always emitted at the end\n *\n * @example Basic usage\n * ```tsx\n * const action = useAction({\n * handler: async (data) => {\n * await api.save(data);\n * }\n * }, []);\n *\n * <button onClick={() => action.run(data)} disabled={action.loading}>\n * Save\n * </button>\n * ```\n *\n * @example With debounce (search input)\n * ```tsx\n * const search = useAction({\n * handler: async (query: string) => {\n * await api.search(query);\n * },\n * debounce: 300 // Wait 300ms after last call\n * }, []);\n *\n * <input onChange={(e) => search.run(e.target.value)} />\n * ```\n *\n * @example Run on component mount\n * ```tsx\n * const fetchData = useAction({\n * handler: async () => {\n * const data = await api.getData();\n * return data;\n * },\n * runOnInit: true // Runs once when component mounts\n * }, []);\n * ```\n *\n * @example Run periodically (polling)\n * ```tsx\n * const pollStatus = useAction({\n * handler: async () => {\n * const status = await api.getStatus();\n * return status;\n * },\n * runEvery: 5000 // Run every 5 seconds\n * }, []);\n *\n * // Or with duration tuple\n * const pollStatus = useAction({\n * handler: async () => {\n * const status = await api.getStatus();\n * return status;\n * },\n * runEvery: [30, 'seconds'] // Run every 30 seconds\n * }, []);\n * ```\n *\n * @example With AbortController\n * ```tsx\n * const fetch = useAction({\n * handler: async (url, { signal }) => {\n * const response = await fetch(url, { signal });\n * return response.json();\n * }\n * }, []);\n * // Automatically cancelled on unmount or when new request starts\n * ```\n *\n * @example With error handling\n * ```tsx\n * const deleteAction = useAction({\n * handler: async (id: string) => {\n * await api.delete(id);\n * },\n * onError: (error) => {\n * if (error.code === 'NOT_FOUND') {\n * // Custom error handling\n * }\n * }\n * }, []);\n *\n * {deleteAction.error && <div>Error: {deleteAction.error.message}</div>}\n * ```\n *\n * @example Global error handling\n * ```tsx\n * // In your root app setup\n * alepha.events.on(\"react:action:error\", ({ error }) => {\n * toast.danger(error.message);\n * Sentry.captureException(error);\n * });\n * ```\n */\nexport function useAction<Args extends any[], Result = void>(\n options: UseActionOptions<Args, Result>,\n deps: DependencyList,\n): UseActionReturn<Args, Result> {\n const alepha = useAlepha();\n const dateTimeProvider = useInject(DateTimeProvider);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | undefined>();\n const isExecutingRef = useRef(false);\n const debounceTimerRef = useRef<Timeout | undefined>(undefined);\n const abortControllerRef = useRef<AbortController | undefined>(undefined);\n const isMountedRef = useRef(true);\n const intervalRef = useRef<Interval | undefined>(undefined);\n\n // Cleanup on unmount\n useEffect(() => {\n return () => {\n isMountedRef.current = false;\n\n // clear debounce timer\n if (debounceTimerRef.current) {\n dateTimeProvider.clearTimeout(debounceTimerRef.current);\n debounceTimerRef.current = undefined;\n }\n\n // clear interval\n if (intervalRef.current) {\n dateTimeProvider.clearInterval(intervalRef.current);\n intervalRef.current = undefined;\n }\n\n // abort in-flight request\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n abortControllerRef.current = undefined;\n }\n };\n }, []);\n\n const executeAction = useCallback(\n async (...args: Args): Promise<Result | undefined> => {\n // Prevent concurrent executions\n if (isExecutingRef.current) {\n return;\n }\n\n // Abort previous request if still running\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n }\n\n // Create new AbortController for this request\n const abortController = new AbortController();\n abortControllerRef.current = abortController;\n\n isExecutingRef.current = true;\n setLoading(true);\n setError(undefined);\n\n await alepha.events.emit(\"react:action:begin\", {\n type: \"custom\",\n id: options.id,\n });\n\n try {\n // Pass abort signal as last argument to handler\n const result = await options.handler(...args, {\n signal: abortController.signal,\n } as any);\n\n // Only update state if still mounted and not aborted\n if (!isMountedRef.current || abortController.signal.aborted) {\n return;\n }\n\n await alepha.events.emit(\"react:action:success\", {\n type: \"custom\",\n id: options.id,\n });\n\n if (options.onSuccess) {\n await options.onSuccess(result);\n }\n\n return result;\n } catch (err) {\n // Ignore abort errors\n if (err instanceof Error && err.name === \"AbortError\") {\n return;\n }\n\n // Only update state if still mounted\n if (!isMountedRef.current) {\n return;\n }\n\n const error = err as Error;\n setError(error);\n\n await alepha.events.emit(\"react:action:error\", {\n type: \"custom\",\n id: options.id,\n error,\n });\n\n if (options.onError) {\n await options.onError(error);\n } else {\n // Re-throw if no custom error handler\n throw error;\n }\n } finally {\n isExecutingRef.current = false;\n setLoading(false);\n\n await alepha.events.emit(\"react:action:end\", {\n type: \"custom\",\n id: options.id,\n });\n\n // Clean up abort controller\n if (abortControllerRef.current === abortController) {\n abortControllerRef.current = undefined;\n }\n }\n },\n [...deps, options.id, options.onError, options.onSuccess],\n );\n\n const handler = useCallback(\n async (...args: Args): Promise<Result | undefined> => {\n if (options.debounce) {\n // clear existing timer\n if (debounceTimerRef.current) {\n dateTimeProvider.clearTimeout(debounceTimerRef.current);\n }\n\n // Set new timer\n return new Promise((resolve) => {\n debounceTimerRef.current = dateTimeProvider.createTimeout(\n async () => {\n const result = await executeAction(...args);\n resolve(result);\n },\n options.debounce ?? 0,\n );\n });\n }\n\n return executeAction(...args);\n },\n [executeAction, options.debounce],\n );\n\n const cancel = useCallback(() => {\n // clear debounce timer\n if (debounceTimerRef.current) {\n dateTimeProvider.clearTimeout(debounceTimerRef.current);\n debounceTimerRef.current = undefined;\n }\n\n // abort in-flight request\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n abortControllerRef.current = undefined;\n }\n\n // reset state\n if (isMountedRef.current) {\n isExecutingRef.current = false;\n setLoading(false);\n }\n }, []);\n\n // Run action on mount if runOnInit is true\n useEffect(() => {\n if (options.runOnInit) {\n handler(...([] as any));\n }\n }, deps);\n\n // Run action periodically if runEvery is specified\n useEffect(() => {\n if (!options.runEvery) {\n return;\n }\n\n // Set up interval\n intervalRef.current = dateTimeProvider.createInterval(\n () => handler(...([] as any)),\n options.runEvery,\n true,\n );\n\n // cleanup on unmount or when runEvery changes\n return () => {\n if (intervalRef.current) {\n dateTimeProvider.clearInterval(intervalRef.current);\n intervalRef.current = undefined;\n }\n };\n }, [handler, options.runEvery]);\n\n return {\n run: handler,\n loading,\n error,\n cancel,\n };\n}\n\n// ---------------------------------------------------------------------------------------------------------------------\n\n/**\n * Context object passed as the last argument to action handlers.\n * Contains an AbortSignal that can be used to cancel the request.\n */\nexport interface ActionContext {\n /**\n * AbortSignal that can be passed to fetch or other async operations.\n * The signal will be aborted when:\n * - The component unmounts\n * - A new action is triggered (cancels previous)\n * - The cancel() method is called\n *\n * @example\n * ```tsx\n * const action = useAction({\n * handler: async (url, { signal }) => {\n * const response = await fetch(url, { signal });\n * return response.json();\n * }\n * }, []);\n * ```\n */\n signal: AbortSignal;\n}\n\nexport interface UseActionOptions<Args extends any[] = any[], Result = any> {\n /**\n * The async action handler function.\n * Receives the action arguments plus an ActionContext as the last parameter.\n */\n handler: (...args: [...Args, ActionContext]) => Async<Result>;\n\n /**\n * Custom error handler. If provided, prevents default error re-throw.\n */\n onError?: (error: Error) => void | Promise<void>;\n\n /**\n * Custom success handler.\n */\n onSuccess?: (result: Result) => void | Promise<void>;\n\n /**\n * Optional identifier for this action (useful for debugging/analytics)\n */\n id?: string;\n\n name?: string;\n\n /**\n * Debounce delay in milliseconds. If specified, the action will only execute\n * after the specified delay has passed since the last call. Useful for search inputs\n * or other high-frequency events.\n *\n * @example\n * ```tsx\n * // Execute search 300ms after user stops typing\n * const search = useAction({ handler: search, debounce: 300 }, [])\n * ```\n */\n debounce?: number;\n\n /**\n * If true, the action will be executed once when the component mounts.\n *\n * @example\n * ```tsx\n * const fetchData = useAction({\n * handler: async () => await api.getData(),\n * runOnInit: true\n * }, []);\n * ```\n */\n runOnInit?: boolean;\n\n /**\n * If specified, the action will be executed periodically at the given interval.\n * The interval is specified as a DurationLike value (number in ms, Duration object, or [number, unit] tuple).\n *\n * @example\n * ```tsx\n * // Run every 5 seconds\n * const poll = useAction({\n * handler: async () => await api.poll(),\n * runEvery: 5000\n * }, []);\n * ```\n *\n * @example\n * ```tsx\n * // Run every 1 minute\n * const poll = useAction({\n * handler: async () => await api.poll(),\n * runEvery: [1, 'minute']\n * }, []);\n * ```\n */\n runEvery?: DurationLike;\n}\n\nexport interface UseActionReturn<Args extends any[], Result> {\n /**\n * Execute the action with the provided arguments.\n *\n * @example\n * ```tsx\n * const action = useAction({ handler: async (data) => { ... } }, []);\n * action.run(data);\n * ```\n */\n run: (...args: Args) => Promise<Result | undefined>;\n\n /**\n * Loading state - true when action is executing.\n */\n loading: boolean;\n\n /**\n * Error state - contains error if action failed, undefined otherwise.\n */\n error?: Error;\n\n /**\n * Cancel any pending debounced action or abort the current in-flight request.\n *\n * @example\n * ```tsx\n * const action = useAction({ ... }, []);\n *\n * <button onClick={action.cancel} disabled={!action.loading}>\n * Cancel\n * </button>\n * ```\n */\n cancel: () => void;\n}\n","import {\n type ClientScope,\n type HttpVirtualClient,\n LinkProvider,\n} from \"alepha/server/links\";\nimport { useInject } from \"./useInject.ts\";\n\n/**\n * Hook to get a virtual client for the specified scope.\n *\n * It's the React-hook version of `$client()`, from `AlephaServerLinks` module.\n */\nexport const useClient = <T extends object>(\n scope?: ClientScope,\n): HttpVirtualClient<T> => {\n return useInject(LinkProvider).client<T>(scope);\n};\n","import type { Async, Hook, Hooks } from \"alepha\";\nimport { type DependencyList, useEffect } from \"react\";\nimport { useAlepha } from \"./useAlepha.ts\";\n\n/**\n * Allow subscribing to multiple Alepha events. See {@link Hooks} for available events.\n *\n * useEvents is fully typed to ensure correct event callback signatures.\n *\n * @example\n * ```tsx\n * useEvents(\n * {\n * \"react:transition:begin\": (ev) => {\n * console.log(\"Transition began to:\", ev.to);\n * },\n * \"react:transition:error\": {\n * priority: \"first\",\n * callback: (ev) => {\n * console.error(\"Transition error:\", ev.error);\n * },\n * },\n * },\n * [],\n * );\n * ```\n */\nexport const useEvents = (opts: UseEvents, deps: DependencyList) => {\n const alepha = useAlepha();\n\n useEffect(() => {\n if (!alepha.isBrowser()) {\n return;\n }\n\n const subs: Function[] = [];\n for (const [name, hook] of Object.entries(opts)) {\n subs.push(alepha.events.on(name as any, hook as any));\n }\n\n return () => {\n for (const clear of subs) {\n clear();\n }\n };\n }, deps);\n};\n\ntype UseEvents = {\n [T in keyof Hooks]?: Hook<T> | ((payload: Hooks[T]) => Async<void>);\n};\n","import type { Alepha } from \"alepha\";\nimport {\n type FetchOptions,\n HttpClient,\n type RequestConfigSchema,\n} from \"alepha/server\";\nimport { LinkProvider, type VirtualAction } from \"alepha/server/links\";\nimport { useEffect, useState } from \"react\";\nimport { useAlepha } from \"./useAlepha.ts\";\nimport { useInject } from \"./useInject.ts\";\n\nexport const useSchema = <TConfig extends RequestConfigSchema>(\n action: VirtualAction<TConfig>,\n): UseSchemaReturn<TConfig> => {\n const name = action.name;\n const alepha = useAlepha();\n const httpClient = useInject(HttpClient);\n const [schema, setSchema] = useState<UseSchemaReturn<TConfig>>(\n ssrSchemaLoading(alepha, name) as UseSchemaReturn<TConfig>,\n );\n\n useEffect(() => {\n if (!schema.loading) {\n return;\n }\n\n const opts: FetchOptions = {\n localCache: true,\n };\n\n httpClient\n .fetch(`${LinkProvider.path.apiLinks}/${name}/schema`, opts)\n .then((it) => setSchema(it.data as UseSchemaReturn<TConfig>));\n }, [name]);\n\n return schema;\n};\n\nexport type UseSchemaReturn<TConfig extends RequestConfigSchema> = TConfig & {\n loading: boolean;\n};\n\n// ---------------------------------------------------------------------------------------------------------------------\n\n/**\n * Get an action schema during server-side rendering (SSR) or client-side rendering (CSR).\n */\nexport const ssrSchemaLoading = (alepha: Alepha, name: string) => {\n // server-side rendering (SSR) context\n if (!alepha.isBrowser()) {\n // get user links\n const linkProvider = alepha.inject(LinkProvider);\n\n // check if user can access the link\n const can = linkProvider\n .getServerLinks()\n .find((link) => link.name === name);\n\n // yes!\n if (can) {\n // user-links have no schema, so we need to get it from the provider\n const schema = linkProvider.links.find((it) => it.name === name)?.schema;\n\n // oh, we have a schema!\n if (schema) {\n // attach to user link, it will be used in the client during hydration\n can.schema = schema;\n return schema;\n }\n }\n\n return { loading: true };\n }\n\n // browser side rendering (CSR) context\n // check if we have the schema already loaded\n const schema = alepha\n .inject(LinkProvider)\n .links.find((it) => it.name === name)?.schema;\n\n // yes!\n if (schema) {\n return schema;\n }\n\n // no, we need to load it\n return { loading: true };\n};\n","import type { State, Static, TAtomObject } from \"alepha\";\nimport { Atom } from \"alepha\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport { useAlepha } from \"./useAlepha.ts\";\n\n/**\n * Hook to access and mutate the Alepha state.\n */\nfunction useStore<T extends TAtomObject>(\n target: Atom<T>,\n defaultValue?: Static<T>,\n): UseStoreReturn<Static<T>>;\nfunction useStore<Key extends keyof State>(\n target: Key,\n defaultValue?: State[Key],\n): UseStoreReturn<State[Key]>;\nfunction useStore(target: any, defaultValue?: any): any {\n const alepha = useAlepha();\n\n useMemo(() => {\n if (defaultValue != null && alepha.store.get(target) == null) {\n alepha.store.set(target, defaultValue);\n }\n }, [defaultValue]);\n\n const [state, setState] = useState(alepha.store.get(target));\n\n useEffect(() => {\n if (!alepha.isBrowser()) {\n return;\n }\n\n const key = target instanceof Atom ? target.key : target;\n\n return alepha.events.on(\"state:mutate\", (ev) => {\n if (ev.key === key) {\n setState(ev.value);\n }\n });\n }, []);\n\n return [\n state,\n (value: any) => {\n alepha.store.set(target, value);\n },\n ] as const;\n}\n\nexport type UseStoreReturn<T> = [T, (value: T) => void];\n\nexport { useStore };\n","import { $module } from \"alepha\";\nimport { AlephaDateTime } from \"alepha/datetime\";\nimport { AlephaServerLinks } from \"alepha/server/links\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport * from \"./index.shared.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport const AlephaReact = $module({\n name: \"alepha.react\",\n primitives: [],\n services: [\n\n ],\n register: (alepha) =>\n alepha\n .with(AlephaDateTime)\n .with(AlephaServerLinks)\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.native.js","names":["error","subs: Function[]","schema"],"sources":["../../src/core/contexts/AlephaContext.ts","../../src/core/contexts/AlephaProvider.tsx","../../src/core/hooks/useAlepha.ts","../../src/core/hooks/useInject.ts","../../src/core/hooks/useAction.ts","../../src/core/hooks/useClient.ts","../../src/core/hooks/useEvents.ts","../../src/core/hooks/useSchema.ts","../../src/core/hooks/useStore.ts","../../src/core/index.native.ts"],"sourcesContent":["import type { Alepha } from \"alepha\";\nimport { createContext } from \"react\";\n\nexport const AlephaContext = createContext<Alepha | undefined>(undefined);\n","import { Alepha } from \"alepha\";\nimport { type ReactNode, useEffect, useMemo, useState } from \"react\";\nimport { AlephaContext } from \"./AlephaContext.ts\";\n\nexport interface AlephaProviderProps {\n children: ReactNode;\n onError: (error: Error) => ReactNode;\n onLoading: () => ReactNode;\n}\n\n/**\n * AlephaProvider component to initialize and provide Alepha instance to the app.\n * This isn't recommended for apps using alepha/react/router, as Router will handle this for you.\n */\nexport const AlephaProvider = (props: AlephaProviderProps) => {\n const alepha = useMemo(() => Alepha.create(), []);\n\n const [started, setStarted] = useState(false);\n const [error, setError] = useState<Error | undefined>();\n\n useEffect(() => {\n alepha\n .start()\n .then(() => setStarted(true))\n .catch((err) => setError(err));\n }, [alepha]);\n\n if (error) {\n return props.onError(error);\n }\n\n if (!started) {\n return props.onLoading();\n }\n\n return (\n <AlephaContext.Provider value={alepha}>\n {props.children}\n </AlephaContext.Provider>\n );\n};\n","import { type Alepha, AlephaError } from \"alepha\";\nimport { useContext } from \"react\";\nimport { AlephaContext } from \"../contexts/AlephaContext.ts\";\n\n/**\n * Main Alepha hook.\n *\n * It provides access to the Alepha instance within a React component.\n *\n * With Alepha, you can access the core functionalities of the framework:\n *\n * - alepha.state() for state management\n * - alepha.inject() for dependency injection\n * - alepha.events.emit() for event handling\n * etc...\n */\nexport const useAlepha = (): Alepha => {\n const alepha = useContext(AlephaContext);\n if (!alepha) {\n throw new AlephaError(\n \"Hook 'useAlepha()' must be used within an AlephaContext.Provider\",\n );\n }\n\n return alepha;\n};\n","import type { Service } from \"alepha\";\nimport { useMemo } from \"react\";\nimport { useAlepha } from \"./useAlepha.ts\";\n\n/**\n * Hook to inject a service instance.\n * It's a wrapper of `useAlepha().inject(service)` with a memoization.\n */\nexport const useInject = <T extends object>(service: Service<T>): T => {\n const alepha = useAlepha();\n return useMemo(() => alepha.inject(service), []);\n};\n","import {\n DateTimeProvider,\n type DurationLike,\n type Interval,\n type Timeout,\n} from \"alepha/datetime\";\nimport {\n type DependencyList,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport { useAlepha } from \"./useAlepha.ts\";\nimport { useInject } from \"./useInject.ts\";\nimport type { Async } from \"alepha\";\n\n/**\n * Hook for handling async actions with automatic error handling and event emission.\n *\n * By default, prevents concurrent executions - if an action is running and you call it again,\n * the second call will be ignored. Use `debounce` option to delay execution instead.\n *\n * Emits lifecycle events:\n * - `react:action:begin` - When action starts\n * - `react:action:success` - When action completes successfully\n * - `react:action:error` - When action throws an error\n * - `react:action:end` - Always emitted at the end\n *\n * @example Basic usage\n * ```tsx\n * const action = useAction({\n * handler: async (data) => {\n * await api.save(data);\n * }\n * }, []);\n *\n * <button onClick={() => action.run(data)} disabled={action.loading}>\n * Save\n * </button>\n * ```\n *\n * @example With debounce (search input)\n * ```tsx\n * const search = useAction({\n * handler: async (query: string) => {\n * await api.search(query);\n * },\n * debounce: 300 // Wait 300ms after last call\n * }, []);\n *\n * <input onChange={(e) => search.run(e.target.value)} />\n * ```\n *\n * @example Run on component mount\n * ```tsx\n * const fetchData = useAction({\n * handler: async () => {\n * const data = await api.getData();\n * return data;\n * },\n * runOnInit: true // Runs once when component mounts\n * }, []);\n * ```\n *\n * @example Run periodically (polling)\n * ```tsx\n * const pollStatus = useAction({\n * handler: async () => {\n * const status = await api.getStatus();\n * return status;\n * },\n * runEvery: 5000 // Run every 5 seconds\n * }, []);\n *\n * // Or with duration tuple\n * const pollStatus = useAction({\n * handler: async () => {\n * const status = await api.getStatus();\n * return status;\n * },\n * runEvery: [30, 'seconds'] // Run every 30 seconds\n * }, []);\n * ```\n *\n * @example With AbortController\n * ```tsx\n * const fetch = useAction({\n * handler: async (url, { signal }) => {\n * const response = await fetch(url, { signal });\n * return response.json();\n * }\n * }, []);\n * // Automatically cancelled on unmount or when new request starts\n * ```\n *\n * @example With error handling\n * ```tsx\n * const deleteAction = useAction({\n * handler: async (id: string) => {\n * await api.delete(id);\n * },\n * onError: (error) => {\n * if (error.code === 'NOT_FOUND') {\n * // Custom error handling\n * }\n * }\n * }, []);\n *\n * {deleteAction.error && <div>Error: {deleteAction.error.message}</div>}\n * ```\n *\n * @example Global error handling\n * ```tsx\n * // In your root app setup\n * alepha.events.on(\"react:action:error\", ({ error }) => {\n * toast.danger(error.message);\n * Sentry.captureException(error);\n * });\n * ```\n */\nexport function useAction<Args extends any[], Result = void>(\n options: UseActionOptions<Args, Result>,\n deps: DependencyList,\n): UseActionReturn<Args, Result> {\n const alepha = useAlepha();\n const dateTimeProvider = useInject(DateTimeProvider);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | undefined>();\n const isExecutingRef = useRef(false);\n const debounceTimerRef = useRef<Timeout | undefined>(undefined);\n const abortControllerRef = useRef<AbortController | undefined>(undefined);\n const isMountedRef = useRef(true);\n const intervalRef = useRef<Interval | undefined>(undefined);\n\n // Cleanup on unmount\n useEffect(() => {\n return () => {\n isMountedRef.current = false;\n\n // clear debounce timer\n if (debounceTimerRef.current) {\n dateTimeProvider.clearTimeout(debounceTimerRef.current);\n debounceTimerRef.current = undefined;\n }\n\n // clear interval\n if (intervalRef.current) {\n dateTimeProvider.clearInterval(intervalRef.current);\n intervalRef.current = undefined;\n }\n\n // abort in-flight request\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n abortControllerRef.current = undefined;\n }\n };\n }, []);\n\n const executeAction = useCallback(\n async (...args: Args): Promise<Result | undefined> => {\n // Prevent concurrent executions\n if (isExecutingRef.current) {\n return;\n }\n\n // Abort previous request if still running\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n }\n\n // Create new AbortController for this request\n const abortController = new AbortController();\n abortControllerRef.current = abortController;\n\n isExecutingRef.current = true;\n setLoading(true);\n setError(undefined);\n\n await alepha.events.emit(\"react:action:begin\", {\n type: \"custom\",\n id: options.id,\n });\n\n try {\n // Pass abort signal as last argument to handler\n const result = await options.handler(...args, {\n signal: abortController.signal,\n } as any);\n\n // Only update state if still mounted and not aborted\n if (!isMountedRef.current || abortController.signal.aborted) {\n return;\n }\n\n await alepha.events.emit(\"react:action:success\", {\n type: \"custom\",\n id: options.id,\n });\n\n if (options.onSuccess) {\n await options.onSuccess(result);\n }\n\n return result;\n } catch (err) {\n // Ignore abort errors\n if (err instanceof Error && err.name === \"AbortError\") {\n return;\n }\n\n // Only update state if still mounted\n if (!isMountedRef.current) {\n return;\n }\n\n const error = err as Error;\n setError(error);\n\n await alepha.events.emit(\"react:action:error\", {\n type: \"custom\",\n id: options.id,\n error,\n });\n\n if (options.onError) {\n await options.onError(error);\n } else {\n // Re-throw if no custom error handler\n throw error;\n }\n } finally {\n isExecutingRef.current = false;\n setLoading(false);\n\n await alepha.events.emit(\"react:action:end\", {\n type: \"custom\",\n id: options.id,\n });\n\n // Clean up abort controller\n if (abortControllerRef.current === abortController) {\n abortControllerRef.current = undefined;\n }\n }\n },\n [...deps, options.id, options.onError, options.onSuccess],\n );\n\n const handler = useCallback(\n async (...args: Args): Promise<Result | undefined> => {\n if (options.debounce) {\n // clear existing timer\n if (debounceTimerRef.current) {\n dateTimeProvider.clearTimeout(debounceTimerRef.current);\n }\n\n // Set new timer\n return new Promise((resolve) => {\n debounceTimerRef.current = dateTimeProvider.createTimeout(\n async () => {\n const result = await executeAction(...args);\n resolve(result);\n },\n options.debounce ?? 0,\n );\n });\n }\n\n return executeAction(...args);\n },\n [executeAction, options.debounce],\n );\n\n const cancel = useCallback(() => {\n // clear debounce timer\n if (debounceTimerRef.current) {\n dateTimeProvider.clearTimeout(debounceTimerRef.current);\n debounceTimerRef.current = undefined;\n }\n\n // abort in-flight request\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n abortControllerRef.current = undefined;\n }\n\n // reset state\n if (isMountedRef.current) {\n isExecutingRef.current = false;\n setLoading(false);\n }\n }, []);\n\n // Run action on mount if runOnInit is true\n useEffect(() => {\n if (options.runOnInit) {\n handler(...([] as any));\n }\n }, deps);\n\n // Run action periodically if runEvery is specified\n useEffect(() => {\n if (!options.runEvery) {\n return;\n }\n\n // Set up interval\n intervalRef.current = dateTimeProvider.createInterval(\n () => handler(...([] as any)),\n options.runEvery,\n true,\n );\n\n // cleanup on unmount or when runEvery changes\n return () => {\n if (intervalRef.current) {\n dateTimeProvider.clearInterval(intervalRef.current);\n intervalRef.current = undefined;\n }\n };\n }, [handler, options.runEvery]);\n\n return {\n run: handler,\n loading,\n error,\n cancel,\n };\n}\n\n// ---------------------------------------------------------------------------------------------------------------------\n\n/**\n * Context object passed as the last argument to action handlers.\n * Contains an AbortSignal that can be used to cancel the request.\n */\nexport interface ActionContext {\n /**\n * AbortSignal that can be passed to fetch or other async operations.\n * The signal will be aborted when:\n * - The component unmounts\n * - A new action is triggered (cancels previous)\n * - The cancel() method is called\n *\n * @example\n * ```tsx\n * const action = useAction({\n * handler: async (url, { signal }) => {\n * const response = await fetch(url, { signal });\n * return response.json();\n * }\n * }, []);\n * ```\n */\n signal: AbortSignal;\n}\n\nexport interface UseActionOptions<Args extends any[] = any[], Result = any> {\n /**\n * The async action handler function.\n * Receives the action arguments plus an ActionContext as the last parameter.\n */\n handler: (...args: [...Args, ActionContext]) => Async<Result>;\n\n /**\n * Custom error handler. If provided, prevents default error re-throw.\n */\n onError?: (error: Error) => void | Promise<void>;\n\n /**\n * Custom success handler.\n */\n onSuccess?: (result: Result) => void | Promise<void>;\n\n /**\n * Optional identifier for this action (useful for debugging/analytics)\n */\n id?: string;\n\n name?: string;\n\n /**\n * Debounce delay in milliseconds. If specified, the action will only execute\n * after the specified delay has passed since the last call. Useful for search inputs\n * or other high-frequency events.\n *\n * @example\n * ```tsx\n * // Execute search 300ms after user stops typing\n * const search = useAction({ handler: search, debounce: 300 }, [])\n * ```\n */\n debounce?: number;\n\n /**\n * If true, the action will be executed once when the component mounts.\n *\n * @example\n * ```tsx\n * const fetchData = useAction({\n * handler: async () => await api.getData(),\n * runOnInit: true\n * }, []);\n * ```\n */\n runOnInit?: boolean;\n\n /**\n * If specified, the action will be executed periodically at the given interval.\n * The interval is specified as a DurationLike value (number in ms, Duration object, or [number, unit] tuple).\n *\n * @example\n * ```tsx\n * // Run every 5 seconds\n * const poll = useAction({\n * handler: async () => await api.poll(),\n * runEvery: 5000\n * }, []);\n * ```\n *\n * @example\n * ```tsx\n * // Run every 1 minute\n * const poll = useAction({\n * handler: async () => await api.poll(),\n * runEvery: [1, 'minute']\n * }, []);\n * ```\n */\n runEvery?: DurationLike;\n}\n\nexport interface UseActionReturn<Args extends any[], Result> {\n /**\n * Execute the action with the provided arguments.\n *\n * @example\n * ```tsx\n * const action = useAction({ handler: async (data) => { ... } }, []);\n * action.run(data);\n * ```\n */\n run: (...args: Args) => Promise<Result | undefined>;\n\n /**\n * Loading state - true when action is executing.\n */\n loading: boolean;\n\n /**\n * Error state - contains error if action failed, undefined otherwise.\n */\n error?: Error;\n\n /**\n * Cancel any pending debounced action or abort the current in-flight request.\n *\n * @example\n * ```tsx\n * const action = useAction({ ... }, []);\n *\n * <button onClick={action.cancel} disabled={!action.loading}>\n * Cancel\n * </button>\n * ```\n */\n cancel: () => void;\n}\n","import {\n type ClientScope,\n type HttpVirtualClient,\n LinkProvider,\n} from \"alepha/server/links\";\nimport { useInject } from \"./useInject.ts\";\n\n/**\n * Hook to get a virtual client for the specified scope.\n *\n * It's the React-hook version of `$client()`, from `AlephaServerLinks` module.\n */\nexport const useClient = <T extends object>(\n scope?: ClientScope,\n): HttpVirtualClient<T> => {\n return useInject(LinkProvider).client<T>(scope);\n};\n","import type { Async, Hook, Hooks } from \"alepha\";\nimport { type DependencyList, useEffect } from \"react\";\nimport { useAlepha } from \"./useAlepha.ts\";\n\n/**\n * Allow subscribing to multiple Alepha events. See {@link Hooks} for available events.\n *\n * useEvents is fully typed to ensure correct event callback signatures.\n *\n * @example\n * ```tsx\n * useEvents(\n * {\n * \"react:transition:begin\": (ev) => {\n * console.log(\"Transition began to:\", ev.to);\n * },\n * \"react:transition:error\": {\n * priority: \"first\",\n * callback: (ev) => {\n * console.error(\"Transition error:\", ev.error);\n * },\n * },\n * },\n * [],\n * );\n * ```\n */\nexport const useEvents = (opts: UseEvents, deps: DependencyList) => {\n const alepha = useAlepha();\n\n useEffect(() => {\n if (!alepha.isBrowser()) {\n return;\n }\n\n const subs: Function[] = [];\n for (const [name, hook] of Object.entries(opts)) {\n subs.push(alepha.events.on(name as any, hook as any));\n }\n\n return () => {\n for (const clear of subs) {\n clear();\n }\n };\n }, deps);\n};\n\ntype UseEvents = {\n [T in keyof Hooks]?: Hook<T> | ((payload: Hooks[T]) => Async<void>);\n};\n","import type { Alepha } from \"alepha\";\nimport {\n type FetchOptions,\n HttpClient,\n type RequestConfigSchema,\n} from \"alepha/server\";\nimport { LinkProvider, type VirtualAction } from \"alepha/server/links\";\nimport { useEffect, useState } from \"react\";\nimport { useAlepha } from \"./useAlepha.ts\";\nimport { useInject } from \"./useInject.ts\";\n\nexport const useSchema = <TConfig extends RequestConfigSchema>(\n action: VirtualAction<TConfig>,\n): UseSchemaReturn<TConfig> => {\n const name = action.name;\n const alepha = useAlepha();\n const httpClient = useInject(HttpClient);\n const [schema, setSchema] = useState<UseSchemaReturn<TConfig>>(\n ssrSchemaLoading(alepha, name) as UseSchemaReturn<TConfig>,\n );\n\n useEffect(() => {\n if (!schema.loading) {\n return;\n }\n\n const opts: FetchOptions = {\n localCache: true,\n };\n\n httpClient\n .fetch(`${LinkProvider.path.apiLinks}/${name}/schema`, opts)\n .then((it) => setSchema(it.data as UseSchemaReturn<TConfig>));\n }, [name]);\n\n return schema;\n};\n\nexport type UseSchemaReturn<TConfig extends RequestConfigSchema> = TConfig & {\n loading: boolean;\n};\n\n// ---------------------------------------------------------------------------------------------------------------------\n\n/**\n * Get an action schema during server-side rendering (SSR) or client-side rendering (CSR).\n */\nexport const ssrSchemaLoading = (alepha: Alepha, name: string) => {\n // server-side rendering (SSR) context\n if (!alepha.isBrowser()) {\n // get user links\n const linkProvider = alepha.inject(LinkProvider);\n\n // check if user can access the link\n const can = linkProvider\n .getServerLinks()\n .find((link) => link.name === name);\n\n // yes!\n if (can) {\n // user-links have no schema, so we need to get it from the provider\n const schema = linkProvider.links.find((it) => it.name === name)?.schema;\n\n // oh, we have a schema!\n if (schema) {\n // attach to user link, it will be used in the client during hydration\n can.schema = schema;\n return schema;\n }\n }\n\n return { loading: true };\n }\n\n // browser side rendering (CSR) context\n // check if we have the schema already loaded\n const schema = alepha\n .inject(LinkProvider)\n .links.find((it) => it.name === name)?.schema;\n\n // yes!\n if (schema) {\n return schema;\n }\n\n // no, we need to load it\n return { loading: true };\n};\n","import type { State, Static, TAtomObject } from \"alepha\";\nimport { Atom } from \"alepha\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport { useAlepha } from \"./useAlepha.ts\";\n\n/**\n * Hook to access and mutate the Alepha state.\n */\nfunction useStore<T extends TAtomObject>(\n target: Atom<T>,\n defaultValue?: Static<T>,\n): UseStoreReturn<Static<T>>;\nfunction useStore<Key extends keyof State>(\n target: Key,\n defaultValue?: State[Key],\n): UseStoreReturn<State[Key]>;\nfunction useStore(target: any, defaultValue?: any): any {\n const alepha = useAlepha();\n\n useMemo(() => {\n if (defaultValue != null && alepha.store.get(target) == null) {\n alepha.store.set(target, defaultValue);\n }\n }, [defaultValue]);\n\n const [state, setState] = useState(alepha.store.get(target));\n\n useEffect(() => {\n if (!alepha.isBrowser()) {\n return;\n }\n\n const key = target instanceof Atom ? target.key : target;\n\n return alepha.events.on(\"state:mutate\", (ev) => {\n if (ev.key === key) {\n setState(ev.value);\n }\n });\n }, []);\n\n return [\n state,\n (value: any) => {\n alepha.store.set(target, value);\n },\n ] as const;\n}\n\nexport type UseStoreReturn<T> = [T, (value: T) => void];\n\nexport { useStore };\n","import { $module } from \"alepha\";\nimport { AlephaDateTime } from \"alepha/datetime\";\nimport { AlephaServerLinks } from \"alepha/server/links\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport * from \"./index.shared.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport const AlephaReact = $module({\n name: \"alepha.react\",\n primitives: [],\n services: [\n\n ],\n register: (alepha) =>\n alepha\n .with(AlephaDateTime)\n .with(AlephaServerLinks)\n});\n"],"mappings":"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"}
|
package/dist/head/index.d.ts
CHANGED
|
@@ -95,7 +95,7 @@ declare const useHead: (options?: UseHeadOptions) => UseHeadReturn;
|
|
|
95
95
|
type UseHeadOptions = Head | ((previous?: Head) => Head);
|
|
96
96
|
type UseHeadReturn = [Head, (head?: Head | ((previous?: Head) => Head)) => void];
|
|
97
97
|
//#endregion
|
|
98
|
-
//#region ../../../alepha/src/server/schemas/errorSchema.d.ts
|
|
98
|
+
//#region ../../../alepha/src/server/core/schemas/errorSchema.d.ts
|
|
99
99
|
declare const errorSchema: alepha22.TObject<{
|
|
100
100
|
error: alepha22.TString;
|
|
101
101
|
status: alepha22.TInteger;
|
|
@@ -109,7 +109,7 @@ declare const errorSchema: alepha22.TObject<{
|
|
|
109
109
|
}>;
|
|
110
110
|
type ErrorSchema = Static<typeof errorSchema>;
|
|
111
111
|
//#endregion
|
|
112
|
-
//#region ../../../alepha/src/server/errors/HttpError.d.ts
|
|
112
|
+
//#region ../../../alepha/src/server/core/errors/HttpError.d.ts
|
|
113
113
|
declare class HttpError extends AlephaError {
|
|
114
114
|
name: string;
|
|
115
115
|
static is: (error: unknown, status?: number) => error is HttpErrorLike;
|
|
@@ -172,11 +172,11 @@ interface Tree<T extends Route> {
|
|
|
172
172
|
};
|
|
173
173
|
}
|
|
174
174
|
//#endregion
|
|
175
|
-
//#region ../../../alepha/src/server/constants/routeMethods.d.ts
|
|
175
|
+
//#region ../../../alepha/src/server/core/constants/routeMethods.d.ts
|
|
176
176
|
declare const routeMethods: readonly ["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS", "CONNECT", "TRACE"];
|
|
177
177
|
type RouteMethod = (typeof routeMethods)[number];
|
|
178
178
|
//#endregion
|
|
179
|
-
//#region ../../../alepha/src/server/helpers/ServerReply.d.ts
|
|
179
|
+
//#region ../../../alepha/src/server/core/helpers/ServerReply.d.ts
|
|
180
180
|
/**
|
|
181
181
|
* Helper for building server replies.
|
|
182
182
|
*/
|
|
@@ -204,7 +204,7 @@ declare class ServerReply {
|
|
|
204
204
|
setBody(body: any): this;
|
|
205
205
|
}
|
|
206
206
|
//#endregion
|
|
207
|
-
//#region ../../../alepha/src/server/services/UserAgentParser.d.ts
|
|
207
|
+
//#region ../../../alepha/src/server/core/services/UserAgentParser.d.ts
|
|
208
208
|
interface UserAgentInfo {
|
|
209
209
|
os: "Windows" | "Android" | "Ubuntu" | "MacOS" | "iOS" | "Linux" | "FreeBSD" | "OpenBSD" | "ChromeOS" | "BlackBerry" | "Symbian" | "Windows Phone";
|
|
210
210
|
browser: "Chrome" | "Firefox" | "Safari" | "Edge" | "Opera" | "Internet Explorer" | "Brave" | "Vivaldi" | "Samsung Browser" | "UC Browser" | "Yandex";
|
|
@@ -220,7 +220,7 @@ declare class UserAgentParser {
|
|
|
220
220
|
parse(userAgent?: string): UserAgentInfo;
|
|
221
221
|
}
|
|
222
222
|
//#endregion
|
|
223
|
-
//#region ../../../alepha/src/server/interfaces/ServerRequest.d.ts
|
|
223
|
+
//#region ../../../alepha/src/server/core/interfaces/ServerRequest.d.ts
|
|
224
224
|
type TRequestBody = TObject | TString | TArray | TRecord | TStream;
|
|
225
225
|
type TResponseBody = TObject | TString | TRecord | TFile | TArray | TStream | TVoid;
|
|
226
226
|
interface RequestConfigSchema {
|
|
@@ -541,7 +541,7 @@ declare module "alepha" {
|
|
|
541
541
|
}
|
|
542
542
|
}
|
|
543
543
|
//#endregion
|
|
544
|
-
//#region ../../../alepha/src/server/services/ServerRequestParser.d.ts
|
|
544
|
+
//#region ../../../alepha/src/server/core/services/ServerRequestParser.d.ts
|
|
545
545
|
declare class ServerRequestParser {
|
|
546
546
|
protected readonly alepha: Alepha;
|
|
547
547
|
protected readonly userAgentParser: UserAgentParser;
|
|
@@ -551,7 +551,7 @@ declare class ServerRequestParser {
|
|
|
551
551
|
getRequestIp(request: ServerRequestData): string | undefined;
|
|
552
552
|
}
|
|
553
553
|
//#endregion
|
|
554
|
-
//#region ../../../alepha/src/server/providers/ServerTimingProvider.d.ts
|
|
554
|
+
//#region ../../../alepha/src/server/core/providers/ServerTimingProvider.d.ts
|
|
555
555
|
type TimingMap = Record<string, [number, number]>;
|
|
556
556
|
declare class ServerTimingProvider {
|
|
557
557
|
protected readonly log: Logger;
|
|
@@ -568,7 +568,7 @@ declare class ServerTimingProvider {
|
|
|
568
568
|
protected setDuration(name: string, timing: TimingMap): void;
|
|
569
569
|
}
|
|
570
570
|
//#endregion
|
|
571
|
-
//#region ../../../alepha/src/server/providers/ServerRouterProvider.d.ts
|
|
571
|
+
//#region ../../../alepha/src/server/core/providers/ServerRouterProvider.d.ts
|
|
572
572
|
/**
|
|
573
573
|
* Main router for all routes on the server side.
|
|
574
574
|
*
|
|
@@ -607,7 +607,7 @@ declare class ServerRouterProvider extends RouterProvider<ServerRouteMatcher> {
|
|
|
607
607
|
}, request: ServerRequestConfig): void;
|
|
608
608
|
}
|
|
609
609
|
//#endregion
|
|
610
|
-
//#region ../../../alepha/src/server/providers/ServerProvider.d.ts
|
|
610
|
+
//#region ../../../alepha/src/server/core/providers/ServerProvider.d.ts
|
|
611
611
|
/**
|
|
612
612
|
* Base server provider to handle incoming requests and route them.
|
|
613
613
|
*
|
|
@@ -646,7 +646,7 @@ declare class ServerProvider {
|
|
|
646
646
|
protected isViteNotFound(url?: string, route?: Route, params?: Record<string, string>): boolean;
|
|
647
647
|
}
|
|
648
648
|
//#endregion
|
|
649
|
-
//#region ../../../alepha/src/cache/providers/CacheProvider.d.ts
|
|
649
|
+
//#region ../../../alepha/src/cache/core/providers/CacheProvider.d.ts
|
|
650
650
|
/**
|
|
651
651
|
* Cache provider interface.
|
|
652
652
|
*
|
|
@@ -689,7 +689,7 @@ declare abstract class CacheProvider {
|
|
|
689
689
|
abstract clear(): Promise<void>;
|
|
690
690
|
}
|
|
691
691
|
//#endregion
|
|
692
|
-
//#region ../../../alepha/src/cache/primitives/$cache.d.ts
|
|
692
|
+
//#region ../../../alepha/src/cache/core/primitives/$cache.d.ts
|
|
693
693
|
interface CachePrimitiveOptions<TReturn = any, TParameter extends any[] = any[]> {
|
|
694
694
|
/**
|
|
695
695
|
* The cache name. This is useful for invalidating multiple caches at once.
|
|
@@ -756,7 +756,7 @@ interface CachePrimitiveFn<TReturn = any, TParameter extends any[] = any[]> exte
|
|
|
756
756
|
(...args: TParameter): Promise<TReturn>;
|
|
757
757
|
}
|
|
758
758
|
//#endregion
|
|
759
|
-
//#region ../../../alepha/src/server/services/HttpClient.d.ts
|
|
759
|
+
//#region ../../../alepha/src/server/core/services/HttpClient.d.ts
|
|
760
760
|
declare class HttpClient {
|
|
761
761
|
protected readonly log: Logger;
|
|
762
762
|
protected readonly alepha: Alepha;
|
|
@@ -828,7 +828,7 @@ interface HttpAction {
|
|
|
828
828
|
};
|
|
829
829
|
}
|
|
830
830
|
//#endregion
|
|
831
|
-
//#region ../../../alepha/src/server/primitives/$action.d.ts
|
|
831
|
+
//#region ../../../alepha/src/server/core/primitives/$action.d.ts
|
|
832
832
|
interface ActionPrimitiveOptions<TConfig extends RequestConfigSchema> extends Omit<ServerRoute, "handler" | "path" | "schema" | "mapParams"> {
|
|
833
833
|
/**
|
|
834
834
|
* Name of the action.
|
|
@@ -963,7 +963,7 @@ type ServerActionHandler<TConfig extends RequestConfigSchema = RequestConfigSche
|
|
|
963
963
|
*/
|
|
964
964
|
interface ServerActionRequest<TConfig extends RequestConfigSchema> extends ServerRequest<TConfig> {}
|
|
965
965
|
//#endregion
|
|
966
|
-
//#region ../../../alepha/src/server/providers/BunHttpServerProvider.d.ts
|
|
966
|
+
//#region ../../../alepha/src/server/core/providers/BunHttpServerProvider.d.ts
|
|
967
967
|
declare const envSchema$1: alepha22.TObject<{
|
|
968
968
|
SERVER_PORT: alepha22.TInteger;
|
|
969
969
|
SERVER_HOST: alepha22.TString;
|
|
@@ -972,7 +972,7 @@ declare module "alepha" {
|
|
|
972
972
|
interface Env extends Partial<Static<typeof envSchema$1>> {}
|
|
973
973
|
}
|
|
974
974
|
//#endregion
|
|
975
|
-
//#region ../../../alepha/src/server/providers/NodeHttpServerProvider.d.ts
|
|
975
|
+
//#region ../../../alepha/src/server/core/providers/NodeHttpServerProvider.d.ts
|
|
976
976
|
declare const envSchema: alepha22.TObject<{
|
|
977
977
|
SERVER_PORT: alepha22.TInteger;
|
|
978
978
|
SERVER_HOST: alepha22.TString;
|
|
@@ -981,7 +981,7 @@ declare module "alepha" {
|
|
|
981
981
|
interface Env extends Partial<Static<typeof envSchema>> {}
|
|
982
982
|
}
|
|
983
983
|
//#endregion
|
|
984
|
-
//#region ../../../alepha/src/server/index.d.ts
|
|
984
|
+
//#region ../../../alepha/src/server/core/index.d.ts
|
|
985
985
|
declare module "alepha" {
|
|
986
986
|
interface State {
|
|
987
987
|
"alepha.node.server"?: Server;
|
package/dist/i18n/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as alepha7 from "alepha";
|
|
2
2
|
import { Alepha, Async, KIND, LogLevel, LoggerInterface, Primitive, Static, TSchema, TypeBoxError } from "alepha";
|
|
3
3
|
import dayjsDuration from "dayjs/plugin/duration.js";
|
|
4
4
|
import DayjsApi, { Dayjs, ManipulateType, PluginFunc } from "dayjs";
|
|
@@ -15,8 +15,8 @@ declare class DateTimeProvider {
|
|
|
15
15
|
protected readonly timeouts: Timeout[];
|
|
16
16
|
protected readonly intervals: Interval[];
|
|
17
17
|
constructor();
|
|
18
|
-
protected readonly onStart:
|
|
19
|
-
protected readonly onStop:
|
|
18
|
+
protected readonly onStart: alepha7.HookPrimitive<"start">;
|
|
19
|
+
protected readonly onStop: alepha7.HookPrimitive<"stop">;
|
|
20
20
|
setLocale(locale: string): void;
|
|
21
21
|
isDateTime(value: unknown): value is DateTime;
|
|
22
22
|
/**
|
|
@@ -138,15 +138,15 @@ interface LocalizeProps {
|
|
|
138
138
|
declare const Localize: (props: LocalizeProps) => string | number;
|
|
139
139
|
//#endregion
|
|
140
140
|
//#region ../../../alepha/src/logger/schemas/logEntrySchema.d.ts
|
|
141
|
-
declare const logEntrySchema:
|
|
142
|
-
level:
|
|
143
|
-
message:
|
|
144
|
-
service:
|
|
145
|
-
module:
|
|
146
|
-
context:
|
|
147
|
-
app:
|
|
148
|
-
data:
|
|
149
|
-
timestamp:
|
|
141
|
+
declare const logEntrySchema: alepha7.TObject<{
|
|
142
|
+
level: alepha7.TUnsafe<"SILENT" | "TRACE" | "DEBUG" | "INFO" | "WARN" | "ERROR">;
|
|
143
|
+
message: alepha7.TString;
|
|
144
|
+
service: alepha7.TString;
|
|
145
|
+
module: alepha7.TString;
|
|
146
|
+
context: alepha7.TOptional<alepha7.TString>;
|
|
147
|
+
app: alepha7.TOptional<alepha7.TString>;
|
|
148
|
+
data: alepha7.TOptional<alepha7.TAny>;
|
|
149
|
+
timestamp: alepha7.TNumber;
|
|
150
150
|
}>;
|
|
151
151
|
type LogEntry = Static<typeof logEntrySchema>;
|
|
152
152
|
//#endregion
|
|
@@ -188,7 +188,7 @@ declare class Logger implements LoggerInterface {
|
|
|
188
188
|
}
|
|
189
189
|
//#endregion
|
|
190
190
|
//#region ../../../alepha/src/logger/index.d.ts
|
|
191
|
-
declare const envSchema:
|
|
191
|
+
declare const envSchema: alepha7.TObject<{
|
|
192
192
|
/**
|
|
193
193
|
* Default log level for the application.
|
|
194
194
|
*
|
|
@@ -205,14 +205,14 @@ declare const envSchema: alepha16.TObject<{
|
|
|
205
205
|
* LOG_LEVEL=my.module.name:debug,info # Set debug level for my.module.name and info for all other modules
|
|
206
206
|
* LOG_LEVEL=alepha:trace, info # Set trace level for all alepha modules and info for all other modules
|
|
207
207
|
*/
|
|
208
|
-
LOG_LEVEL:
|
|
208
|
+
LOG_LEVEL: alepha7.TOptional<alepha7.TString>;
|
|
209
209
|
/**
|
|
210
210
|
* Built-in log formats.
|
|
211
211
|
* - "json" - JSON format, useful for structured logging and log aggregation. {@link JsonFormatterProvider}
|
|
212
212
|
* - "pretty" - Simple text format, human-readable, with colors. {@link PrettyFormatterProvider}
|
|
213
213
|
* - "raw" - Raw format, no formatting, just the message. {@link RawFormatterProvider}
|
|
214
214
|
*/
|
|
215
|
-
LOG_FORMAT:
|
|
215
|
+
LOG_FORMAT: alepha7.TOptional<alepha7.TUnsafe<"json" | "pretty" | "raw">>;
|
|
216
216
|
}>;
|
|
217
217
|
declare module "alepha" {
|
|
218
218
|
interface Env extends Partial<Static<typeof envSchema>> {}
|
|
@@ -230,7 +230,7 @@ declare module "alepha" {
|
|
|
230
230
|
}
|
|
231
231
|
}
|
|
232
232
|
//#endregion
|
|
233
|
-
//#region ../../../alepha/src/server
|
|
233
|
+
//#region ../../../alepha/src/server/cookies/primitives/$cookie.d.ts
|
|
234
234
|
interface CookiePrimitiveOptions<T extends TSchema> {
|
|
235
235
|
/** The schema for the cookie's value, used for validation and type safety. */
|
|
236
236
|
schema: T;
|
|
@@ -283,7 +283,7 @@ interface Cookie {
|
|
|
283
283
|
domain?: string;
|
|
284
284
|
}
|
|
285
285
|
//#endregion
|
|
286
|
-
//#region ../../../alepha/src/server
|
|
286
|
+
//#region ../../../alepha/src/server/cookies/index.d.ts
|
|
287
287
|
declare module "alepha/server" {
|
|
288
288
|
interface ServerRequest {
|
|
289
289
|
cookies: Cookies;
|
|
@@ -312,7 +312,7 @@ declare class I18nProvider<S extends object, K$1 extends keyof ServiceDictionary
|
|
|
312
312
|
protected log: Logger;
|
|
313
313
|
protected alepha: Alepha;
|
|
314
314
|
protected dateTimeProvider: DateTimeProvider;
|
|
315
|
-
protected cookie: AbstractCookiePrimitive<
|
|
315
|
+
protected cookie: AbstractCookiePrimitive<alepha7.TString>;
|
|
316
316
|
readonly registry: Array<{
|
|
317
317
|
target: string;
|
|
318
318
|
name: string;
|
|
@@ -331,11 +331,11 @@ declare class I18nProvider<S extends object, K$1 extends keyof ServiceDictionary
|
|
|
331
331
|
};
|
|
332
332
|
get languages(): string[];
|
|
333
333
|
constructor();
|
|
334
|
-
protected readonly onRender:
|
|
335
|
-
protected readonly onStart:
|
|
334
|
+
protected readonly onRender: alepha7.HookPrimitive<"server:onRequest">;
|
|
335
|
+
protected readonly onStart: alepha7.HookPrimitive<"start">;
|
|
336
336
|
protected refreshLocale(): void;
|
|
337
337
|
setLang: (lang: string) => Promise<void>;
|
|
338
|
-
protected readonly mutate:
|
|
338
|
+
protected readonly mutate: alepha7.HookPrimitive<"state:mutate">;
|
|
339
339
|
get lang(): string;
|
|
340
340
|
translate: (key: string, args?: string[]) => string;
|
|
341
341
|
readonly l: (value: I18nLocalizeType, options?: I18nLocalizeOptions) => string | number;
|
|
@@ -431,7 +431,7 @@ declare module "alepha" {
|
|
|
431
431
|
*
|
|
432
432
|
* @module alepha.react.i18n
|
|
433
433
|
*/
|
|
434
|
-
declare const AlephaReactI18n:
|
|
434
|
+
declare const AlephaReactI18n: alepha7.Service<alepha7.Module>;
|
|
435
435
|
//#endregion
|
|
436
436
|
export { $dictionary, AlephaReactI18n, DictionaryPrimitive, DictionaryPrimitiveOptions, I18nLocalizeOptions, I18nLocalizeType, I18nProvider, Localize, type LocalizeProps, ServiceDictionary, useI18n };
|
|
437
437
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as alepha55 from "alepha";
|
|
2
2
|
import { Primitive, Static, TObject, TString, TUnion } from "alepha";
|
|
3
3
|
|
|
4
4
|
//#region ../../../alepha/src/websocket/primitives/$channel.d.ts
|
|
@@ -40,21 +40,21 @@ interface ChannelPrimitiveOptions<TClient extends TWSObject, TServer extends TWS
|
|
|
40
40
|
declare class ChannelPrimitive<TClient extends TWSObject, TServer extends TWSObject> extends Primitive<ChannelPrimitiveOptions<TClient, TServer>> {}
|
|
41
41
|
//#endregion
|
|
42
42
|
//#region ../../../alepha/src/logger/schemas/logEntrySchema.d.ts
|
|
43
|
-
declare const logEntrySchema:
|
|
44
|
-
level:
|
|
45
|
-
message:
|
|
46
|
-
service:
|
|
47
|
-
module:
|
|
48
|
-
context:
|
|
49
|
-
app:
|
|
50
|
-
data:
|
|
51
|
-
timestamp:
|
|
43
|
+
declare const logEntrySchema: alepha55.TObject<{
|
|
44
|
+
level: alepha55.TUnsafe<"SILENT" | "TRACE" | "DEBUG" | "INFO" | "WARN" | "ERROR">;
|
|
45
|
+
message: alepha55.TString;
|
|
46
|
+
service: alepha55.TString;
|
|
47
|
+
module: alepha55.TString;
|
|
48
|
+
context: alepha55.TOptional<alepha55.TString>;
|
|
49
|
+
app: alepha55.TOptional<alepha55.TString>;
|
|
50
|
+
data: alepha55.TOptional<alepha55.TAny>;
|
|
51
|
+
timestamp: alepha55.TNumber;
|
|
52
52
|
}>;
|
|
53
53
|
type LogEntry = Static<typeof logEntrySchema>;
|
|
54
54
|
//#endregion
|
|
55
55
|
//#region ../../../alepha/src/logger/index.d.ts
|
|
56
56
|
|
|
57
|
-
declare const envSchema$2:
|
|
57
|
+
declare const envSchema$2: alepha55.TObject<{
|
|
58
58
|
/**
|
|
59
59
|
* Default log level for the application.
|
|
60
60
|
*
|
|
@@ -71,14 +71,14 @@ declare const envSchema$2: alepha53.TObject<{
|
|
|
71
71
|
* LOG_LEVEL=my.module.name:debug,info # Set debug level for my.module.name and info for all other modules
|
|
72
72
|
* LOG_LEVEL=alepha:trace, info # Set trace level for all alepha modules and info for all other modules
|
|
73
73
|
*/
|
|
74
|
-
LOG_LEVEL:
|
|
74
|
+
LOG_LEVEL: alepha55.TOptional<alepha55.TString>;
|
|
75
75
|
/**
|
|
76
76
|
* Built-in log formats.
|
|
77
77
|
* - "json" - JSON format, useful for structured logging and log aggregation. {@link JsonFormatterProvider}
|
|
78
78
|
* - "pretty" - Simple text format, human-readable, with colors. {@link PrettyFormatterProvider}
|
|
79
79
|
* - "raw" - Raw format, no formatting, just the message. {@link RawFormatterProvider}
|
|
80
80
|
*/
|
|
81
|
-
LOG_FORMAT:
|
|
81
|
+
LOG_FORMAT: alepha55.TOptional<alepha55.TUnsafe<"json" | "pretty" | "raw">>;
|
|
82
82
|
}>;
|
|
83
83
|
declare module "alepha" {
|
|
84
84
|
interface Env extends Partial<Static<typeof envSchema$2>> {}
|
|
@@ -97,10 +97,10 @@ declare module "alepha" {
|
|
|
97
97
|
}
|
|
98
98
|
//#endregion
|
|
99
99
|
//#region ../../../alepha/src/websocket/services/WebSocketClient.d.ts
|
|
100
|
-
declare const envSchema$1:
|
|
101
|
-
WEBSOCKET_URL:
|
|
102
|
-
WEBSOCKET_RECONNECT_INTERVAL:
|
|
103
|
-
WEBSOCKET_MAX_RECONNECT_ATTEMPTS:
|
|
100
|
+
declare const envSchema$1: alepha55.TObject<{
|
|
101
|
+
WEBSOCKET_URL: alepha55.TString;
|
|
102
|
+
WEBSOCKET_RECONNECT_INTERVAL: alepha55.TInteger;
|
|
103
|
+
WEBSOCKET_MAX_RECONNECT_ATTEMPTS: alepha55.TInteger;
|
|
104
104
|
}>;
|
|
105
105
|
declare module "alepha" {
|
|
106
106
|
interface Env extends Partial<Static<typeof envSchema$1>> {}
|
|
@@ -113,8 +113,8 @@ declare module "alepha" {
|
|
|
113
113
|
*/
|
|
114
114
|
//#endregion
|
|
115
115
|
//#region ../../../alepha/src/websocket/providers/NodeWebSocketServerProvider.d.ts
|
|
116
|
-
declare const envSchema:
|
|
117
|
-
WEBSOCKET_PATH:
|
|
116
|
+
declare const envSchema: alepha55.TObject<{
|
|
117
|
+
WEBSOCKET_PATH: alepha55.TString;
|
|
118
118
|
}>;
|
|
119
119
|
declare module "alepha" {
|
|
120
120
|
interface Env extends Partial<Static<typeof envSchema>> {}
|
package/package.json
CHANGED
|
@@ -2,38 +2,37 @@
|
|
|
2
2
|
"name": "@alepha/react",
|
|
3
3
|
"description": "React components and hooks for building Alepha applications.",
|
|
4
4
|
"author": "Nicolas Foures",
|
|
5
|
-
"version": "0.13.
|
|
5
|
+
"version": "0.13.8",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"engines": {
|
|
8
8
|
"node": ">=22.0.0"
|
|
9
9
|
},
|
|
10
10
|
"license": "MIT",
|
|
11
|
-
"main": "./dist/index.js",
|
|
12
|
-
"types": "./dist/index.d.ts",
|
|
11
|
+
"main": "./dist/core/index.js",
|
|
12
|
+
"types": "./dist/core/index.d.ts",
|
|
13
13
|
"files": [
|
|
14
14
|
"dist",
|
|
15
15
|
"src",
|
|
16
16
|
"assets"
|
|
17
17
|
],
|
|
18
|
-
"bin": "./dist/index.js",
|
|
19
18
|
"dependencies": {
|
|
20
19
|
"@vitejs/plugin-react": "^5.1.2",
|
|
21
|
-
"react-dom": "^19
|
|
20
|
+
"react-dom": "^19"
|
|
22
21
|
},
|
|
23
22
|
"devDependencies": {
|
|
24
|
-
"@biomejs/biome": "^2.3.
|
|
23
|
+
"@biomejs/biome": "^2.3.10",
|
|
25
24
|
"@testing-library/dom": "^10.4.1",
|
|
26
|
-
"@testing-library/react": "^16.3.
|
|
27
|
-
"@types/react": "^19
|
|
28
|
-
"@types/react-dom": "^19
|
|
29
|
-
"alepha": "0.13.
|
|
25
|
+
"@testing-library/react": "^16.3.1",
|
|
26
|
+
"@types/react": "^19",
|
|
27
|
+
"@types/react-dom": "^19",
|
|
28
|
+
"alepha": "0.13.8",
|
|
30
29
|
"jsdom": "^27.3.0",
|
|
31
|
-
"react": "^19.2.
|
|
32
|
-
"vitest": "^4.0.
|
|
30
|
+
"react": "^19.2.3",
|
|
31
|
+
"vitest": "^4.0.16"
|
|
33
32
|
},
|
|
34
33
|
"peerDependencies": {
|
|
35
|
-
"alepha": "0.13.
|
|
36
|
-
"react": "^19
|
|
34
|
+
"alepha": "0.13.8",
|
|
35
|
+
"react": "^19"
|
|
37
36
|
},
|
|
38
37
|
"scripts": {
|
|
39
38
|
"lint": "alepha lint",
|
|
@@ -56,41 +55,40 @@
|
|
|
56
55
|
],
|
|
57
56
|
"exports": {
|
|
58
57
|
"./auth": {
|
|
59
|
-
"types": "./dist/auth/index.
|
|
58
|
+
"types": "./dist/auth/index.d.ts",
|
|
60
59
|
"react-native": "./dist/auth/index.browser.js",
|
|
61
60
|
"browser": "./dist/auth/index.browser.js",
|
|
62
61
|
"import": "./dist/auth/index.js",
|
|
63
62
|
"default": "./dist/auth/index.js"
|
|
64
63
|
},
|
|
65
64
|
".": {
|
|
66
|
-
"types": "./dist/core/index.
|
|
65
|
+
"types": "./dist/core/index.d.ts",
|
|
67
66
|
"react-native": "./dist/core/index.native.js",
|
|
68
67
|
"browser": "./dist/core/index.browser.js",
|
|
69
68
|
"import": "./dist/core/index.js",
|
|
70
69
|
"default": "./dist/core/index.js"
|
|
71
70
|
},
|
|
72
71
|
"./form": {
|
|
73
|
-
"types": "./dist/form/index.
|
|
72
|
+
"types": "./dist/form/index.d.ts",
|
|
74
73
|
"import": "./dist/form/index.js",
|
|
75
74
|
"default": "./dist/form/index.js"
|
|
76
75
|
},
|
|
77
76
|
"./head": {
|
|
78
|
-
"types": "./dist/head/index.
|
|
77
|
+
"types": "./dist/head/index.d.ts",
|
|
79
78
|
"react-native": "./dist/head/index.browser.js",
|
|
80
79
|
"browser": "./dist/head/index.browser.js",
|
|
81
80
|
"import": "./dist/head/index.js",
|
|
82
81
|
"default": "./dist/head/index.js"
|
|
83
82
|
},
|
|
84
83
|
"./i18n": {
|
|
85
|
-
"types": "./dist/i18n/index.
|
|
84
|
+
"types": "./dist/i18n/index.d.ts",
|
|
86
85
|
"import": "./dist/i18n/index.js",
|
|
87
86
|
"default": "./dist/i18n/index.js"
|
|
88
87
|
},
|
|
89
88
|
"./websocket": {
|
|
90
|
-
"types": "./dist/websocket/index.
|
|
89
|
+
"types": "./dist/websocket/index.d.ts",
|
|
91
90
|
"import": "./dist/websocket/index.js",
|
|
92
91
|
"default": "./dist/websocket/index.js"
|
|
93
92
|
}
|
|
94
|
-
}
|
|
95
|
-
"module": "./dist/index.js"
|
|
93
|
+
}
|
|
96
94
|
}
|