# API Reference

This document provides a comprehensive reference for the `@zubridge/electron` API.

## Backend (Main Process) APIs

### Bridge APIs

#### `createCoreBridge(stateManager, windows?)`

Creates a core bridge between the main process and renderer processes, using any state manager that implements the `StateManager` interface. This is useful for creating custom bridges with state management libraries not directly supported by Zubridge.

##### Parameters:

- `stateManager`: Implementation of the `StateManager<State>` interface
- `windows?`: Optional array of `BrowserWindow`, `BrowserView`, `WebContentsView`, or `WebContents` instances to subscribe to the store. Can be empty or undefined.

##### Returns:

A `CoreBridge` object with:

- `subscribe(windows)`: Function to subscribe additional windows to the state updates. Returns an object with an `unsubscribe` method.
- `unsubscribe(windows?)`: Function to unsubscribe windows from updates. When called without arguments, unsubscribes all windows.
- `getSubscribedWindows()`: Function to get all currently subscribed window IDs.
- `destroy()`: Function to clean up resources used by the bridge.

##### Example:

```ts
import { app, BrowserWindow } from 'electron';
import { createCoreBridge } from '@zubridge/electron/main';
import { myStateManager } from './state-manager';

const mainWindow = new BrowserWindow({
  /* options */
});

// Create bridge without initial windows (subscribe later)
const bridge = createCoreBridge(myStateManager);

// Or create with initial windows
const bridgeWithWindows = createCoreBridge(myStateManager, [mainWindow]);

// Subscribe additional windows later
const secondWindow = new BrowserWindow(/* options */);
const subscription = bridge.subscribe([secondWindow]);

// Unsubscribe when quitting
app.on('quit', bridge.unsubscribe);
```

#### `createZustandBridge(store, windows?, options?)`

Creates a bridge between a Zustand store in the main process and renderer processes. This is the recommended way to integrate a Zustand store with Electron's IPC system.

##### Parameters:

- `store`: The Zustand store to bridge
- `windows?`: Optional array of `BrowserWindow`, `BrowserView`, `WebContentsView`, or `WebContents` instances to subscribe to the store. Can be empty or undefined.
- `options`: Optional configuration object
  - `handlers`: Optional object containing store handler functions
  - `reducer`: Optional root reducer function for Redux-style state management

##### Returns:

A `ZustandBridge` object with:

- `subscribe(windows)`: Function to subscribe additional windows to the store updates. Returns an object with an `unsubscribe` method.
- `unsubscribe(windows?)`: Function to unsubscribe windows from the store. When called without arguments, unsubscribes all windows.
- `getSubscribedWindows()`: Function to get all currently subscribed window IDs.
- `dispatch`: Function to dispatch actions to the store.
- `destroy()`: Function to clean up resources used by the bridge.

##### Example:

```ts
import { app, BrowserWindow } from 'electron';
import { createZustandBridge } from '@zubridge/electron/main';
import { store } from './store';

const mainWindow = new BrowserWindow({
  /* options */
});

// Create bridge with initial windows
const { unsubscribe, subscribe, dispatch } = createZustandBridge(store, [mainWindow]);

// Or create without windows and subscribe later
const bridge = createZustandBridge(store);
const subscription = bridge.subscribe([mainWindow]);

// Using with handlers option
const bridgeWithHandlers = createZustandBridge(store, [mainWindow], {
  handlers: {
    CUSTOM_ACTION: (payload) => {
      console.log('Custom action received:', payload);
      store.setState((state) => ({ ...state, customValue: payload }));
    },
  },
});

// Using with reducer option
const bridgeWithReducer = createZustandBridge(store, [mainWindow], {
  reducer: (state, action) => {
    switch (action.type) {
      case 'SET_VALUE':
        return { ...state, value: action.payload };
      default:
        return state;
    }
  },
});

// Dispatch actions from the main process
dispatch('INCREMENT');

// Unsubscribe when quitting
app.on('quit', unsubscribe);
```

#### `createReduxBridge(store, windows?, options?)`

Creates a bridge between a Redux store in the main process and renderer processes. This is the recommended way to integrate a Redux store with Electron's IPC system.

##### Parameters:

- `store`: The Redux store to bridge
- `windows?`: Optional array of `BrowserWindow`, `BrowserView`, `WebContentsView`, or `WebContents` instances to subscribe to the store. Can be empty or undefined.
- `options`: Optional configuration object for customizing store integration

##### Returns:

A `ReduxBridge` object with:

