import * as _vue_reactivity from '@vue/reactivity';
import { ref, shallowRef, reactive, shallowReactive, effect, effectScope, stop, computed, readonly, shallowReadonly } from '@vue/reactivity';
export { enableTracking, pauseTracking, toReadonly } from '@vue/reactivity';
import { InjectionToken, ClassProvider, FactoryProvider, ValueProvider, TokenProvider, DependencyContainer } from 'tsyringe';
export { delay, inject } from 'tsyringe';
import { FC, ReactElement, PropsWithChildren } from 'react';
import * as react_jsx_runtime from 'react/jsx-runtime';

type Constructor<T = any> = new (...args: any[]) => T;
type InstanceLifecycle = 'singleton' | 'transient' | 'container' | 'resolution';
type RegistrationObject<T = any> = {
    token: InjectionToken<T>;
    provider: ClassProvider<T>;
    lifecycle: InstanceLifecycle;
} | {
    token: InjectionToken<T>;
    provider: FactoryProvider<T> | ValueProvider<T> | TokenProvider<T>;
};
type Registration = Constructor | RegistrationObject | [Constructor, InstanceLifecycle] | [InjectionToken, ClassProvider<any>['useClass']] | [InjectionToken, ClassProvider<any>['useClass'], InstanceLifecycle]
/**
 * Must be a plain js object
 * Given object will be provided as a shallow reactive object with the given injection token
 * Changes in the object properties will be reflected as reactive properties
 */
 | [InjectionToken, object];
type ProviderProps<P extends object = object> = {
    provide: Registration[];
    props?: P;
    /**
     * Normally provided services are created lazily when they are first resolved.
     * If this option is set to true, all provided singleton services will be created immediately.
     */
    initializeSingletons?: boolean;
};
type Registrations = ProviderProps['provide'];
type Dispose = () => void;
interface RendererViewModel {
    render(): ReactElement | null;
}
type TriggerCleanup = (cleanup: () => void) => void;
type ReactiveComponent<P extends object> = FC<P> & {
    provide: (...args: Registrations) => FC<P>;
};
interface ServiceProps<P extends object = object> {
    props: P;
}
type ServicePropsType<T extends InjectionToken, TDefault = any> = T extends Constructor ? InstanceType<T> extends ServiceProps<infer P> ? P : TDefault : TDefault;

declare function component<P extends object>(component: FC<P>): ReactiveComponent<P>;
declare namespace component {
    var fromViewModel: {
        <T extends Constructor<RendererViewModel>>(viewModel: T): FC<ServicePropsType<T, object>>;
        <P extends object>(viewModel: Constructor<RendererViewModel>): FC<P>;
    };
}

declare function useResolve<T extends Constructor>(token: T): InstanceType<T>;
declare function useResolve<T extends Constructor>(token: T, props: ServicePropsType<T>): InstanceType<T>;

declare function useService<T extends Constructor>(service: T): InstanceType<T>;
declare function useService<T>(token: InjectionToken): T;

declare function useViewModel<T extends Constructor>(viewModel: T): InstanceType<T>;

declare function injectable<T extends Constructor>(): (target: T) => void;

declare function provide(registrations: ProviderProps<any>['provide']): <T extends Constructor>(target: T) => void;

declare class Container {
    private container;
    constructor(container: DependencyContainer);
    resolve<T extends Constructor>(token: T, props?: ServicePropsType<T>): InstanceType<T>;
    resolve<T>(token: InjectionToken): T;
    resolveAll: DependencyContainer['resolveAll'];
    register: DependencyContainer['register'];
    isRegistered: DependencyContainer['isRegistered'];
}

declare const Props: InjectionToken;

/**
 * @onDispose decorator
 * @description This decorator is used to mark a method as a dispose method. It will automatically
 * create a dispose function that will be called when the instance is disposed by the disposal of the parent dependency container.
 *
 * The method can also accept an optional Cleanup function as a parameter.
 *
 * @example
 * \@onDispose
 *  dispose() {
 *     // do something
 *  }
 */
declare function onDispose(target: any, propertyKey: string): void;

/**
 * This decorator is used to mark a method as an init method.
 * Init methods are called after the instance is created and all the decorators are processed
 * Takes an optional cleanup function as a parameter.
 * The cleanup function will be called when the instance is disposed by the disposal of the parent dependency container.
 *```ts
 * \@onInit
 *public init(cleanup: Cleanup) {
 *  const abortController = new AbortController()
 *  cleanup(() => {
 *    abortController.abort()
 *  })
 *
 *  const response = await loadData(this.state.id, abortController.signal);
 *  // do something
 *}
 *```
 */
declare function onInit(target: any, propertyKey: string): void;

/**
 * This decorator is used to mark a method as an onMount method.
 * It will automatically create a mount function that will be called when the containing ServiceProvider or Component is mounted
 * The method can also accept an optional Cleanup function which will be called when containing ServiceProvider or Component is unmounted.
 *```ts
 * \@onMount
 *  public mount(cleanup: Cleanup) {
 *     // do something
 *  }
 * ```
 */
declare function onMount(target: any, propertyKey: string): void;

/**
 * @onUnmount decorator
 * @description This decorator is used to mark a method as an onUnmount method.
 * It will automatically create a unmount function that will be called when the containing ServiceProvider or Component is unmounted
 * @example
 * \@onUnmount
 *  unmount() {
 *     // do something
 *  }
 */
