/**
* React framework for decentralized apps.
*
* ## Purpose
*
* The `framework` module is the highest-level abstraction provided by the Self.ID SDK, aimed at
* helping developers to quickly get started with building decentralized apps using Ceramic with
* React.
*
* The framework is built on top of the {@linkcode core}, {@linkcode web} and {@linkcode react}
* modules to provide APIs to easily authenticate users, keep track of the current user and
* interact with both public (read-only) and user-owned (mutable) records.
*
* ## Installation
*
* ```sh
* npm install @self.id/framework
* ```
*
* ## Common use-cases
*
* ### Configure the Provider
*
* The {@linkcode react.Provider Provider} component must be added at the root of the
* application tree in order to use the hooks described below. It can be used to provide a custom
* configuration for the Self.ID clients, authentication, state and UI options.
*
* ```ts
* import { Provider } from '@self.id/framework'
*
* function App({ children }) {
* return
* An injected Ethereum provider such as{' '} * MetaMask is needed to authenticate. *
* ) * } * ``` * * ### Interact with a viewer record * * The {@linkcode react.useViewerRecord useViewerRecord} hook loads the record for a given * definition in the index of the current viewer, with the following variants: * * - If no viewer is set, no record can be loaded * - If the viewer is not authenticated, the record gets loaded but cannot be mutated * - If the viewer is authenticated, the record gets loaded and be mutated * * ```ts * import { useViewerRecord } from '@self.id/framework' * * // Load and display the record contents * function ShowViewerName() { * const record = useViewerRecord('basicProfile') * * const text = record.isLoading * ? 'Loading...' * : record.content * ? `Hello ${record.content.name || 'stranger'}` * : 'No profile to load' * return{text}
* } * * // Mutate the record * function SetViewerName() { * const record = useViewerRecord('basicProfile') * * return ( * * ) * } * ``` * * ### Read a public record * * The {@linkcode react.usePublicRecord usePublicRecord} hook is similar to the * `useViewerRecord` hook described above, but reading from the index of an explicitly provided * account rather than the viewer. Public records are read-only, `useViewerRecord` must be used in * case mutations are needed. * * ```ts * import { usePublicRecord } from '@self.id/framework' * * function ShowProfileName({ did }) { * const record = usePublicRecord('basicProfile', did) * * const text = record.isLoading * ? 'Loading...' * : record.content * ? `Hello ${record.content.name || 'stranger'}` * : 'No profile to load' * return{text}
* } * ``` * * ### Server-side prefetching * * Server-side rendering can be used to improve the user experience for the first load of an app or * page. The framework exports a {@linkcode react.RequestClient RequestClient} class from the * {@linkcode react @self.id/react} package that can be used to fetch wanted records on the server * in order to have them immediately available by the `usePublicRecord` and `useViewerRecord` * hooks. * * The following example shows how this can be used in a [Next.js](https://nextjs.org/) page, using * the `ShowViewerName` component created in the previous example: * * ```ts * import { Provider, RequestClient } from '@self.id/framework' * * export const getServerSideProps = async (ctx) => { * const client = new RequestClient({ * ceramic: 'testnet-clay', * // Inject the cookie from the request headers to parse the viewerID * cookie: ctx.req.headers.cookie, * }) * if (client.viewerID != null) { * // If the viewerID is set, fetch its profile * await client.prefetch('basicProfile', client.viewerID) * } * return { props: { state: client.getState() } } * } * * // Use the state prop injected by the server * export default function Home({ state }) { * return ( *