@confect/react 9.2.4 → 10.0.0-next.1
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 +25 -6
- package/dist/OptimisticLocalStore.js +2 -1
- package/dist/OptimisticLocalStore.js.map +1 -1
- package/dist/QueryResult.d.ts.map +1 -1
- package/dist/QueryResult.js +6 -5
- package/dist/QueryResult.js.map +1 -1
- package/dist/_virtual/_rolldown/runtime.js +11 -6
- package/dist/index.d.ts +8 -8
- package/dist/index.js +19 -19
- package/dist/index.js.map +1 -1
- package/dist/tsconfig.src.tsbuildinfo +1 -1
- package/package.json +12 -13
- package/src/QueryResult.ts +5 -8
- package/src/index.ts +25 -25
package/CHANGELOG.md
CHANGED
|
@@ -1,18 +1,37 @@
|
|
|
1
1
|
# @confect/react
|
|
2
2
|
|
|
3
|
-
##
|
|
4
|
-
|
|
5
|
-
## 9.2.3
|
|
3
|
+
## 10.0.0-next.1
|
|
6
4
|
|
|
7
5
|
### Patch Changes
|
|
8
6
|
|
|
9
|
-
-
|
|
7
|
+
- 4d98ea8: Raise the required `effect` peer version to `^4.0.0-beta.98` (from `^4.0.0-beta.97`).
|
|
8
|
+
|
|
9
|
+
`effect`'s `SchemaError` is now exposed as its own public module (`effect/SchemaError`), which changes the import path TypeScript picks when Confect emits `.d.ts` declarations that reference `Schema.SchemaError` (for example in generated `services.d.ts`). Existing `Schema.SchemaError` / `Schema.isSchemaError` usage is unaffected — this is purely a declaration-emit detail that consumers relying on generated types may notice.
|
|
10
|
+
|
|
11
|
+
- Updated dependencies [4d98ea8]
|
|
12
|
+
- @confect/core@10.0.0-next.1
|
|
13
|
+
|
|
14
|
+
## 10.0.0-next.0
|
|
15
|
+
|
|
16
|
+
### Major Changes
|
|
17
|
+
|
|
18
|
+
- 70e313e: Migrate to Effect v4. All `@confect/*` packages now require `effect@^4.0.0-beta.97`; `@effect/platform` and `@effect/cli` are no longer dependencies (their functionality moved into `effect` core and `effect/unstable/*`).
|
|
10
19
|
|
|
11
|
-
|
|
20
|
+
Breaking changes for users:
|
|
21
|
+
- **Schemas** follow Effect v4's Schema API: `Schema.Union([a, b])` (array form), `Schema.Literals([...])` for literal unions, `Schema.optionalKey` in place of `optionalWith({ exact: true })`, `Schema.TaggedErrorClass` in place of `Schema.TaggedError`, and checks like `Schema.String.check(Schema.isMaxLength(...))` in place of piped filters.
|
|
22
|
+
- **Option-returning functions** must use a codec with a serializable encoded form, such as `Schema.OptionFromNullOr(...)` — v4's `Schema.Option` encodes to an `Option` instance, which is not a Convex value.
|
|
23
|
+
- **Table schemas** may now be transformations (`Schema.decodeTo` chains, `Schema.encodeKeys`), branded structs, suspended schemas, or unions of these — Convex's system fields are carried through the whole encoding chain. Schemas that do not resolve to an object shape at every step (such as `Schema.Class`) are rejected with a descriptive error when the table is defined.
|
|
24
|
+
- **Clients**: decode failures surface as `SchemaError` rather than `ParseError` in `@confect/js` and `@confect/react`, and `@confect/react`'s `useMutation`/`useAction` handles with an `error` schema now resolve to `Result` (v4's replacement for `Either`).
|
|
25
|
+
- **HTTP** is now mounted through the renamed `HttpRouter` module (formerly `HttpApi`). `HttpRouter.make(routes)` takes a single route-registering `Layer` composed from Effect's own `effect/unstable/http` and `effect/unstable/httpapi` modules — `HttpApiBuilder.layer(api)` (with group handler layers supplied via `Layer.provide`; a missing group is a compile-time error), `HttpApiScalar.layer` for docs, `HttpRouter.add` for plain routes, and `HttpRouter.middleware(fn, { global: true })` for middleware, merged with `Layer.mergeAll`. The per-path-prefix record and its `api`/`apiLive`/`middleware`/`scalar` options are gone; Confect registers one catch-all Convex HTTP action at `/`, and plain Convex routes added to the returned router still take precedence. Handlers, middleware, and route-layer construction all run with Confect's Convex-aware `ConfigProvider` in context.
|
|
26
|
+
- **Node actions** use `effect/unstable/process` (`ChildProcessSpawner`) and `@effect/platform-node`'s `NodeServices` in place of `@effect/platform` `Command`/`NodeContext`.
|
|
27
|
+
- **Configuration**: Confect's Convex-aware `ConfigProvider` treats empty-string environment variables as missing values (matching Effect v4's built-in providers), so `Config.withDefault` and `Config.option` recover from them.
|
|
28
|
+
- **CLI**: a malformed `convex.json` now fails codegen with a descriptive error instead of being silently ignored.
|
|
29
|
+
- Confect queries no longer stub the global `Date.now`. Queries run with a `Clock` whose unsafe accessors return constants, so Effect-internal reads (log timestamps, spans) never evict a query from Convex's cache; explicit time reads — `Clock.currentTimeMillis`/`currentTimeNanos` or a raw `Date.now()` call — opt the query out and evict as they honestly should.
|
|
12
30
|
|
|
13
31
|
### Patch Changes
|
|
14
32
|
|
|
15
|
-
-
|
|
33
|
+
- Updated dependencies [70e313e]
|
|
34
|
+
- @confect/core@10.0.0-next.0
|
|
16
35
|
|
|
17
36
|
## 9.2.1
|
|
18
37
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { __exportAll } from "./_virtual/_rolldown/runtime.js";
|
|
2
2
|
import { Ref } from "@confect/core";
|
|
3
3
|
import * as Option from "effect/Option";
|
|
4
|
+
|
|
4
5
|
//#region src/OptimisticLocalStore.ts
|
|
5
6
|
var OptimisticLocalStore_exports = /* @__PURE__ */ __exportAll({ make: () => make });
|
|
6
7
|
/**
|
|
@@ -32,7 +33,7 @@ const make = (convexLocalStore) => ({
|
|
|
32
33
|
convexLocalStore.setQuery(functionReference, encodedArgs, encodedValue);
|
|
33
34
|
}
|
|
34
35
|
});
|
|
36
|
+
|
|
35
37
|
//#endregion
|
|
36
38
|
export { OptimisticLocalStore_exports, make };
|
|
37
|
-
|
|
38
39
|
//# sourceMappingURL=OptimisticLocalStore.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OptimisticLocalStore.js","names":[],"sources":["../src/OptimisticLocalStore.ts"],"sourcesContent":["import { Ref } from \"@confect/core\";\nimport type { OptimisticLocalStore as ConvexOptimisticLocalStore } from \"convex/browser\";\nimport * as Option from \"effect/Option\";\n\n/**\n * The Confect counterpart to Convex's `OptimisticLocalStore`.\n *\n * Its methods accept Confect query `Ref`s and operate on decoded (Effect\n * Schema) values rather than the encoded values stored by Convex. Query values\n * are wrapped in `Option`: `Option.none()` represents a query that is not\n * present in the store, and `Option.some(value)` carries the decoded value.\n */\nexport interface OptimisticLocalStore {\n getQuery<Query extends Ref.AnyPublicQuery>(\n queryRef: Query,\n ...args: Ref.OptionalArgs<Query>\n ): Option.Option<Ref.Returns<Query>>;\n\n getAllQueries<Query extends Ref.AnyPublicQuery>(\n queryRef: Query,\n ): Array<{\n args: Ref.Args<Query>;\n value: Option.Option<Ref.Returns<Query>>;\n }>;\n\n setQuery<Query extends Ref.AnyPublicQuery>(\n queryRef: Query,\n args: Ref.Args<Query>,\n value: Option.Option<Ref.Returns<Query>>,\n ): void;\n}\n\n/**\n * Wraps Convex's `OptimisticLocalStore` so that it accepts Confect query `Ref`s\n * and decoded values, handling the encoding/decoding against Convex's store.\n */\nexport const make = (\n convexLocalStore: ConvexOptimisticLocalStore,\n): OptimisticLocalStore => ({\n getQuery: (queryRef, ...rest) => {\n const functionReference = Ref.getFunctionReference(queryRef);\n const args = (rest[0] ?? {}) as Ref.Args<typeof queryRef>;\n const encodedArgs = Ref.encodeArgsSync(queryRef, args);\n const encoded = convexLocalStore.getQuery(functionReference, encodedArgs);\n return encoded === undefined\n ? Option.none()\n : Option.some(Ref.decodeReturnsSync(queryRef, encoded));\n },\n getAllQueries: (queryRef) => {\n const functionReference = Ref.getFunctionReference(queryRef);\n return convexLocalStore\n .getAllQueries(functionReference)\n .map(({ args, value }) => ({\n args: Ref.decodeArgsSync(queryRef, args),\n value:\n value === undefined\n ? Option.none()\n : Option.some(Ref.decodeReturnsSync(queryRef, value)),\n }));\n },\n setQuery: (queryRef, args, value) => {\n const functionReference = Ref.getFunctionReference(queryRef);\n const encodedArgs = Ref.encodeArgsSync(queryRef, args);\n const encodedValue = Option.match(value, {\n onNone: () => undefined,\n onSome: (decoded) => Ref.encodeReturnsSync(queryRef, decoded),\n });\n convexLocalStore.setQuery(functionReference, encodedArgs, encodedValue);\n },\n});\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"OptimisticLocalStore.js","names":[],"sources":["../src/OptimisticLocalStore.ts"],"sourcesContent":["import { Ref } from \"@confect/core\";\nimport type { OptimisticLocalStore as ConvexOptimisticLocalStore } from \"convex/browser\";\nimport * as Option from \"effect/Option\";\n\n/**\n * The Confect counterpart to Convex's `OptimisticLocalStore`.\n *\n * Its methods accept Confect query `Ref`s and operate on decoded (Effect\n * Schema) values rather than the encoded values stored by Convex. Query values\n * are wrapped in `Option`: `Option.none()` represents a query that is not\n * present in the store, and `Option.some(value)` carries the decoded value.\n */\nexport interface OptimisticLocalStore {\n getQuery<Query extends Ref.AnyPublicQuery>(\n queryRef: Query,\n ...args: Ref.OptionalArgs<Query>\n ): Option.Option<Ref.Returns<Query>>;\n\n getAllQueries<Query extends Ref.AnyPublicQuery>(\n queryRef: Query,\n ): Array<{\n args: Ref.Args<Query>;\n value: Option.Option<Ref.Returns<Query>>;\n }>;\n\n setQuery<Query extends Ref.AnyPublicQuery>(\n queryRef: Query,\n args: Ref.Args<Query>,\n value: Option.Option<Ref.Returns<Query>>,\n ): void;\n}\n\n/**\n * Wraps Convex's `OptimisticLocalStore` so that it accepts Confect query `Ref`s\n * and decoded values, handling the encoding/decoding against Convex's store.\n */\nexport const make = (\n convexLocalStore: ConvexOptimisticLocalStore,\n): OptimisticLocalStore => ({\n getQuery: (queryRef, ...rest) => {\n const functionReference = Ref.getFunctionReference(queryRef);\n const args = (rest[0] ?? {}) as Ref.Args<typeof queryRef>;\n const encodedArgs = Ref.encodeArgsSync(queryRef, args);\n const encoded = convexLocalStore.getQuery(functionReference, encodedArgs);\n return encoded === undefined\n ? Option.none()\n : Option.some(Ref.decodeReturnsSync(queryRef, encoded));\n },\n getAllQueries: (queryRef) => {\n const functionReference = Ref.getFunctionReference(queryRef);\n return convexLocalStore\n .getAllQueries(functionReference)\n .map(({ args, value }) => ({\n args: Ref.decodeArgsSync(queryRef, args),\n value:\n value === undefined\n ? Option.none()\n : Option.some(Ref.decodeReturnsSync(queryRef, value)),\n }));\n },\n setQuery: (queryRef, args, value) => {\n const functionReference = Ref.getFunctionReference(queryRef);\n const encodedArgs = Ref.encodeArgsSync(queryRef, args);\n const encodedValue = Option.match(value, {\n onNone: () => undefined,\n onSome: (decoded) => Ref.encodeReturnsSync(queryRef, decoded),\n });\n convexLocalStore.setQuery(functionReference, encodedArgs, encodedValue);\n },\n});\n"],"mappings":";;;;;;;;;;AAoCA,MAAa,QACX,sBAC0B;CAC1B,WAAW,UAAU,GAAG,SAAS;EAC/B,MAAM,oBAAoB,IAAI,qBAAqB,SAAS;EAC5D,MAAM,OAAQ,KAAK,MAAM,EAAE;EAC3B,MAAM,cAAc,IAAI,eAAe,UAAU,KAAK;EACtD,MAAM,UAAU,iBAAiB,SAAS,mBAAmB,YAAY;AACzE,SAAO,YAAY,SACf,OAAO,MAAM,GACb,OAAO,KAAK,IAAI,kBAAkB,UAAU,QAAQ,CAAC;;CAE3D,gBAAgB,aAAa;EAC3B,MAAM,oBAAoB,IAAI,qBAAqB,SAAS;AAC5D,SAAO,iBACJ,cAAc,kBAAkB,CAChC,KAAK,EAAE,MAAM,aAAa;GACzB,MAAM,IAAI,eAAe,UAAU,KAAK;GACxC,OACE,UAAU,SACN,OAAO,MAAM,GACb,OAAO,KAAK,IAAI,kBAAkB,UAAU,MAAM,CAAC;GAC1D,EAAE;;CAEP,WAAW,UAAU,MAAM,UAAU;EACnC,MAAM,oBAAoB,IAAI,qBAAqB,SAAS;EAC5D,MAAM,cAAc,IAAI,eAAe,UAAU,KAAK;EACtD,MAAM,eAAe,OAAO,MAAM,OAAO;GACvC,cAAc;GACd,SAAS,YAAY,IAAI,kBAAkB,UAAU,QAAQ;GAC9D,CAAC;AACF,mBAAiB,SAAS,mBAAmB,aAAa,aAAa;;CAE1E"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"QueryResult.d.ts","sourceRoot":"","sources":["../src/QueryResult.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,QAAQ,MAAM,iBAAiB,CAAC;AAG5C,QAAA,MAAM,MAAM,+BAA+B,CAAC;AAC5C,KAAK,MAAM,GAAG,OAAO,MAAM,CAAC;AAE5B;;;;;GAKG;AACH,MAAM,MAAM,WAAW,CAAC,CAAC,EAAE,CAAC,GAAG,KAAK,IAChC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,GACb,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,GACb,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAElB,MAAM,CAAC,OAAO,WAAW,WAAW,CAAC;IACnC,UAAiB,KAAK,CAAC,CAAC,EAAE,CAAC,CAAE,SAAQ,QAAQ,CAAC,QAAQ;QACpD,QAAQ,CAAC,CAAC,MAAM,CAAC,EAAE;YACjB,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,KAAK,CAAC,CAAC;YAC5B,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,KAAK,CAAC,CAAC;SAC7B,CAAC;KACH;IAGD,KAAY,OAAO,CAAC,CAAC,IAAI,CAAC,SAAS,WAAW,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IAG9E,KAAY,OAAO,CAAC,CAAC,IAAI,CAAC,SAAS,WAAW,CAAC,MAAM,EAAE,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;CAC/E;AAED,MAAM,WAAW,OAAO,CAAC,CAAC,EAAE,CAAC,GAAG,KAAK,CAAE,SAAQ,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;IACpE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,OAAO,CAAC,CAAC,EAAE,CAAC,GAAG,KAAK,CAAE,SAAQ,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;IACpE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;CACnB;AAED,MAAM,WAAW,OAAO,CAAC,CAAC,EAAE,CAAC,GAAG,KAAK,CAAE,SAAQ,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;IACpE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;CACnB;AAED,eAAO,MAAM,aAAa,GAAI,GAAG,OAAO,KAAG,CAAC,IAAI,WAAW,CAAC,OAAO,EAAE,OAAO,CAC1C,CAAC;
|
|
1
|
+
{"version":3,"file":"QueryResult.d.ts","sourceRoot":"","sources":["../src/QueryResult.ts"],"names":[],"mappings":"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"}
|
package/dist/QueryResult.js
CHANGED
|
@@ -5,6 +5,7 @@ import * as Equal from "effect/Equal";
|
|
|
5
5
|
import * as Hash from "effect/Hash";
|
|
6
6
|
import * as Pipeable from "effect/Pipeable";
|
|
7
7
|
import * as Predicate from "effect/Predicate";
|
|
8
|
+
|
|
8
9
|
//#region src/QueryResult.ts
|
|
9
10
|
var QueryResult_exports = /* @__PURE__ */ __exportAll({
|
|
10
11
|
fail: () => fail,
|
|
@@ -37,9 +38,9 @@ const QueryResultProto = {
|
|
|
37
38
|
[Hash.symbol]() {
|
|
38
39
|
const tagHash = Hash.string(this._tag);
|
|
39
40
|
switch (this._tag) {
|
|
40
|
-
case "Loading": return Hash.
|
|
41
|
-
case "Success": return Hash.
|
|
42
|
-
case "Failure": return Hash.
|
|
41
|
+
case "Loading": return Hash.combine(tagHash)(Hash.hash(this.skipped));
|
|
42
|
+
case "Success": return Hash.combine(tagHash)(Hash.hash(this.value));
|
|
43
|
+
case "Failure": return Hash.combine(tagHash)(Hash.hash(this.error));
|
|
43
44
|
}
|
|
44
45
|
}
|
|
45
46
|
};
|
|
@@ -80,7 +81,7 @@ const match = Function.dual(2, (self, options) => {
|
|
|
80
81
|
throw new Error("`onFailure` is required when error schema is provided");
|
|
81
82
|
}
|
|
82
83
|
});
|
|
83
|
-
//#endregion
|
|
84
|
-
export { QueryResult_exports, fail, isFailure, isLoading, isQueryResult, isSuccess, load, match, succeed };
|
|
85
84
|
|
|
85
|
+
//#endregion
|
|
86
|
+
export { QueryResult_exports, fail, load, succeed };
|
|
86
87
|
//# sourceMappingURL=QueryResult.js.map
|
package/dist/QueryResult.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"QueryResult.js","names":[],"sources":["../src/QueryResult.ts"],"sourcesContent":["import { identity } from \"effect/Function\";\nimport * as Equal from \"effect/Equal\";\nimport * as Function from \"effect/Function\";\nimport * as Hash from \"effect/Hash\";\nimport * as Pipeable from \"effect/Pipeable\";\nimport * as Predicate from \"effect/Predicate\";\n\nconst TypeId = \"@confect/react/QueryResult\";\ntype TypeId = typeof TypeId;\n\n/**\n * A `QueryResult` represents the result of a Confect query.\n *\n * @typeParam A - The type of the decoded `returns` value in the `Success` variant.\n * @typeParam E - The type of the decoded typed error in the `Failure` variant.\n */\nexport type QueryResult<A, E = never> =\n | Loading<A, E>\n | Success<A, E>\n | Failure<A, E>;\n\nexport declare namespace QueryResult {\n export interface Proto<A, E> extends Pipeable.Pipeable {\n readonly [TypeId]: {\n readonly E: (_: never) => E;\n readonly A: (_: never) => A;\n };\n }\n\n //
|
|
1
|
+
{"version":3,"file":"QueryResult.js","names":[],"sources":["../src/QueryResult.ts"],"sourcesContent":["import { identity } from \"effect/Function\";\nimport * as Equal from \"effect/Equal\";\nimport * as Function from \"effect/Function\";\nimport * as Hash from \"effect/Hash\";\nimport * as Pipeable from \"effect/Pipeable\";\nimport * as Predicate from \"effect/Predicate\";\n\nconst TypeId = \"@confect/react/QueryResult\";\ntype TypeId = typeof TypeId;\n\n/**\n * A `QueryResult` represents the result of a Confect query.\n *\n * @typeParam A - The type of the decoded `returns` value in the `Success` variant.\n * @typeParam E - The type of the decoded typed error in the `Failure` variant.\n */\nexport type QueryResult<A, E = never> =\n | Loading<A, E>\n | Success<A, E>\n | Failure<A, E>;\n\nexport declare namespace QueryResult {\n export interface Proto<A, E> extends Pipeable.Pipeable {\n readonly [TypeId]: {\n readonly E: (_: never) => E;\n readonly A: (_: never) => A;\n };\n }\n\n // oxlint-disable-next-line no-shadow\n export type Success<R> = R extends QueryResult<infer A, infer _E> ? A : never;\n\n // oxlint-disable-next-line no-shadow\n export type Failure<R> = R extends QueryResult<infer _A, infer E> ? E : never;\n}\n\nexport interface Loading<A, E = never> extends QueryResult.Proto<A, E> {\n readonly _tag: \"Loading\";\n readonly skipped: boolean;\n}\n\nexport interface Success<A, E = never> extends QueryResult.Proto<A, E> {\n readonly _tag: \"Success\";\n readonly value: A;\n}\n\nexport interface Failure<A, E = never> extends QueryResult.Proto<A, E> {\n readonly _tag: \"Failure\";\n readonly error: E;\n}\n\nexport const isQueryResult = (u: unknown): u is QueryResult<unknown, unknown> =>\n Predicate.hasProperty(u, TypeId);\n\nconst QueryResultProto = {\n [TypeId]: {\n E: identity,\n A: identity,\n },\n pipe(this: QueryResult<any, any>, ...args: ReadonlyArray<unknown>) {\n return Pipeable.pipeArguments(\n this,\n args as unknown as Parameters<typeof Pipeable.pipeArguments>[1],\n );\n },\n [Equal.symbol](\n this: QueryResult<any, any>,\n that: QueryResult<any, any>,\n ): boolean {\n if (this._tag !== that._tag) {\n return false;\n }\n switch (this._tag) {\n case \"Loading\":\n return this.skipped === (that as Loading<any, any>).skipped;\n case \"Success\":\n return Equal.equals(this.value, (that as Success<any, any>).value);\n case \"Failure\":\n return Equal.equals(this.error, (that as Failure<any, any>).error);\n }\n },\n [Hash.symbol](this: QueryResult<any, any>): number {\n const tagHash = Hash.string(this._tag);\n switch (this._tag) {\n case \"Loading\":\n return Hash.combine(tagHash)(Hash.hash(this.skipped));\n case \"Success\":\n return Hash.combine(tagHash)(Hash.hash(this.value));\n case \"Failure\":\n return Hash.combine(tagHash)(Hash.hash(this.error));\n }\n },\n};\n\nexport const load = <A = never, E = never>(skipped: boolean): Loading<A, E> =>\n Object.assign(Object.create(QueryResultProto), {\n _tag: \"Loading\" as const,\n skipped,\n });\n\nexport const succeed = <A, E = never>(value: A): Success<A, E> =>\n Object.assign(Object.create(QueryResultProto), {\n _tag: \"Success\" as const,\n value,\n });\n\nexport const fail = <E, A = never>(error: E): Failure<A, E> =>\n Object.assign(Object.create(QueryResultProto), {\n _tag: \"Failure\" as const,\n error,\n });\n\nexport const isLoading = <A, E>(\n queryResult: QueryResult<A, E>,\n): queryResult is Loading<A, E> => queryResult._tag === \"Loading\";\n\nexport const isSuccess = <A, E>(\n queryResult: QueryResult<A, E>,\n): queryResult is Success<A, E> => queryResult._tag === \"Success\";\n\nexport const isFailure = <A, E>(\n queryResult: QueryResult<A, E>,\n): queryResult is Failure<A, E> => queryResult._tag === \"Failure\";\n\ntype MatchOptions<A, E, X, Y, Z> = {\n readonly onLoading: (skipped: boolean) => X;\n readonly onSuccess: (value: A) => Y;\n} & ([E] extends [never] ? {} : { readonly onFailure: (error: E) => Z });\n\ntype MatchReturns<E, X, Y, Z> = [E] extends [never] ? X | Y : X | Y | Z;\n\n/**\n * Matches a {@link QueryResult} to the appropriate handler based on its tag. If\n * the provided `QueryResult` cannot fail (i.e. `E` is `never`), `onFailure` is\n * not required.\n *\n * @example\n * ```tsx\n * const result = QueryResult.match(queryResult, {\n * onLoading: (skipped) => skipped ? null : <p>Loading…</p>,\n * onSuccess: (value) => <p>{value.text}</p>,\n * onFailure: (error) => <p>Error: {error.message}</p>,\n * });\n */\nexport const match: {\n <A, E, X, Y, Z = never>(\n options: MatchOptions<A, E, X, Y, Z>,\n ): (self: QueryResult<A, E>) => MatchReturns<E, X, Y, Z>;\n <A, E, X, Y, Z = never>(\n self: QueryResult<A, E>,\n options: MatchOptions<A, E, X, Y, Z>,\n ): MatchReturns<E, X, Y, Z>;\n} = Function.dual(\n 2,\n <A, E, X, Y, Z = never>(\n self: QueryResult<A, E>,\n options: MatchOptions<A, E, X, Y, Z>,\n ): MatchReturns<E, X, Y, Z> => {\n switch (self._tag) {\n case \"Loading\":\n return options.onLoading(self.skipped);\n case \"Success\":\n return options.onSuccess(self.value);\n case \"Failure\": {\n if (Predicate.hasProperty(options, \"onFailure\")) {\n return options.onFailure(self.error) as MatchReturns<E, X, Y, Z>;\n }\n throw new Error(\n \"`onFailure` is required when error schema is provided\",\n );\n }\n }\n },\n);\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAOA,MAAM,SAAS;AA4Cf,MAAa,iBAAiB,MAC5B,UAAU,YAAY,GAAG,OAAO;AAElC,MAAM,mBAAmB;EACtB,SAAS;EACR,GAAG;EACH,GAAG;EACJ;CACD,KAAkC,GAAG,MAA8B;AACjE,SAAO,SAAS,cACd,MACA,KACD;;CAEH,CAAC,MAAM,QAEL,MACS;AACT,MAAI,KAAK,SAAS,KAAK,KACrB,QAAO;AAET,UAAQ,KAAK,MAAb;GACE,KAAK,UACH,QAAO,KAAK,YAAa,KAA2B;GACtD,KAAK,UACH,QAAO,MAAM,OAAO,KAAK,OAAQ,KAA2B,MAAM;GACpE,KAAK,UACH,QAAO,MAAM,OAAO,KAAK,OAAQ,KAA2B,MAAM;;;CAGxE,CAAC,KAAK,UAA6C;EACjD,MAAM,UAAU,KAAK,OAAO,KAAK,KAAK;AACtC,UAAQ,KAAK,MAAb;GACE,KAAK,UACH,QAAO,KAAK,QAAQ,QAAQ,CAAC,KAAK,KAAK,KAAK,QAAQ,CAAC;GACvD,KAAK,UACH,QAAO,KAAK,QAAQ,QAAQ,CAAC,KAAK,KAAK,KAAK,MAAM,CAAC;GACrD,KAAK,UACH,QAAO,KAAK,QAAQ,QAAQ,CAAC,KAAK,KAAK,KAAK,MAAM,CAAC;;;CAG1D;AAED,MAAa,QAA8B,YACzC,OAAO,OAAO,OAAO,OAAO,iBAAiB,EAAE;CAC7C,MAAM;CACN;CACD,CAAC;AAEJ,MAAa,WAAyB,UACpC,OAAO,OAAO,OAAO,OAAO,iBAAiB,EAAE;CAC7C,MAAM;CACN;CACD,CAAC;AAEJ,MAAa,QAAsB,UACjC,OAAO,OAAO,OAAO,OAAO,iBAAiB,EAAE;CAC7C,MAAM;CACN;CACD,CAAC;AAEJ,MAAa,aACX,gBACiC,YAAY,SAAS;AAExD,MAAa,aACX,gBACiC,YAAY,SAAS;AAExD,MAAa,aACX,gBACiC,YAAY,SAAS;;;;;;;;;;;;;;AAsBxD,MAAa,QAQT,SAAS,KACX,IAEE,MACA,YAC6B;AAC7B,SAAQ,KAAK,MAAb;EACE,KAAK,UACH,QAAO,QAAQ,UAAU,KAAK,QAAQ;EACxC,KAAK,UACH,QAAO,QAAQ,UAAU,KAAK,MAAM;EACtC,KAAK;AACH,OAAI,UAAU,YAAY,SAAS,YAAY,CAC7C,QAAO,QAAQ,UAAU,KAAK,MAAM;AAEtC,SAAM,IAAI,MACR,wDACD;;EAIR"}
|
|
@@ -2,12 +2,17 @@
|
|
|
2
2
|
var __defProp = Object.defineProperty;
|
|
3
3
|
var __exportAll = (all, no_symbols) => {
|
|
4
4
|
let target = {};
|
|
5
|
-
for (var name in all)
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
for (var name in all) {
|
|
6
|
+
__defProp(target, name, {
|
|
7
|
+
get: all[name],
|
|
8
|
+
enumerable: true
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
if (!no_symbols) {
|
|
12
|
+
__defProp(target, Symbol.toStringTag, { value: "Module" });
|
|
13
|
+
}
|
|
10
14
|
return target;
|
|
11
15
|
};
|
|
16
|
+
|
|
12
17
|
//#endregion
|
|
13
|
-
export { __exportAll };
|
|
18
|
+
export { __exportAll };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { Ref } from "@confect/core";
|
|
2
|
-
import * as
|
|
2
|
+
import * as Result from "effect/Result";
|
|
3
3
|
import * as OptimisticLocalStore from "./OptimisticLocalStore";
|
|
4
4
|
import * as QueryResult from "./QueryResult";
|
|
5
5
|
export { OptimisticLocalStore, QueryResult };
|
|
6
6
|
export type InvokeReturn<Ref_ extends Ref.Any> = [Ref.Error<Ref_>] extends [
|
|
7
7
|
never
|
|
8
|
-
] ? Promise<Ref.Returns<Ref_>> : Promise<
|
|
8
|
+
] ? Promise<Ref.Returns<Ref_>> : Promise<Result.Result<Ref.Returns<Ref_>, Ref.Error<Ref_>>>;
|
|
9
9
|
type UseQueryArgs<Query extends Ref.AnyPublicQuery> = keyof Ref.Args<Query> extends never ? [args?: Ref.Args<Query> | "skip"] : [args: Ref.Args<Query> | "skip"];
|
|
10
10
|
export declare const useQuery: <Query extends Ref.AnyPublicQuery>(ref: Query, ...rest: UseQueryArgs<Query>) => QueryResult.QueryResult<Ref.Returns<Query>, Ref.Error<Query>>;
|
|
11
11
|
/**
|
|
@@ -30,9 +30,9 @@ export interface ReactMutation<Mutation extends Ref.AnyPublicMutation> {
|
|
|
30
30
|
* for attaching an optimistic update, mirroring `useMutation` from
|
|
31
31
|
* `convex/react`.
|
|
32
32
|
*
|
|
33
|
-
* If the `Ref` declares an `error` schema, the returned promise resolves to
|
|
34
|
-
* `
|
|
35
|
-
*
|
|
33
|
+
* If the `Ref` declares an `error` schema, the returned promise resolves to a
|
|
34
|
+
* `Result` with the decoded `returns` value in the `Success` and the decoded
|
|
35
|
+
* error in the `Failure`.
|
|
36
36
|
*
|
|
37
37
|
* If the `Ref` does not declare an `error` schema, the promise resolves
|
|
38
38
|
* directly to the decoded `returns` value, matching the behavior of
|
|
@@ -44,9 +44,9 @@ export declare const useMutation: <Mutation extends Ref.AnyPublicMutation>(ref:
|
|
|
44
44
|
/**
|
|
45
45
|
* Returns a function that invokes the provided `Ref`'s action.
|
|
46
46
|
*
|
|
47
|
-
* If the `Ref` declares an `error` schema, the returned promise resolves to
|
|
48
|
-
* `
|
|
49
|
-
*
|
|
47
|
+
* If the `Ref` declares an `error` schema, the returned promise resolves to a
|
|
48
|
+
* `Result` with the decoded `returns` value in the `Success` and the decoded
|
|
49
|
+
* error in the `Failure`.
|
|
50
50
|
*
|
|
51
51
|
* If the `Ref` does not declare an `error` schema, the promise resolves
|
|
52
52
|
* directly to the decoded `returns` value, matching the behavior of
|
package/dist/index.js
CHANGED
|
@@ -4,20 +4,21 @@ import { Ref } from "@confect/core";
|
|
|
4
4
|
import { useAction as useAction$1, useMutation as useMutation$1, useQuery as useQuery$1 } from "convex/react";
|
|
5
5
|
import * as Cause from "effect/Cause";
|
|
6
6
|
import * as Effect from "effect/Effect";
|
|
7
|
-
import * as
|
|
7
|
+
import * as Result from "effect/Result";
|
|
8
8
|
import * as Exit from "effect/Exit";
|
|
9
9
|
import * as Option from "effect/Option";
|
|
10
10
|
import { useCallback, useMemo } from "react";
|
|
11
|
+
|
|
11
12
|
//#region src/index.ts
|
|
12
13
|
const useQuery = (ref, ...rest) => {
|
|
13
14
|
const functionReference = Ref.getFunctionReference(ref);
|
|
14
15
|
const args = rest[0];
|
|
15
16
|
const skipped = args === "skip";
|
|
16
17
|
const encodedArgs = skipped ? "skip" : Ref.encodeArgsSync(ref, args ?? {});
|
|
17
|
-
const encodedReturnsOrError =
|
|
18
|
-
return useMemo(() =>
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
const encodedReturnsOrError = Result.try(() => useQuery$1(functionReference, encodedArgs));
|
|
19
|
+
return useMemo(() => Result.match(encodedReturnsOrError, {
|
|
20
|
+
onSuccess: (encodedReturnsOrUndefined) => encodedReturnsOrUndefined === void 0 ? load(skipped) : succeed(Ref.decodeReturnsSync(ref, encodedReturnsOrUndefined)),
|
|
21
|
+
onFailure: (error) => {
|
|
21
22
|
if (Ref.isConvexError(error)) {
|
|
22
23
|
const decoded = Ref.decodeErrorSync(ref, error.data);
|
|
23
24
|
if (Option.isSome(decoded)) return fail(decoded.value);
|
|
@@ -27,18 +28,17 @@ const useQuery = (ref, ...rest) => {
|
|
|
27
28
|
}), [
|
|
28
29
|
ref,
|
|
29
30
|
skipped,
|
|
30
|
-
|
|
31
|
+
Result.merge(encodedReturnsOrError)
|
|
31
32
|
]);
|
|
32
33
|
};
|
|
33
34
|
const makeReactMutation = (ref, convexReactMutation) => {
|
|
34
|
-
const callable = ((...args) =>
|
|
35
|
+
const callable = ((...args) => invokeAsResult(ref, (_, encodedArgs) => convexReactMutation(encodedArgs), args).then((result) => Ref.hasErrorSchema(ref) ? result : Result.getOrThrow(result)));
|
|
35
36
|
const withOptimisticUpdate = (optimisticUpdate) => {
|
|
36
37
|
const wrappedUpdate = (convexLocalStore, encodedArgs) => {
|
|
37
38
|
const decodedArgs = Ref.decodeArgsSync(ref, encodedArgs);
|
|
38
39
|
optimisticUpdate(make(convexLocalStore), decodedArgs);
|
|
39
40
|
};
|
|
40
|
-
|
|
41
|
-
return makeReactMutation(ref, nextConvexReactMutation);
|
|
41
|
+
return makeReactMutation(ref, convexReactMutation.withOptimisticUpdate(wrappedUpdate));
|
|
42
42
|
};
|
|
43
43
|
return Object.assign(callable, { withOptimisticUpdate });
|
|
44
44
|
};
|
|
@@ -48,9 +48,9 @@ const makeReactMutation = (ref, convexReactMutation) => {
|
|
|
48
48
|
* for attaching an optimistic update, mirroring `useMutation` from
|
|
49
49
|
* `convex/react`.
|
|
50
50
|
*
|
|
51
|
-
* If the `Ref` declares an `error` schema, the returned promise resolves to
|
|
52
|
-
* `
|
|
53
|
-
*
|
|
51
|
+
* If the `Ref` declares an `error` schema, the returned promise resolves to a
|
|
52
|
+
* `Result` with the decoded `returns` value in the `Success` and the decoded
|
|
53
|
+
* error in the `Failure`.
|
|
54
54
|
*
|
|
55
55
|
* If the `Ref` does not declare an `error` schema, the promise resolves
|
|
56
56
|
* directly to the decoded `returns` value, matching the behavior of
|
|
@@ -65,9 +65,9 @@ const useMutation = (ref) => {
|
|
|
65
65
|
/**
|
|
66
66
|
* Returns a function that invokes the provided `Ref`'s action.
|
|
67
67
|
*
|
|
68
|
-
* If the `Ref` declares an `error` schema, the returned promise resolves to
|
|
69
|
-
* `
|
|
70
|
-
*
|
|
68
|
+
* If the `Ref` declares an `error` schema, the returned promise resolves to a
|
|
69
|
+
* `Result` with the decoded `returns` value in the `Success` and the decoded
|
|
70
|
+
* error in the `Failure`.
|
|
71
71
|
*
|
|
72
72
|
* If the `Ref` does not declare an `error` schema, the promise resolves
|
|
73
73
|
* directly to the decoded `returns` value, matching the behavior of
|
|
@@ -77,14 +77,14 @@ const useMutation = (ref) => {
|
|
|
77
77
|
*/
|
|
78
78
|
const useAction = (ref) => {
|
|
79
79
|
const actualAction = useAction$1(Ref.getFunctionReference(ref));
|
|
80
|
-
return useCallback(((...args) =>
|
|
80
|
+
return useCallback(((...args) => invokeAsResult(ref, (_, encodedArgs) => actualAction(encodedArgs), args).then((result) => Ref.hasErrorSchema(ref) ? result : Result.getOrThrow(result))), [ref, actualAction]);
|
|
81
81
|
};
|
|
82
|
-
const
|
|
83
|
-
const exit = await Effect.runPromiseExit(Ref.runWithCodec(ref, args[0] ?? {}, invoke).pipe(Effect.catchTag("
|
|
82
|
+
const invokeAsResult = async (ref, invoke, args) => {
|
|
83
|
+
const exit = await Effect.runPromiseExit(Ref.runWithCodec(ref, args[0] ?? {}, invoke).pipe(Effect.catchTag("SchemaError", Effect.die), Effect.result));
|
|
84
84
|
if (Exit.isSuccess(exit)) return exit.value;
|
|
85
85
|
throw Cause.squash(exit.cause);
|
|
86
86
|
};
|
|
87
|
+
|
|
87
88
|
//#endregion
|
|
88
89
|
export { OptimisticLocalStore_exports as OptimisticLocalStore, QueryResult_exports as QueryResult, useAction, useMutation, useQuery };
|
|
89
|
-
|
|
90
90
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["useConvexQuery","QueryResult.load","QueryResult.succeed","QueryResult.fail","OptimisticLocalStore.make","useConvexMutation","useConvexAction"],"sources":["../src/index.ts"],"sourcesContent":["import { Ref } from \"@confect/core\";\nimport type { OptimisticUpdate as ConvexOptimisticUpdate } from \"convex/browser\";\nimport {\n useAction as useConvexAction,\n useMutation as useConvexMutation,\n useQuery as useConvexQuery,\n type ReactMutation as ConvexReactMutation,\n} from \"convex/react\";\nimport type { FunctionReference } from \"convex/server\";\nimport type { Value } from \"convex/values\";\nimport * as Cause from \"effect/Cause\";\nimport * as Effect from \"effect/Effect\";\nimport * as Either from \"effect/Either\";\nimport * as Exit from \"effect/Exit\";\nimport * as Option from \"effect/Option\";\nimport { useCallback, useMemo } from \"react\";\n\nimport * as OptimisticLocalStore from \"./OptimisticLocalStore\";\nimport * as QueryResult from \"./QueryResult\";\n\nexport { OptimisticLocalStore, QueryResult };\n\nexport type InvokeReturn<Ref_ extends Ref.Any> = [Ref.Error<Ref_>] extends [\n never,\n]\n ? Promise<Ref.Returns<Ref_>>\n : Promise<Either.Either<Ref.Returns<Ref_>, Ref.Error<Ref_>>>;\n\ntype UseQueryArgs<Query extends Ref.AnyPublicQuery> =\n keyof Ref.Args<Query> extends never\n ? [args?: Ref.Args<Query> | \"skip\"]\n : [args: Ref.Args<Query> | \"skip\"];\n\nexport const useQuery = <Query extends Ref.AnyPublicQuery>(\n ref: Query,\n ...rest: UseQueryArgs<Query>\n): QueryResult.QueryResult<Ref.Returns<Query>, Ref.Error<Query>> => {\n const functionReference = Ref.getFunctionReference(ref);\n const args = rest[0];\n const skipped = args === \"skip\";\n const encodedArgs = skipped\n ? \"skip\"\n : Ref.encodeArgsSync(ref, (args ?? {}) as Ref.Args<Query>);\n\n // `useConvexQuery` returns a referentially stable value while the underlying\n // Convex result is unchanged, and throws a stable error when the query\n // fails. We capture either outcome as an `Either` and decode/wrap it inside\n // `useMemo` so that the returned `QueryResult` keeps a stable identity across\n // renders when nothing has actually changed. Decoding on every render would\n // hand consumers a fresh object each time, breaking effects and memoization\n // that depend on the result's identity.\n const encodedReturnsOrError: Either.Either<unknown, unknown> = Either.try(\n () => useConvexQuery(functionReference, encodedArgs),\n );\n\n return useMemo(\n () =>\n Either.match(encodedReturnsOrError, {\n onRight: (encodedReturnsOrUndefined) =>\n encodedReturnsOrUndefined === undefined\n ? QueryResult.load(skipped)\n : QueryResult.succeed(\n Ref.decodeReturnsSync(ref, encodedReturnsOrUndefined),\n ),\n onLeft: (error) => {\n if (Ref.isConvexError(error)) {\n const decoded = Ref.decodeErrorSync(ref, error.data);\n if (Option.isSome(decoded)) {\n return QueryResult.fail(decoded.value);\n }\n }\n throw error;\n },\n }),\n // `Either.try` allocates a fresh wrapper each render, so we key the memo on\n // the stable value it carries (the Convex result or thrown error) rather\n // than the wrapper itself; the decoded result is a function of that value,\n // `ref`, and `skipped`.\n [ref, skipped, Either.merge(encodedReturnsOrError)],\n );\n};\n\n/**\n * An optimistic update for a Confect mutation. Mirrors Convex's\n * `OptimisticUpdate`, but receives a Confect {@link OptimisticLocalStore} and\n * the decoded mutation `args`.\n */\nexport type OptimisticUpdate<Mutation extends Ref.AnyPublicMutation> = (\n localStore: OptimisticLocalStore.OptimisticLocalStore,\n args: Ref.Args<Mutation>,\n) => void;\n\n/**\n * The handle returned by {@link useMutation}. It is callable like the function\n * returned by Convex's `useMutation`, and additionally exposes\n * `withOptimisticUpdate` for attaching an optimistic update. Mirrors the\n * `ReactMutation` type from `convex/react`.\n */\nexport interface ReactMutation<Mutation extends Ref.AnyPublicMutation> {\n (...args: Ref.OptionalArgs<Mutation>): InvokeReturn<Mutation>;\n withOptimisticUpdate(\n optimisticUpdate: OptimisticUpdate<Mutation>,\n ): ReactMutation<Mutation>;\n}\n\nconst makeReactMutation = <Mutation extends Ref.AnyPublicMutation>(\n ref: Mutation,\n convexReactMutation: ConvexReactMutation<\n Ref.FunctionReference<Mutation> & FunctionReference<\"mutation\">\n >,\n): ReactMutation<Mutation> => {\n const callable = ((...args: Ref.OptionalArgs<Mutation>) =>\n invokeAsEither(\n ref,\n (_, encodedArgs) => convexReactMutation(encodedArgs as never),\n args,\n ).then((either) =>\n Ref.hasErrorSchema(ref) ? either : Either.getOrThrow(either),\n )) as (...args: Ref.OptionalArgs<Mutation>) => InvokeReturn<Mutation>;\n\n const withOptimisticUpdate = (\n optimisticUpdate: OptimisticUpdate<Mutation>,\n ): ReactMutation<Mutation> => {\n const wrappedUpdate: ConvexOptimisticUpdate<Record<string, Value>> = (\n convexLocalStore,\n encodedArgs,\n ) => {\n const decodedArgs = Ref.decodeArgsSync(ref, encodedArgs);\n optimisticUpdate(\n OptimisticLocalStore.make(convexLocalStore),\n decodedArgs,\n );\n };\n const nextConvexReactMutation =\n convexReactMutation.withOptimisticUpdate(wrappedUpdate);\n return makeReactMutation(ref, nextConvexReactMutation);\n };\n\n return Object.assign(callable, { withOptimisticUpdate });\n};\n\n/**\n * Returns a {@link ReactMutation} handle for the provided `Ref`'s mutation. The\n * handle is callable to invoke the mutation, and exposes `withOptimisticUpdate`\n * for attaching an optimistic update, mirroring `useMutation` from\n * `convex/react`.\n *\n * If the `Ref` declares an `error` schema, the returned promise resolves to an\n * `Either` with the decoded `returns` value on the right and the decoded error\n * on the left.\n *\n * If the `Ref` does not declare an `error` schema, the promise resolves\n * directly to the decoded `returns` value, matching the behavior of\n * `useMutation` from `convex/react`.\n *\n * Any other failure rejects the promise.\n */\nexport const useMutation = <Mutation extends Ref.AnyPublicMutation>(\n ref: Mutation,\n): ReactMutation<Mutation> => {\n const functionReference = Ref.getFunctionReference(ref);\n const convexReactMutation = useConvexMutation(functionReference);\n\n return useMemo(\n () =>\n makeReactMutation(\n ref,\n convexReactMutation as ConvexReactMutation<\n Ref.FunctionReference<Mutation> & FunctionReference<\"mutation\">\n >,\n ),\n [ref, convexReactMutation],\n );\n};\n\n/**\n * Returns a function that invokes the provided `Ref`'s action.\n *\n * If the `Ref` declares an `error` schema, the returned promise resolves to an\n * `Either` with the decoded `returns` value on the right and the decoded error\n * on the left.\n *\n * If the `Ref` does not declare an `error` schema, the promise resolves\n * directly to the decoded `returns` value, matching the behavior of\n * `useMutation` from `convex/react`.\n *\n * Any other failure rejects the promise.\n */\nexport const useAction = <Action extends Ref.AnyPublicAction>(\n ref: Action,\n): ((...args: Ref.OptionalArgs<Action>) => InvokeReturn<Action>) => {\n const functionReference = Ref.getFunctionReference(ref);\n const actualAction = useConvexAction(functionReference);\n\n return useCallback(\n ((...args: Ref.OptionalArgs<Action>) =>\n invokeAsEither(\n ref,\n (_, encodedArgs) => actualAction(encodedArgs),\n args,\n ).then((either) =>\n Ref.hasErrorSchema(ref) ? either : Either.getOrThrow(either),\n )) as (...args: Ref.OptionalArgs<Action>) => InvokeReturn<Action>,\n [ref, actualAction],\n );\n};\n\nconst invokeAsEither = async <Ref_ extends Ref.Any>(\n ref: Ref_,\n invoke: (\n fnRef: Ref.FunctionReference<Ref_>,\n encodedArgs: unknown,\n ) => PromiseLike<unknown>,\n args: Ref.OptionalArgs<Ref_>,\n): Promise<Either.Either<Ref.Returns<Ref_>, Ref.Error<Ref_>>> => {\n const exit = await Effect.runPromiseExit(\n Ref.runWithCodec(ref, (args[0] ?? {}) as Ref.Args<Ref_>, invoke).pipe(\n Effect.catchTag(\"ParseError\", Effect.die),\n Effect.either,\n ),\n );\n if (Exit.isSuccess(exit)) return exit.value;\n throw Cause.squash(exit.cause);\n};\n"],"mappings":";;;;;;;;;;;AAiCA,MAAa,YACX,KACA,GAAG,SAC+D;CAClE,MAAM,oBAAoB,IAAI,qBAAqB,GAAG;CACtD,MAAM,OAAO,KAAK;CAClB,MAAM,UAAU,SAAS;CACzB,MAAM,cAAc,UAChB,SACA,IAAI,eAAe,KAAM,QAAQ,CAAC,CAAqB;CAS3D,MAAM,wBAAyD,OAAO,UAC9DA,WAAe,mBAAmB,WAAW,CACrD;CAEA,OAAO,cAEH,OAAO,MAAM,uBAAuB;EAClC,UAAU,8BACR,8BAA8B,KAAA,IAC1BC,KAAiB,OAAO,IACxBC,QACE,IAAI,kBAAkB,KAAK,yBAAyB,CACtD;EACN,SAAS,UAAU;GACjB,IAAI,IAAI,cAAc,KAAK,GAAG;IAC5B,MAAM,UAAU,IAAI,gBAAgB,KAAK,MAAM,IAAI;IACnD,IAAI,OAAO,OAAO,OAAO,GACvB,OAAOC,KAAiB,QAAQ,KAAK;GAEzC;GACA,MAAM;EACR;CACF,CAAC,GAKH;EAAC;EAAK;EAAS,OAAO,MAAM,qBAAqB;CAAC,CACpD;AACF;AAyBA,MAAM,qBACJ,KACA,wBAG4B;CAC5B,MAAM,aAAa,GAAG,SACpB,eACE,MACC,GAAG,gBAAgB,oBAAoB,WAAoB,GAC5D,IACF,CAAC,CAAC,MAAM,WACN,IAAI,eAAe,GAAG,IAAI,SAAS,OAAO,WAAW,MAAM,CAC7D;CAEF,MAAM,wBACJ,qBAC4B;EAC5B,MAAM,iBACJ,kBACA,gBACG;GACH,MAAM,cAAc,IAAI,eAAe,KAAK,WAAW;GACvD,iBACEC,KAA0B,gBAAgB,GAC1C,WACF;EACF;EACA,MAAM,0BACJ,oBAAoB,qBAAqB,aAAa;EACxD,OAAO,kBAAkB,KAAK,uBAAuB;CACvD;CAEA,OAAO,OAAO,OAAO,UAAU,EAAE,qBAAqB,CAAC;AACzD;;;;;;;;;;;;;;;;;AAkBA,MAAa,eACX,QAC4B;CAE5B,MAAM,sBAAsBC,cADF,IAAI,qBAAqB,GACW,CAAC;CAE/D,OAAO,cAEH,kBACE,KACA,mBAGF,GACF,CAAC,KAAK,mBAAmB,CAC3B;AACF;;;;;;;;;;;;;;AAeA,MAAa,aACX,QACkE;CAElE,MAAM,eAAeC,YADK,IAAI,qBAAqB,GACE,CAAC;CAEtD,OAAO,cACH,GAAG,SACH,eACE,MACC,GAAG,gBAAgB,aAAa,WAAW,GAC5C,IACF,CAAC,CAAC,MAAM,WACN,IAAI,eAAe,GAAG,IAAI,SAAS,OAAO,WAAW,MAAM,CAC7D,IACF,CAAC,KAAK,YAAY,CACpB;AACF;AAEA,MAAM,iBAAiB,OACrB,KACA,QAIA,SAC+D;CAC/D,MAAM,OAAO,MAAM,OAAO,eACxB,IAAI,aAAa,KAAM,KAAK,MAAM,CAAC,GAAsB,MAAM,CAAC,CAAC,KAC/D,OAAO,SAAS,cAAc,OAAO,GAAG,GACxC,OAAO,MACT,CACF;CACA,IAAI,KAAK,UAAU,IAAI,GAAG,OAAO,KAAK;CACtC,MAAM,MAAM,OAAO,KAAK,KAAK;AAC/B"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["useConvexQuery","QueryResult.load","QueryResult.succeed","QueryResult.fail","OptimisticLocalStore.make","useConvexMutation","useConvexAction"],"sources":["../src/index.ts"],"sourcesContent":["import { Ref } from \"@confect/core\";\nimport type { OptimisticUpdate as ConvexOptimisticUpdate } from \"convex/browser\";\nimport {\n useAction as useConvexAction,\n useMutation as useConvexMutation,\n useQuery as useConvexQuery,\n type ReactMutation as ConvexReactMutation,\n} from \"convex/react\";\nimport type { FunctionReference } from \"convex/server\";\nimport type { Value } from \"convex/values\";\nimport * as Cause from \"effect/Cause\";\nimport * as Effect from \"effect/Effect\";\nimport * as Result from \"effect/Result\";\nimport * as Exit from \"effect/Exit\";\nimport * as Option from \"effect/Option\";\nimport { useCallback, useMemo } from \"react\";\n\nimport * as OptimisticLocalStore from \"./OptimisticLocalStore\";\nimport * as QueryResult from \"./QueryResult\";\n\nexport { OptimisticLocalStore, QueryResult };\n\nexport type InvokeReturn<Ref_ extends Ref.Any> = [Ref.Error<Ref_>] extends [\n never,\n]\n ? Promise<Ref.Returns<Ref_>>\n : Promise<Result.Result<Ref.Returns<Ref_>, Ref.Error<Ref_>>>;\n\ntype UseQueryArgs<Query extends Ref.AnyPublicQuery> =\n keyof Ref.Args<Query> extends never\n ? [args?: Ref.Args<Query> | \"skip\"]\n : [args: Ref.Args<Query> | \"skip\"];\n\nexport const useQuery = <Query extends Ref.AnyPublicQuery>(\n ref: Query,\n ...rest: UseQueryArgs<Query>\n): QueryResult.QueryResult<Ref.Returns<Query>, Ref.Error<Query>> => {\n const functionReference = Ref.getFunctionReference(ref);\n const args = rest[0];\n const skipped = args === \"skip\";\n const encodedArgs = skipped\n ? \"skip\"\n : Ref.encodeArgsSync(ref, (args ?? {}) as Ref.Args<Query>);\n\n // `useConvexQuery` returns a referentially stable value while the underlying\n // Convex result is unchanged, and throws a stable error when the query\n // fails. We capture either outcome as a `Result` and decode/wrap it inside\n // `useMemo` so that the returned `QueryResult` keeps a stable identity across\n // renders when nothing has actually changed. Decoding on every render would\n // hand consumers a fresh object each time, breaking effects and memoization\n // that depend on the result's identity.\n const encodedReturnsOrError: Result.Result<unknown, unknown> = Result.try(\n () => useConvexQuery(functionReference, encodedArgs),\n );\n\n return useMemo(\n () =>\n Result.match(encodedReturnsOrError, {\n onSuccess: (encodedReturnsOrUndefined) =>\n encodedReturnsOrUndefined === undefined\n ? QueryResult.load(skipped)\n : QueryResult.succeed(\n Ref.decodeReturnsSync(ref, encodedReturnsOrUndefined),\n ),\n onFailure: (error) => {\n if (Ref.isConvexError(error)) {\n const decoded = Ref.decodeErrorSync(ref, error.data);\n if (Option.isSome(decoded)) {\n return QueryResult.fail(decoded.value);\n }\n }\n throw error;\n },\n }),\n // `Result.try` allocates a fresh wrapper each render, so we key the memo on\n // the stable value it carries (the Convex result or thrown error) rather\n // than the wrapper itself; the decoded result is a function of that value,\n // `ref`, and `skipped`.\n [ref, skipped, Result.merge(encodedReturnsOrError)],\n );\n};\n\n/**\n * An optimistic update for a Confect mutation. Mirrors Convex's\n * `OptimisticUpdate`, but receives a Confect {@link OptimisticLocalStore} and\n * the decoded mutation `args`.\n */\nexport type OptimisticUpdate<Mutation extends Ref.AnyPublicMutation> = (\n localStore: OptimisticLocalStore.OptimisticLocalStore,\n args: Ref.Args<Mutation>,\n) => void;\n\n/**\n * The handle returned by {@link useMutation}. It is callable like the function\n * returned by Convex's `useMutation`, and additionally exposes\n * `withOptimisticUpdate` for attaching an optimistic update. Mirrors the\n * `ReactMutation` type from `convex/react`.\n */\nexport interface ReactMutation<Mutation extends Ref.AnyPublicMutation> {\n (...args: Ref.OptionalArgs<Mutation>): InvokeReturn<Mutation>;\n withOptimisticUpdate(\n optimisticUpdate: OptimisticUpdate<Mutation>,\n ): ReactMutation<Mutation>;\n}\n\nconst makeReactMutation = <Mutation extends Ref.AnyPublicMutation>(\n ref: Mutation,\n convexReactMutation: ConvexReactMutation<\n Ref.FunctionReference<Mutation> & FunctionReference<\"mutation\">\n >,\n): ReactMutation<Mutation> => {\n const callable = ((...args: Ref.OptionalArgs<Mutation>) =>\n invokeAsResult(\n ref,\n (_, encodedArgs) => convexReactMutation(encodedArgs as never),\n args,\n ).then((result) =>\n Ref.hasErrorSchema(ref) ? result : Result.getOrThrow(result),\n )) as (...args: Ref.OptionalArgs<Mutation>) => InvokeReturn<Mutation>;\n\n const withOptimisticUpdate = (\n optimisticUpdate: OptimisticUpdate<Mutation>,\n ): ReactMutation<Mutation> => {\n const wrappedUpdate: ConvexOptimisticUpdate<Record<string, Value>> = (\n convexLocalStore,\n encodedArgs,\n ) => {\n const decodedArgs = Ref.decodeArgsSync(ref, encodedArgs);\n optimisticUpdate(\n OptimisticLocalStore.make(convexLocalStore),\n decodedArgs,\n );\n };\n const nextConvexReactMutation =\n convexReactMutation.withOptimisticUpdate(wrappedUpdate);\n return makeReactMutation(ref, nextConvexReactMutation);\n };\n\n return Object.assign(callable, { withOptimisticUpdate });\n};\n\n/**\n * Returns a {@link ReactMutation} handle for the provided `Ref`'s mutation. The\n * handle is callable to invoke the mutation, and exposes `withOptimisticUpdate`\n * for attaching an optimistic update, mirroring `useMutation` from\n * `convex/react`.\n *\n * If the `Ref` declares an `error` schema, the returned promise resolves to a\n * `Result` with the decoded `returns` value in the `Success` and the decoded\n * error in the `Failure`.\n *\n * If the `Ref` does not declare an `error` schema, the promise resolves\n * directly to the decoded `returns` value, matching the behavior of\n * `useMutation` from `convex/react`.\n *\n * Any other failure rejects the promise.\n */\nexport const useMutation = <Mutation extends Ref.AnyPublicMutation>(\n ref: Mutation,\n): ReactMutation<Mutation> => {\n const functionReference = Ref.getFunctionReference(ref);\n const convexReactMutation = useConvexMutation(functionReference);\n\n return useMemo(\n () =>\n makeReactMutation(\n ref,\n convexReactMutation as ConvexReactMutation<\n Ref.FunctionReference<Mutation> & FunctionReference<\"mutation\">\n >,\n ),\n [ref, convexReactMutation],\n );\n};\n\n/**\n * Returns a function that invokes the provided `Ref`'s action.\n *\n * If the `Ref` declares an `error` schema, the returned promise resolves to a\n * `Result` with the decoded `returns` value in the `Success` and the decoded\n * error in the `Failure`.\n *\n * If the `Ref` does not declare an `error` schema, the promise resolves\n * directly to the decoded `returns` value, matching the behavior of\n * `useMutation` from `convex/react`.\n *\n * Any other failure rejects the promise.\n */\nexport const useAction = <Action extends Ref.AnyPublicAction>(\n ref: Action,\n): ((...args: Ref.OptionalArgs<Action>) => InvokeReturn<Action>) => {\n const functionReference = Ref.getFunctionReference(ref);\n const actualAction = useConvexAction(functionReference);\n\n return useCallback(\n ((...args: Ref.OptionalArgs<Action>) =>\n invokeAsResult(\n ref,\n (_, encodedArgs) => actualAction(encodedArgs),\n args,\n ).then((result) =>\n Ref.hasErrorSchema(ref) ? result : Result.getOrThrow(result),\n )) as (...args: Ref.OptionalArgs<Action>) => InvokeReturn<Action>,\n [ref, actualAction],\n );\n};\n\nconst invokeAsResult = async <Ref_ extends Ref.Any>(\n ref: Ref_,\n invoke: (\n fnRef: Ref.FunctionReference<Ref_>,\n encodedArgs: unknown,\n ) => PromiseLike<unknown>,\n args: Ref.OptionalArgs<Ref_>,\n): Promise<Result.Result<Ref.Returns<Ref_>, Ref.Error<Ref_>>> => {\n const exit = await Effect.runPromiseExit(\n Ref.runWithCodec(ref, (args[0] ?? {}) as Ref.Args<Ref_>, invoke).pipe(\n Effect.catchTag(\"SchemaError\", Effect.die),\n Effect.result,\n ),\n );\n if (Exit.isSuccess(exit)) return exit.value;\n throw Cause.squash(exit.cause);\n};\n"],"mappings":";;;;;;;;;;;;AAiCA,MAAa,YACX,KACA,GAAG,SAC+D;CAClE,MAAM,oBAAoB,IAAI,qBAAqB,IAAI;CACvD,MAAM,OAAO,KAAK;CAClB,MAAM,UAAU,SAAS;CACzB,MAAM,cAAc,UAChB,SACA,IAAI,eAAe,KAAM,QAAQ,EAAE,CAAqB;CAS5D,MAAM,wBAAyD,OAAO,UAC9DA,WAAe,mBAAmB,YAAY,CACrD;AAED,QAAO,cAEH,OAAO,MAAM,uBAAuB;EAClC,YAAY,8BACV,8BAA8B,SAC1BC,KAAiB,QAAQ,GACzBC,QACE,IAAI,kBAAkB,KAAK,0BAA0B,CACtD;EACP,YAAY,UAAU;AACpB,OAAI,IAAI,cAAc,MAAM,EAAE;IAC5B,MAAM,UAAU,IAAI,gBAAgB,KAAK,MAAM,KAAK;AACpD,QAAI,OAAO,OAAO,QAAQ,CACxB,QAAOC,KAAiB,QAAQ,MAAM;;AAG1C,SAAM;;EAET,CAAC,EAKJ;EAAC;EAAK;EAAS,OAAO,MAAM,sBAAsB;EAAC,CACpD;;AA0BH,MAAM,qBACJ,KACA,wBAG4B;CAC5B,MAAM,aAAa,GAAG,SACpB,eACE,MACC,GAAG,gBAAgB,oBAAoB,YAAqB,EAC7D,KACD,CAAC,MAAM,WACN,IAAI,eAAe,IAAI,GAAG,SAAS,OAAO,WAAW,OAAO,CAC7D;CAEH,MAAM,wBACJ,qBAC4B;EAC5B,MAAM,iBACJ,kBACA,gBACG;GACH,MAAM,cAAc,IAAI,eAAe,KAAK,YAAY;AACxD,oBACEC,KAA0B,iBAAiB,EAC3C,YACD;;AAIH,SAAO,kBAAkB,KADvB,oBAAoB,qBAAqB,cAAc,CACH;;AAGxD,QAAO,OAAO,OAAO,UAAU,EAAE,sBAAsB,CAAC;;;;;;;;;;;;;;;;;;AAmB1D,MAAa,eACX,QAC4B;CAE5B,MAAM,sBAAsBC,cADF,IAAI,qBAAqB,IAAI,CACS;AAEhE,QAAO,cAEH,kBACE,KACA,oBAGD,EACH,CAAC,KAAK,oBAAoB,CAC3B;;;;;;;;;;;;;;;AAgBH,MAAa,aACX,QACkE;CAElE,MAAM,eAAeC,YADK,IAAI,qBAAqB,IAAI,CACA;AAEvD,QAAO,cACH,GAAG,SACH,eACE,MACC,GAAG,gBAAgB,aAAa,YAAY,EAC7C,KACD,CAAC,MAAM,WACN,IAAI,eAAe,IAAI,GAAG,SAAS,OAAO,WAAW,OAAO,CAC7D,GACH,CAAC,KAAK,aAAa,CACpB;;AAGH,MAAM,iBAAiB,OACrB,KACA,QAIA,SAC+D;CAC/D,MAAM,OAAO,MAAM,OAAO,eACxB,IAAI,aAAa,KAAM,KAAK,MAAM,EAAE,EAAqB,OAAO,CAAC,KAC/D,OAAO,SAAS,eAAe,OAAO,IAAI,EAC1C,OAAO,OACR,CACF;AACD,KAAI,KAAK,UAAU,KAAK,CAAE,QAAO,KAAK;AACtC,OAAM,MAAM,OAAO,KAAK,MAAM"}
|