declare function onUnmount(target: any, propertyKey: string): void;

declare function ServiceProvider<P extends object>({ provide, children, props, initializeSingletons, }: PropsWithChildren<ProviderProps<P>>): react_jsx_runtime.JSX.Element;

/**
 * This decorator is used to mark a property as a derived property. It will automatically
 * create a computed property that will be updated when the reactive dependencies change.
 * The property must be a getter function.
 */
declare function derived(target: any, propertyKey: string, descriptor: PropertyDescriptor): any;

type StateType = 'shallow' | 'deep' | 'atom' | 'default';
/**
 * @state decorator
 * @description This decorator is used to mark a property as a reactive state. reactivity level is 'deep' by default.
 * you can configure it using the 'configure' function
 */
declare function state(target: any, propertyKey: string): any;
declare namespace state {
    var shallow: typeof shallowState;
    var atom: typeof atomState;
    var deep: typeof deepState;
}
/**
 * @state.shallow decorator
 * @description This decorator is used to mark a property as a shallow reactive state. Reactivity by 1st level properties of
 * object, arrays, maps, sets
 * @link https://vuejs.org/api/reactivity-advanced.html#shallowreactive
 */
declare function shallowState(target: any, propertyKey: string): any;
/**
 * @state.atom decorator
 * @description This decorator is used to mark a property as an atom reactive state. Reactivity by re-assignment
 * @link https://vuejs.org/api/reactivity-advanced.html#shallowref
 */
declare function atomState(target: any, propertyKey: string): any;
/**
 * @state.deep decorator
 * @description This decorator is used to mark a property as a deep reactive state. Reactive to deep mutations
 * @link https://vuejs.org/api/reactivity-core.html#ref
 */
declare function deepState(target: any, propertyKey: string): any;

/**
 * This decorator is used to mark a method as a trigger. It will automatically
 * create a reactive effect that will call the method when the reactive dependencies change.
 * The method can also accept an optional Cleanup function as a parameter.
 *```ts
 *  @trigger
 *  public fetchData(cleanup: Cleanup) {
 *   const abortController = new AbortController()
 *   cleanup(() => {
 *     abortController.abort()
 *   })
 *
 *   const response = await loadData(this.state.id, abortController.signal);
 *   // do something
 * }
 *```
 */
declare function trigger(target: any, propertyKey: string): any;
declare namespace trigger {
    var async: (target: any, propertyKey: string) => any;
    var debounce: (ms: number) => (target: any, propertyKey: string) => any;
    var throttle: (ms: number) => (target: any, propertyKey: string) => any;
}

/**
 * Disables dependency tracking within the provided function's execution context.
 * Reactive properties accessed inside the function will not be tracked as dependencies,
 * meaning changes to them will not trigger reactive updates for the current effect scope.
 * This can be useful in triggers, derived computations, or component renders where
 * you want to access reactive data without establishing a dependency.
 * ```ts
 * \@state firstName = 'John'
 * \@state lastName = 'Doe'
 *
 * \@trigger
 * public logFullName() {
 *   const fullName = this.firstName + untrack(() => this.lastName);
 *   console.log(fullName); // Will log only when firstName changes
 * });
 * ```
 */
declare function untrack<T extends () => any>(fn: T): ReturnType<T>;

type ResolutionParams = {
    token: InjectionToken;
    instance: any;
    container: DependencyContainer;
};
type Configuration = {
    readonlyProxiesForView: boolean;
    defaultStateReactiveLevel: Exclude<StateType, 'default'>;
    devtools?: boolean;
    afterResolve?(params: ResolutionParams): any;
};
declare function configure(options: Partial<Configuration>): void;

declare const Reactivity: {
    readonly ref: typeof ref;
    readonly shallowRef: typeof shallowRef;
    readonly reactive: typeof reactive;
    readonly shallowReactive: typeof shallowReactive;
    readonly effect: typeof effect;
    readonly effectScope: typeof effectScope;
    readonly stop: typeof stop;
    readonly computed: typeof computed;
    readonly readonly: typeof readonly;
    readonly shallowReadonly: typeof shallowReadonly;
};
type DecoratorInitializer = (instance: any, propertyKey: string, reactivity: typeof Reactivity) => Dispose | void;
type Decorator = (target: any, propertyKey: string) => void;
declare function createDecorator(initializer: DecoratorInitializer): Decorator;

declare function toRaw<T>(value: T): T;
declare function toRaw<T>(value: T, deep: boolean): T;

/**
 * A hook that creates a shallow reactive object from source object and updates it when object properties changes.
 * @returns A referentially stable shallow reactive object that reflects the current state of the props.
 */
declare function useReactiveObject<P extends object>(obj?: P): Readonly<_vue_reactivity.ShallowReactive<P>> | undefined;

export { Container, Props, ServiceProvider, component, configure, createDecorator, derived, injectable, onDispose, onInit, onMount, onUnmount, provide, state, toRaw, trigger, untrack, useReactiveObject, useResolve, useService, useViewModel };
export type { TriggerCleanup as Cleanup, Constructor, DecoratorInitializer, InstanceLifecycle, ProviderProps, Registration, Registrations, RendererViewModel, ServiceProps };
