@greendrake/rpc 0.6.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -54,7 +54,7 @@ const user = await client.call('user.get', 'U1') // User
54
54
  await client.call('user.update', { id: 'U1', name: 'Ann' })
55
55
  ```
56
56
 
57
- `new RpcClient<M>(transport, locale?)` — `locale` is `() => string | undefined`, evaluated per call, so a language switch applies from the next call. `call(method, ...args)` is the one way to invoke a method, and every request it sends carries a nonce. `MethodMap` and `MethodMapConstraint<M>` are the constraint types; a plain interface qualifies.
57
+ `new RpcClient<M>(transport, locale?)` — `locale` is `() => string | undefined`, evaluated per call, so a language switch applies from the next call. `call(method, ...args)` is the one way to invoke a method, and every request it sends carries a nonce. A method that takes no arguments is called with none, and its request carries no `arguments` field. `Caller<M>` is that `call`, which `RpcClient` and `@greendrake/vue-api`'s `ApiClient` both implement: the type for code handed either. `MethodMap` and `MethodMapConstraint<M>` are the constraint types; a plain interface qualifies.
58
58
 
59
59
  `Transport` is one method, `send(request: RpcRequest): Promise<unknown>`, resolving to the response `data` or rejecting with a mapped error. Anything implementing it plugs into the client.
60
60
 
@@ -211,7 +211,6 @@ cache.get('taxonomy.tree', [{ taxonomy: 'category' }]) // { hit: boolean; data?:
211
211
  cache.set('taxonomy.tree', [{ taxonomy: 'category' }], tree) // no-op for an unlisted method
212
212
  cache.invalidate('search.things') // every entry for the method
213
213
  cache.invalidate('search.things', { q: 'x' }) // that args-key only
214
- cache.prime('taxonomy.tree', [{ taxonomy: 'category' }], pushed) // seed from a server push
215
214
  cache.clear() // everything, e.g. when the session identity changes
216
215
  ```
217
216
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@greendrake/rpc",
3
- "version": "0.6.0",
3
+ "version": "0.7.0",
4
4
  "description": "RPC client over JSON: typed method-map API, HTTP and reconnecting WebSocket transports, pluggable codec and headers, TTL response cache",
5
5
  "license": "MIT",
6
6
  "author": "Eugene Greendrake <eugene@greendrake.nz>",
@@ -34,10 +34,10 @@
34
34
  },
35
35
  "prettier": "@greendrake/dev-config/prettier",
36
36
  "dependencies": {
37
- "@greendrake/util": "0.6.0"
37
+ "@greendrake/util": "0.7.0"
38
38
  },
39
39
  "devDependencies": {
40
- "@greendrake/dev-config": "0.6.0",
40
+ "@greendrake/dev-config": "0.7.0",
41
41
  "typescript": "6.0.3"
42
42
  }
43
43
  }
@@ -85,12 +85,4 @@ export class ResponseCache {
85
85
  clear(): void {
86
86
  this.#entries.clear()
87
87
  }
88
-
89
- // Seed the cache with a known-fresh response — a server push already
90
- // carrying the full DTO a read would return — so the next read serves it
91
- // without a round-trip. `args` must match the read's args so the same key
92
- // is hit.
93
- prime(method: string, args: unknown[], data: unknown): void {
94
- this.set(method, args, data)
95
- }
96
88
  }
package/src/RpcClient.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { MethodMap, MethodMapConstraint, Transport } from './types'
1
+ import type { Caller, MethodMap, MethodMapConstraint, Transport } from './types'
2
2
  import { packRequest } from './protocol'
3
3
 
4
4
  // Typed facade over a transport: methods come from the app's declared
@@ -6,7 +6,7 @@ import { packRequest } from './protocol'
6
6
  // proxies, no casts at call sites.
7
7
  // const client = new RpcClient<Methods>(transport)
8
8
  // const user = await client.call('user.get', id)
9
- export class RpcClient<M extends MethodMapConstraint<M> = MethodMap> {
9
+ export class RpcClient<M extends MethodMapConstraint<M> = MethodMap> implements Caller<M> {
10
10
  readonly transport: Transport
11
11
  // Supplies the caller's UI language tag per request. Evaluated per call,
12
12
  // like HttpTransport's headers provider, so a locale switch takes effect on
package/src/main.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { identityCodec, type Codec, type HeadersProvider, type RpcRequest, type RpcResponse, type MethodMap, type MethodMapConstraint, type Transport } from './types'
1
+ export { identityCodec, type Caller, type Codec, type HeadersProvider, type RpcRequest, type RpcResponse, type MethodMap, type MethodMapConstraint, type Transport } from './types'
2
2
  export { ApiError, NotFoundError, OneOutcomeError, WebSocketClosedError, codeOf } from './errors'
3
3
  export { makeError, packRequest, settleResponse } from './protocol'
4
4
  export { HttpTransport, type HttpTransportOptions } from './http'
package/src/types.ts CHANGED
@@ -51,6 +51,12 @@ export type MethodMap = Record<string, (...args: never[]) => unknown>
51
51
 
52
52
  export type MethodMapConstraint<M> = Record<keyof M, (...args: never[]) => unknown>
53
53
 
54
+ // What calls the methods of M: each with exactly its own arguments, and a method
55
+ // that takes none with none at all.
56
+ export interface Caller<M extends MethodMapConstraint<M>> {
57
+ call<K extends keyof M & string>(method: K, ...args: Parameters<M[K]>): Promise<Awaited<ReturnType<M[K]>>>
58
+ }
59
+
54
60
  export interface Transport {
55
61
  send(request: RpcRequest): Promise<unknown>
56
62
  }