Options
All
  • Public
  • Public/Protected
  • All
Menu

React-Pond

Use the Actyx Pond framework fully integrated into React. Expand your toolchain with <Pond>, useFish, and usePond to speed up your UI projects and write distributed apps in a couple of hours.

📦 Installation

React-Pond is available as a npm package.

npm install @actyx-contrib/react-pond

📖 Documentation and detailed examples

You can access the full API documentation and related examples by visiting: https://actyx-contrib.github.io/react-pond

You will find detailed examples here. They can be executed running e.g. `npm run example:chatRoom'.

🤓 Quick start

🌊 <Pond>...</Pond>

Wrap your application with the <Pond> to use you fish everywhere in the code.

Example

ReactDOM.render(
  <Pond
    manifest={{
      appId: 'com.example.react-pond-example',
      displayName: 'React Pond Example',
      version: '0.0.1'
    }}
    onError={() => {
      setTimeout(() => location.reload(), 5000)
      return <div>Connection to Actyx rejected: {JSON.stringify(e)}. Next reconnect in 5 seconds.</div>
    }}
  >
    <AmazingDistributedApp />
  </Pond>,
  document.getElementById('root')!,
)

🐟 useFish and useFishFn

Write your distributed logic with the well-known fish and get the state as easy as possible.

  • useFish(fish): Hydrate one explicit fish without a factory
  • useFishFn(fishFactory, properties): Use a factory function to hydrate fish with properties

📖 Example

const MaterialRequest = ({ id }: Props) => {
  const allOpenMatReq = useFish(MatRequest.allOpen)
  const matReq = useFishFn(MatRequest.of, id)

  return (
    <div>
      <div>Open Material Requests: {allOpenMatReq.ids.length}</div>
      <div>
        Material Request ({id}): {matReq.state.status}
      </div>
      <button
        onClick={() =>
          matReq.run((_state, enqueue) => enqueue(Tag('material').withId(id), EventType.Done))
        }
      >
        Done
      </button>
    </div>
  )
}

🎏 useRegistryFish

Map your registry fish to the entities and create tables, lists, complex autocomplete fields, ...

📖 Example

const MaterialRequests = () => {
  const allOpenMatReq = useRegistryFish(MatRequest.allOpen, reg => reg.ids, MatRequestFish.of)

  const done = (matReq: ReactFish<State, Events, string>) => {
    matReq.run((_state, enqueue) => enqueue(Tag('material').withId(matReq.props), EventType.Done))
  }

  return (
    <div>
      <div>Open Material Requests: {allOpenMatReq.length}</div>
      {allOpenMatReq.map(matReq => (
        <div key={matReq.props}>
          <div>
            {matReq.props}: {matReq.state.status}
          </div>
          <button onClick={() => done(matReq)}>Done</button>
        </div>
      ))}
    </div>
  )
}

🌊 usePond

The pond is not hidden from you. Use it as usual with const pond = usePond().

📖 Example

export const App = () => {
  const pond = usePond()
  const { info, getPondState } = pond 
  const [pondState, setPondState] = React.useState<PondState>()
  React.useEffect(() => {
    getPondState(setPondState)
  }, [])

  return (
    <div>
      <hr />
      <h3>Pond State</h3>
      <pre>{JSON.stringify(pondState, undefined, 2)}</pre>
      <hr />
      <h3>Pond Info</h3>
      <pre>{JSON.stringify(info(), undefined, 2)}</pre>
    </div>
  )
}

Index

Type aliases

PondProps

PondProps: { children: React.ReactNode; connectionOpts?: ActyxOpts; loadComponent?: JSX.Element; manifest: AppManifest; onError: (error: unknown) => void | Element; opts?: PondOptions }

Pond component properties to get some feedback

Type declaration

  • children: React.ReactNode

    React application. Components are shown when the initialize is done

  • Optional connectionOpts?: ActyxOpts

    Optionally change the Actyx endpoint the Pond connects to and provide an error handler if the connection to Actyx is dropped. Defaults to {}

  • Optional loadComponent?: JSX.Element

    Component to show during the connect (very shortly)

  • manifest: AppManifest

    Manifest describing an Actyx application. Used for authorizing API access. Use com.example.<somestring> as appId for testing and development purposes, so you don't require a signed certificate.

    Example:

    {
      appId: 'com.example.react-pond-example',
      displayName: 'React Pond Example',
      version: '0.0.1'
    }
  • onError: (error: unknown) => void | Element

    Error callback the the pond is not able to reach actyxOS locally

      • (error: unknown): void | Element
      • Parameters

        • error: unknown

        Returns void | Element

  • Optional opts?: PondOptions

    Advanced Pond configuration options. Defaults to {}

ReactFish

ReactFish<State, Event, Props>: { props: Props; run: (eff: StateEffect<State, Event>) => Promise<void>; state: State }

ReactFish type.

This fish will handle all interactions with the React component.

Type parameters

  • State

  • Event

  • Props

Type declaration

  • props: Props

    props of the fish

  • run: (eff: StateEffect<State, Event>) => Promise<void>

    run function for the observed fish

      • (eff: StateEffect<State, Event>): Promise<void>
      • Parameters

        • eff: StateEffect<State, Event>

        Returns Promise<void>

  • state: State

    current public state of the observed fish

Functions

Const Pond

  • Pond(__namedParameters: { children: undefined | null | string | number | false | true | {} | ReactElement<any, string | ((props: P) => ReactElement | null) | {}> | ReactNodeArray | ReactPortal; connectionOpts: undefined | {}; loadComponent: undefined | Element; manifest: {}; onError: (error: unknown) => void | Element; opts: undefined | { fishErrorReporter?: FishErrorReporter } }): Element
  • Top level component to initialize the pond

    Minimal example:

    ReactDOM.render(
      <Pond
        onError={onError}
        manifest={{
          appId: 'io.actyx.react-pond-example',
          displayName: 'React Pond Example',
          version: '0.0.1',
          signature: 'v2tz...JBPT3/'
        }}
      >
        <App />
      </Pond>,
      document.getElementById('root')
    )

    Complete example:

    ReactDOM.render(
      <Pond
        onError={onError}
        manifest={{
          appId: 'io.actyx.react-pond-example',
          displayName: 'React Pond Example',
          version: '0.0.1',
          signature: 'v2tz...JBPT3/'
        }}
        connectionOpts={{
          actyxHost: 'actyx',
          actyxPort: 4232,
          onConnectionLost: onConnectionLostHandler
        }}
        opts={{
          fishErrorReporter: fishErrorReporter
        }}
      >
        <App />
      </Pond>,
      document.getElementById('root')
    )

    Parameters

    • __namedParameters: { children: undefined | null | string | number | false | true | {} | ReactElement<any, string | ((props: P) => ReactElement | null) | {}> | ReactNodeArray | ReactPortal; connectionOpts: undefined | {}; loadComponent: undefined | Element; manifest: {}; onError: (error: unknown) => void | Element; opts: undefined | { fishErrorReporter?: FishErrorReporter } }

      reactProperties for the pond @see PondProps

      • children: undefined | null | string | number | false | true | {} | ReactElement<any, string | ((props: P) => ReactElement | null) | {}> | ReactNodeArray | ReactPortal
      • connectionOpts: undefined | {}
      • loadComponent: undefined | Element
      • manifest: {}
      • onError: (error: unknown) => void | Element
          • (error: unknown): void | Element
          • Parameters

            • error: unknown

            Returns void | Element

      • opts: undefined | { fishErrorReporter?: FishErrorReporter }

    Returns Element

    React component

Const useFish

  • useFish<State, Events>(fish: Fish<State, Events>): ReactFish<State, Events, void>
  • Stateful integration of an actyx Pond Fish.

    Learn more about the fish: https://developer.actyx.com/docs/pond/getting-started

    Example:

    export const App = () => {
      const chatRoomsFish = useFish(ChatRoomFish.channelList)
    
      return (
        <div>
          <div>List of existing chat rooms</div>
          <ul>
            {chatRoomsFish.map((name) => <li key={name}>{name}</li>)}
          </ul>
        </div>
      )
    }

    Type parameters

    • State

    • Events

    Parameters

    • fish: Fish<State, Events>

      fish to get the public state for

    Returns ReactFish<State, Events, void>

    ReactFish

Const useFishFn

  • useFishFn<State, Events, Props>(mkFish: (props: Props) => Fish<State, Events>, props: Props | undefined): ReactFish<State, Events, Props> | void
  • Stateful integration of an actyx Pond Fish factory.

    Learn more about the fish: https://developer.actyx.com/docs/pond/getting-started

    Example:

    export const App = () => {
      const [channel, setChannel] = React.useState('lobby')
      const chatRoomFish = useFishFn(ChatRoomFish.forChannel, channel)
    
      const send = () =>
        chatRoomFish && chatRoomFish.run((_state, enqueue) =>
          enqueue(ChatRoom.tags.channel.withId(channel), {
            type: 'message',
            message,
            sender: userName,
            channel
          })
        )
    
      return (
        <div>
          {chatRoomFish && (
            <>
              <div>current chat room: {chatRoomFish.props}</div>
              <div>
                {chatRoomFish.state.map((message, idx) => (
                  <div key={idx}>{message}</div>
                ))}
              </div>
              <div>
                <button onClick={send}>send</button>
              </div>
            </>
          )}
        </div>
      )
    }

    Type parameters

    • State

    • Events

    • Props

    Parameters

    • mkFish: (props: Props) => Fish<State, Events>
        • (props: Props): Fish<State, Events>
        • Parameters

          • props: Props

          Returns Fish<State, Events>

    • props: Props | undefined

      props for the factory

    Returns ReactFish<State, Events, Props> | void

    ReactFish | undefined If the props are undefined

Const usePond

  • usePond(): PondType
  • Get the pond in your react application.

    Learn more about the pond: https://developer.actyx.com/docs/pond/getting-started

    emit<E>(tags: Tags<E>, event: E): PendingEmission;
    observe<S, E>(fish: Fish<S, E>, callback: (newState: S) => void): CancelSubscription;
    run<S, EWrite>(fish: Fish<S, any>, fn: StateEffect<S, EWrite>): PendingEmission;
    keepRunning<S, EWrite>(fish: Fish<S, any>, fn: StateEffect<S, EWrite>, autoCancel?: (state: S) => boolean): CancelSubscription;
    dispose(): void;
    info(): PondInfo;
    getPondState(callback: (newState: PondState) => void): CancelSubscription;
    getNodeConnectivity(params: GetNodeConnectivityParams): CancelSubscription;
    waitForSwarmSync(params: WaitForSwarmSyncParams): void;
    throws

    Error if is not used before

    Returns PondType

    pond instance

Const useRegistryFish

  • useRegistryFish<RegState, State, Events, Props>(regFish: Fish<RegState, any>, map: (regState: RegState) => (undefined | Props)[], mkFish: (props: Props) => Fish<State, Events>): ReactFish<State, Events, Props>[]
  • Stateful integration of an actyx Pond Fish factory.

    Learn more about the fish: https://developer.actyx.com/docs/pond/getting-started

    Example:

    export const App = () => {
      const allChatRooms = useRegistryFish(ChatRoom.channelList, (s) => s, ChatRoom.forChannel)
    
      return (
        <div>
         {allChatRooms.map(f => (
           <div key={f.props}>{f.props}: {f.state.join(', ')}</div>
         ))}
        </div>
      )
    }

    Type parameters

    • RegState

    • State

    • Events

    • Props

    Parameters

    • regFish: Fish<RegState, any>

      fish to get the public state for, or fish factory function

    • map: (regState: RegState) => (undefined | Props)[]

      map the registry state to an array of properties used by the mkFish

        • (regState: RegState): (undefined | Props)[]
        • Parameters

          • regState: RegState

          Returns (undefined | Props)[]

    • mkFish: (props: Props) => Fish<State, Events>

      fish factory function to get the public state for

        • (props: Props): Fish<State, Events>
        • Parameters

          • props: Props

          Returns Fish<State, Events>

    Returns ReactFish<State, Events, Props>[]

    ReactFish[] entities of the registry

Legend

Generated using TypeDoc