- `subscribe(windows)`: Function to subscribe additional windows to the store updates. Returns an object with an `unsubscribe` method.
- `unsubscribe(windows?)`: Function to unsubscribe windows from the store. When called without arguments, unsubscribes all windows.
- `getSubscribedWindows()`: Function to get all currently subscribed window IDs.
- `dispatch`: Function to dispatch actions to the store.
- `destroy()`: Function to clean up resources used by the bridge.

##### Example:

```ts
import { app, BrowserWindow } from 'electron';
import { createReduxBridge } from '@zubridge/electron/main';
import { store } from './redux-store';

const mainWindow = new BrowserWindow({
  /* options */
});

// Create bridge with initial windows
const { unsubscribe, subscribe, dispatch } = createReduxBridge(store, [mainWindow]);

// Or create without windows and subscribe later
const bridge = createReduxBridge(store);
const subscription = bridge.subscribe([mainWindow]);

// Dispatch actions from the main process
dispatch({ type: 'INCREMENT' });

// Unsubscribe when quitting
app.on('quit', unsubscribe);
```

#### `mainZustandBridge(store, windows, options?)` (Deprecated)

**Deprecated:** This is now an alias for `createZustandBridge` and uses the new IPC channels. Please migrate to `createZustandBridge`.

##### Parameters and returns:

Same as `createZustandBridge`.

### Dispatch APIs

#### `createDispatch(store, options?)`

Creates a dispatch function that can be used in the main process to dispatch actions to the store. This function supports both Zustand and Redux stores.

##### Parameters:

- `store`: Either a Zustand store (`StoreApi<State>`) or Redux store (`Store<State>`)
- `options?`: Optional configuration object
  - For Zustand stores: can include `handlers` or `reducer` options
  - For Redux stores: can include Redux-specific integration options

##### Returns:

A function that can dispatch actions to the store. This dispatch function supports:

- String action types with optional payload
- Action objects with type and payload
- Thunk functions for complex logic

##### Example:

```ts
import { createDispatch } from '@zubridge/electron/main';
import { myStore } from './store';

// Create dispatch function
export const dispatch = createDispatch(myStore);

// Use the dispatch function
dispatch('INCREMENT');

// Dispatch with a payload
dispatch('SET_VALUE', 42);

// Dispatch an action object
dispatch({ type: 'SET_VALUE', payload: 42 });

// Dispatch a thunk function
dispatch((getState, dispatch) => {
  const currentState = getState();
  if (currentState.counter < 10) {
    dispatch('INCREMENT');
  }
});
```

##### Internal API: createDispatch with StateManager

There's also an internal overload that accepts a state manager directly, but this is primarily for internal use by bridge implementations.

## Frontend (Renderer Process) APIs

### Preload Script APIs

#### `preloadBridge()`

Creates handlers for the renderer process to interact with the main process through the backend contract.

##### Returns:

An object with a `handlers` property that should be exposed to the renderer process.

##### Example:

```ts
// preload.js
import { contextBridge } from 'electron';
import { preloadBridge } from '@zubridge/electron/preload';

const { handlers } = preloadBridge();

// Expose the handlers to the renderer process
contextBridge.exposeInMainWorld('zubridge', handlers);
```

#### `preloadZustandBridge()` (Deprecated)

**Deprecated:** This is now an alias for `preloadBridge` and uses the new IPC channels. Please migrate to `preloadBridge`.

##### Returns:

Same as `preloadBridge`.

### Renderer Process Hooks

#### `createUseStore<State>(customHandlers?)`

Function that creates a hook to access the store state in the renderer process.

##### Parameters:

- `customHandlers`: Optional custom handlers to use instead of `window.zubridge`
- `State`: Type parameter representing your application state

##### Returns:

A hook that can be used to select state from the store.

##### Example:

```ts
// hooks/useStore.ts
import { createUseStore } from '@zubridge/electron';
import type { AppState } from '../types';

export const useStore = createUseStore<AppState>();

// Component.tsx
import { useStore } from './hooks/useStore';

function Counter() {
  const counter = useStore(state => state.counter);
  return <div>{counter}</div>;
}
```

#### `useDispatch<State>(customHandlers?)`

Hook to dispatch actions to the store from the renderer process.

##### Parameters:

- `customHandlers`: Optional custom handlers to use instead of `window.zubridge`
- `State`: Type parameter representing your application state
- `ActionTypes`: Optional generic type parameter for typed action objects

##### Returns:

A dispatch function that can be used to send actions to the main process.

##### Example:

