# Data Sharing

### <mark style="color:red;">Overview</mark>

It provides a flexible API to share data effectively, ensuring that each component within your ecosystem can access application data easily.

{% hint style="info" %}
Data shared with micro-applications is **read-only**. Clients cannot modify the shared data directly.
{% endhint %}

### <mark style="color:red;">How It Works</mark>

Data sharing is facilitated through a combination of React context and the [framebus](https://github.com/braintree/framebus) library for cross-origin communication. This setup ensures that micro-frontends running in isolated iframes can receive shared data seamlessly.

#### Flow

1. **Initialization** - `AppShellProvider` initializes with the shared data
2. **Client Connection** - When a client iframe loads, it sends a `SET_CONFIG` event
3. **Data Distribution** - Shell responds with `SET_DATA` containing the shared data
4. **Updates** - When shared data changes, shell broadcasts updates to all connected clients

### <mark style="color:red;">Usage</mark>

Pass the `data` prop to `AppShellProvider`:

```tsx
import { AppShellProvider, type ApplicationData } from '@akinon/app-shell';

const App = () => {
  const data: ApplicationData = {
    user: {
      id: 1,
      name: 'Jane Doe',
      email: 'jane@example.com'
    },
    theme: 'dark',
    locale: 'en'
  };

  return (
    <AppShellProvider
      apps={registeredApps}
      data={data}
      navigation={navigationConfig}
      actions={shellActions}
    >
      {/* Your shell application */}
    </AppShellProvider>
  );
};
```

### <mark style="color:red;">ApplicationData Type</mark>

```typescript
interface ApplicationData {
  searchParams?: Record<string, string>;
  [key: string]: any;
}
```

The `ApplicationData` type is flexible, allowing you to share any serializable data. The optional `searchParams` field is commonly used for URL query parameters.

#### Example Data Structure

```typescript
const sharedData: ApplicationData = {
  // User information
  user: {
    id: 123,
    name: 'John Doe',
    role: 'admin'
  },
  
  // Application settings
  settings: {
    theme: 'dark',
    language: 'tr',
    timezone: 'Europe/Istanbul'
  },
  
  // URL parameters
  searchParams: {
    page: '1',
    limit: '20'
  }
};
```

### <mark style="color:red;">Dynamic Data Updates</mark>

When shared data changes, update the `data` prop and the changes will be propagated to all connected clients:

```tsx
import { useState } from 'react';
import { AppShellProvider } from '@akinon/app-shell';

const App = () => {
  const [sharedData, setSharedData] = useState<ApplicationData>({
    user: null,
    theme: 'light'
  });

  const handleLogin = (user: User) => {
    setSharedData(prev => ({
      ...prev,
      user
    }));
  };

  const toggleTheme = () => {
    setSharedData(prev => ({
      ...prev,
      theme: prev.theme === 'light' ? 'dark' : 'light'
    }));
  };

  return (
    <AppShellProvider
      apps={registeredApps}
      data={sharedData}
      navigation={navigationConfig}
      actions={shellActions}
    >
      <button onClick={toggleTheme}>Toggle Theme</button>
      {/* Rest of your application */}
    </AppShellProvider>
  );
};
```

### <mark style="color:red;">Accessing Shared Data (Client Side)</mark>

Clients access shared data via the `useAppClient` hook:

```tsx
// In the client application
import { useAppClient } from '@akinon/app-client';

const ClientComponent = () => {
  const { data } = useAppClient();

  return (
    <div>
      <p>Welcome, {data.user?.name}</p>
      <p>Theme: {data.theme}</p>
    </div>
  );
};
```

{% hint style="info" %}
For detailed information about accessing data on the client side, see the [Client Application](/akinon-ui/ui-protocol/client-application.md) documentation.
{% endhint %}

### <mark style="color:red;">Best Practices</mark>

#### 1. Share Only Necessary Data

Avoid sharing the entire application state. Share only the data that micro-applications need for their functionality.

```tsx
// ❌ Bad - Sharing entire Redux store
const data = {
  ...entireReduxStore
};

// ✅ Good - Selective data sharing
const data = {
  user: store.getState().auth.user,
  locale: store.getState().settings.locale
};
```

#### 2. Avoid Data Duplication

Clients should not copy shared data into their own state. Always reference the shared data from `useAppClient`.

```tsx
// ❌ Bad - Duplicating data in client state
const ClientComponent = () => {
  const { data } = useAppClient();
  const [user, setUser] = useState(data.user); // Don't do this!
  
  return <div>{user.name}</div>;
};

// ✅ Good - Direct reference to shared data
const ClientComponent = () => {
  const { data } = useAppClient();
  
  return <div>{data.user?.name}</div>;
};
```

#### 3. Use Serializable Data Only

Only serializable data can be shared via postMessage. Functions, class instances, and circular references cannot be shared.

```tsx
// ❌ Bad - Non-serializable data
const data = {
  user: userInstance,           // Class instance
  formatDate: (d) => d.toISOString(), // Function
  element: document.getElementById('app') // DOM element
};

// ✅ Good - Serializable data only
const data = {
  user: {
    id: userInstance.id,
    name: userInstance.name
  },
  dateFormat: 'ISO',
  elementId: 'app'
};
```

{% hint style="warning" %}
See [MDN Structured Clone Algorithm](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm) for the full list of supported types.
{% endhint %}

#### 4. Keep Data Flat When Possible

Deeply nested data structures can be harder to work with and may impact performance during serialization.

```tsx
// Consider flattening when appropriate
const data = {
  userId: 123,
  userName: 'John Doe',
  userRole: 'admin',
  // Instead of: user: { id, name, role }
};
```

### <mark style="color:red;">Next Steps</mark>

* [Actions](/akinon-ui/ui-protocol/shell-application/configuration/actions.md) - Define custom actions for clients
* [Navigation](/akinon-ui/ui-protocol/shell-application/configuration/navigation.md) - Configure navigation helpers


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.akinon.com/akinon-ui/ui-protocol/shell-application/configuration/data-sharing.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
