// Copyright 2024 The Lynx Authors. All rights reserved.
// Licensed under the Apache License Version 2.0 that can be found in the
// LICENSE file in the root directory of this source tree.
import { render } from 'preact';
import { createContext, createElement } from 'preact/compat';
import { useState } from 'preact/hooks';
import { useLynxGlobalEventListener } from './core/hooks/useLynxGlobalEventListener.js';
import { __root } from './root.js';
import { profileEnd, profileStart } from './shared/profile.js';
import { factory, withInitDataInState } from './snapshot/compat/initData.js';
import { LifecycleConstant } from './snapshot/lifecycle/constant.js';
import { flushDelayedLifecycleEvents } from './snapshot/lynx/tt.js';
/**
 * The default and only root of ReactLynx for you to render JSX
 * @example
 * ```ts
 * import { root } from "@lynx-js/react"
 * ```
 *
 * @public
 */
export const root = {
    render: (jsx) => {
        /* v8 ignore next 2 */
        if (typeof __MAIN_THREAD__ !== 'undefined' && __MAIN_THREAD__) {
            __root.__jsx = jsx;
        }
        else {
            __root.__jsx = jsx;
            if (typeof __PROFILE__ !== 'undefined' && __PROFILE__) {
                profileStart('ReactLynx::renderBackground');
            }
            // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
            render(jsx, __root);
            if (typeof __PROFILE__ !== 'undefined' && __PROFILE__) {
                profileEnd();
            }
            if (__FIRST_SCREEN_SYNC_TIMING__ === 'immediately') {
                // This is for cases where `root.render()` is called asynchronously,
                // `firstScreen` message might have been reached.
                flushDelayedLifecycleEvents();
            }
            else {
                lynx.getNativeApp().callLepusMethod(LifecycleConstant.jsReady, {});
            }
        }
    },
    /* v8 ignore next 3 */
    registerDataProcessors: (dataProcessorDefinition) => {
        lynx.registerDataProcessors(dataProcessorDefinition);
    },
};
const _InitData = /* @__PURE__ */ factory({
    createContext,
    useState,
    createElement,
    useLynxGlobalEventListener,
}, '__initData', 'onDataChanged');
/**
 * The {@link https://react.dev/reference/react/createContext#provider | Provider} Component that provide `initData`,
 * you must wrap your JSX inside it
 * @group Components
 *
 * @example
 *
 * ```ts
 * import { root } from "@lynx-js/react"
 *
 * function App() {
 *   return (
 *     <InitDataConsumer children={(initData) => <view>...</view>}/>
 *   )
 * }
 *
 * root.render(
 *   <InitDataProvider>
 *      <App/>
 *   </InitDataProvider>
 * );
 *
 * ```
 *
 * @public
 */
// @ts-expect-error make preact and react types work
export const InitDataProvider = /* @__PURE__ */ _InitData.Provider();
/**
 * The {@link https://react.dev/reference/react/createContext#consumer | Consumer} Component that provide `initData`.
 * This should be used with {@link InitDataProvider}
 * @group Components
 * @public
 */
// @ts-expect-error make preact and react types work
export const InitDataConsumer = /* @__PURE__ */ _InitData.Consumer();
/**
 * A React Hooks for you to get `initData`.
 * If `initData` is changed, a re-render will be triggered automatically.
 *
 * @example
 *
 * ```ts
 * function App() {
 *   const initData = useInitData();
 *
 *   initData.someProperty // use it
 * }
 * ```
 *
 * @public
 */
export const useInitData = /* @__PURE__ */ _InitData.use();
/**
 * A React Hooks for you to get notified when `initData` changed.
 *
 * @example
 * ```ts
 * function App() {
 *   useInitDataChanged((data) => {
 *     data.someProperty // can use it
 *   })
 * }
 * ```
 * @public
 */
