Refactor ServiceContext as generic#322
Conversation
|
hm I feel pretty strongly we shouldn't change the default ServiceSchema.define into ServiceSchema.defineWithContext() for this to work, we might be able to get away with a slightly less breaking change my other main nit is that in theory, we shouldn't need to change the generics on createClient either as ServiceContext is purely a server-side concept so it makes no sense for a client to reason about ServiceContext let's talk about this more tomorrow in the office but perhaps we can subclass ServiceSchema to be ServiceSchemaWithContext (metaclasses/class factories :)) |
|
Another idea is to do something like: import { Procedure as BaseProcedure } from '@replit/river'
export const Procedure = BaseProcedure.extend<ExtendedContext>() |
|
Ah yeah Jacky's idea is better, we basically want a server builder scaffold |
|
Do we have to pass the extended context as a parameter? That goes against how e.g. Chort defines its services and will require a significant refactor I think it goes against the spirit of River's service schema if you have to instantiate a bunch of potential side effects just to construct the schema |
There is another option which is const extendedContext = {
testctx: Math.random().toString(),
};
const ServiceSchema = createServiceSchema<typeof extendedContext>();Would this work for Chort? |
|
yeah now that i think of it just having the type and not constructing the whole object is probably better, lets go with the second approach |
Yup, it is updated to |
|
id like to see if we can spend a bit more time avoiding the |
Looking into the code. We might not be able to do it without type Handler<T> = (ctx: T) => void;
const specificHandler: Handler<{ db: string }> = (ctx) => {
console.log(ctx.db); // Expects 'db' to exist
};
type AnyHandlerMap<Context extends object = object> = Record<string, Handler<Context>>
const services = {
specificHandler
}
const generalServices: AnyHandlerMap<object> = servicesTypeScript would complain about Because AnyHandlerMap is not actual accepting "Any" procedures unless we set it to |
|
As we discussed offline, we are going to keep |
41423f7 to
b25fee8
Compare
This stack of pull requests is managed by Graphite. Learn more about stacking. |
Merge activity
|

Why
When we are creating a server using river, we have to declare the
ServiceContextinterface globally so TypeScript can infer the type forctxwithin a procedure.However, it will be an issue in a mono repo setup where we want to create multiple servers with different
ServiceContext.What changed
Use builder pattern for
ServiceSchemaso we can create aServiceSchemawith Context likeconst ServiceSchema = createServiceSchema<Context>();Example:
When we create a server, it will perform type checking to make sure that all the services are expecting the same
ServiceContextas the type ofextendedContextin the config.There is no type-checking for
Contextin createClient(). We are usinganyto skip it behind the scene because it is a implementation detail on the server side.Versioning