1.0.3 • Published 6 months ago

@casipe/react-service-provider v1.0.3

Weekly downloads
-
License
GPL-3.0
Repository
github
Last release
6 months ago

react-lib-chat-front

aka react-service-provider

Service Provider is an asynchronous resource to an application make requests to APIs, these providers also manage the requests, retrying failed requests, and also provide a local storage cache.

The application will able to do any HTTP request and navigate to other resources without lose these request.

  • Retry failed request by number of retries
  • Retry failed request by timeout
  • Cache with TTL
  • Use Observables

Installation

npm install --save-dev @casipe/react-service-provider@latest

Pipeline status by branch

publish-legacy

N/A

publish

Build Status

publish-next

N/A


Usage

Custom service class

import { Service } from '@casipe/react-service-provider'

class FooService extends Service {
  // config service behavior
  public requestConfig = {
    retriesTimeout: 1000,
    retryDelay: 200
  }

  observableBased() {
    return this.request({
      url: this.params.API_URL_FOO,
      headers: {
        key: this.getProp('key') // prop of ServiceProvider
      }
    })
  }

  promiseBased() {
    return this.requestAsync({
      url: this.params.API_URL_FOO,
      headers: {
        key: this.getProp('key') // prop of ServiceProvider
      }
    })
  }
}
// App.jsx
import { ServiceProvider } from '@casipe/react-service-provider'
import { useConfig } from '@casipe/react-app-context'
const services = [FooService] => {
  const appContextConfig = getConfig()
  const token = '<TOKEN>'
  return (
    <ServiceProvider services={services} authorizationToken={token} config={appContextConfig}>
      <Component />
    </ServiceProvider>
  )
}
import { useObservable, useServices } from '@casipe/react-service-provider'
export const Component = () => {
  const [fooService] = useServices(FooService)
  const [foo, setFoo] = useRequest<FruitInterface[]>([])

  useEffect(() => {
    const subscriber = fooService.observableBased().subscribe( response => {
      setFoo(response)
    })
    return () => {
      subscriber.unsubscribe()
    }
  }, [])

  return (
    <div>
      {foo.isCached && 'CACHED'}
      {foo.error && <h1>{list.error?.message}</h1>}
      {foo.isLoading && <div>...loading</div>}
      {!foo.isLoading && list.data && (
        <div>{foo.data?.map(fruitItemComponent)}</div>
      )}
    </div>
  )
}

Connect to web socket

SocketIO Configuration

const App: FC = () => {
  const config = useConfig()
  const socketIo: SocketIOConfigInterface = {
    url: config.SOCKETIO_URL,
    namespaces: [USER_ID_FROM_TOKEN, MERCHANT_ID_FROM_TOKEN],
    socketIoOptions: {
      extraHeaders: { hello: 'message', Authorization: TOKEN_FROM_SESSION }
    }
  }
  return (
    <ServiceProvider
      config={config}
      services={[ChatService]}
      socketIo={socketIo} // SocketIOConfigInterface
      authorizationToken={TOKEN_FROM_SESSION}
    >{...}</ServiceProvider>
  )
}

Usage

  • This example's about an incoming chat message from WebSocket
  • The WS service doesn't send messages through socket just receive
  • Send request through REST
  • Wait response through websocket
// services/ChatService.ts
export interface ChatPayloadInterface {
  message: string
}

export class ChatService extends Service<DemoAppParams> {
  private chatSubject = new ReplaySubject<string>(Infinity)
  public chat$ = this.chatSubject.asObservable()
  public init() {
    this.socket<ChatPayloadInterface>('chat')
      .pipe(map((message) => message.payload.message))
      .subscribe(this.chatSubject)
  }
}

Solutions

  1. Messages to user and user groups, is posted to a namespace, configure these namespaces on SocketIOConfigInterface object.
  2. Use action to identify behavior in service
  3. Use payload to identify a document inside the application
  4. When you expect a message for a specific job, use the jobId method to control this flow, see an example in the demo