···11+---
22+'@urql/core': minor
33+---
44+55+Return a new `OperationResultSource` from all `Client` methods (which replaces `PromisifiedSource` on shortcut methods). This allows not only `toPromise()` to be called, but it can also be used as an awaitable `PromiseLike` and has a `.subscribe(onResult)` method aliasing the subscribe utility from `wonka`.
+49-52
packages/core/src/client.ts
···3737 OperationInstance,
3838 OperationContext,
3939 OperationResult,
4040+ OperationResultSource,
4041 OperationType,
4142 RequestPolicy,
4242- PromisifiedSource,
4343 DebugEvent,
4444} from './types';
4545···313313 Variables extends AnyVariables = AnyVariables
314314 >(
315315 operation: Operation<Data, Variables>
316316- ): Source<OperationResult<Data, Variables>>;
316316+ ): OperationResultSource<OperationResult<Data, Variables>>;
317317318318 /** Creates a `Source` that executes the GraphQL query operation created from the passed parameters.
319319 *
320320 * @param query - a GraphQL document containing the query operation that will be executed.
321321 * @param variables - the variables used to execute the operation.
322322 * @param opts - {@link OperationContext} options that'll override and be merged with options from the {@link ClientOptions}.
323323- * @returns A {@link PromisifiedSource} issuing the {@link OperationResult | OperationResults} for the GraphQL operation.
323323+ * @returns A {@link OperationResultSource} issuing the {@link OperationResult | OperationResults} for the GraphQL operation.
324324 *
325325 * @remarks
326326 * The `Client.query` method is useful to programmatically create and issue a GraphQL query operation.
327327 * It automatically calls {@link createRequest}, {@link client.createRequestOperation}, and
328328 * {@link client.executeRequestOperation} for you, and is a convenience method.
329329 *
330330- * Since it returns a {@link PromisifiedSource} it may be chained with a `toPromise()` call to only
330330+ * Since it returns a {@link OperationResultSource} it may be chained with a `toPromise()` call to only
331331 * await a single result in an async function.
332332 *
333333 * Hint: This is the recommended way to create queries programmatically when not using the bindings,
···361361 query: DocumentNode | TypedDocumentNode<Data, Variables> | string,
362362 variables: Variables,
363363 context?: Partial<OperationContext>
364364- ): PromisifiedSource<OperationResult<Data, Variables>>;
364364+ ): OperationResultSource<OperationResult<Data, Variables>>;
365365366366 /** Returns the first synchronous result a `Client` provides for a given operation.
367367 *
···405405 executeQuery<Data = any, Variables extends AnyVariables = AnyVariables>(
406406 query: GraphQLRequest<Data, Variables>,
407407 opts?: Partial<OperationContext> | undefined
408408- ): Source<OperationResult<Data, Variables>>;
408408+ ): OperationResultSource<OperationResult<Data, Variables>>;
409409410410 /** Creates a `Source` that executes the GraphQL subscription operation created from the passed parameters.
411411 *
···453453 query: DocumentNode | TypedDocumentNode<Data, Variables> | string,
454454 variables: Variables,
455455 context?: Partial<OperationContext>
456456- ): Source<OperationResult<Data, Variables>>;
456456+ ): OperationResultSource<OperationResult<Data, Variables>>;
457457458458 /** Creates a `Source` that executes the GraphQL subscription operation for the passed `GraphQLRequest`.
459459 *
···474474 >(
475475 query: GraphQLRequest<Data, Variables>,
476476 opts?: Partial<OperationContext> | undefined
477477- ): Source<OperationResult<Data, Variables>>;
477477+ ): OperationResultSource<OperationResult<Data, Variables>>;
478478479479 /** Creates a `Source` that executes the GraphQL mutation operation created from the passed parameters.
480480 *
···522522 query: DocumentNode | TypedDocumentNode<Data, Variables> | string,
523523 variables: Variables,
524524 context?: Partial<OperationContext>
525525- ): PromisifiedSource<OperationResult<Data, Variables>>;
525525+ ): OperationResultSource<OperationResult<Data, Variables>>;
526526527527 /** Creates a `Source` that executes the GraphQL mutation operation for the passed `GraphQLRequest`.
528528 *
···540540 executeMutation<Data = any, Variables extends AnyVariables = AnyVariables>(
541541 query: GraphQLRequest<Data, Variables>,
542542 opts?: Partial<OperationContext> | undefined
543543- ): Source<OperationResult<Data, Variables>>;
543543+ ): OperationResultSource<OperationResult<Data, Variables>>;
544544}
545545546546export const Client: new (opts: ClientOptions) => Client = function Client(
···721721722722 executeRequestOperation(operation) {
723723 if (operation.kind === 'mutation') {
724724- return makeResultSource(operation);
724724+ return withPromise(makeResultSource(operation));
725725 }
726726727727- return make<OperationResult>(observer => {
728728- let source = active.get(operation.key);
729729- if (!source) {
730730- active.set(operation.key, (source = makeResultSource(operation)));
731731- }
727727+ return withPromise(
728728+ make<OperationResult>(observer => {
729729+ let source = active.get(operation.key);
730730+ if (!source) {
731731+ active.set(operation.key, (source = makeResultSource(operation)));
732732+ }
732733733733- return pipe(
734734- source,
735735- onStart(() => {
736736- const prevReplay = replays.get(operation.key);
737737- const isNetworkOperation =
738738- operation.context.requestPolicy === 'cache-and-network' ||
739739- operation.context.requestPolicy === 'network-only';
740740- if (operation.kind !== 'query') {
741741- return;
742742- } else if (isNetworkOperation) {
743743- dispatchOperation(operation);
744744- if (prevReplay && !prevReplay.hasNext) prevReplay.stale = true;
745745- }
734734+ return pipe(
735735+ source,
736736+ onStart(() => {
737737+ const prevReplay = replays.get(operation.key);
738738+ const isNetworkOperation =
739739+ operation.context.requestPolicy === 'cache-and-network' ||
740740+ operation.context.requestPolicy === 'network-only';
741741+ if (operation.kind !== 'query') {
742742+ return;
743743+ } else if (isNetworkOperation) {
744744+ dispatchOperation(operation);
745745+ if (prevReplay && !prevReplay.hasNext) prevReplay.stale = true;
746746+ }
746747747747- if (
748748- prevReplay != null &&
749749- prevReplay === replays.get(operation.key)
750750- ) {
751751- observer.next(prevReplay);
752752- } else if (!isNetworkOperation) {
753753- dispatchOperation(operation);
754754- }
755755- }),
756756- onEnd(() => {
757757- isOperationBatchActive = false;
758758- observer.complete();
759759- }),
760760- subscribe(observer.next)
761761- ).unsubscribe;
762762- });
748748+ if (
749749+ prevReplay != null &&
750750+ prevReplay === replays.get(operation.key)
751751+ ) {
752752+ observer.next(prevReplay);
753753+ } else if (!isNetworkOperation) {
754754+ dispatchOperation(operation);
755755+ }
756756+ }),
757757+ onEnd(() => {
758758+ isOperationBatchActive = false;
759759+ observer.complete();
760760+ }),
761761+ subscribe(observer.next)
762762+ ).unsubscribe;
763763+ })
764764+ );
763765 },
764766765767 executeQuery(query, opts) {
···785787 if (!context || typeof context.suspense !== 'boolean') {
786788 context = { ...context, suspense: false };
787789 }
788788-789789- return withPromise(
790790- client.executeQuery(createRequest(query, variables), context)
791791- );
790790+ return client.executeQuery(createRequest(query, variables), context);
792791 },
793792794793 readQuery(query, variables, context) {
···812811 },
813812814813 mutation(query, variables, context) {
815815- return withPromise(
816816- client.executeMutation(createRequest(query, variables), context)
817817- );
814814+ return client.executeMutation(createRequest(query, variables), context);
818815 },
819816 } as Client);
820817
+22-8
packages/core/src/types.ts
···11import type { GraphQLError, DocumentNode } from 'graphql';
22-import { Source } from 'wonka';
22+import { Subscription, Source } from 'wonka';
33import { Client } from './client';
44import { CombinedError } from './utils/error';
55···127127 hasNext?: boolean;
128128}
129129130130-/** A `Source` with a `PromisifiedSource.toPromise` helper method, to promisify a single result.
130130+/** A source of {@link OperationResult | OperationResults}, convertable to a promise, subscribable, or Wonka Source.
131131 *
132132 * @remarks
133133- * The {@link Client} will often return a `PromisifiedSource` to provide the `toPromise` method. When called, this returns
134134- * a promise of the source that resolves on the first {@link OperationResult} of the `Source` that doesn't have `stale: true`
135135- * nor `hasNext: true` set, meaning, it'll resolve to the first result that is stable and complete.
133133+ * The {@link Client} will often return a `OperationResultSource` to provide a more flexible Wonka {@link Source}.
134134+ *
135135+ * While a {@link Source} may require you to import helpers to convert it to a `Promise` for a single result, or
136136+ * to subscribe to it, the `OperationResultSource` is a `PromiseLike` and has methods to convert it to a promise,
137137+ * or to subscribe to it with a single method call.
136138 */
137137-export type PromisifiedSource<T = any> = Source<T> & {
138138- toPromise: () => Promise<T>;
139139-};
139139+export type OperationResultSource<T extends OperationResult> = Source<T> &
140140+ PromiseLike<T> & {
141141+ /** Returns the first non-stale, settled results of the source.
142142+ * @remarks
143143+ * The `toPromise` method gives you the first result of an `OperationResultSource`
144144+ * that has `hasNext: false` and `stale: false` set as a `Promise`.
145145+ *
146146+ * Hint: If you're trying to get updates for your results, this won't work.
147147+ * This gives you only a single, promisified result, so it won't receive
148148+ * cache or other updates.
149149+ */
150150+ toPromise(): Promise<T>;
151151+ /** Alias for Wonka's `subscribe` and calls `onResult` when subscribed to for each new `OperationResult`. */
152152+ subscribe(onResult: (value: T) => void): Subscription;
153153+ };
140154141155/** A type of Operation, either a GraphQL `query`, `mutation`, or `subscription`; or a `teardown` signal.
142156 *