@ephaptic/client
v0.1.6
Published
The universal JavaScript client for ephaptic.
Readme
What is ephaptic?
Nah, just kidding. It's an RPC framework.
ephaptic — Call your backend straight from your frontend. No JSON. Low latency. Invisible middleware.
Getting Started
Ephaptic is designed to be invisible. Write a function on the server, call it on the client. No extra boilerplate.
Plus, it's horizontally scalable with Redis (optional), and features extremely low latency thanks to msgpack.
Oh, and the client can also listen to events broadcasted by the server. No, like literally. You just need to add an
eventListener. Did I mention? Events can be sent to specific targets, specific users - not just anyone online.Saved the best for last: it's type-safe. Don't believe me? Try it out for yourself. Simply type hint return values and parameters on the backend, and watch those very Python types transform into interfaces and types on the TypeScript frontend. Plus, you can use Pydantic - which means, for those of you who are FastAPI users, this is going to be great.
What are you waiting for? Let's go.
$ pip install ephaptic$ pip install ephaptic[server]from fastapi import FastAPI # or `from quart import Quart`
from ephaptic import Ephaptic
app = FastAPI() # or `app = Quart(__name__)`
ephaptic = Ephaptic.from_app(app) # Finds which framework you're using, and creates an ephaptic server.You can also specify a custom path:
ephaptic = Ephaptic.from_app(app, path="/websocket")And you can even use Redis for horizontal scaling!
ephaptic = Ephaptic.from_app(app, redis_url="redis://my-redis-container:6379/0")Now, how do you expose your function to the frontend?
@ephaptic.expose
async def add(num1: int, num2: int) -> int:
return num1 + num2Yep, it's really that simple.
But what if your code throws an error? No sweat, it just throws up on the frontend, with the error name.
And, want to say something to the frontend?
await ephaptic.to(user1, user2).notification("Hello, world!", priority="high")To create a schema of your RPC endpoints:
$ ephaptic src.app:app -o schema.json # --watch to run in background and auto-reload on file change.Pydantic is entirely supported. It's validated for arguments, it's auto-serialized when you return a pydantic model, and your models receive type definitions in the schema.
To receive authentication objects and handle them:
from ephaptic import identity_loader
@identity_loader
async def load_identity(auth): # You can use synchronous functions here too.
jwt = auth.get("token")
if not jwt: return None # unauthorized
... # app logic to retrieve user ID
return user_idFrom here, you can use ephaptic.active_user within any exposed function, and it will give you the current active user ID / whatever else your identity loading function returns. (This is also how ephaptic.to works.)
$ npm install @ephaptic/clientThen:
import { connect } from "@ephaptic/client";
const client = connect(); // Defaults to `/_ephaptic`.Or, you can use it with a custom URL:
const client = connect({ url: '/ws' });const client = connect({ url: 'wss://my-backend.deployment/ephaptic' });You can even send auth objects to the server for identity loading.
const client = connect({ url: '...', auth: { token: window.localStorage.getItem('jwtToken') } })And you can load types, too.
$ npm i --save-dev @ephaptic/type-gen
$ npx @ephaptic/type-gen ./schema.json -o schema.d.ts # --watch to auto-reload upon changesimport { connect } from "@ephaptic/client";
import { type EphapticService } from './schema';
const client = connect(...) as unknown as EphapticService;<script type="module">
import { connect } from 'https://cdn.jsdelivr.net/npm/@ephaptic/client@latest/+esm';
const client = connect(...);
</script>See more in the docs.
