effect-app 4.0.0-beta.172 → 4.0.0-beta.174
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 +14 -0
- package/dist/client/InvalidationKeys.d.ts +23 -0
- package/dist/client/InvalidationKeys.d.ts.map +1 -0
- package/dist/client/InvalidationKeys.js +23 -0
- package/dist/client/apiClientFactory.d.ts +2 -2
- package/dist/client/apiClientFactory.d.ts.map +1 -1
- package/dist/client/apiClientFactory.js +31 -12
- package/dist/client.d.ts +2 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +2 -1
- package/dist/middleware.d.ts +9 -2
- package/dist/middleware.d.ts.map +1 -1
- package/dist/middleware.js +6 -2
- package/dist/rpc/Invalidation.d.ts +211 -0
- package/dist/rpc/Invalidation.d.ts.map +1 -0
- package/dist/rpc/Invalidation.js +97 -0
- package/dist/rpc.d.ts +2 -1
- package/dist/rpc.d.ts.map +1 -1
- package/dist/rpc.js +2 -1
- package/package.json +9 -1
- package/src/client/InvalidationKeys.ts +38 -0
- package/src/client/apiClientFactory.ts +33 -11
- package/src/client.ts +1 -0
- package/src/middleware.ts +5 -1
- package/src/rpc/Invalidation.ts +123 -0
- package/src/rpc.ts +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# @effect-app/prelude
|
|
2
2
|
|
|
3
|
+
## 4.0.0-beta.174
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 821468d: Add server-driven cache invalidation via RPC response headers.
|
|
8
|
+
|
|
9
|
+
- `effect-app/rpc`: new `Invalidation` module with `InvalidationKey` / `InvalidationKeys` schemas, `Invalidates` annotation (for declaring static invalidation on Rpc definitions), `InvalidationSet` reference (request-scoped accumulator), and `makeInvalidationSet` helper.
|
|
10
|
+
- `effect-app/middleware`: new `InvalidationMiddleware` RPC middleware tag; included in `DefaultGenericMiddlewares`.
|
|
11
|
+
- `effect-app/client`: new `InvalidationKeys` module with `InvalidationKeysFromServer` reference and `makeInvalidationKeysService` helper; `apiClientFactory` now taps HTTP responses to read the `x-invalidate` header and forward keys to `InvalidationKeysFromServer`.
|
|
12
|
+
- `@effect-app/infra`: new `InvalidationMiddlewareLive` RPC middleware implementation that owns the full lifecycle — creates a request-scoped `InvalidationSet` (backed by a `Ref`), pre-populates it from the `Invalidates` annotation, provides it to the handler, and after the handler completes registers an HTTP pre-response handler (via `appendPreResponseHandlerUnsafe`) to write the accumulated keys as an `x-invalidate` response header. No separate HTTP middleware is needed.
|
|
13
|
+
- `@effect-app/vue`: `invalidateQueries` / `useMutation` now reads server-provided invalidation keys from `InvalidationKeysFromServer` after each mutation and applies them alongside the client-side invalidation.
|
|
14
|
+
|
|
15
|
+
## 4.0.0-beta.173
|
|
16
|
+
|
|
3
17
|
## 4.0.0-beta.172
|
|
4
18
|
|
|
5
19
|
## 4.0.0-beta.171
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import * as Ref from "effect/Ref";
|
|
2
|
+
import * as Context from "../Context.js";
|
|
3
|
+
import * as Effect from "../Effect.js";
|
|
4
|
+
import type { InvalidationKey } from "../rpc/Invalidation.js";
|
|
5
|
+
export type { InvalidationKey };
|
|
6
|
+
/** Shape of the per-mutation service that accumulates server-provided invalidation keys. */
|
|
7
|
+
export interface InvalidationKeysService {
|
|
8
|
+
readonly add: (key: InvalidationKey) => Effect.Effect<void>;
|
|
9
|
+
readonly get: Effect.Effect<ReadonlyArray<InvalidationKey>>;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Context.Reference that accumulates invalidation keys received from the server via the
|
|
13
|
+
* `x-invalidate` HTTP response header.
|
|
14
|
+
*
|
|
15
|
+
* The default is a no-op: when not explicitly provided (e.g. outside a mutation wrapper)
|
|
16
|
+
* all calls are ignored. The mutation wrapper in `@effect-app/vue` provides a real
|
|
17
|
+
* implementation backed by a `Ref`.
|
|
18
|
+
*/
|
|
19
|
+
export declare const InvalidationKeysFromServer: Context.Reference<InvalidationKeysService>;
|
|
20
|
+
export type InvalidationKeysFromServer = typeof InvalidationKeysFromServer;
|
|
21
|
+
/** Creates a fresh `InvalidationKeysService` implementation backed by a `Ref`. */
|
|
22
|
+
export declare const makeInvalidationKeysService: (ref: Ref.Ref<ReadonlyArray<InvalidationKey>>) => InvalidationKeysService;
|
|
23
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiSW52YWxpZGF0aW9uS2V5cy5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NsaWVudC9JbnZhbGlkYXRpb25LZXlzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxHQUFHLE1BQU0sWUFBWSxDQUFBO0FBQ2pDLE9BQU8sS0FBSyxPQUFPLE1BQU0sZUFBZSxDQUFBO0FBQ3hDLE9BQU8sS0FBSyxNQUFNLE1BQU0sY0FBYyxDQUFBO0FBQ3RDLE9BQU8sS0FBSyxFQUFFLGVBQWUsRUFBRSxNQUFNLHdCQUF3QixDQUFBO0FBRTdELFlBQVksRUFBRSxlQUFlLEVBQUUsQ0FBQTtBQUMvQiw0RkFBNEY7QUFDNUYsTUFBTSxXQUFXLHVCQUF1QjtJQUN0QyxRQUFRLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxFQUFFLGVBQWUsS0FBSyxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFBO0lBQzNELFFBQVEsQ0FBQyxHQUFHLEVBQUUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQTtDQUM1RDtBQUVEOzs7Ozs7O0dBT0c7QUFDSCxlQUFPLE1BQU0sMEJBQTBCLDRDQVF0QyxDQUFBO0FBQ0QsTUFBTSxNQUFNLDBCQUEwQixHQUFHLE9BQU8sMEJBQTBCLENBQUE7QUFFMUUsa0ZBQWtGO0FBQ2xGLGVBQU8sTUFBTSwyQkFBMkIsUUFDakMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxhQUFhLENBQUMsZUFBZSxDQUFDLENBQUMsS0FDM0MsdUJBR0QsQ0FBQSJ9
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InvalidationKeys.d.ts","sourceRoot":"","sources":["../../src/client/InvalidationKeys.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,YAAY,CAAA;AACjC,OAAO,KAAK,OAAO,MAAM,eAAe,CAAA;AACxC,OAAO,KAAK,MAAM,MAAM,cAAc,CAAA;AACtC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AAE7D,YAAY,EAAE,eAAe,EAAE,CAAA;AAC/B,4FAA4F;AAC5F,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,eAAe,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IAC3D,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,eAAe,CAAC,CAAC,CAAA;CAC5D;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,0BAA0B,4CAQtC,CAAA;AACD,MAAM,MAAM,0BAA0B,GAAG,OAAO,0BAA0B,CAAA;AAE1E,kFAAkF;AAClF,eAAO,MAAM,2BAA2B,QACjC,GAAG,CAAC,GAAG,CAAC,aAAa,CAAC,eAAe,CAAC,CAAC,KAC3C,uBAGD,CAAA"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import * as Ref from "effect/Ref";
|
|
2
|
+
import * as Context from "../Context.js";
|
|
3
|
+
import * as Effect from "../Effect.js";
|
|
4
|
+
/**
|
|
5
|
+
* Context.Reference that accumulates invalidation keys received from the server via the
|
|
6
|
+
* `x-invalidate` HTTP response header.
|
|
7
|
+
*
|
|
8
|
+
* The default is a no-op: when not explicitly provided (e.g. outside a mutation wrapper)
|
|
9
|
+
* all calls are ignored. The mutation wrapper in `@effect-app/vue` provides a real
|
|
10
|
+
* implementation backed by a `Ref`.
|
|
11
|
+
*/
|
|
12
|
+
export const InvalidationKeysFromServer = Context.Reference("effect-app/client/InvalidationKeysFromServer", {
|
|
13
|
+
defaultValue: () => ({
|
|
14
|
+
add: (_key) => Effect.void,
|
|
15
|
+
get: Effect.succeed([])
|
|
16
|
+
})
|
|
17
|
+
});
|
|
18
|
+
/** Creates a fresh `InvalidationKeysService` implementation backed by a `Ref`. */
|
|
19
|
+
export const makeInvalidationKeysService = (ref) => ({
|
|
20
|
+
add: (key) => Ref.update(ref, (keys) => [...keys, key]),
|
|
21
|
+
get: Ref.get(ref)
|
|
22
|
+
});
|
|
23
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiSW52YWxpZGF0aW9uS2V5cy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jbGllbnQvSW52YWxpZGF0aW9uS2V5cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssR0FBRyxNQUFNLFlBQVksQ0FBQTtBQUNqQyxPQUFPLEtBQUssT0FBTyxNQUFNLGVBQWUsQ0FBQTtBQUN4QyxPQUFPLEtBQUssTUFBTSxNQUFNLGNBQWMsQ0FBQTtBQVV0Qzs7Ozs7OztHQU9HO0FBQ0gsTUFBTSxDQUFDLE1BQU0sMEJBQTBCLEdBQUcsT0FBTyxDQUFDLFNBQVMsQ0FDekQsOENBQThDLEVBQzlDO0lBQ0UsWUFBWSxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUM7UUFDbkIsR0FBRyxFQUFFLENBQUMsSUFBcUIsRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLElBQUk7UUFDM0MsR0FBRyxFQUFFLE1BQU0sQ0FBQyxPQUFPLENBQUMsRUFBb0MsQ0FBQztLQUMxRCxDQUFDO0NBQ0gsQ0FDRixDQUFBO0FBR0Qsa0ZBQWtGO0FBQ2xGLE1BQU0sQ0FBQyxNQUFNLDJCQUEyQixHQUFHLENBQ3pDLEdBQTRDLEVBQ25CLEVBQUUsQ0FBQyxDQUFDO0lBQzdCLEdBQUcsRUFBRSxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsR0FBRyxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUM7SUFDdkQsR0FBRyxFQUFFLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDO0NBQ2xCLENBQUMsQ0FBQSJ9
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import * as Layer from "effect/Layer";
|
|
2
|
+
import * as Option from "effect/Option";
|
|
2
3
|
import { Rpc, RpcGroup, RpcSerialization } from "effect/unstable/rpc";
|
|
3
4
|
import * as Config from "../Config.js";
|
|
4
5
|
import * as Context from "../Context.js";
|
|
5
6
|
import * as Effect from "../Effect.js";
|
|
6
7
|
import { HttpClient } from "../http.js";
|
|
7
|
-
import * as Option from "../Option.js";
|
|
8
8
|
import type * as S from "../Schema.js";
|
|
9
9
|
import type { ClientForOptions, ExtractModuleName, RequestsAny } from "./clientFor.js";
|
|
10
10
|
export interface ApiConfig {
|
|
@@ -49,4 +49,4 @@ export declare class ApiClientFactory extends ApiClientFactory_base {
|
|
|
49
49
|
static readonly makeFor: (requestLevelLayers: Layer.Layer<never, never, never>, options?: ClientForOptions) => <M extends RequestsAny>(resource: M) => Effect.Effect<import("./clientFor.js").RequestHandlers<never, never, M, ExtractModuleName<M>>, never, ApiClientFactory>;
|
|
50
50
|
}
|
|
51
51
|
export {};
|
|
52
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
52
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBpQ2xpZW50RmFjdG9yeS5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NsaWVudC9hcGlDbGllbnRGYWN0b3J5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUVBLE9BQU8sS0FBSyxLQUFLLE1BQU0sY0FBYyxDQUFBO0FBRXJDLE9BQU8sS0FBSyxNQUFNLE1BQU0sZUFBZSxDQUFBO0FBSXZDLE9BQU8sRUFBRSxHQUFHLEVBQWEsUUFBUSxFQUFFLGdCQUFnQixFQUFFLE1BQU0scUJBQXFCLENBQUE7QUFDaEYsT0FBTyxLQUFLLE1BQU0sTUFBTSxjQUFjLENBQUE7QUFDdEMsT0FBTyxLQUFLLE9BQU8sTUFBTSxlQUFlLENBQUE7QUFDeEMsT0FBTyxLQUFLLE1BQU0sTUFBTSxjQUFjLENBQUE7QUFDdEMsT0FBTyxFQUFFLFVBQVUsRUFBcUIsTUFBTSxZQUFZLENBQUE7QUFFMUQsT0FBTyxLQUFLLEtBQUssQ0FBQyxNQUFNLGNBQWMsQ0FBQTtBQUV0QyxPQUFPLEtBQUssRUFBVSxnQkFBZ0IsRUFBRSxpQkFBaUIsRUFBRSxXQUFXLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQTtBQUc5RixNQUFNLFdBQVcsU0FBUztJQUN4QixHQUFHLEVBQUUsTUFBTSxDQUFBO0lBQ1gsT0FBTyxFQUFFLE1BQU0sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFBO0NBQy9DO0FBRUQsZUFBTyxNQUFNLGdCQUFnQjs7Ozs7RUFRM0IsQ0FBQTtBQUVGLE1BQU0sTUFBTSxHQUFHLEdBQUcsQ0FBQyxDQUFDLEdBQUcsR0FBRztJQUN4QixRQUFRLENBQUMsSUFBSSxFQUFFLENBQUMsR0FBRyxJQUFJLEVBQUUsR0FBRyxFQUFFLEtBQUssR0FBRyxDQUFBO0lBQ3RDLElBQUksRUFBRSxNQUFNLENBQUE7SUFDWixNQUFNLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUE7SUFDdkIsT0FBTyxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUE7SUFDZCxLQUFLLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQTtJQUNaLE1BQU0sQ0FBQyxFQUFFLE1BQU0sQ0FBQyxNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUE7SUFDNUIsUUFBUSxDQUFDLEVBQUUsRUFBRSxNQUFNLENBQUE7SUFDbkIsUUFBUSxDQUFDLFVBQVUsRUFBRSxNQUFNLENBQUE7SUFDM0IsUUFBUSxDQUFDLElBQUksRUFBRSxTQUFTLEdBQUcsT0FBTyxDQUFBO0lBQ2xDLFFBQVEsQ0FBQyxtQkFBbUIsQ0FBQyxFQUFFLE9BQU8sQ0FBQTtDQUN2QyxDQUFBO0FBTUQsZUFBTyxNQUFNLGVBQWUsV0FBWSxTQUFTLHFFQXFCOUMsQ0FBQTtBQUVILGVBQU8sTUFBTSx5QkFBeUIsK0VBS3JDLENBQUE7QUFFRCxlQUFPLE1BQU0scUJBQXFCLFdBQVksU0FBUyx5R0FJcEQsQ0FBQTtBQUVILEtBQUssV0FBVyxDQUFDLENBQUMsU0FBUyxXQUFXLElBQUk7S0FDdkMsQ0FBQyxJQUFJLE1BQU0sQ0FBQyxHQUFHLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0NBQzVFLENBQUE7QUFvQkQsZUFBTyxNQUFNLE9BQU8sR0FBSSxDQUFDLFNBQVMsV0FBVyxZQUFZLENBQUMsS0FBRztJQUFFLFVBQVUsRUFBRSxpQkFBaUIsQ0FBQyxDQUFDLENBQUMsQ0FBQTtDQUk5RixDQUFBO0FBRUQsZUFBTyxNQUFNLHFDQUFxQyxHQUFJLENBQUMsU0FBUyxXQUFXLEVBQUUsS0FBSyxDQUFDLFVBQVUsU0FBUyxNQUFNLFlBQ2hHLENBQUMsY0FDQyxVQUFVLG1EQXhCbkIsQ0FBQyxpTUE0Q0wsQ0FBQTtvSEF3SW9ELEtBQUssQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLENBQUMsWUFBWSxnQkFBZ0IsTUFPeEUsQ0FBQyxTQUFTLFdBQVc7QUFlOUQ7O0dBRUc7QUFDSCxxQkFBYSxnQkFDWCxTQUFRLHFCQUFtRztJQUUzRyxNQUFNLENBQUMsUUFBUSxDQUFDLEtBQUssV0FBWSxTQUFTLGlFQUN5RDtJQUNuRyxNQUFNLENBQUMsUUFBUSxDQUFDLGVBQWUsMkVBSzlCO0lBRUQsTUFBTSxDQUFDLFFBQVEsQ0FBQyxPQUFPLHVCQUNBLEtBQUssQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLENBQUMsWUFBWSxnQkFBZ0IsTUFDaEYsQ0FBQyxTQUFTLFdBQVcsWUFDVixDQUFDLDZIQUtUO0NBQ1AifQ==
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apiClientFactory.d.ts","sourceRoot":"","sources":["../../src/client/apiClientFactory.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,cAAc,CAAA;
|
|
1
|
+
{"version":3,"file":"apiClientFactory.d.ts","sourceRoot":"","sources":["../../src/client/apiClientFactory.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { flow } from "effect/Function";
|
|
3
3
|
import * as Layer from "effect/Layer";
|
|
4
4
|
import * as ManagedRuntime from "effect/ManagedRuntime";
|
|
5
|
+
import * as Option from "effect/Option";
|
|
5
6
|
import * as Predicate from "effect/Predicate";
|
|
6
7
|
import * as Schema from "effect/Schema";
|
|
7
8
|
import * as Struct from "effect/Struct";
|
|
@@ -10,8 +11,9 @@ import * as Config from "../Config.js";
|
|
|
10
11
|
import * as Context from "../Context.js";
|
|
11
12
|
import * as Effect from "../Effect.js";
|
|
12
13
|
import { HttpClient, HttpClientRequest } from "../http.js";
|
|
13
|
-
import
|
|
14
|
+
import { Invalidation } from "../rpc.js";
|
|
14
15
|
import { typedKeysOf, typedValuesOf } from "../utils.js";
|
|
16
|
+
import { InvalidationKeysFromServer } from "./InvalidationKeys.js";
|
|
15
17
|
export const DefaultApiConfig = Config.all({
|
|
16
18
|
url: Config.string("apiUrl").pipe(Config.withDefault("/api")),
|
|
17
19
|
headers: Config
|
|
@@ -54,7 +56,13 @@ export const makeRpcGroupFromRequestsAndModuleName = (resource, moduleName) => {
|
|
|
54
56
|
const filtered = getFiltered(resource);
|
|
55
57
|
const rpcs = RpcGroup
|
|
56
58
|
.make(...typedValuesOf(filtered).map((_) => {
|
|
57
|
-
return Rpc.make(_._tag, {
|
|
59
|
+
return Rpc.make(_._tag, {
|
|
60
|
+
payload: _,
|
|
61
|
+
success: _.type === "command"
|
|
62
|
+
? Invalidation.CommandResponseWithMetaData(_.success)
|
|
63
|
+
: _.success,
|
|
64
|
+
error: _.error
|
|
65
|
+
});
|
|
58
66
|
}))
|
|
59
67
|
.prefix(`${moduleName}.`);
|
|
60
68
|
return rpcs;
|
|
@@ -81,12 +89,16 @@ const makeApiClientFactory = Effect
|
|
|
81
89
|
// add ApiClientFactory for nested schemas
|
|
82
90
|
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
|
83
91
|
Layer.provide(Layer.succeed(ApiClientFactory, makeClientForCached)), Layer.provide(RpcClient
|
|
84
|
-
.layerProtocolHttp({
|
|
85
|
-
url: "" // why not here set meta.moduleName as root?
|
|
86
|
-
})
|
|
92
|
+
.layerProtocolHttp({ url: "" }) // why not here set meta.moduleName as root?
|
|
87
93
|
.pipe(Layer.provideMerge(Layer.succeedContext(ctx)))));
|
|
88
94
|
const mr = ManagedRuntime.make(clientLayer);
|
|
89
95
|
const filtered = getFiltered(resource);
|
|
96
|
+
const unwrapCommand = (eff) => eff.pipe(Effect.flatMap((result) => Effect.gen(function* () {
|
|
97
|
+
const keys = result?.metadata?.invalidateQueries ?? [];
|
|
98
|
+
const invalidationKeys = yield* InvalidationKeysFromServer;
|
|
99
|
+
yield* Effect.forEach(keys, (key) => invalidationKeys.add(key), { discard: true });
|
|
100
|
+
return result.payload;
|
|
101
|
+
})));
|
|
90
102
|
return {
|
|
91
103
|
mr,
|
|
92
104
|
client: typedKeysOf(filtered)
|
|
@@ -107,18 +119,25 @@ const makeApiClientFactory = Effect
|
|
|
107
119
|
const layers = requestLevelLayers.pipe(Layer.provideMerge(requestNameLayer));
|
|
108
120
|
const fields = Struct.omit(Request.fields, ["_tag"]);
|
|
109
121
|
const requestAttr = `${meta.moduleName}.${h._tag}`;
|
|
122
|
+
const isCommand = h.type === "command";
|
|
110
123
|
// @ts-expect-error doc
|
|
111
124
|
prev[cur] = Object.keys(fields).length === 0
|
|
112
125
|
? {
|
|
113
|
-
handler: mr.contextEffect.pipe(Effect.flatMap((svcs) =>
|
|
114
|
-
|
|
115
|
-
|
|
126
|
+
handler: mr.contextEffect.pipe(Effect.flatMap((svcs) => {
|
|
127
|
+
const rpcEffect = TheClient
|
|
128
|
+
.use((client) => client[requestAttr](Request.make({})))
|
|
129
|
+
.pipe(Effect.provide(layers), Effect.provide(svcs));
|
|
130
|
+
return isCommand ? unwrapCommand(rpcEffect) : rpcEffect;
|
|
131
|
+
})),
|
|
116
132
|
...requestMeta
|
|
117
133
|
}
|
|
118
134
|
: {
|
|
119
|
-
handler: (req) => mr.contextEffect.pipe(Effect.flatMap((svcs) =>
|
|
120
|
-
|
|
121
|
-
|
|
135
|
+
handler: (req) => mr.contextEffect.pipe(Effect.flatMap((svcs) => {
|
|
136
|
+
const rpcEffect = TheClient
|
|
137
|
+
.use((client) => client[requestAttr](Request.make(req)))
|
|
138
|
+
.pipe(Effect.provide(layers), Effect.provide(svcs));
|
|
139
|
+
return isCommand ? unwrapCommand(rpcEffect) : rpcEffect;
|
|
140
|
+
})),
|
|
122
141
|
...requestMeta
|
|
123
142
|
};
|
|
124
143
|
return prev;
|
|
@@ -161,4 +180,4 @@ export class ApiClientFactory extends Context.Opaque()("ApiClientFactory") {
|
|
|
161
180
|
return f(resource);
|
|
162
181
|
});
|
|
163
182
|
}
|
|
164
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBpQ2xpZW50RmFjdG9yeS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jbGllbnQvYXBpQ2xpZW50RmFjdG9yeS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSx1REFBdUQ7QUFDdkQsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLGlCQUFpQixDQUFBO0FBQ3RDLE9BQU8sS0FBSyxLQUFLLE1BQU0sY0FBYyxDQUFBO0FBQ3JDLE9BQU8sS0FBSyxjQUFjLE1BQU0sdUJBQXVCLENBQUE7QUFDdkQsT0FBTyxLQUFLLFNBQVMsTUFBTSxrQkFBa0IsQ0FBQTtBQUM3QyxPQUFPLEtBQUssTUFBTSxNQUFNLGVBQWUsQ0FBQTtBQUN2QyxPQUFPLEtBQUssTUFBTSxNQUFNLGVBQWUsQ0FBQTtBQUN2QyxPQUFPLEVBQUUsR0FBRyxFQUFFLFNBQVMsRUFBRSxRQUFRLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQTtBQUNoRixPQUFPLEtBQUssTUFBTSxNQUFNLGNBQWMsQ0FBQTtBQUN0QyxPQUFPLEtBQUssT0FBTyxNQUFNLGVBQWUsQ0FBQTtBQUN4QyxPQUFPLEtBQUssTUFBTSxNQUFNLGNBQWMsQ0FBQTtBQUN0QyxPQUFPLEVBQUUsVUFBVSxFQUFFLGlCQUFpQixFQUFFLE1BQU0sWUFBWSxDQUFBO0FBQzFELE9BQU8sS0FBSyxNQUFNLE1BQU0sY0FBYyxDQUFBO0FBRXRDLE9BQU8sRUFBRSxXQUFXLEVBQUUsYUFBYSxFQUFFLE1BQU0sYUFBYSxDQUFBO0FBUXhELE1BQU0sQ0FBQyxNQUFNLGdCQUFnQixHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUM7SUFDekMsR0FBRyxFQUFFLE1BQU0sQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDN0QsT0FBTyxFQUFFLE1BQU07U0FDWixNQUFNLENBQ0wsTUFBTSxDQUFDLE1BQU0sQ0FBQyxN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
|
|
183
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBpQ2xpZW50RmFjdG9yeS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jbGllbnQvYXBpQ2xpZW50RmFjdG9yeS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSx1REFBdUQ7QUFDdkQsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLGlCQUFpQixDQUFBO0FBQ3RDLE9BQU8sS0FBSyxLQUFLLE1BQU0sY0FBYyxDQUFBO0FBQ3JDLE9BQU8sS0FBSyxjQUFjLE1BQU0sdUJBQXVCLENBQUE7QUFDdkQsT0FBTyxLQUFLLE1BQU0sTUFBTSxlQUFlLENBQUE7QUFDdkMsT0FBTyxLQUFLLFNBQVMsTUFBTSxrQkFBa0IsQ0FBQTtBQUM3QyxPQUFPLEtBQUssTUFBTSxNQUFNLGVBQWUsQ0FBQTtBQUN2QyxPQUFPLEtBQUssTUFBTSxNQUFNLGVBQWUsQ0FBQTtBQUN2QyxPQUFPLEVBQUUsR0FBRyxFQUFFLFNBQVMsRUFBRSxRQUFRLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQTtBQUNoRixPQUFPLEtBQUssTUFBTSxNQUFNLGNBQWMsQ0FBQTtBQUN0QyxPQUFPLEtBQUssT0FBTyxNQUFNLGVBQWUsQ0FBQTtBQUN4QyxPQUFPLEtBQUssTUFBTSxNQUFNLGNBQWMsQ0FBQTtBQUN0QyxPQUFPLEVBQUUsVUFBVSxFQUFFLGlCQUFpQixFQUFFLE1BQU0sWUFBWSxDQUFBO0FBQzFELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxXQUFXLENBQUE7QUFFeEMsT0FBTyxFQUFFLFdBQVcsRUFBRSxhQUFhLEVBQUUsTUFBTSxhQUFhLENBQUE7QUFFeEQsT0FBTyxFQUFFLDBCQUEwQixFQUFFLE1BQU0sdUJBQXVCLENBQUE7QUFPbEUsTUFBTSxDQUFDLE1BQU0sZ0JBQWdCLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQztJQUN6QyxHQUFHLEVBQUUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxD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
|
package/dist/client.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export * from "./client/apiClientFactory.js";
|
|
2
2
|
export * from "./client/clientFor.js";
|
|
3
3
|
export * from "./client/errors.js";
|
|
4
|
+
export * from "./client/InvalidationKeys.js";
|
|
4
5
|
export * from "./client/makeClient.js";
|
|
5
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
6
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xpZW50LmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvY2xpZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLGNBQWMsOEJBQThCLENBQUE7QUFDNUMsY0FBYyx1QkFBdUIsQ0FBQTtBQUNyQyxjQUFjLG9CQUFvQixDQUFBO0FBQ2xDLGNBQWMsOEJBQThCLENBQUE7QUFDNUMsY0FBYyx3QkFBd0IsQ0FBQSJ9
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AACA,cAAc,8BAA8B,CAAA;AAC5C,cAAc,uBAAuB,CAAA;AACrC,cAAc,oBAAoB,CAAA;AAClC,cAAc,wBAAwB,CAAA"}
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AACA,cAAc,8BAA8B,CAAA;AAC5C,cAAc,uBAAuB,CAAA;AACrC,cAAc,oBAAoB,CAAA;AAClC,cAAc,8BAA8B,CAAA;AAC5C,cAAc,wBAAwB,CAAA"}
|
package/dist/client.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
export * from "./client/apiClientFactory.js";
|
|
3
3
|
export * from "./client/clientFor.js";
|
|
4
4
|
export * from "./client/errors.js";
|
|
5
|
+
export * from "./client/InvalidationKeys.js";
|
|
5
6
|
export * from "./client/makeClient.js";
|
|
6
7
|
// codegen:end
|
|
7
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
8
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xpZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2NsaWVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSx5REFBeUQ7QUFDekQsY0FBYyw4QkFBOEIsQ0FBQTtBQUM1QyxjQUFjLHVCQUF1QixDQUFBO0FBQ3JDLGNBQWMsb0JBQW9CLENBQUE7QUFDbEMsY0FBYyw4QkFBOEIsQ0FBQTtBQUM1QyxjQUFjLHdCQUF3QixDQUFBO0FBQ3RDLGNBQWMifQ==
|
package/dist/middleware.d.ts
CHANGED
|
@@ -27,6 +27,13 @@ declare const DevModeMiddleware_base: RpcMiddleware.TagClass<DevModeMiddleware,
|
|
|
27
27
|
}>;
|
|
28
28
|
export declare class DevModeMiddleware extends DevModeMiddleware_base {
|
|
29
29
|
}
|
|
30
|
-
|
|
30
|
+
declare const InvalidationMiddleware_base: RpcMiddleware.TagClass<InvalidationMiddleware, "InvalidationMiddleware", {}, {
|
|
31
|
+
requires: never;
|
|
32
|
+
provides: never;
|
|
33
|
+
}>;
|
|
34
|
+
/** RPC middleware that reads the `Invalidates` annotation and populates `InvalidationSet` before the handler runs. */
|
|
35
|
+
export declare class InvalidationMiddleware extends InvalidationMiddleware_base {
|
|
36
|
+
}
|
|
37
|
+
export declare const DefaultGenericMiddlewares: readonly [typeof RequestCacheMiddleware, typeof ConfigureInterruptibilityMiddleware, typeof LoggerMiddleware, typeof DevModeMiddleware, typeof InvalidationMiddleware];
|
|
31
38
|
export {};
|
|
32
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
39
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWlkZGxld2FyZS5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL21pZGRsZXdhcmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLFlBQVksQ0FBQTtBQUNwQyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sVUFBVSxDQUFBOztBQUV4QyxxQkFBYSxPQUFRLFNBQVEsWUFBMkQ7Q0FBRzs7Ozs7QUFFM0YscUJBQWEsc0JBQXVCLFNBQVEsMkJBQXFFO0NBQUc7Ozs7O0FBRXBILHFCQUFhLG1DQUNYLFNBQVEsd0NBQStGO0NBQ3ZHOzs7OztBQUVGLHFCQUFhLGdCQUFpQixTQUFRLHFCQUF5RDtDQUFHOzs7OztBQUVsRyxxQkFBYSxpQkFBa0IsU0FBUSxzQkFBMkQ7Q0FBRzs7Ozs7QUFFckcsc0hBQXNIO0FBQ3RILHFCQUFhLHNCQUF1QixTQUFRLDJCQUFxRTtDQUFHO0FBRXBILGVBQU8sTUFBTSx5QkFBeUIsd0tBTTVCLENBQUEifQ==
|
package/dist/middleware.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;;AAExC,qBAAa,OAAQ,SAAQ,YAA2D;CAAG;;;;;AAE3F,qBAAa,sBAAuB,SAAQ,2BAAqE;CAAG;;;;;AAEpH,qBAAa,mCACX,SAAQ,wCAA+F;CACvG;;;;;AAEF,qBAAa,gBAAiB,SAAQ,qBAAyD;CAAG;;;;;AAElG,qBAAa,iBAAkB,SAAQ,sBAA2D;CAAG
|
|
1
|
+
{"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;;AAExC,qBAAa,OAAQ,SAAQ,YAA2D;CAAG;;;;;AAE3F,qBAAa,sBAAuB,SAAQ,2BAAqE;CAAG;;;;;AAEpH,qBAAa,mCACX,SAAQ,wCAA+F;CACvG;;;;;AAEF,qBAAa,gBAAiB,SAAQ,qBAAyD;CAAG;;;;;AAElG,qBAAa,iBAAkB,SAAQ,sBAA2D;CAAG;;;;;AAErG,sHAAsH;AACtH,qBAAa,sBAAuB,SAAQ,2BAAqE;CAAG;AAEpH,eAAO,MAAM,yBAAyB,wKAM5B,CAAA"}
|
package/dist/middleware.js
CHANGED
|
@@ -11,10 +11,14 @@ export class LoggerMiddleware extends RpcMiddleware.Tag()("LoggerMiddleware") {
|
|
|
11
11
|
}
|
|
12
12
|
export class DevModeMiddleware extends RpcMiddleware.Tag()("DevModeMiddleware") {
|
|
13
13
|
}
|
|
14
|
+
/** RPC middleware that reads the `Invalidates` annotation and populates `InvalidationSet` before the handler runs. */
|
|
15
|
+
export class InvalidationMiddleware extends RpcMiddleware.Tag()("InvalidationMiddleware") {
|
|
16
|
+
}
|
|
14
17
|
export const DefaultGenericMiddlewares = [
|
|
15
18
|
RequestCacheMiddleware,
|
|
16
19
|
ConfigureInterruptibilityMiddleware,
|
|
17
20
|
LoggerMiddleware,
|
|
18
|
-
DevModeMiddleware
|
|
21
|
+
DevModeMiddleware,
|
|
22
|
+
InvalidationMiddleware
|
|
19
23
|
];
|
|
20
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
24
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWlkZGxld2FyZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9taWRkbGV3YXJlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLHVEQUF1RDtBQUN2RCxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sWUFBWSxDQUFBO0FBQ3BDLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxVQUFVLENBQUE7QUFFeEMsTUFBTSxPQUFPLE9BQVEsU0FBUSxPQUFPLENBQUMsU0FBUyxDQUFDLFNBQVMsRUFBRSxFQUFFLFlBQVksRUFBRSxHQUFHLEVBQUUsQ0FBQyxLQUFLLEVBQUUsQ0FBQztDQUFHO0FBRTNGLE1BQU0sT0FBTyxzQkFBdUIsU0FBUSxhQUFhLENBQUMsR0FBRyxFQUEwQixDQUFDLHdCQUF3QixDQUFDO0NBQUc7QUFFcEgsTUFBTSxPQUFPLG1DQUNYLFNBQVEsYUFBYSxDQUFDLEdBQUcsRUFBdUMsQ0FBQyxxQ0FBcUMsQ0FBQztDQUN2RztBQUVGLE1BQU0sT0FBTyxnQkFBaUIsU0FBUSxhQUFhLENBQUMsR0FBRyxFQUFvQixDQUFDLGtCQUFrQixDQUFDO0NBQUc7QUFFbEcsTUFBTSxPQUFPLGlCQUFrQixTQUFRLGFBQWEsQ0FBQyxHQUFHLEVBQXFCLENBQUMsbUJBQW1CLENBQUM7Q0FBRztBQUVyRyxzSEFBc0g7QUFDdEgsTUFBTSxPQUFPLHNCQUF1QixTQUFRLGFBQWEsQ0FBQyxHQUFHLEVBQTBCLENBQUMsd0JBQXdCLENBQUM7Q0FBRztBQUVwSCxNQUFNLENBQUMsTUFBTSx5QkFBeUIsR0FBRztJQUN2QyxzQkFBc0I7SUFDdEIsbUNBQW1DO0lBQ25DLGdCQUFnQjtJQUNoQixpQkFBaUI7SUFDakIsc0JBQXNCO0NBQ2QsQ0FBQSJ9
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import * as Ref from "effect/Ref";
|
|
2
|
+
import * as Context from "../Context.js";
|
|
3
|
+
import * as Effect from "../Effect.js";
|
|
4
|
+
import * as S from "../Schema.js";
|
|
5
|
+
/**
|
|
6
|
+
* A single segment within an `InvalidationKey` array.
|
|
7
|
+
* Accepts any JSON-compatible value: string, number, boolean, null,
|
|
8
|
+
* arrays and objects recursively — matching TanStack Query's `queryKey` element type.
|
|
9
|
+
*/
|
|
10
|
+
export declare const InvalidationKeySegment: S.Codec<S.Json, S.Json, never, never>;
|
|
11
|
+
export type InvalidationKeySegment = S.Schema.Type<typeof InvalidationKeySegment>;
|
|
12
|
+
/** Schema for a single invalidation key – an array of segments compatible with TanStack Query `queryKey`. */
|
|
13
|
+
export declare const InvalidationKey: S.$Array<S.Codec<S.Json, S.Json, never, never>> & {
|
|
14
|
+
withDefault: S.withConstructorDefault<S.$Array<S.Codec<S.Json, S.Json, never, never>>>;
|
|
15
|
+
withDecodingDefaultType: S.withDecodingDefaultType<S.$Array<S.Codec<S.Json, S.Json, never, never>>>;
|
|
16
|
+
};
|
|
17
|
+
export type InvalidationKey = S.Schema.Type<typeof InvalidationKey>;
|
|
18
|
+
/** Schema for the full set of invalidation keys – an array of `InvalidationKey`. */
|
|
19
|
+
export declare const InvalidationKeys: S.$Array<S.$Array<S.Codec<S.Json, S.Json, never, never>> & {
|
|
20
|
+
withDefault: S.withConstructorDefault<S.$Array<S.Codec<S.Json, S.Json, never, never>>>;
|
|
21
|
+
withDecodingDefaultType: S.withDecodingDefaultType<S.$Array<S.Codec<S.Json, S.Json, never, never>>>;
|
|
22
|
+
}> & {
|
|
23
|
+
withDefault: S.withConstructorDefault<S.$Array<S.$Array<S.Codec<S.Json, S.Json, never, never>> & {
|
|
24
|
+
withDefault: S.withConstructorDefault<S.$Array<S.Codec<S.Json, S.Json, never, never>>>;
|
|
25
|
+
withDecodingDefaultType: S.withDecodingDefaultType<S.$Array<S.Codec<S.Json, S.Json, never, never>>>;
|
|
26
|
+
}>>;
|
|
27
|
+
withDecodingDefaultType: S.withDecodingDefaultType<S.$Array<S.$Array<S.Codec<S.Json, S.Json, never, never>> & {
|
|
28
|
+
withDefault: S.withConstructorDefault<S.$Array<S.Codec<S.Json, S.Json, never, never>>>;
|
|
29
|
+
withDecodingDefaultType: S.withDecodingDefaultType<S.$Array<S.Codec<S.Json, S.Json, never, never>>>;
|
|
30
|
+
}>>;
|
|
31
|
+
};
|
|
32
|
+
export type InvalidationKeys = S.Schema.Type<typeof InvalidationKeys>;
|
|
33
|
+
/** Metadata included in every command response for server-driven cache invalidation. */
|
|
34
|
+
export declare const CommandMetaData: S.Struct<{
|
|
35
|
+
readonly invalidateQueries: S.$Array<S.$Array<S.Codec<S.Json, S.Json, never, never>> & {
|
|
36
|
+
withDefault: S.withConstructorDefault<S.$Array<S.Codec<S.Json, S.Json, never, never>>>;
|
|
37
|
+
withDecodingDefaultType: S.withDecodingDefaultType<S.$Array<S.Codec<S.Json, S.Json, never, never>>>;
|
|
38
|
+
}> & {
|
|
39
|
+
withDefault: S.withConstructorDefault<S.$Array<S.$Array<S.Codec<S.Json, S.Json, never, never>> & {
|
|
40
|
+
withDefault: S.withConstructorDefault<S.$Array<S.Codec<S.Json, S.Json, never, never>>>;
|
|
41
|
+
withDecodingDefaultType: S.withDecodingDefaultType<S.$Array<S.Codec<S.Json, S.Json, never, never>>>;
|
|
42
|
+
}>>;
|
|
43
|
+
withDecodingDefaultType: S.withDecodingDefaultType<S.$Array<S.$Array<S.Codec<S.Json, S.Json, never, never>> & {
|
|
44
|
+
withDefault: S.withConstructorDefault<S.$Array<S.Codec<S.Json, S.Json, never, never>>>;
|
|
45
|
+
withDecodingDefaultType: S.withDecodingDefaultType<S.$Array<S.Codec<S.Json, S.Json, never, never>>>;
|
|
46
|
+
}>>;
|
|
47
|
+
};
|
|
48
|
+
}>;
|
|
49
|
+
export type CommandMetaData = S.Schema.Type<typeof CommandMetaData>;
|
|
50
|
+
/**
|
|
51
|
+
* Wraps a command's success schema so that the wire format carries both the `payload`
|
|
52
|
+
* (the handler's actual return value) and `metadata` (server-driven cache invalidation keys).
|
|
53
|
+
* Transparent to users: the server handler returns the plain payload and the client receives
|
|
54
|
+
* the plain payload — wrapping/unwrapping is handled internally by the routing layer.
|
|
55
|
+
*/
|
|
56
|
+
export declare const CommandResponseWithMetaData: <S extends S.Top>(success: S) => S.Struct<{
|
|
57
|
+
readonly payload: S;
|
|
58
|
+
readonly metadata: S.Struct<{
|
|
59
|
+
readonly invalidateQueries: S.$Array<S.$Array<S.Codec<S.Json, S.Json, never, never>> & {
|
|
60
|
+
withDefault: S.withConstructorDefault<S.$Array<S.Codec<S.Json, S.Json, never, never>>>;
|
|
61
|
+
withDecodingDefaultType: S.withDecodingDefaultType<S.$Array<S.Codec<S.Json, S.Json, never, never>>>;
|
|
62
|
+
}> & {
|
|
63
|
+
withDefault: S.withConstructorDefault<S.$Array<S.$Array<S.Codec<S.Json, S.Json, never, never>> & {
|
|
64
|
+
withDefault: S.withConstructorDefault<S.$Array<S.Codec<S.Json, S.Json, never, never>>>;
|
|
65
|
+
withDecodingDefaultType: S.withDecodingDefaultType<S.$Array<S.Codec<S.Json, S.Json, never, never>>>;
|
|
66
|
+
}>>;
|
|
67
|
+
withDecodingDefaultType: S.withDecodingDefaultType<S.$Array<S.$Array<S.Codec<S.Json, S.Json, never, never>> & {
|
|
68
|
+
withDefault: S.withConstructorDefault<S.$Array<S.Codec<S.Json, S.Json, never, never>>>;
|
|
69
|
+
withDecodingDefaultType: S.withDecodingDefaultType<S.$Array<S.Codec<S.Json, S.Json, never, never>>>;
|
|
70
|
+
}>>;
|
|
71
|
+
};
|
|
72
|
+
}>;
|
|
73
|
+
}> & ({} extends (import("effect/Schema").Struct.MakeIn_<{
|
|
74
|
+
readonly payload: S;
|
|
75
|
+
readonly metadata: S.Struct<{
|
|
76
|
+
readonly invalidateQueries: S.$Array<S.$Array<S.Codec<S.Json, S.Json, never, never>> & {
|
|
77
|
+
withDefault: S.withConstructorDefault<S.$Array<S.Codec<S.Json, S.Json, never, never>>>;
|
|
78
|
+
withDecodingDefaultType: S.withDecodingDefaultType<S.$Array<S.Codec<S.Json, S.Json, never, never>>>;
|
|
79
|
+
}> & {
|
|
80
|
+
withDefault: S.withConstructorDefault<S.$Array<S.$Array<S.Codec<S.Json, S.Json, never, never>> & {
|
|
81
|
+
withDefault: S.withConstructorDefault<S.$Array<S.Codec<S.Json, S.Json, never, never>>>;
|
|
82
|
+
withDecodingDefaultType: S.withDecodingDefaultType<S.$Array<S.Codec<S.Json, S.Json, never, never>>>;
|
|
83
|
+
}>>;
|
|
84
|
+
withDecodingDefaultType: S.withDecodingDefaultType<S.$Array<S.$Array<S.Codec<S.Json, S.Json, never, never>> & {
|
|
85
|
+
withDefault: S.withConstructorDefault<S.$Array<S.Codec<S.Json, S.Json, never, never>>>;
|
|
86
|
+
withDecodingDefaultType: S.withDecodingDefaultType<S.$Array<S.Codec<S.Json, S.Json, never, never>>>;
|
|
87
|
+
}>>;
|
|
88
|
+
};
|
|
89
|
+
}>;
|
|
90
|
+
}, (S extends {
|
|
91
|
+
readonly "~type.optionality": "optional";
|
|
92
|
+
} ? "payload" : never) | (S extends {
|
|
93
|
+
readonly "~type.constructor.default": "with-default";
|
|
94
|
+
} ? "payload" : never)> extends infer T ? { [K in keyof T]: T[K]; } : never) ? {
|
|
95
|
+
make(input?: (import("effect/Schema").Struct.MakeIn_<{
|
|
96
|
+
readonly payload: S;
|
|
97
|
+
readonly metadata: S.Struct<{
|
|
98
|
+
readonly invalidateQueries: S.$Array<S.$Array<S.Codec<S.Json, S.Json, never, never>> & {
|
|
99
|
+
withDefault: S.withConstructorDefault<S.$Array<S.Codec<S.Json, S.Json, never, never>>>;
|
|
100
|
+
withDecodingDefaultType: S.withDecodingDefaultType<S.$Array<S.Codec<S.Json, S.Json, never, never>>>;
|
|
101
|
+
}> & {
|
|
102
|
+
withDefault: S.withConstructorDefault<S.$Array<S.$Array<S.Codec<S.Json, S.Json, never, never>> & {
|
|
103
|
+
withDefault: S.withConstructorDefault<S.$Array<S.Codec<S.Json, S.Json, never, never>>>;
|
|
104
|
+
withDecodingDefaultType: S.withDecodingDefaultType<S.$Array<S.Codec<S.Json, S.Json, never, never>>>;
|
|
105
|
+
}>>;
|
|
106
|
+
withDecodingDefaultType: S.withDecodingDefaultType<S.$Array<S.$Array<S.Codec<S.Json, S.Json, never, never>> & {
|
|
107
|
+
withDefault: S.withConstructorDefault<S.$Array<S.Codec<S.Json, S.Json, never, never>>>;
|
|
108
|
+
withDecodingDefaultType: S.withDecodingDefaultType<S.$Array<S.Codec<S.Json, S.Json, never, never>>>;
|
|
109
|
+
}>>;
|
|
110
|
+
};
|
|
111
|
+
}>;
|
|
112
|
+
}, (S extends {
|
|
113
|
+
readonly "~type.optionality": "optional";
|
|
114
|
+
} ? "payload" : never) | (S extends {
|
|
115
|
+
readonly "~type.constructor.default": "with-default";
|
|
116
|
+
} ? "payload" : never)> extends infer T_1 ? { [K in keyof T_1]: T_1[K]; } : never) | undefined, options?: S.MakeOptions): import("effect/Schema").Struct.Type_<{
|
|
117
|
+
readonly payload: S;
|
|
118
|
+
readonly metadata: S.Struct<{
|
|
119
|
+
readonly invalidateQueries: S.$Array<S.$Array<S.Codec<S.Json, S.Json, never, never>> & {
|
|
120
|
+
withDefault: S.withConstructorDefault<S.$Array<S.Codec<S.Json, S.Json, never, never>>>;
|
|
121
|
+
withDecodingDefaultType: S.withDecodingDefaultType<S.$Array<S.Codec<S.Json, S.Json, never, never>>>;
|
|
122
|
+
}> & {
|
|
123
|
+
withDefault: S.withConstructorDefault<S.$Array<S.$Array<S.Codec<S.Json, S.Json, never, never>> & {
|
|
124
|
+
withDefault: S.withConstructorDefault<S.$Array<S.Codec<S.Json, S.Json, never, never>>>;
|
|
125
|
+
withDecodingDefaultType: S.withDecodingDefaultType<S.$Array<S.Codec<S.Json, S.Json, never, never>>>;
|
|
126
|
+
}>>;
|
|
127
|
+
withDecodingDefaultType: S.withDecodingDefaultType<S.$Array<S.$Array<S.Codec<S.Json, S.Json, never, never>> & {
|
|
128
|
+
withDefault: S.withConstructorDefault<S.$Array<S.Codec<S.Json, S.Json, never, never>>>;
|
|
129
|
+
withDecodingDefaultType: S.withDecodingDefaultType<S.$Array<S.Codec<S.Json, S.Json, never, never>>>;
|
|
130
|
+
}>>;
|
|
131
|
+
};
|
|
132
|
+
}>;
|
|
133
|
+
}, S extends {
|
|
134
|
+
readonly "~type.optionality": "optional";
|
|
135
|
+
} ? "payload" : never, S extends {
|
|
136
|
+
readonly "~type.mutability": "mutable";
|
|
137
|
+
} ? "payload" : never> extends infer T_2 ? { [K in keyof T_2]: T_2[K]; } : never;
|
|
138
|
+
} : {});
|
|
139
|
+
/**
|
|
140
|
+
* Context annotation for declaring static cache invalidation keys on a low-level `Rpc` definition.
|
|
141
|
+
* These keys are always included in the command response metadata, regardless of the handler logic.
|
|
142
|
+
*
|
|
143
|
+
* Prefer using `makeQueryKey` over raw string arrays to stay in sync with the actual query
|
|
144
|
+
* definitions without manual string maintenance:
|
|
145
|
+
*
|
|
146
|
+
* ```ts
|
|
147
|
+
* import { makeQueryKey } from "effect-app/client"
|
|
148
|
+
* import { Invalidation } from "effect-app/rpc"
|
|
149
|
+
* import * as UserRsc from "../User/index.js" // separate module to avoid circular deps
|
|
150
|
+
*
|
|
151
|
+
* class UpdateProfile extends Rpc.make("UpdateProfile", { ... })
|
|
152
|
+
* .annotate(Invalidation.Invalidates, [makeQueryKey(UserRsc.GetMe), makeQueryKey(UserRsc.GetProfile)]) {}
|
|
153
|
+
* ```
|
|
154
|
+
*
|
|
155
|
+
* **Circular dependency note:** if mutations and queries live in the same file you may hit a
|
|
156
|
+
* circular reference at evaluation time. The idiomatic fix is to move mutations into their own
|
|
157
|
+
* module (e.g. `User/mutations.ts`) that directly imports the relevant query classes rather than
|
|
158
|
+
* re-exporting them through a barrel.
|
|
159
|
+
*
|
|
160
|
+
* For the higher-level `Command`/`Query` builders from `makeRpcClient`, use the
|
|
161
|
+
* `invalidatesQueries` callback argument instead (it receives the same query keys at runtime).
|
|
162
|
+
*/
|
|
163
|
+
export declare const Invalidates: Context.Reference<readonly (readonly S.Json[])[]>;
|
|
164
|
+
export type Invalidates = typeof Invalidates;
|
|
165
|
+
/** The shape of the per-request service that accumulates invalidation keys. */
|
|
166
|
+
export interface InvalidationSetService {
|
|
167
|
+
readonly add: (key: InvalidationKey) => Effect.Effect<void>;
|
|
168
|
+
readonly get: Effect.Effect<ReadonlyArray<InvalidationKey>>;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Request-scoped service for accumulating invalidation keys dynamically inside a handler.
|
|
172
|
+
* Provided by `InvalidationMiddlewareLive` for every RPC call; has a no-op default so it is
|
|
173
|
+
* safe to use even when the HTTP middleware is absent (tests, workers, etc.).
|
|
174
|
+
*
|
|
175
|
+
* Use `InvalidationSet.use(_ => _.add(key))` (or `.useSync` for non-Effect callbacks) as a
|
|
176
|
+
* shorthand instead of yielding the service manually.
|
|
177
|
+
*
|
|
178
|
+
* Prefer `makeQueryKey` over raw string arrays so invalidation keys stay in sync with the
|
|
179
|
+
* actual query definitions automatically:
|
|
180
|
+
*
|
|
181
|
+
* ```ts
|
|
182
|
+
* import { makeQueryKey } from "effect-app/client"
|
|
183
|
+
* import { Effect } from "effect"
|
|
184
|
+
* import { Invalidation } from "effect-app/rpc"
|
|
185
|
+
* import * as CartRsc from "../Cart/queries.js"
|
|
186
|
+
* import * as UserRsc from "../User/queries.js"
|
|
187
|
+
*
|
|
188
|
+
* const handler = Effect.fnUntraced(function*(req: UpdateCartRequest) {
|
|
189
|
+
* const cart = yield* CartRepo.save(req.cart)
|
|
190
|
+
*
|
|
191
|
+
* // Stage 1 – unconditional: always invalidate after saving
|
|
192
|
+
* yield* Invalidation.InvalidationSet.use(_ => _.add(makeQueryKey(UserRsc.GetMe)))
|
|
193
|
+
*
|
|
194
|
+
* // Stage 2 – conditional: only if the cart changed state
|
|
195
|
+
* if (cart.isCheckedOut) {
|
|
196
|
+
* yield* Invalidation.InvalidationSet.use(_ => _.add(makeQueryKey(CartRsc.GetCartStats)))
|
|
197
|
+
* }
|
|
198
|
+
*
|
|
199
|
+
* return cart
|
|
200
|
+
* })
|
|
201
|
+
* ```
|
|
202
|
+
*
|
|
203
|
+
* You can combine static (`Invalidates` annotation) and dynamic (`InvalidationSet.use`) keys:
|
|
204
|
+
* the annotation pre-populates the set before the handler runs; dynamic additions accumulate
|
|
205
|
+
* throughout the handler. All keys are included in the command response metadata.
|
|
206
|
+
*/
|
|
207
|
+
export declare const InvalidationSet: Context.Reference<InvalidationSetService>;
|
|
208
|
+
export type InvalidationSet = typeof InvalidationSet;
|
|
209
|
+
/** Creates a fresh `InvalidationSet` implementation backed by a `Ref`. */
|
|
210
|
+
export declare const makeInvalidationSet: (ref: Ref.Ref<ReadonlyArray<InvalidationKey>>) => InvalidationSetService;
|
|
211
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiSW52YWxpZGF0aW9uLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcnBjL0ludmFsaWRhdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssR0FBRyxNQUFNLFlBQVksQ0FBQTtBQUNqQyxPQUFPLEtBQUssT0FBTyxNQUFNLGVBQWUsQ0FBQTtBQUN4QyxPQUFPLEtBQUssTUFBTSxNQUFNLGNBQWMsQ0FBQTtBQUN0QyxPQUFPLEtBQUssQ0FBQyxNQUFNLGNBQWMsQ0FBQTtBQUVqQzs7OztHQUlHO0FBQ0gsZUFBTyxNQUFNLHNCQUFzQix1Q0FBUyxDQUFBO0FBQzVDLE1BQU0sTUFBTSxzQkFBc0IsR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLHNCQUFzQixDQUFDLENBQUE7QUFFakYsNkdBQTZHO0FBQzdHLGVBQU8sTUFBTSxlQUFlOzs7Q0FBa0MsQ0FBQTtBQUM5RCxNQUFNLE1BQU0sZUFBZSxHQUFHLENBQUMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sZUFBZSxDQUFDLENBQUE7QUFFbkUsb0ZBQW9GO0FBQ3BGLGVBQU8sTUFBTSxnQkFBZ0I7Ozs7Ozs7Ozs7OztDQUEyQixDQUFBO0FBQ3hELE1BQU0sTUFBTSxnQkFBZ0IsR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLGdCQUFnQixDQUFDLENBQUE7QUFFckUsd0ZBQXdGO0FBQ3hGLGVBQU8sTUFBTSxlQUFlOzs7Ozs7Ozs7Ozs7OztFQUFvRCxDQUFBO0FBQ2hGLE1BQU0sTUFBTSxlQUFlLEdBQUcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxlQUFlLENBQUMsQ0FBQTtBQUVuRTs7Ozs7R0FLRztBQUNILGVBQU8sTUFBTSwyQkFBMkIsR0FBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLEdBQUcsV0FBVyxDQUFDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O09BQ1osQ0FBQTtBQUUzRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0F1Qkc7QUFDSCxlQUFPLE1BQU0sV0FBVyxtREFHdkIsQ0FBQTtBQUNELE1BQU0sTUFBTSxXQUFXLEdBQUcsT0FBTyxXQUFXLENBQUE7QUFFNUMsK0VBQStFO0FBQy9FLE1BQU0sV0FBVyxzQkFBc0I7SUFDckMsUUFBUSxDQUFDLEdBQUcsRUFBRSxDQUFDLEdBQUcsRUFBRSxlQUFlLEtBQUssTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQTtJQUMzRCxRQUFRLENBQUMsR0FBRyxFQUFFLE1BQU0sQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUE7Q0FDNUQ7QUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBb0NHO0FBQ0gsZUFBTyxNQUFNLGVBQWUsMkNBUTNCLENBQUE7QUFDRCxNQUFNLE1BQU0sZUFBZSxHQUFHLE9BQU8sZUFBZSxDQUFBO0FBRXBELDBFQUEwRTtBQUMxRSxlQUFPLE1BQU0sbUJBQW1CLFFBQVMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxhQUFhLENBQUMsZUFBZSxDQUFDLENBQUMsS0FBRyxzQkFHakYsQ0FBQSJ9
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Invalidation.d.ts","sourceRoot":"","sources":["../../src/rpc/Invalidation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,YAAY,CAAA;AACjC,OAAO,KAAK,OAAO,MAAM,eAAe,CAAA;AACxC,OAAO,KAAK,MAAM,MAAM,cAAc,CAAA;AACtC,OAAO,KAAK,CAAC,MAAM,cAAc,CAAA;AAEjC;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,uCAAS,CAAA;AAC5C,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,sBAAsB,CAAC,CAAA;AAEjF,6GAA6G;AAC7G,eAAO,MAAM,eAAe;;;CAAkC,CAAA;AAC9D,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,eAAe,CAAC,CAAA;AAEnE,oFAAoF;AACpF,eAAO,MAAM,gBAAgB;;;;;;;;;;;;CAA2B,CAAA;AACxD,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,gBAAgB,CAAC,CAAA;AAErE,wFAAwF;AACxF,eAAO,MAAM,eAAe;;;;;;;;;;;;;;EAAoD,CAAA;AAChF,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,eAAe,CAAC,CAAA;AAEnE;;;;;GAKG;AACH,eAAO,MAAM,2BAA2B,GAAI,CAAC,SAAS,CAAC,CAAC,GAAG,WAAW,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OACZ,CAAA;AAE3D;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,WAAW,mDAGvB,CAAA;AACD,MAAM,MAAM,WAAW,GAAG,OAAO,WAAW,CAAA;AAE5C,+EAA+E;AAC/E,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,eAAe,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IAC3D,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,eAAe,CAAC,CAAC,CAAA;CAC5D;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,eAAO,MAAM,eAAe,2CAQ3B,CAAA;AACD,MAAM,MAAM,eAAe,GAAG,OAAO,eAAe,CAAA;AAEpD,0EAA0E;AAC1E,eAAO,MAAM,mBAAmB,QAAS,GAAG,CAAC,GAAG,CAAC,aAAa,CAAC,eAAe,CAAC,CAAC,KAAG,sBAGjF,CAAA"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import * as Ref from "effect/Ref";
|
|
2
|
+
import * as Context from "../Context.js";
|
|
3
|
+
import * as Effect from "../Effect.js";
|
|
4
|
+
import * as S from "../Schema.js";
|
|
5
|
+
/**
|
|
6
|
+
* A single segment within an `InvalidationKey` array.
|
|
7
|
+
* Accepts any JSON-compatible value: string, number, boolean, null,
|
|
8
|
+
* arrays and objects recursively — matching TanStack Query's `queryKey` element type.
|
|
9
|
+
*/
|
|
10
|
+
export const InvalidationKeySegment = S.Json;
|
|
11
|
+
/** Schema for a single invalidation key – an array of segments compatible with TanStack Query `queryKey`. */
|
|
12
|
+
export const InvalidationKey = S.Array(InvalidationKeySegment);
|
|
13
|
+
/** Schema for the full set of invalidation keys – an array of `InvalidationKey`. */
|
|
14
|
+
export const InvalidationKeys = S.Array(InvalidationKey);
|
|
15
|
+
/** Metadata included in every command response for server-driven cache invalidation. */
|
|
16
|
+
export const CommandMetaData = S.Struct({ invalidateQueries: InvalidationKeys });
|
|
17
|
+
/**
|
|
18
|
+
* Wraps a command's success schema so that the wire format carries both the `payload`
|
|
19
|
+
* (the handler's actual return value) and `metadata` (server-driven cache invalidation keys).
|
|
20
|
+
* Transparent to users: the server handler returns the plain payload and the client receives
|
|
21
|
+
* the plain payload — wrapping/unwrapping is handled internally by the routing layer.
|
|
22
|
+
*/
|
|
23
|
+
export const CommandResponseWithMetaData = (success) => S.Struct({ payload: success, metadata: CommandMetaData });
|
|
24
|
+
/**
|
|
25
|
+
* Context annotation for declaring static cache invalidation keys on a low-level `Rpc` definition.
|
|
26
|
+
* These keys are always included in the command response metadata, regardless of the handler logic.
|
|
27
|
+
*
|
|
28
|
+
* Prefer using `makeQueryKey` over raw string arrays to stay in sync with the actual query
|
|
29
|
+
* definitions without manual string maintenance:
|
|
30
|
+
*
|
|
31
|
+
* ```ts
|
|
32
|
+
* import { makeQueryKey } from "effect-app/client"
|
|
33
|
+
* import { Invalidation } from "effect-app/rpc"
|
|
34
|
+
* import * as UserRsc from "../User/index.js" // separate module to avoid circular deps
|
|
35
|
+
*
|
|
36
|
+
* class UpdateProfile extends Rpc.make("UpdateProfile", { ... })
|
|
37
|
+
* .annotate(Invalidation.Invalidates, [makeQueryKey(UserRsc.GetMe), makeQueryKey(UserRsc.GetProfile)]) {}
|
|
38
|
+
* ```
|
|
39
|
+
*
|
|
40
|
+
* **Circular dependency note:** if mutations and queries live in the same file you may hit a
|
|
41
|
+
* circular reference at evaluation time. The idiomatic fix is to move mutations into their own
|
|
42
|
+
* module (e.g. `User/mutations.ts`) that directly imports the relevant query classes rather than
|
|
43
|
+
* re-exporting them through a barrel.
|
|
44
|
+
*
|
|
45
|
+
* For the higher-level `Command`/`Query` builders from `makeRpcClient`, use the
|
|
46
|
+
* `invalidatesQueries` callback argument instead (it receives the same query keys at runtime).
|
|
47
|
+
*/
|
|
48
|
+
export const Invalidates = Context.Reference("effect-app/rpc/Invalidates", { defaultValue: () => [] });
|
|
49
|
+
/**
|
|
50
|
+
* Request-scoped service for accumulating invalidation keys dynamically inside a handler.
|
|
51
|
+
* Provided by `InvalidationMiddlewareLive` for every RPC call; has a no-op default so it is
|
|
52
|
+
* safe to use even when the HTTP middleware is absent (tests, workers, etc.).
|
|
53
|
+
*
|
|
54
|
+
* Use `InvalidationSet.use(_ => _.add(key))` (or `.useSync` for non-Effect callbacks) as a
|
|
55
|
+
* shorthand instead of yielding the service manually.
|
|
56
|
+
*
|
|
57
|
+
* Prefer `makeQueryKey` over raw string arrays so invalidation keys stay in sync with the
|
|
58
|
+
* actual query definitions automatically:
|
|
59
|
+
*
|
|
60
|
+
* ```ts
|
|
61
|
+
* import { makeQueryKey } from "effect-app/client"
|
|
62
|
+
* import { Effect } from "effect"
|
|
63
|
+
* import { Invalidation } from "effect-app/rpc"
|
|
64
|
+
* import * as CartRsc from "../Cart/queries.js"
|
|
65
|
+
* import * as UserRsc from "../User/queries.js"
|
|
66
|
+
*
|
|
67
|
+
* const handler = Effect.fnUntraced(function*(req: UpdateCartRequest) {
|
|
68
|
+
* const cart = yield* CartRepo.save(req.cart)
|
|
69
|
+
*
|
|
70
|
+
* // Stage 1 – unconditional: always invalidate after saving
|
|
71
|
+
* yield* Invalidation.InvalidationSet.use(_ => _.add(makeQueryKey(UserRsc.GetMe)))
|
|
72
|
+
*
|
|
73
|
+
* // Stage 2 – conditional: only if the cart changed state
|
|
74
|
+
* if (cart.isCheckedOut) {
|
|
75
|
+
* yield* Invalidation.InvalidationSet.use(_ => _.add(makeQueryKey(CartRsc.GetCartStats)))
|
|
76
|
+
* }
|
|
77
|
+
*
|
|
78
|
+
* return cart
|
|
79
|
+
* })
|
|
80
|
+
* ```
|
|
81
|
+
*
|
|
82
|
+
* You can combine static (`Invalidates` annotation) and dynamic (`InvalidationSet.use`) keys:
|
|
83
|
+
* the annotation pre-populates the set before the handler runs; dynamic additions accumulate
|
|
84
|
+
* throughout the handler. All keys are included in the command response metadata.
|
|
85
|
+
*/
|
|
86
|
+
export const InvalidationSet = Context.Reference("effect-app/rpc/InvalidationSet", {
|
|
87
|
+
defaultValue: () => ({
|
|
88
|
+
add: (_key) => Effect.void,
|
|
89
|
+
get: Effect.succeed([])
|
|
90
|
+
})
|
|
91
|
+
});
|
|
92
|
+
/** Creates a fresh `InvalidationSet` implementation backed by a `Ref`. */
|
|
93
|
+
export const makeInvalidationSet = (ref) => ({
|
|
94
|
+
add: (key) => Ref.update(ref, (keys) => [...keys, key]),
|
|
95
|
+
get: Ref.get(ref)
|
|
96
|
+
});
|
|
97
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiSW52YWxpZGF0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3JwYy9JbnZhbGlkYXRpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLEdBQUcsTUFBTSxZQUFZLENBQUE7QUFDakMsT0FBTyxLQUFLLE9BQU8sTUFBTSxlQUFlLENBQUE7QUFDeEMsT0FBTyxLQUFLLE1BQU0sTUFBTSxjQUFjLENBQUE7QUFDdEMsT0FBTyxLQUFLLENBQUMsTUFBTSxjQUFjLENBQUE7QUFFakM7Ozs7R0FJRztBQUNILE1BQU0sQ0FBQyxNQUFNLHNCQUFzQixHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUE7QUFHNUMsNkdBQTZHO0FBQzdHLE1BQU0sQ0FBQyxNQUFNLGVBQWUsR0FBRyxDQUFDLENBQUMsS0FBSyxDQUFDLHNCQUFzQixDQUFDLENBQUE7QUFHOUQsb0ZBQW9GO0FBQ3BGLE1BQU0sQ0FBQyxNQUFNLGdCQUFnQixHQUFHLENBQUMsQ0FBQyxLQUFLLENBQUMsZUFBZSxDQUFDLENBQUE7QUFHeEQsd0ZBQXdGO0FBQ3hGLE1BQU0sQ0FBQyxNQUFNLGVBQWUsR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDLEVBQUUsaUJBQWlCLEVBQUUsZ0JBQWdCLEVBQUUsQ0FBQyxDQUFBO0FBR2hGOzs7OztHQUtHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sMkJBQTJCLEdBQUcsQ0FBa0IsT0FBVSxFQUFFLEVBQUUsQ0FDekUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsUUFBUSxFQUFFLGVBQWUsRUFBRSxDQUFDLENBQUE7QUFFM0Q7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBdUJHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sV0FBVyxHQUFHLE9BQU8sQ0FBQyxTQUFTLENBQzFDLDRCQUE0QixFQUM1QixFQUFFLFlBQVksRUFBRSxHQUFHLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FDM0IsQ0FBQTtBQVNEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FvQ0c7QUFDSCxNQUFNLENBQUMsTUFBTSxlQUFlLEdBQUcsT0FBTyxDQUFDLFNBQVMsQ0FDOUMsZ0NBQWdDLEVBQ2hDO0lBQ0UsWUFBWSxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUM7UUFDbkIsR0FBRyxFQUFFLENBQUMsSUFBcUIsRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLElBQUk7UUFDM0MsR0FBRyxFQUFFLE1BQU0sQ0FBQyxPQUFPLENBQUMsRUFBb0MsQ0FBQztLQUMxRCxDQUFDO0NBQ0gsQ0FDRixDQUFBO0FBR0QsMEVBQTBFO0FBQzFFLE1BQU0sQ0FBQyxNQUFNLG1CQUFtQixHQUFHLENBQUMsR0FBNEMsRUFBMEIsRUFBRSxDQUFDLENBQUM7SUFDNUcsR0FBRyxFQUFFLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQyxHQUFHLElBQUksRUFBRSxHQUFHLENBQUMsQ0FBQztJQUN2RCxHQUFHLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUM7Q0FDbEIsQ0FBQyxDQUFBIn0=
|
package/dist/rpc.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
+
export * as Invalidation from "./rpc/Invalidation.js";
|
|
1
2
|
export * as MiddlewareMaker from "./rpc/MiddlewareMaker.js";
|
|
2
3
|
export * as RpcContextMap from "./rpc/RpcContextMap.js";
|
|
3
4
|
export * as RpcMiddleware from "./rpc/RpcMiddleware.js";
|
|
4
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
5
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnBjLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvcnBjLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxZQUFZLE1BQU0sdUJBQXVCLENBQUE7QUFDckQsT0FBTyxLQUFLLGVBQWUsTUFBTSwwQkFBMEIsQ0FBQTtBQUMzRCxPQUFPLEtBQUssYUFBYSxNQUFNLHdCQUF3QixDQUFBO0FBQ3ZELE9BQU8sS0FBSyxhQUFhLE1BQU0sd0JBQXdCLENBQUEifQ==
|
package/dist/rpc.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rpc.d.ts","sourceRoot":"","sources":["../src/rpc.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,eAAe,MAAM,0BAA0B,CAAA;AAC3D,OAAO,KAAK,aAAa,MAAM,wBAAwB,CAAA;AACvD,OAAO,KAAK,aAAa,MAAM,wBAAwB,CAAA"}
|
|
1
|
+
{"version":3,"file":"rpc.d.ts","sourceRoot":"","sources":["../src/rpc.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,YAAY,MAAM,uBAAuB,CAAA;AACrD,OAAO,KAAK,eAAe,MAAM,0BAA0B,CAAA;AAC3D,OAAO,KAAK,aAAa,MAAM,wBAAwB,CAAA;AACvD,OAAO,KAAK,aAAa,MAAM,wBAAwB,CAAA"}
|
package/dist/rpc.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
+
export * as Invalidation from "./rpc/Invalidation.js";
|
|
1
2
|
export * as MiddlewareMaker from "./rpc/MiddlewareMaker.js";
|
|
2
3
|
export * as RpcContextMap from "./rpc/RpcContextMap.js";
|
|
3
4
|
export * as RpcMiddleware from "./rpc/RpcMiddleware.js";
|
|
4
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
5
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnBjLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3JwYy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssWUFBWSxNQUFNLHVCQUF1QixDQUFBO0FBQ3JELE9BQU8sS0FBSyxlQUFlLE1BQU0sMEJBQTBCLENBQUE7QUFDM0QsT0FBTyxLQUFLLGFBQWEsTUFBTSx3QkFBd0IsQ0FBQTtBQUN2RCxPQUFPLEtBQUssYUFBYSxNQUFNLHdCQUF3QixDQUFBIn0=
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "effect-app",
|
|
3
|
-
"version": "4.0.0-beta.
|
|
3
|
+
"version": "4.0.0-beta.174",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"dependencies": {
|
|
@@ -195,6 +195,10 @@
|
|
|
195
195
|
"types": "./dist/client.d.ts",
|
|
196
196
|
"default": "./dist/client.js"
|
|
197
197
|
},
|
|
198
|
+
"./client/InvalidationKeys": {
|
|
199
|
+
"types": "./dist/client/InvalidationKeys.d.ts",
|
|
200
|
+
"default": "./dist/client/InvalidationKeys.js"
|
|
201
|
+
},
|
|
198
202
|
"./client/apiClientFactory": {
|
|
199
203
|
"types": "./dist/client/apiClientFactory.d.ts",
|
|
200
204
|
"default": "./dist/client/apiClientFactory.js"
|
|
@@ -239,6 +243,10 @@
|
|
|
239
243
|
"types": "./dist/rpc.d.ts",
|
|
240
244
|
"default": "./dist/rpc.js"
|
|
241
245
|
},
|
|
246
|
+
"./rpc/Invalidation": {
|
|
247
|
+
"types": "./dist/rpc/Invalidation.d.ts",
|
|
248
|
+
"default": "./dist/rpc/Invalidation.js"
|
|
249
|
+
},
|
|
242
250
|
"./rpc/MiddlewareMaker": {
|
|
243
251
|
"types": "./dist/rpc/MiddlewareMaker.d.ts",
|
|
244
252
|
"default": "./dist/rpc/MiddlewareMaker.js"
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import * as Ref from "effect/Ref"
|
|
2
|
+
import * as Context from "../Context.js"
|
|
3
|
+
import * as Effect from "../Effect.js"
|
|
4
|
+
import type { InvalidationKey } from "../rpc/Invalidation.js"
|
|
5
|
+
|
|
6
|
+
export type { InvalidationKey }
|
|
7
|
+
/** Shape of the per-mutation service that accumulates server-provided invalidation keys. */
|
|
8
|
+
export interface InvalidationKeysService {
|
|
9
|
+
readonly add: (key: InvalidationKey) => Effect.Effect<void>
|
|
10
|
+
readonly get: Effect.Effect<ReadonlyArray<InvalidationKey>>
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Context.Reference that accumulates invalidation keys received from the server via the
|
|
15
|
+
* `x-invalidate` HTTP response header.
|
|
16
|
+
*
|
|
17
|
+
* The default is a no-op: when not explicitly provided (e.g. outside a mutation wrapper)
|
|
18
|
+
* all calls are ignored. The mutation wrapper in `@effect-app/vue` provides a real
|
|
19
|
+
* implementation backed by a `Ref`.
|
|
20
|
+
*/
|
|
21
|
+
export const InvalidationKeysFromServer = Context.Reference<InvalidationKeysService>(
|
|
22
|
+
"effect-app/client/InvalidationKeysFromServer",
|
|
23
|
+
{
|
|
24
|
+
defaultValue: () => ({
|
|
25
|
+
add: (_key: InvalidationKey) => Effect.void,
|
|
26
|
+
get: Effect.succeed([] as ReadonlyArray<InvalidationKey>)
|
|
27
|
+
})
|
|
28
|
+
}
|
|
29
|
+
)
|
|
30
|
+
export type InvalidationKeysFromServer = typeof InvalidationKeysFromServer
|
|
31
|
+
|
|
32
|
+
/** Creates a fresh `InvalidationKeysService` implementation backed by a `Ref`. */
|
|
33
|
+
export const makeInvalidationKeysService = (
|
|
34
|
+
ref: Ref.Ref<ReadonlyArray<InvalidationKey>>
|
|
35
|
+
): InvalidationKeysService => ({
|
|
36
|
+
add: (key) => Ref.update(ref, (keys) => [...keys, key]),
|
|
37
|
+
get: Ref.get(ref)
|
|
38
|
+
})
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { flow } from "effect/Function"
|
|
3
3
|
import * as Layer from "effect/Layer"
|
|
4
4
|
import * as ManagedRuntime from "effect/ManagedRuntime"
|
|
5
|
+
import * as Option from "effect/Option"
|
|
5
6
|
import * as Predicate from "effect/Predicate"
|
|
6
7
|
import * as Schema from "effect/Schema"
|
|
7
8
|
import * as Struct from "effect/Struct"
|
|
@@ -10,10 +11,11 @@ import * as Config from "../Config.js"
|
|
|
10
11
|
import * as Context from "../Context.js"
|
|
11
12
|
import * as Effect from "../Effect.js"
|
|
12
13
|
import { HttpClient, HttpClientRequest } from "../http.js"
|
|
13
|
-
import
|
|
14
|
+
import { Invalidation } from "../rpc.js"
|
|
14
15
|
import type * as S from "../Schema.js"
|
|
15
16
|
import { typedKeysOf, typedValuesOf } from "../utils.js"
|
|
16
17
|
import type { Client, ClientForOptions, ExtractModuleName, RequestsAny } from "./clientFor.js"
|
|
18
|
+
import { InvalidationKeysFromServer } from "./InvalidationKeys.js"
|
|
17
19
|
|
|
18
20
|
export interface ApiConfig {
|
|
19
21
|
url: string
|
|
@@ -120,7 +122,13 @@ export const makeRpcGroupFromRequestsAndModuleName = <M extends RequestsAny, con
|
|
|
120
122
|
const rpcs = RpcGroup
|
|
121
123
|
.make(
|
|
122
124
|
...typedValuesOf(filtered).map((_) => {
|
|
123
|
-
return Rpc.make((_ as any)._tag, {
|
|
125
|
+
return Rpc.make((_ as any)._tag, {
|
|
126
|
+
payload: _ as any,
|
|
127
|
+
success: (_ as any).type === "command"
|
|
128
|
+
? Invalidation.CommandResponseWithMetaData((_ as any).success)
|
|
129
|
+
: (_ as any).success,
|
|
130
|
+
error: (_ as any).error
|
|
131
|
+
})
|
|
124
132
|
})
|
|
125
133
|
)
|
|
126
134
|
.prefix(`${moduleName}.`) as unknown as RpcGroup.RpcGroup<
|
|
@@ -167,9 +175,7 @@ const makeApiClientFactory = Effect
|
|
|
167
175
|
Layer.provide(Layer.succeed(ApiClientFactory, makeClientForCached as any)),
|
|
168
176
|
Layer.provide(
|
|
169
177
|
RpcClient
|
|
170
|
-
.layerProtocolHttp({
|
|
171
|
-
url: "" // why not here set meta.moduleName as root?
|
|
172
|
-
})
|
|
178
|
+
.layerProtocolHttp({ url: "" }) // why not here set meta.moduleName as root?
|
|
173
179
|
.pipe(
|
|
174
180
|
Layer.provideMerge(Layer.succeedContext(ctx))
|
|
175
181
|
)
|
|
@@ -178,6 +184,19 @@ const makeApiClientFactory = Effect
|
|
|
178
184
|
const mr = ManagedRuntime.make(clientLayer)
|
|
179
185
|
|
|
180
186
|
const filtered = getFiltered(resource)
|
|
187
|
+
|
|
188
|
+
const unwrapCommand = (eff: Effect.Effect<any, any, any>): Effect.Effect<any, any, any> =>
|
|
189
|
+
eff.pipe(
|
|
190
|
+
Effect.flatMap((result: any) =>
|
|
191
|
+
Effect.gen(function*() {
|
|
192
|
+
const keys: ReadonlyArray<Invalidation.InvalidationKey> = result?.metadata?.invalidateQueries ?? []
|
|
193
|
+
const invalidationKeys = yield* InvalidationKeysFromServer
|
|
194
|
+
yield* Effect.forEach(keys, (key) => invalidationKeys.add(key), { discard: true })
|
|
195
|
+
return result.payload
|
|
196
|
+
})
|
|
197
|
+
)
|
|
198
|
+
)
|
|
199
|
+
|
|
181
200
|
return {
|
|
182
201
|
mr,
|
|
183
202
|
client: typedKeysOf(filtered)
|
|
@@ -204,12 +223,13 @@ const makeApiClientFactory = Effect
|
|
|
204
223
|
|
|
205
224
|
const fields = Struct.omit(Request.fields, ["_tag"] as const)
|
|
206
225
|
const requestAttr = `${meta.moduleName}.${h._tag}`
|
|
226
|
+
const isCommand = h.type === "command"
|
|
207
227
|
// @ts-expect-error doc
|
|
208
228
|
prev[cur] = Object.keys(fields).length === 0
|
|
209
229
|
? {
|
|
210
230
|
handler: mr.contextEffect.pipe(
|
|
211
|
-
Effect.flatMap((svcs) =>
|
|
212
|
-
TheClient
|
|
231
|
+
Effect.flatMap((svcs) => {
|
|
232
|
+
const rpcEffect = TheClient
|
|
213
233
|
.use((client) =>
|
|
214
234
|
(client as any)[requestAttr]!(Request.make({})) as Effect.Effect<any, any, never>
|
|
215
235
|
)
|
|
@@ -217,15 +237,16 @@ const makeApiClientFactory = Effect
|
|
|
217
237
|
Effect.provide(layers),
|
|
218
238
|
Effect.provide(svcs)
|
|
219
239
|
)
|
|
220
|
-
|
|
240
|
+
return isCommand ? unwrapCommand(rpcEffect) : rpcEffect
|
|
241
|
+
})
|
|
221
242
|
),
|
|
222
243
|
...requestMeta
|
|
223
244
|
}
|
|
224
245
|
: {
|
|
225
246
|
handler: (req: any) =>
|
|
226
247
|
mr.contextEffect.pipe(
|
|
227
|
-
Effect.flatMap((svcs) =>
|
|
228
|
-
TheClient
|
|
248
|
+
Effect.flatMap((svcs) => {
|
|
249
|
+
const rpcEffect = TheClient
|
|
229
250
|
.use((client) =>
|
|
230
251
|
(client as any)[requestAttr]!(Request.make(req)) as Effect.Effect<any, any, never>
|
|
231
252
|
)
|
|
@@ -233,7 +254,8 @@ const makeApiClientFactory = Effect
|
|
|
233
254
|
Effect.provide(layers),
|
|
234
255
|
Effect.provide(svcs)
|
|
235
256
|
)
|
|
236
|
-
|
|
257
|
+
return isCommand ? unwrapCommand(rpcEffect) : rpcEffect
|
|
258
|
+
})
|
|
237
259
|
),
|
|
238
260
|
|
|
239
261
|
...requestMeta
|
package/src/client.ts
CHANGED
package/src/middleware.ts
CHANGED
|
@@ -14,9 +14,13 @@ export class LoggerMiddleware extends RpcMiddleware.Tag<LoggerMiddleware>()("Log
|
|
|
14
14
|
|
|
15
15
|
export class DevModeMiddleware extends RpcMiddleware.Tag<DevModeMiddleware>()("DevModeMiddleware") {}
|
|
16
16
|
|
|
17
|
+
/** RPC middleware that reads the `Invalidates` annotation and populates `InvalidationSet` before the handler runs. */
|
|
18
|
+
export class InvalidationMiddleware extends RpcMiddleware.Tag<InvalidationMiddleware>()("InvalidationMiddleware") {}
|
|
19
|
+
|
|
17
20
|
export const DefaultGenericMiddlewares = [
|
|
18
21
|
RequestCacheMiddleware,
|
|
19
22
|
ConfigureInterruptibilityMiddleware,
|
|
20
23
|
LoggerMiddleware,
|
|
21
|
-
DevModeMiddleware
|
|
24
|
+
DevModeMiddleware,
|
|
25
|
+
InvalidationMiddleware
|
|
22
26
|
] as const
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import * as Ref from "effect/Ref"
|
|
2
|
+
import * as Context from "../Context.js"
|
|
3
|
+
import * as Effect from "../Effect.js"
|
|
4
|
+
import * as S from "../Schema.js"
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* A single segment within an `InvalidationKey` array.
|
|
8
|
+
* Accepts any JSON-compatible value: string, number, boolean, null,
|
|
9
|
+
* arrays and objects recursively — matching TanStack Query's `queryKey` element type.
|
|
10
|
+
*/
|
|
11
|
+
export const InvalidationKeySegment = S.Json
|
|
12
|
+
export type InvalidationKeySegment = S.Schema.Type<typeof InvalidationKeySegment>
|
|
13
|
+
|
|
14
|
+
/** Schema for a single invalidation key – an array of segments compatible with TanStack Query `queryKey`. */
|
|
15
|
+
export const InvalidationKey = S.Array(InvalidationKeySegment)
|
|
16
|
+
export type InvalidationKey = S.Schema.Type<typeof InvalidationKey>
|
|
17
|
+
|
|
18
|
+
/** Schema for the full set of invalidation keys – an array of `InvalidationKey`. */
|
|
19
|
+
export const InvalidationKeys = S.Array(InvalidationKey)
|
|
20
|
+
export type InvalidationKeys = S.Schema.Type<typeof InvalidationKeys>
|
|
21
|
+
|
|
22
|
+
/** Metadata included in every command response for server-driven cache invalidation. */
|
|
23
|
+
export const CommandMetaData = S.Struct({ invalidateQueries: InvalidationKeys })
|
|
24
|
+
export type CommandMetaData = S.Schema.Type<typeof CommandMetaData>
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Wraps a command's success schema so that the wire format carries both the `payload`
|
|
28
|
+
* (the handler's actual return value) and `metadata` (server-driven cache invalidation keys).
|
|
29
|
+
* Transparent to users: the server handler returns the plain payload and the client receives
|
|
30
|
+
* the plain payload — wrapping/unwrapping is handled internally by the routing layer.
|
|
31
|
+
*/
|
|
32
|
+
export const CommandResponseWithMetaData = <S extends S.Top>(success: S) =>
|
|
33
|
+
S.Struct({ payload: success, metadata: CommandMetaData })
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Context annotation for declaring static cache invalidation keys on a low-level `Rpc` definition.
|
|
37
|
+
* These keys are always included in the command response metadata, regardless of the handler logic.
|
|
38
|
+
*
|
|
39
|
+
* Prefer using `makeQueryKey` over raw string arrays to stay in sync with the actual query
|
|
40
|
+
* definitions without manual string maintenance:
|
|
41
|
+
*
|
|
42
|
+
* ```ts
|
|
43
|
+
* import { makeQueryKey } from "effect-app/client"
|
|
44
|
+
* import { Invalidation } from "effect-app/rpc"
|
|
45
|
+
* import * as UserRsc from "../User/index.js" // separate module to avoid circular deps
|
|
46
|
+
*
|
|
47
|
+
* class UpdateProfile extends Rpc.make("UpdateProfile", { ... })
|
|
48
|
+
* .annotate(Invalidation.Invalidates, [makeQueryKey(UserRsc.GetMe), makeQueryKey(UserRsc.GetProfile)]) {}
|
|
49
|
+
* ```
|
|
50
|
+
*
|
|
51
|
+
* **Circular dependency note:** if mutations and queries live in the same file you may hit a
|
|
52
|
+
* circular reference at evaluation time. The idiomatic fix is to move mutations into their own
|
|
53
|
+
* module (e.g. `User/mutations.ts`) that directly imports the relevant query classes rather than
|
|
54
|
+
* re-exporting them through a barrel.
|
|
55
|
+
*
|
|
56
|
+
* For the higher-level `Command`/`Query` builders from `makeRpcClient`, use the
|
|
57
|
+
* `invalidatesQueries` callback argument instead (it receives the same query keys at runtime).
|
|
58
|
+
*/
|
|
59
|
+
export const Invalidates = Context.Reference<ReadonlyArray<InvalidationKey>>(
|
|
60
|
+
"effect-app/rpc/Invalidates",
|
|
61
|
+
{ defaultValue: () => [] }
|
|
62
|
+
)
|
|
63
|
+
export type Invalidates = typeof Invalidates
|
|
64
|
+
|
|
65
|
+
/** The shape of the per-request service that accumulates invalidation keys. */
|
|
66
|
+
export interface InvalidationSetService {
|
|
67
|
+
readonly add: (key: InvalidationKey) => Effect.Effect<void>
|
|
68
|
+
readonly get: Effect.Effect<ReadonlyArray<InvalidationKey>>
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Request-scoped service for accumulating invalidation keys dynamically inside a handler.
|
|
73
|
+
* Provided by `InvalidationMiddlewareLive` for every RPC call; has a no-op default so it is
|
|
74
|
+
* safe to use even when the HTTP middleware is absent (tests, workers, etc.).
|
|
75
|
+
*
|
|
76
|
+
* Use `InvalidationSet.use(_ => _.add(key))` (or `.useSync` for non-Effect callbacks) as a
|
|
77
|
+
* shorthand instead of yielding the service manually.
|
|
78
|
+
*
|
|
79
|
+
* Prefer `makeQueryKey` over raw string arrays so invalidation keys stay in sync with the
|
|
80
|
+
* actual query definitions automatically:
|
|
81
|
+
*
|
|
82
|
+
* ```ts
|
|
83
|
+
* import { makeQueryKey } from "effect-app/client"
|
|
84
|
+
* import { Effect } from "effect"
|
|
85
|
+
* import { Invalidation } from "effect-app/rpc"
|
|
86
|
+
* import * as CartRsc from "../Cart/queries.js"
|
|
87
|
+
* import * as UserRsc from "../User/queries.js"
|
|
88
|
+
*
|
|
89
|
+
* const handler = Effect.fnUntraced(function*(req: UpdateCartRequest) {
|
|
90
|
+
* const cart = yield* CartRepo.save(req.cart)
|
|
91
|
+
*
|
|
92
|
+
* // Stage 1 – unconditional: always invalidate after saving
|
|
93
|
+
* yield* Invalidation.InvalidationSet.use(_ => _.add(makeQueryKey(UserRsc.GetMe)))
|
|
94
|
+
*
|
|
95
|
+
* // Stage 2 – conditional: only if the cart changed state
|
|
96
|
+
* if (cart.isCheckedOut) {
|
|
97
|
+
* yield* Invalidation.InvalidationSet.use(_ => _.add(makeQueryKey(CartRsc.GetCartStats)))
|
|
98
|
+
* }
|
|
99
|
+
*
|
|
100
|
+
* return cart
|
|
101
|
+
* })
|
|
102
|
+
* ```
|
|
103
|
+
*
|
|
104
|
+
* You can combine static (`Invalidates` annotation) and dynamic (`InvalidationSet.use`) keys:
|
|
105
|
+
* the annotation pre-populates the set before the handler runs; dynamic additions accumulate
|
|
106
|
+
* throughout the handler. All keys are included in the command response metadata.
|
|
107
|
+
*/
|
|
108
|
+
export const InvalidationSet = Context.Reference<InvalidationSetService>(
|
|
109
|
+
"effect-app/rpc/InvalidationSet",
|
|
110
|
+
{
|
|
111
|
+
defaultValue: () => ({
|
|
112
|
+
add: (_key: InvalidationKey) => Effect.void,
|
|
113
|
+
get: Effect.succeed([] as ReadonlyArray<InvalidationKey>)
|
|
114
|
+
})
|
|
115
|
+
}
|
|
116
|
+
)
|
|
117
|
+
export type InvalidationSet = typeof InvalidationSet
|
|
118
|
+
|
|
119
|
+
/** Creates a fresh `InvalidationSet` implementation backed by a `Ref`. */
|
|
120
|
+
export const makeInvalidationSet = (ref: Ref.Ref<ReadonlyArray<InvalidationKey>>): InvalidationSetService => ({
|
|
121
|
+
add: (key) => Ref.update(ref, (keys) => [...keys, key]),
|
|
122
|
+
get: Ref.get(ref)
|
|
123
|
+
})
|
package/src/rpc.ts
CHANGED