```ts
import { useDispatch } from '@zubridge/electron';
import type { AppState } from '../types';

function Counter() {
  const dispatch = useDispatch<AppState>();

  // Dispatch a string action
  const handleIncrement = () => dispatch('INCREMENT');

  // Dispatch an action with payload
  const handleSetCounter = (value) => dispatch('SET_COUNTER', value);

  // Dispatch an action object
  const handleCustomIncrement = (amount) => dispatch({
    type: 'INCREMENT_BY',
    payload: amount
  });

  // Dispatch with typed actions
  const typedDispatch = useDispatch<AppState, { 'SET_COUNTER': number }>();
  const handleTypedSetCounter = (value: number) => typedDispatch({
    type: 'SET_COUNTER',
    payload: value // Type checked to be a number
  });

  // Dispatch a thunk for complex logic
  const handleFetchAndUpdate = () => dispatch(async (getState, dispatch) => {
    const response = await fetch('/api/counter');
    const data = await response.json();
    dispatch('SET_COUNTER', data.value);
  });

  return (
    <div>
      <button onClick={handleIncrement}>+1</button>
      <button onClick={() => handleSetCounter(0)}>Reset</button>
      <button onClick={() => handleCustomIncrement(5)}>+5</button>
      <button onClick={() => handleTypedSetCounter(10)}>Set to 10 (Typed)</button>
      <button onClick={handleFetchAndUpdate}>Fetch</button>
    </div>
  );
}
```

## Type Definitions and Interfaces

### `StateManager<State>`

Interface that defines the contract for state managers used with the bridge. Any state management solution can be integrated with the bridge system by implementing this interface.

```ts
interface StateManager<State> {
  getState: () => State;
  subscribe: (listener: (state: State) => void) => () => void;
  processAction: (action: Action) => void;
}
```

### `CoreBridge`

Interface for the bridge created by `createCoreBridge`.

```ts
interface CoreBridge extends BaseBridge<number> {
  subscribe: (wrappers: WebContentsWrapper[]) => { unsubscribe: () => void };
  unsubscribe: (wrappers?: WebContentsWrapper[]) => void;
  getSubscribedWindows: () => number[];
  destroy: () => void;
}
```

### `ZustandBridge`

Interface for the bridge created by `createZustandBridge`.

```ts
interface ZustandBridge extends BackendBridge<number> {
  subscribe: (windows: WrapperOrWebContents[]) => { unsubscribe: () => void };
  unsubscribe: (windows?: WrapperOrWebContents[]) => void;
  getSubscribedWindows: () => number[];
  dispatch: Dispatch<S>;
  destroy: () => void;
}
```

### `ReduxBridge`

Interface for the bridge created by `createReduxBridge`.

```ts
interface ReduxBridge extends BackendBridge<number> {
  subscribe: (windows: WrapperOrWebContents[]) => { unsubscribe: () => void };
  unsubscribe: (windows?: WrapperOrWebContents[]) => void;
  getSubscribedWindows: () => number[];
  dispatch: Dispatch<S>;
  destroy: () => void;
}
```

### `BaseBridge<WindowId>`

Base interface that all bridge implementations extend.

```ts
interface BaseBridge<WindowId> {
  unsubscribe: (...args: any[]) => void;
  getSubscribedWindows: () => WindowId[];
}
```

### `Action`

Represents a Redux-style action with a type and optional payload.

```ts
type Action<T extends string = string> = {
  type: T;
  payload: unknown;
};
```

### `Thunk<State>`

Represents a thunk function for handling asynchronous logic.

```ts
type Thunk<State> = (getState: StoreApi<State>['getState'], dispatch: Dispatch<State>) => void;
```

### `ZustandOptions<State>`

Configuration options for the Zustand bridge.

```ts
type ZustandOptions<State extends AnyState> = {
  handlers?: Record<string, Handler>;
  reducer?: RootReducer<State>;
};
```

### `ReduxOptions<State>`

Configuration options for the Redux bridge.

```ts
type ReduxOptions<State extends AnyState> = {
  // Custom options for Redux integration
};
```

### `WebContentsWrapper`

Represents any Electron object that has WebContents. This includes BrowserWindow, BrowserView, and WebContentsView.

```ts
type WrapperOrWebContents = WebContents | { webContents: WebContents; isDestroyed?: () => boolean };
```

### `Handlers<State>`

Interface for the handlers exposed to the renderer process.

```ts
interface Handlers<State extends AnyState> extends BaseHandler<State> {
  getState(): Promise<State>;
  subscribe(callback: (newState: State) => void): () => void;
}
```