export const useInitDataChanged = /* @__PURE__ */ _InitData.useChanged();
const _GlobalProps = typeof __GLOBAL_PROPS_MODE__ !== 'undefined' && __GLOBAL_PROPS_MODE__ === 'event'
    ? /* @__PURE__ */ factory({
        createContext,
        useState,
        createElement,
        useLynxGlobalEventListener,
    }, '__globalProps', 'onGlobalPropsChanged')
    : /* @__PURE__ */ createFallbackGlobalProps();
function warnGlobalPropsMode() {
    if (typeof __LEPUS__ !== 'undefined' && !__LEPUS__ && typeof __DEV__ !== 'undefined' && __DEV__) {
        console.warn(`No need to use this API when 'globalPropsMode' is not 'event', `
            + `updates will be triggered automatically by full re-render. `
            + `Please set 'globalPropsMode' to 'event' to enable optimized updates.`);
    }
}
function createFallbackGlobalProps() {
    return {
        Provider: () => {
            return ({ children }) => {
                warnGlobalPropsMode();
                return children;
            };
        },
        Consumer: () => {
            return ({ children }) => {
                warnGlobalPropsMode();
                return children(lynx.__globalProps);
            };
        },
        use: () => {
            return () => {
                warnGlobalPropsMode();
                return lynx.__globalProps;
            };
        },
        useChanged: () => {
            return (callback) => {
                if (!__LEPUS__) {
                    useLynxGlobalEventListener('onGlobalPropsChanged', callback);
                }
            };
        },
    };
}
/**
 * The {@link https://react.dev/reference/react/createContext#provider | Provider} Component that provide `lynx.__globalProps`,
 * you must wrap your JSX inside it
 * @group Components
 *
 * @example
 *
 * ```ts
 * import { root } from "@lynx-js/react"
 *
 * function App() {
 *   return (
 *     <GlobalPropsConsumer children={(globalProps) => <view>...</view>}/>
 *   )
 * }
 *
 * root.render(
 *   <GlobalPropsProvider>
 *      <App/>
 *   </GlobalPropsProvider>
 * );
 *
 * ```
 *
 * @public
 */
// @ts-expect-error make preact and react types work
export const GlobalPropsProvider = /* @__PURE__ */ _GlobalProps.Provider();
/**
 * The {@link https://react.dev/reference/react/createContext#consumer | Consumer} Component that provide `lynx.__globalProps`.
 * This should be used with {@link GlobalPropsProvider}
 * @group Components
 * @public
 */
// @ts-expect-error make preact and react types work
export const GlobalPropsConsumer = /* @__PURE__ */ _GlobalProps.Consumer();
/**
 * A React Hooks for you to get `lynx.__globalProps`.
 * If `lynx.__globalProps` is changed, a re-render will be triggered automatically.
 *
 * @example
 *
 * ```ts
 * function App() {
 *   const globalProps = useGlobalProps();
 *
 *   globalProps.someProperty // use it
 * }
 * ```
 *
 * @public
 */
export const useGlobalProps = /* @__PURE__ */ _GlobalProps.use();
/**
 * A React Hooks for you to get notified when `__globalProps` changed.
 *
 * @example
 * ```ts
 * function App() {
 *   useGlobalPropsChanged((data) => {
 *     lynx.__globalProps.someProperty // can use lynx.__globalProps
 *     data.someProperty // can use data
 *   })
 * }
 * ```
 * @public
 */
export const useGlobalPropsChanged = /* @__PURE__ */ _GlobalProps
    .useChanged();
export { withInitDataInState };
export { useLynxGlobalEventListener } from './core/hooks/useLynxGlobalEventListener.js';
export { runOnBackground } from './snapshot/worklet/call/runOnBackground.js';
export { runOnMainThread } from './snapshot/worklet/call/runOnMainThread.js';
export { MainThreadRef, useMainThreadRef } from './snapshot/worklet/ref/workletRef.js';
//# sourceMappingURL=lynx-api.js.map