#Service Workers and Typescript

13 messages · Page 1 of 1 (latest)

sharp matrix
#

Hello!

I'm trying to call worker B from worker A.

I've set up everything as described in the docs (https://developers.cloudflare.com/workers/runtime-apis/bindings/service-bindings/) and the calls work, but receive Typescript errors:

Property 'add' does not exist on type '{ fetch(input: RequestInfo<unknown, CfProperties<unknown>>, init?: RequestInit<CfProperties<unknown>> | undefined): Promise<Response>; connect(address: string | SocketAddress, options?: SocketOptions | undefined): Socket; }'.ts(2339)

I found this on the forum: https://community.cloudflare.com/t/binding-service-rpc-using-typescript/652041

Still can't get something working 😦

Found this as well, still can't figure it out: https://developers.cloudflare.com/workers/runtime-apis/rpc/typescript/

Note worker A and worker B are in separate repos, so maybe it's a moot point in this case? I'm not super familar with RPC stuff.

Cloudflare Docs

Facilitate Worker-to-Worker communication.

Cloudflare Docs

How TypeScript types for your Worker or Durable Object's RPC methods are generated and exposed to clients

hoary grove
#

Hey @sharp matrix! did you find a solution? 🤔

novel hinge
#

The @cloudflare/workers-types package defines the type Service<MyEntrypointType>, which describes the type of a service binding. MyEntrypointType is the type of your server-side interface. Service<MyEntrypointType> applies all the necessary transformations to turn this into a client-side type, such as converting all methods to async, replacing functions and RpcTargets with (properly-typed) stubs, and so on.

It is up to you to share the definition of MyEntrypointType between your server app and its clients. You might do this by defining the interface in a separate shared TypeScript file, or by extracting a .d.ts type declaration file from your server code using tsc --declaration.

https://blog.cloudflare.com/javascript-native-rpc#what-about-type-safety

seems the approach, combined with the forum post you ref.d @sharp matrix

as for sharing types between your repos, that's a whole new rabbit hole.

monorepos are fun lol

The Cloudflare Blog

Cloudflare Workers now features a built-in RPC (Remote Procedure Call) system for use in Worker-to-Worker and Worker-to-Durable Object communication, with absolutely minimal boilerplate. We've designed an RPC system so expressive that calling a remote service can feel like using a library.

novel hinge
#

ok so. i got something working. jeez.

// WORKER A

export default class extends WorkerEntrypoint {
    async parse(input: ReadableStream) {
// logic
}

// WORKER B

interface Env {
// OTHER BINDINGS
  EPUB: Service<import("../epub-rpc-parser-worker/src/index.ts").default>;
}

bun link (was) working pretty well for me for using as a package across repos

wangler types command overwrites as Fetcher, so that's the next fun choice to make

Bun

Install local packages as dependencies in your project.

novel hinge
#

more!

so got an image generator working with workers-og

initially by bundling within the default class. that worked fine

broke when moved outside to its own class

#

fix: have to define entrypoint in wrangler.toml. again: wrangler types will reset to Fetcher, so be aware

[[services]]
binding = "OG"
service = "epub-rpc-parser-worker"
entrypoint = "OGWorker"

all working deployed 😭 bun link working a dream now. semver.

flat karma
#

@novel hinge thanks for the links

finite void
#

Did anyone found a way for wrangler types to actually write the correct types and not reset to Fetcher.. I would like wrangler types to set the following ORM: Service<import('../orm/src/index').ORM>;

novel hinge
#

@finite void no, yet to find a way to avoid the Fetcher overwrite

#

& am now running into your issue with consumer worker types on a fresh project lol

finite void
#

@novel hinge thanks for the updated.. looks like right now only interface merging or manual codemod works

#

Did you ever get it working so you can CTRL+CLICK or "Go to definition" on the actual function, and not just the binding?