@shivaedev/contract 0.19.1 → 0.20.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/CHANGELOG.md +13 -0
- package/README.md +23 -23
- package/dist/automaticLive.d.ts +8 -7
- package/dist/automaticLive.d.ts.map +1 -1
- package/dist/automaticLive.js +101 -51
- package/dist/automaticLive.js.map +1 -1
- package/dist/bind.d.ts +1 -0
- package/dist/bind.d.ts.map +1 -1
- package/dist/bind.js +4 -4
- package/dist/bind.js.map +1 -1
- package/dist/clientOptions.d.ts +6 -5
- package/dist/clientOptions.d.ts.map +1 -1
- package/dist/internal/clientOperations.d.ts +2 -2
- package/dist/internal/clientOperations.d.ts.map +1 -1
- package/dist/internal/clientOperations.js +10 -16
- package/dist/internal/clientOperations.js.map +1 -1
- package/dist/internal/queryReactivity.d.ts +1 -1
- package/dist/internal/queryReactivity.d.ts.map +1 -1
- package/dist/internal/queryReactivity.js +1 -2
- package/dist/internal/queryReactivity.js.map +1 -1
- package/dist/internal/queryResult.d.ts +3 -0
- package/dist/internal/queryResult.d.ts.map +1 -0
- package/dist/internal/queryResult.js +19 -0
- package/dist/internal/queryResult.js.map +1 -0
- package/dist/internal/{httpClient.d.ts → rpcClient.d.ts} +6 -4
- package/dist/internal/rpcClient.d.ts.map +1 -0
- package/dist/internal/rpcClient.js +31 -0
- package/dist/internal/rpcClient.js.map +1 -0
- package/dist/live.d.ts +1 -0
- package/dist/live.d.ts.map +1 -1
- package/dist/live.js +14 -1
- package/dist/live.js.map +1 -1
- package/dist/makeLiveServer.js +6 -4
- package/dist/makeLiveServer.js.map +1 -1
- package/package.json +3 -3
- package/src/automaticLive.ts +113 -70
- package/src/bind.ts +7 -6
- package/src/clientOptions.ts +6 -5
- package/src/internal/clientOperations.ts +14 -27
- package/src/internal/queryReactivity.ts +1 -7
- package/src/internal/queryResult.ts +19 -0
- package/src/internal/rpcClient.ts +53 -0
- package/src/live.ts +14 -1
- package/src/makeLiveServer.ts +6 -6
- package/dist/internal/httpClient.d.ts.map +0 -1
- package/dist/internal/httpClient.js +0 -13
- package/dist/internal/httpClient.js.map +0 -1
- package/src/internal/httpClient.ts +0 -21
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as AsyncResult from "effect/reactivity/AsyncResult";
|
|
2
2
|
import * as Atom from "effect/reactivity/Atom";
|
|
3
3
|
import type * as AtomRegistry from "effect/reactivity/AtomRegistry";
|
|
4
|
-
export declare function queryReactivity<R, E>(runtime: Atom.AtomRuntime<R, E>): (atom: Atom.Atom<AsyncResult.AsyncResult<unknown, unknown>>, keys: readonly string[],
|
|
4
|
+
export declare function queryReactivity<R, E>(runtime: Atom.AtomRuntime<R, E>): (atom: Atom.Atom<AsyncResult.AsyncResult<unknown, unknown>>, keys: readonly string[], owner?: AtomRegistry.AtomRegistry) => Atom.Atom<AsyncResult.AsyncResult<unknown, unknown>>;
|
|
5
5
|
//# sourceMappingURL=queryReactivity.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queryReactivity.d.ts","sourceRoot":"","sources":["../../src/internal/queryReactivity.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,WAAW,MAAM,+BAA+B,CAAC;AAC7D,OAAO,KAAK,IAAI,MAAM,wBAAwB,CAAC;AAC/C,OAAO,KAAK,KAAK,YAAY,MAAM,gCAAgC,CAAC;AAKpE,wBAAgB,eAAe,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"queryReactivity.d.ts","sourceRoot":"","sources":["../../src/internal/queryReactivity.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,WAAW,MAAM,+BAA+B,CAAC;AAC7D,OAAO,KAAK,IAAI,MAAM,wBAAwB,CAAC;AAC/C,OAAO,KAAK,KAAK,YAAY,MAAM,gCAAgC,CAAC;AAKpE,wBAAgB,eAAe,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,sEAIzC,SAAS,MAAM,EAAE,UAAU,YAAY,CAAC,YAAY,0DA0F/E"}
|
|
@@ -7,7 +7,7 @@ import { liveBatches, liveKeys } from "./liveInvalidation.js";
|
|
|
7
7
|
export function queryReactivity(runtime) {
|
|
8
8
|
const service = runtime.atom(Effect.service(Reactivity.Reactivity));
|
|
9
9
|
const cached = new WeakMap();
|
|
10
|
-
return (atom, keys,
|
|
10
|
+
return (atom, keys, owner) => {
|
|
11
11
|
const existing = cached.get(atom);
|
|
12
12
|
if (existing !== undefined) {
|
|
13
13
|
return existing;
|
|
@@ -22,7 +22,6 @@ export function queryReactivity(runtime) {
|
|
|
22
22
|
return get(source);
|
|
23
23
|
}
|
|
24
24
|
const reactivity = context.value;
|
|
25
|
-
get.addFinalizer(track(get.registry));
|
|
26
25
|
let pending;
|
|
27
26
|
let timer;
|
|
28
27
|
function clear() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queryReactivity.js","sourceRoot":"","sources":["../../src/internal/queryReactivity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC1C,OAAO,KAAK,WAAW,MAAM,+BAA+B,CAAC;AAC7D,OAAO,KAAK,IAAI,MAAM,wBAAwB,CAAC;AAE/C,OAAO,KAAK,UAAU,MAAM,8BAA8B,CAAC;AAC3D,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAE9D,MAAM,UAAU,eAAe,CAAO,OAA+B;IACpE,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC;IAEpE,MAAM,MAAM,GAAG,IAAI,OAAO,EAAgB,CAAC;IAC3C,OAAO,
|
|
1
|
+
{"version":3,"file":"queryReactivity.js","sourceRoot":"","sources":["../../src/internal/queryReactivity.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import * as AsyncResult from "effect/reactivity/AsyncResult";
|
|
2
|
+
export declare function queryResult<A, E>(equivalent: (left: A, right: A) => boolean, publish: (value: AsyncResult.AsyncResult<A, E>) => void): (value: AsyncResult.AsyncResult<A, E>) => void;
|
|
3
|
+
//# sourceMappingURL=queryResult.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queryResult.d.ts","sourceRoot":"","sources":["../../src/internal/queryResult.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,WAAW,MAAM,+BAA+B,CAAC;AAE7D,wBAAgB,WAAW,CAAC,CAAC,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,KAAK,OAAO,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,WAAW,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,IAAI,WAErH,WAAW,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,UAc5C"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import * as AsyncResult from "effect/reactivity/AsyncResult";
|
|
2
|
+
export function queryResult(equivalent, publish) {
|
|
3
|
+
let settled;
|
|
4
|
+
return (value) => {
|
|
5
|
+
if (!AsyncResult.isSuccess(value)) {
|
|
6
|
+
publish(value);
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
if (settled !== undefined && equivalent(settled.value, value.value)) {
|
|
10
|
+
publish(value.waiting ? AsyncResult.waiting(settled) : settled);
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
if (!value.waiting) {
|
|
14
|
+
settled = value;
|
|
15
|
+
}
|
|
16
|
+
publish(value);
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=queryResult.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queryResult.js","sourceRoot":"","sources":["../../src/internal/queryResult.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,WAAW,MAAM,+BAA+B,CAAC;AAE7D,MAAM,UAAU,WAAW,CAAO,UAA0C,EAAE,OAAuD;IACpI,IAAI,OAA8C,CAAC;IACnD,OAAO,CAAC,KAAoC,EAAE,EAAE;QAC/C,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;YACnC,OAAO,CAAC,KAAK,CAAC,CAAC;YACf,OAAO;QACR,CAAC;QACD,IAAI,OAAO,KAAK,SAAS,IAAI,UAAU,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;YACrE,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;YAChE,OAAO;QACR,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;YACpB,OAAO,GAAG,KAAK,CAAC;QACjB,CAAC;QACD,OAAO,CAAC,KAAK,CAAC,CAAC;IAChB,CAAC,CAAC;AACH,CAAC"}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { type Context, Effect, Layer } from "effect";
|
|
2
|
+
import * as Atom from "effect/reactivity/Atom";
|
|
2
3
|
import * as AtomRpc from "effect/reactivity/AtomRpc";
|
|
3
4
|
import { type Rpc } from "effect/rpc";
|
|
4
5
|
import type { ClientOptions } from "#clientOptions.ts";
|
|
5
|
-
export interface
|
|
6
|
+
export interface RpcSource {
|
|
6
7
|
readonly annotations: Context.Context<never>;
|
|
7
8
|
readonly requests: ReadonlyMap<string, Rpc.Any>;
|
|
8
9
|
}
|
|
9
|
-
export declare function
|
|
10
|
+
export declare function rpcClient(name: string, source: RpcSource, options: ClientOptions): Layer.Layer<unknown, never, never> & {
|
|
10
11
|
Client: AtomRpc.AtomRpcClient<unknown, `${string}/Client`, Rpc.Any>;
|
|
11
12
|
client: Effect.Effect<{
|
|
12
13
|
readonly [x: string]: <const AsQueue extends boolean = false, const Discard = false>(input: never, options?: {
|
|
@@ -16,6 +17,7 @@ export declare function httpClient(name: string, source: HttpGroup, options: Cli
|
|
|
16
17
|
readonly context?: Context.Context<never> | undefined;
|
|
17
18
|
} | undefined) => never;
|
|
18
19
|
}, never, import("effect/Scope").Scope>;
|
|
19
|
-
runtime:
|
|
20
|
+
runtime: Atom.AtomRuntime<unknown, never>;
|
|
20
21
|
};
|
|
21
|
-
|
|
22
|
+
export declare const socketIdentity: Atom.Writable<string | undefined, string | undefined>;
|
|
23
|
+
//# sourceMappingURL=rpcClient.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rpcClient.d.ts","sourceRoot":"","sources":["../../src/internal/rpcClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AACrD,OAAO,KAAK,IAAI,MAAM,wBAAwB,CAAC;AAC/C,OAAO,KAAK,OAAO,MAAM,2BAA2B,CAAC;AACrD,OAAO,EAAE,KAAK,GAAG,EAAyC,MAAM,YAAY,CAAC;AAE7E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEvD,MAAM,WAAW,SAAS;IACzB,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAC7C,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;CAChD;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,aAAa;;;;;;;;;;;EAkBhF;AAED,eAAO,MAAM,cAAc,uDAA2C,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Effect, Layer } from "effect";
|
|
2
|
+
import * as Atom from "effect/reactivity/Atom";
|
|
3
|
+
import * as AtomRpc from "effect/reactivity/AtomRpc";
|
|
4
|
+
import { RpcClient, RpcGroup, RpcSerialization } from "effect/rpc";
|
|
5
|
+
import * as Socket from "effect/socket/Socket";
|
|
6
|
+
export function rpcClient(name, source, options) {
|
|
7
|
+
const group = RpcGroup.make(...source.requests.values()).annotateMerge(source.annotations);
|
|
8
|
+
function sharedProtocol(identity) {
|
|
9
|
+
return socketProtocol({
|
|
10
|
+
headers: options.headers,
|
|
11
|
+
identity,
|
|
12
|
+
url: options.url.replace(/^http/u, "ws"),
|
|
13
|
+
webSocketConstructor: options.webSocketConstructor,
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
const protocol = options.protocol ?? sharedProtocol();
|
|
17
|
+
const Client = AtomRpc.Service()(`${name}/Client`, {
|
|
18
|
+
group,
|
|
19
|
+
protocol: options.protocol ?? ((get) => sharedProtocol(get(socketIdentity))),
|
|
20
|
+
});
|
|
21
|
+
const client = Effect.flatMap(Layer.build(protocol), (context) => RpcClient.make(group).pipe(Effect.provideContext(context)));
|
|
22
|
+
const layer = Layer.effect(Client, RpcClient.make(group, { flatten: true })).pipe(Layer.provide(protocol));
|
|
23
|
+
return Object.assign(layer, { Client, client, runtime: Client.runtime });
|
|
24
|
+
}
|
|
25
|
+
export const socketIdentity = Atom.make(undefined);
|
|
26
|
+
const socketMemoMap = Layer.makeMemoMapUnsafe();
|
|
27
|
+
const socketProtocol = Atom.family((options) => {
|
|
28
|
+
const protocol = RpcClient.layerProtocolSocket().pipe(Layer.provide(Socket.layerWebSocket(options.url, { headers: options.headers }).pipe(Layer.provide(options.webSocketConstructor ?? Socket.layerWebSocketConstructorGlobal))), Layer.provide(RpcSerialization.layerNdjson));
|
|
29
|
+
return Layer.effectContext(Effect.flatMap(Effect.scope, (scope) => Layer.buildWithMemoMap(protocol, socketMemoMap, scope)));
|
|
30
|
+
});
|
|
31
|
+
//# sourceMappingURL=rpcClient.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rpcClient.js","sourceRoot":"","sources":["../../src/internal/rpcClient.ts"],"names":[],"mappings":"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"}
|
package/dist/live.d.ts
CHANGED
|
@@ -30,6 +30,7 @@ export interface LiveStatus<E> {
|
|
|
30
30
|
}
|
|
31
31
|
export interface LiveOptions<E, R> {
|
|
32
32
|
readonly coalesceWindow?: Duration.Input;
|
|
33
|
+
readonly initialResync?: boolean;
|
|
33
34
|
readonly keyContext?: KeyContext | undefined;
|
|
34
35
|
readonly resume?: Atom.Atom<unknown>;
|
|
35
36
|
readonly resyncKeys: readonly Key[] | ((registry: AtomRegistry.AtomRegistry) => readonly Key[]);
|
package/dist/live.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"live.d.ts","sourceRoot":"","sources":["../src/live.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,KAAK,EAAE,QAAQ,EAAU,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9E,OAAO,KAAK,IAAI,MAAM,wBAAwB,CAAC;AAC/C,OAAO,KAAK,KAAK,YAAY,MAAM,gCAAgC,CAAC;AAEpE,OAAO,EAAoB,GAAG,EAAE,KAAK,UAAU,EAAY,MAAM,4BAA4B,CAAC;AAG9F,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;IAGnB,CAAC;AACH,MAAM,MAAM,QAAQ,GAAG,OAAO,QAAQ,CAAC,IAAI,CAAC;AAC5C,MAAM,WAAW,UAAU,CAAC,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,YAAY,GAAG,MAAM,GAAG,cAAc,CAAC;IAC5D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAChD,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CACzB;AACD,MAAM,WAAW,WAAW,CAAC,CAAC,EAAE,CAAC;IAChC,QAAQ,CAAC,cAAc,CAAC,EAAE,QAAQ,CAAC,KAAK,CAAC;IACzC,QAAQ,CAAC,UAAU,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;IAC7C,QAAQ,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACrC,QAAQ,CAAC,UAAU,EAAE,SAAS,GAAG,EAAE,GAAG,CAAC,CAAC,QAAQ,EAAE,YAAY,CAAC,YAAY,KAAK,SAAS,GAAG,EAAE,CAAC,CAAC;IAChG,QAAQ,CAAC,UAAU,CAAC,EAAE,QAAQ,CAAC,KAAK,CAAC;IACrC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;CAC/C;AAID,wBAAgB,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,aAAa,EAAE,OAAO,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,EAAE,aAAa,CAAC,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC;;;;;
|
|
1
|
+
{"version":3,"file":"live.d.ts","sourceRoot":"","sources":["../src/live.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,KAAK,EAAE,QAAQ,EAAU,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9E,OAAO,KAAK,IAAI,MAAM,wBAAwB,CAAC;AAC/C,OAAO,KAAK,KAAK,YAAY,MAAM,gCAAgC,CAAC;AAEpE,OAAO,EAAoB,GAAG,EAAE,KAAK,UAAU,EAAY,MAAM,4BAA4B,CAAC;AAG9F,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;IAGnB,CAAC;AACH,MAAM,MAAM,QAAQ,GAAG,OAAO,QAAQ,CAAC,IAAI,CAAC;AAC5C,MAAM,WAAW,UAAU,CAAC,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,YAAY,GAAG,MAAM,GAAG,cAAc,CAAC;IAC5D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAChD,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CACzB;AACD,MAAM,WAAW,WAAW,CAAC,CAAC,EAAE,CAAC;IAChC,QAAQ,CAAC,cAAc,CAAC,EAAE,QAAQ,CAAC,KAAK,CAAC;IACzC,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;IACjC,QAAQ,CAAC,UAAU,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;IAC7C,QAAQ,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACrC,QAAQ,CAAC,UAAU,EAAE,SAAS,GAAG,EAAE,GAAG,CAAC,CAAC,QAAQ,EAAE,YAAY,CAAC,YAAY,KAAK,SAAS,GAAG,EAAE,CAAC,CAAC;IAChG,QAAQ,CAAC,UAAU,CAAC,EAAE,QAAQ,CAAC,KAAK,CAAC;IACrC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;CAC/C;AAID,wBAAgB,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,aAAa,EAAE,OAAO,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,EAAE,aAAa,CAAC,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC;;;;;EAwGhH"}
|
package/dist/live.js
CHANGED
|
@@ -30,6 +30,9 @@ export function live(runtime, options) {
|
|
|
30
30
|
get.addFinalizer(() => {
|
|
31
31
|
active = false;
|
|
32
32
|
clear();
|
|
33
|
+
if (get.registry.getNodes().has(status)) {
|
|
34
|
+
update({ connection: "connecting", failure: Option.none(), needsResync: true, pending: 0 });
|
|
35
|
+
}
|
|
33
36
|
});
|
|
34
37
|
function changed(changedKeys) {
|
|
35
38
|
const window = get.once(coalesceWindow);
|
|
@@ -73,6 +76,15 @@ export function live(runtime, options) {
|
|
|
73
76
|
get.once(options.resume);
|
|
74
77
|
get.subscribe(options.resume, resync);
|
|
75
78
|
}
|
|
79
|
+
let connected = false;
|
|
80
|
+
function reconcile() {
|
|
81
|
+
if (connected || options.initialResync !== false) {
|
|
82
|
+
resync();
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
update({ needsResync: false });
|
|
86
|
+
}
|
|
87
|
+
}
|
|
76
88
|
const attempt = Effect.suspend(() => {
|
|
77
89
|
let isFirst = true;
|
|
78
90
|
function observe(hint) {
|
|
@@ -81,11 +93,12 @@ export function live(runtime, options) {
|
|
|
81
93
|
update({ needsResync: true, pending: Math.min(MAX_PENDING, get.once(status).pending + 1) });
|
|
82
94
|
}
|
|
83
95
|
else if (isFirst || hint._tag === "Resync") {
|
|
84
|
-
|
|
96
|
+
reconcile();
|
|
85
97
|
}
|
|
86
98
|
else {
|
|
87
99
|
changed(hint.keys);
|
|
88
100
|
}
|
|
101
|
+
connected = true;
|
|
89
102
|
isFirst = false;
|
|
90
103
|
}
|
|
91
104
|
return options.stream.pipe(Stream.runForEach((hint) => Effect.sync(() => observe(hint))), Effect.scoped, Effect.catchCause((failure) => Effect.sync(() => update({ failure: Option.some(failure) }))), Effect.andThen(Effect.sync(() => update({ connection: "reconnecting", needsResync: true }))), Effect.andThen(Effect.sleep(options.retryDelay ?? "1 second")));
|
package/dist/live.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"live.js","sourceRoot":"","sources":["../src/live.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9E,OAAO,KAAK,IAAI,MAAM,wBAAwB,CAAC;AAE/C,OAAO,KAAK,UAAU,MAAM,8BAA8B,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,GAAG,EAAmB,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAC9F,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAE/D,MAAM,CAAC,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC;IACpC,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,YAAY,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;IACvI,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;CACjD,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"live.js","sourceRoot":"","sources":["../src/live.ts"],"names":[],"mappings":"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"}
|
package/dist/makeLiveServer.js
CHANGED
|
@@ -48,10 +48,12 @@ export const makeLiveServer = Effect.gen(function* () {
|
|
|
48
48
|
}));
|
|
49
49
|
yield* Queue.offer(queue, { _tag: "Resync" });
|
|
50
50
|
function authorizeHint(hint) {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
51
|
+
return Effect.map(subscription?.authorized ?? Effect.succeed(true), (allowed) => {
|
|
52
|
+
if (!allowed) {
|
|
53
|
+
return changedHint([], subscription?.scopes);
|
|
54
|
+
}
|
|
55
|
+
return hint._tag === "Resync" ? hint : changedHint(hint.keys, subscription?.scopes);
|
|
56
|
+
});
|
|
55
57
|
}
|
|
56
58
|
return Stream.fromQueue(queue).pipe(Stream.mapEffect(authorizeHint), Stream.filter((hint) => hint._tag === "Resync" || hint.keys.length > 0));
|
|
57
59
|
}));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"makeLiveServer.js","sourceRoot":"","sources":["../src/makeLiveServer.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"makeLiveServer.js","sourceRoot":"","sources":["../src/makeLiveServer.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shivaedev/contract",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.20.0",
|
|
4
4
|
"description": "Typed query and command contracts over native Effect RPC and reactivity",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"effect"
|
|
@@ -50,10 +50,10 @@
|
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"@effect/platform-node": "4.0.5",
|
|
52
52
|
"@effect/vitest": "4.0.5",
|
|
53
|
-
"@shivaedev/quality": "0.44.
|
|
53
|
+
"@shivaedev/quality": "0.44.1",
|
|
54
54
|
"@shivaedev/test": "0.10.0",
|
|
55
55
|
"@shivaedev/test-sql": "0.10.2",
|
|
56
|
-
"@shivaedev/test-story": "0.
|
|
56
|
+
"@shivaedev/test-story": "0.23.0",
|
|
57
57
|
"@types/node": "24.19.2",
|
|
58
58
|
"effect": "4.0.5",
|
|
59
59
|
"esbuild": "0.28.2",
|
package/src/automaticLive.ts
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
|
-
import { type Duration, Effect,
|
|
1
|
+
import { type Duration, Effect, Option, Stream } from "effect";
|
|
2
|
+
import * as AsyncResult from "effect/reactivity/AsyncResult";
|
|
2
3
|
import * as Atom from "effect/reactivity/Atom";
|
|
3
|
-
import * as AtomRegistry from "effect/reactivity/AtomRegistry";
|
|
4
4
|
import type * as AtomRpc from "effect/reactivity/AtomRpc";
|
|
5
|
-
import {
|
|
5
|
+
import type { Key } from "@shivaedev/changes/keys.ts";
|
|
6
6
|
import type { BindingOwner } from "#internal/bindingOwner.ts";
|
|
7
7
|
import { localQueryKeys, queryHint } from "#internal/queryHints.ts";
|
|
8
|
+
import { queryResult } from "#internal/queryResult.ts";
|
|
9
|
+
import { socketIdentity } from "#internal/rpcClient.ts";
|
|
8
10
|
import { type LiveStatus, live } from "#live.ts";
|
|
11
|
+
import { queryCoalesceWindow } from "#queryCoalesceWindow.ts";
|
|
9
12
|
import { type ResumeSource, type ResumeWindow, resumeSignal } from "#resume.ts";
|
|
10
13
|
import type { changesRpc, QueryReference } from "#serverMetadata.ts";
|
|
11
14
|
|
|
@@ -16,83 +19,123 @@ export interface LiveBound {
|
|
|
16
19
|
readonly [LiveConnection]: {
|
|
17
20
|
readonly coalesceWindow: Atom.Writable<Duration.Input>;
|
|
18
21
|
readonly connection: Atom.Atom<unknown>;
|
|
22
|
+
readonly identity?: Atom.Writable<string | undefined>;
|
|
19
23
|
readonly status: Atom.Atom<LiveStatus<unknown>>;
|
|
20
24
|
};
|
|
21
25
|
}
|
|
22
26
|
|
|
23
27
|
export type ChangesClient = AtomRpc.AtomRpcClient<unknown, string, ReturnType<typeof changesRpc>>;
|
|
24
28
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
export function automaticLive(service: ChangesClient, name: string, owner?: BindingOwner, resume?: ResumeSource) {
|
|
31
|
-
const eager = owner === undefined ? Effect.runSync(SubscriptionRef.make<ReadonlyMap<object, Tracked>>(new Map())) : undefined;
|
|
32
|
-
const known = new Set<string>();
|
|
33
|
-
const tracked = Atom.keepAlive(Atom.make(() => eager ?? Effect.runSync(SubscriptionRef.make<ReadonlyMap<object, Tracked>>(new Map()))));
|
|
34
|
-
function track(registry: AtomRegistry.AtomRegistry | undefined, reference: QueryReference, keys: readonly Key[]) {
|
|
35
|
-
const fresh =
|
|
36
|
-
eager === undefined
|
|
37
|
-
? keys
|
|
38
|
-
: keys.filter((key) => {
|
|
39
|
-
const id = readKeys([key])[0] ?? "";
|
|
40
|
-
if (known.has(id)) {
|
|
41
|
-
return false;
|
|
42
|
-
}
|
|
43
|
-
known.add(id);
|
|
44
|
-
return true;
|
|
45
|
-
});
|
|
46
|
-
if (fresh.length === 0) {
|
|
47
|
-
return () => undefined;
|
|
48
|
-
}
|
|
49
|
-
const token = {};
|
|
50
|
-
const state = eager ?? registry?.get(tracked);
|
|
51
|
-
if (state === undefined) {
|
|
52
|
-
throw new Error("Session query tracking requires its owning registry");
|
|
53
|
-
}
|
|
54
|
-
Effect.runSync(SubscriptionRef.update(state, (current) => new Map([...current, [token, { keys: fresh, reference }]])));
|
|
55
|
-
if (eager !== undefined) {
|
|
56
|
-
return () => undefined;
|
|
29
|
+
export function automaticLive(service: ChangesClient, name: string, owner?: BindingOwner, resume?: ResumeSource, enabled = true) {
|
|
30
|
+
function assertOwner(get: Atom.AtomContext) {
|
|
31
|
+
if (owner !== undefined && owner.registry !== get.registry) {
|
|
32
|
+
throw new Error("A session-scoped query belongs to its binding registry");
|
|
57
33
|
}
|
|
58
|
-
return () =>
|
|
59
|
-
Effect.runSync(
|
|
60
|
-
SubscriptionRef.update(state, (current) => {
|
|
61
|
-
const next = new Map(current);
|
|
62
|
-
next.delete(token);
|
|
63
|
-
return next;
|
|
64
|
-
}),
|
|
65
|
-
);
|
|
66
34
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
35
|
+
const coalesceWindow = Atom.keepAlive(Atom.make<Duration.Input>("20 millis"));
|
|
36
|
+
const statuses = Atom.make<ReadonlyMap<object, LiveStatus<unknown>>>(new Map());
|
|
37
|
+
const status = Atom.map(statuses, (current): LiveStatus<unknown> => {
|
|
38
|
+
const values = [...current.values()];
|
|
39
|
+
let connection: LiveStatus<unknown>["connection"] = "live";
|
|
40
|
+
if (values.some((value) => value.connection === "connecting")) {
|
|
41
|
+
connection = "connecting";
|
|
70
42
|
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
keyContext: owner?.context,
|
|
81
|
-
resume: signal,
|
|
82
|
-
resyncKeys: (registry) => [...Effect.runSync(SubscriptionRef.get(registry.get(tracked))).values()].flatMap(({ keys }) => localQueryKeys(keys)),
|
|
83
|
-
stream: Stream.unwrap(
|
|
84
|
-
Effect.map(AtomRegistry.AtomRegistry, (registry) =>
|
|
85
|
-
Stream.zipLatest(SubscriptionRef.changes(registry.get(tracked)), AtomRegistry.toStream(registry, signal)).pipe(
|
|
86
|
-
Stream.switchMap(([current]) => subscribe(current)),
|
|
87
|
-
),
|
|
88
|
-
),
|
|
89
|
-
),
|
|
43
|
+
if (values.some((value) => value.connection === "reconnecting")) {
|
|
44
|
+
connection = "reconnecting";
|
|
45
|
+
}
|
|
46
|
+
return {
|
|
47
|
+
connection,
|
|
48
|
+
failure: values.find((value) => Option.isSome(value.failure))?.failure ?? Option.none(),
|
|
49
|
+
needsResync: values.some((value) => value.needsResync),
|
|
50
|
+
pending: values.reduce((sum, value) => sum + value.pending, 0),
|
|
51
|
+
};
|
|
90
52
|
});
|
|
53
|
+
const signal = resumeSignal({ ...(typeof window === "undefined" ? {} : { window }), ...(resume === undefined ? {} : { native: resume }) });
|
|
91
54
|
const connection = Atom.make((get) => {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
return get(subscription.connection);
|
|
55
|
+
assertOwner(get);
|
|
56
|
+
get.mount(service.runtime);
|
|
57
|
+
return get(status);
|
|
96
58
|
}).pipe(Atom.setIdleTTL(0));
|
|
97
|
-
|
|
59
|
+
function query<A, E>(
|
|
60
|
+
atom: Atom.Atom<AsyncResult.AsyncResult<A, E>>,
|
|
61
|
+
reference: QueryReference,
|
|
62
|
+
keys: readonly Key[],
|
|
63
|
+
equivalent: (left: A, right: A) => boolean,
|
|
64
|
+
) {
|
|
65
|
+
if (!enabled) {
|
|
66
|
+
return atom;
|
|
67
|
+
}
|
|
68
|
+
const ready = Atom.make(false);
|
|
69
|
+
const subscription = live(service.runtime, {
|
|
70
|
+
initialResync: false,
|
|
71
|
+
keyContext: owner?.context,
|
|
72
|
+
resume: signal,
|
|
73
|
+
resyncKeys: localQueryKeys(keys),
|
|
74
|
+
stream: Stream.unwrap(service.use((client) => Effect.succeed(client(`${name}.$changes`, { queries: [reference] })))).pipe(
|
|
75
|
+
Stream.map((hint) => queryHint(hint, [{ keys }])),
|
|
76
|
+
),
|
|
77
|
+
});
|
|
78
|
+
const gated = Atom.readable(
|
|
79
|
+
(get) => {
|
|
80
|
+
assertOwner(get);
|
|
81
|
+
const registry = get.registry;
|
|
82
|
+
get.set(ready, false);
|
|
83
|
+
get.once(queryCoalesceWindow(gated));
|
|
84
|
+
get.subscribe(queryCoalesceWindow(gated), (value) => get.set(queryCoalesceWindow(atom), value), { immediate: true });
|
|
85
|
+
const token = {};
|
|
86
|
+
function observe(value: LiveStatus<unknown>) {
|
|
87
|
+
registry.update(statuses, (current) => new Map([...current, [token, value]]));
|
|
88
|
+
if (value.connection === "live") {
|
|
89
|
+
registry.set(ready, true);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
get.addFinalizer(() => {
|
|
93
|
+
if (registry.getNodes().has(statuses)) {
|
|
94
|
+
registry.update(statuses, (current) => {
|
|
95
|
+
const next = new Map(current);
|
|
96
|
+
next.delete(token);
|
|
97
|
+
return next;
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
get.addFinalizer(registry.subscribe(subscription.status, observe, { immediate: true }));
|
|
102
|
+
get.addFinalizer(registry.subscribe(coalesceWindow, (value) => registry.set(subscription.coalesceWindow, value), { immediate: true }));
|
|
103
|
+
let started = false;
|
|
104
|
+
function start() {
|
|
105
|
+
if (started) {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
started = true;
|
|
109
|
+
get.refresh(atom);
|
|
110
|
+
const publish = queryResult<A, E>(equivalent, (value) => get.setSelf(value));
|
|
111
|
+
get.subscribe(atom, publish);
|
|
112
|
+
publish(get.once(atom));
|
|
113
|
+
}
|
|
114
|
+
get.once(ready);
|
|
115
|
+
get.subscribe(ready, (value) => {
|
|
116
|
+
if (value) {
|
|
117
|
+
start();
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
get.subscribe(subscription.status, (value) => {
|
|
121
|
+
if (!started && Option.isSome(value.failure)) {
|
|
122
|
+
get.setSelf(AsyncResult.failure(value.failure.value));
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
get.mount(subscription.connection);
|
|
126
|
+
if (get.once(ready)) {
|
|
127
|
+
start();
|
|
128
|
+
return get.once(atom);
|
|
129
|
+
}
|
|
130
|
+
return AsyncResult.initial();
|
|
131
|
+
},
|
|
132
|
+
(refresh) => refresh(atom),
|
|
133
|
+
).pipe(Atom.setIdleTTL(0));
|
|
134
|
+
Object.assign(gated, { initialValueTarget: atom });
|
|
135
|
+
if (Atom.isSerializable(atom)) {
|
|
136
|
+
Object.assign(gated, { [Atom.SerializableTypeId]: atom[Atom.SerializableTypeId] });
|
|
137
|
+
}
|
|
138
|
+
return gated;
|
|
139
|
+
}
|
|
140
|
+
return { query, subscription: { coalesceWindow, connection, identity: socketIdentity, status } };
|
|
98
141
|
}
|
package/src/bind.ts
CHANGED
|
@@ -12,7 +12,7 @@ import type { ClientOptions, MadeClient } from "#clientOptions.ts";
|
|
|
12
12
|
import type { Contract, Declared, Tag } from "#contract.ts";
|
|
13
13
|
import { bindingOwner } from "#internal/bindingOwner.ts";
|
|
14
14
|
import { boundCommand, boundQuery, boundStream } from "#internal/clientOperations.ts";
|
|
15
|
-
import { type
|
|
15
|
+
import { type RpcSource, rpcClient } from "#internal/rpcClient.ts";
|
|
16
16
|
import type { CommandShape, QueryShape, StreamShape } from "#operation.ts";
|
|
17
17
|
import type { MissingReadPolicy } from "#readPolicyErrors.ts";
|
|
18
18
|
import type { ResumeSource } from "#resume.ts";
|
|
@@ -71,6 +71,7 @@ type MatchingClient<TRpcs extends Rpc.Any, TClientRpcs extends Rpc.Any> = [TRpcs
|
|
|
71
71
|
: "Client must implement the contract RPCs";
|
|
72
72
|
|
|
73
73
|
interface BindOptions {
|
|
74
|
+
readonly live?: boolean;
|
|
74
75
|
readonly registry?: AtomRegistry.AtomRegistry;
|
|
75
76
|
readonly resume?: ResumeSource;
|
|
76
77
|
}
|
|
@@ -105,10 +106,10 @@ function bindApi(
|
|
|
105
106
|
) {
|
|
106
107
|
const { name, queries, commands, streams, keyScope } = contract.declaration;
|
|
107
108
|
const owner = bindingOwner(keyScope, options?.registry);
|
|
108
|
-
const automatic = automaticLive(service, name, owner, options?.resume);
|
|
109
|
+
const automatic = automaticLive(service, name, owner, options?.resume, options?.live);
|
|
109
110
|
return Object.assign(
|
|
110
111
|
Object.fromEntries([
|
|
111
|
-
...queries.map((query) => [query.name, boundQuery(service, `${name}.${query.name}`, query, automatic
|
|
112
|
+
...queries.map((query) => [query.name, boundQuery(service, `${name}.${query.name}`, query, automatic, owner)] as const),
|
|
112
113
|
...commands.map((command) => [command.name, boundCommand(service, `${name}.${command.name}`, command, owner)] as const),
|
|
113
114
|
...streams.map((stream) => [stream.name, boundStream(service, `${name}.${stream.name}`)] as const),
|
|
114
115
|
]),
|
|
@@ -131,15 +132,15 @@ export function makeClient<
|
|
|
131
132
|
: { readonly registry?: AtomRegistry.AtomRegistry }),
|
|
132
133
|
): MadeClient<TName, TQueries, TCommands, TRpcs, TStreams, TExtra>;
|
|
133
134
|
export function makeClient(
|
|
134
|
-
contract:
|
|
135
|
+
contract: RpcSource & {
|
|
135
136
|
readonly declaration: Declared<string, readonly QueryShape[], readonly CommandShape[], readonly StreamShape[], "session" | undefined>;
|
|
136
137
|
},
|
|
137
138
|
options: ClientOptions & {
|
|
138
|
-
readonly group?:
|
|
139
|
+
readonly group?: RpcSource;
|
|
139
140
|
readonly registry?: AtomRegistry.AtomRegistry;
|
|
140
141
|
},
|
|
141
142
|
): Layer.Layer<never> {
|
|
142
|
-
const connection =
|
|
143
|
+
const connection = rpcClient(contract.declaration.name, options.group ?? contract, options);
|
|
143
144
|
const api = bindApi(contract, connection.Client, options);
|
|
144
145
|
return Object.assign(connection, { api });
|
|
145
146
|
}
|
package/src/clientOptions.ts
CHANGED
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
import type { Context, Effect, Layer, Scope } from "effect";
|
|
2
|
-
import type { HttpClient } from "effect/http/HttpClient";
|
|
3
2
|
import type * as Atom from "effect/reactivity/Atom";
|
|
4
3
|
import type * as AtomRpc from "effect/reactivity/AtomRpc";
|
|
5
|
-
import type { Rpc, RpcClient
|
|
4
|
+
import type { Rpc, RpcClient } from "effect/rpc";
|
|
6
5
|
import type { RpcClientError } from "effect/rpc/RpcClientError";
|
|
6
|
+
import type * as Socket from "effect/socket/Socket";
|
|
7
7
|
import type { LiveBound } from "#automaticLive.ts";
|
|
8
8
|
import type { Bound } from "#bind.ts";
|
|
9
9
|
import type { CommandShape, QueryShape, StreamShape } from "#operation.ts";
|
|
10
10
|
|
|
11
11
|
export interface ClientOptions {
|
|
12
|
-
readonly
|
|
13
|
-
readonly
|
|
14
|
-
readonly
|
|
12
|
+
readonly headers?: Readonly<Record<string, string>>;
|
|
13
|
+
readonly live?: boolean;
|
|
14
|
+
readonly protocol?: Layer.Layer<RpcClient.Protocol>;
|
|
15
15
|
readonly url: string;
|
|
16
|
+
readonly webSocketConstructor?: Layer.Layer<Socket.WebSocketConstructor>;
|
|
16
17
|
}
|
|
17
18
|
|
|
18
19
|
export type ClientService<TName extends string, TRpcs extends Rpc.Any> = Context.ServiceClass.Shape<
|