@lewebsimple/nuxt-graphql 0.7.10 → 0.7.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -381,15 +381,20 @@ export default defineRemoteExecutorHooks({
381
381
  });
382
382
  },
383
383
 
384
- onResult(result, context) {
384
+ onResult(result, context, meta) {
385
385
  // You can also access context in onResult
386
386
  console.log("User from context:", context?.user);
387
387
  console.log("Result:", result.data);
388
+ // Upstream HTTP response metadata (headers + status)
389
+ const session = meta.headers.get("woocommerce-session");
390
+ if (session) context?.setSession?.(session);
388
391
  },
389
392
 
390
- onError(error, context) {
393
+ onError(error, context, meta) {
391
394
  // And in onError for logging/monitoring
392
- console.error("Remote execution failed for user:", context?.user?.id);
395
+ // `meta` is undefined when the failure happened before the HTTP response
396
+ // (e.g. fetch/network error); defined for non-2xx or JSON parse errors.
397
+ console.error("Remote execution failed for user:", context?.user?.id, meta?.status);
393
398
  },
394
399
  });
395
400
  ```
package/dist/module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "nuxt-graphql",
3
3
  "configKey": "graphql",
4
- "version": "0.7.10",
4
+ "version": "0.7.12",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.2",
7
7
  "unbuild": "unknown"
package/dist/module.mjs CHANGED
@@ -16,7 +16,7 @@ import zodPreset from '@lewebsimple/graphql-codegen-zod';
16
16
  import { createRequire } from 'node:module';
17
17
  import { resolveCacheConfig } from '../dist/runtime/app/lib/cache-config.js';
18
18
 
19
- const version = "0.7.10";
19
+ const version = "0.7.12";
20
20
 
21
21
  const buildCache = /* @__PURE__ */ new Map();
22
22
  function getCachedLoader(baseKey, loader) {
@@ -16,11 +16,11 @@ type Connection<TItem> = {
16
16
  * @returns An object containing the items, loading state, error state, and pagination functions.
17
17
  */
18
18
  export declare function useGraphQLLoadMore<TName extends QueryName, TConnection extends Connection<unknown>>(operationName: TName, variables: MaybeRefOrGetter<Omit<VariablesOf<TName>, "after">>, getConnection: (data?: ResultOf<TName>) => TConnection | null | undefined): Promise<{
19
- items: any;
20
- pending: any;
21
- error: any;
22
- hasNextPage: any;
23
- isLoadingMore: any;
19
+ items: import("vue").ShallowRef<TConnection["nodes"][number][], TConnection["nodes"][number][]>;
20
+ pending: import("vue").Ref<boolean, boolean>;
21
+ error: import("vue").Ref<import("../../shared/utils/error.js").NormalizedError | undefined, import("../../shared/utils/error.js").NormalizedError | undefined>;
22
+ hasNextPage: import("vue").ComputedRef<boolean>;
23
+ isLoadingMore: import("vue").Ref<boolean, boolean>;
24
24
  loadMore: () => void;
25
25
  reset: () => void;
26
26
  }>;
@@ -1,5 +1,5 @@
1
1
  import { hash } from "ohash";
2
- import { computed, ref, shallowRef, toValue, watchEffect } from "vue";
2
+ import { computed, ref, shallowRef, toValue, watch } from "vue";
3
3
  import { useAsyncGraphQLQuery } from "./useAsyncGraphQLQuery.js";
4
4
  export async function useGraphQLLoadMore(operationName, variables, getConnection) {
5
5
  const after = ref(null);
@@ -16,20 +16,29 @@ export async function useGraphQLLoadMore(operationName, variables, getConnection
16
16
  const connection = computed(() => getConnection(query.data.value));
17
17
  const hasNextPage = computed(() => connection.value?.pageInfo?.hasNextPage ?? false);
18
18
  const endCursor = computed(() => connection.value?.pageInfo?.endCursor ?? null);
19
+ items.value = connection.value?.nodes ?? [];
19
20
  let lastInputHash = baseVariablesHash.value;
20
- watchEffect(() => {
21
- const newItems = connection.value?.nodes ?? [];
22
- if (baseVariablesHash.value !== lastInputHash) {
23
- lastInputHash = baseVariablesHash.value;
24
- reset();
25
- }
26
- if (after.value === null) {
27
- items.value = newItems;
28
- } else if (isLoadingMore.value) {
29
- items.value = [...items.value, ...newItems];
30
- }
31
- isLoadingMore.value = false;
21
+ watch(baseVariablesHash, (newHash) => {
22
+ if (newHash === lastInputHash) return;
23
+ lastInputHash = newHash;
24
+ after.value = null;
25
+ lastRequestedCursor.value = null;
26
+ items.value = [];
32
27
  });
28
+ watch(
29
+ () => query.pending.value,
30
+ (pending, wasPending) => {
31
+ if (pending || !wasPending) return;
32
+ const newItems = connection.value?.nodes ?? [];
33
+ if (after.value === null) {
34
+ items.value = newItems;
35
+ } else if (isLoadingMore.value) {
36
+ items.value = [...items.value, ...newItems];
37
+ }
38
+ isLoadingMore.value = false;
39
+ },
40
+ { flush: "post" }
41
+ );
33
42
  function loadMore() {
34
43
  const cursor = endCursor.value;
35
44
  if (isLoadingMore.value || !hasNextPage.value || !cursor || cursor === lastRequestedCursor.value) {
@@ -50,6 +50,6 @@ export type MutationHooks<TName extends MutationName, TContext = unknown> = {
50
50
  * @returns Mutation executor and pending state.
51
51
  */
52
52
  export declare function useGraphQLMutation<TName extends MutationName, TContext = unknown>(operationName: TName, hooks?: MutationHooks<TName, TContext>): {
53
- pending: any;
54
- mutate: (variables: VariablesInputOf<TName>) => Promise<any>;
53
+ pending: import("vue").ComputedRef<boolean>;
54
+ mutate: (variables: VariablesInputOf<TName>) => Promise<ExecuteGraphQLResult<TName>>;
55
55
  };
@@ -4,7 +4,11 @@ import { type Client as SSEClient } from "graphql-sse";
4
4
  *
5
5
  * @returns Nuxt plugin with SSE client provider.
6
6
  */
7
- declare const _default: any;
7
+ declare const _default: import("#app").Plugin<{
8
+ getGraphQLSSEClient: () => SSEClient;
9
+ }> & import("#app").ObjectPlugin<{
10
+ getGraphQLSSEClient: () => SSEClient;
11
+ }>;
8
12
  export default _default;
9
13
  declare module "#app/nuxt" {
10
14
  interface NuxtApp {
@@ -5,7 +5,11 @@ import type { OperationName } from "../../shared/utils/registry.js";
5
5
  *
6
6
  * @returns Nuxt plugin with GraphQL operation executor.
7
7
  */
8
- declare const _default: any;
8
+ declare const _default: import("#app").Plugin<{
9
+ executeOperation: <TName extends OperationName>(input: ExecuteGraphQLInput<TName>) => Promise<ExecuteGraphQLResult<TName>>;
10
+ }> & import("#app").ObjectPlugin<{
11
+ executeOperation: <TName extends OperationName>(input: ExecuteGraphQLInput<TName>) => Promise<ExecuteGraphQLResult<TName>>;
12
+ }>;
9
13
  export default _default;
10
14
  type ExecuteGraphQL = <TName extends OperationName>(input: ExecuteGraphQLInput<TName>) => Promise<ExecuteGraphQLResult<TName>>;
11
15
  declare module "#app/nuxt" {
@@ -15,14 +15,25 @@ export type GraphQLRemoteExecutorRequest<TContext extends Record<string, unknown
15
15
  /** Execution context. */
16
16
  context?: TContext;
17
17
  };
18
+ /** Metadata from the upstream HTTP response. */
19
+ export type GraphQLRemoteExecutorResponseMeta = {
20
+ /** Response headers from the upstream endpoint. */
21
+ headers: Headers;
22
+ /** HTTP status code from the upstream endpoint. */
23
+ status: number;
24
+ };
18
25
  /** Remote executor hook handlers. */
19
26
  export type GraphQLRemoteExecutorHook<TContext extends Record<string, unknown> = GraphQLContext> = {
20
27
  /** Called before sending remote request. */
21
28
  onRequest?: (request: GraphQLRemoteExecutorRequest<TContext>, context: TContext | undefined) => void | Promise<void>;
22
- /** Called after receiving a result. */
23
- onResult?: (result: unknown, context: TContext | undefined) => void | Promise<void>;
24
- /** Called when execution throws. */
25
- onError?: (error: unknown, context: TContext | undefined) => void | Promise<void>;
29
+ /** Called after receiving a result, with the upstream response metadata. */
30
+ onResult?: (result: unknown, context: TContext | undefined, meta: GraphQLRemoteExecutorResponseMeta) => void | Promise<void>;
31
+ /**
32
+ * Called when execution throws. `meta` is provided when the failure happened
33
+ * after the HTTP response was received (non-2xx, JSON parse error, hook
34
+ * error); it is `undefined` for fetch/network failures.
35
+ */
36
+ onError?: (error: unknown, context: TContext | undefined, meta?: GraphQLRemoteExecutorResponseMeta) => void | Promise<void>;
26
37
  };
27
38
  /** Remote executor factory input. */
28
39
  type RemoteExecutorInput<TContext extends Record<string, unknown> = GraphQLContext> = {
@@ -6,6 +6,7 @@ export function getRemoteExecutor({
6
6
  }) {
7
7
  return async function execute(request) {
8
8
  const context = request.context;
9
+ let meta;
9
10
  try {
10
11
  for (const hook of hooks) {
11
12
  await hook.onRequest?.(request, context);
@@ -23,17 +24,18 @@ export function getRemoteExecutor({
23
24
  operationName: request.operationName
24
25
  })
25
26
  });
27
+ meta = { headers: response.headers, status: response.status };
26
28
  if (!response.ok) {
27
29
  throw new Error(`GraphQL HTTP ${response.status}`);
28
30
  }
29
31
  const result = await response.json();
30
32
  for (const hook of hooks) {
31
- await hook.onResult?.(result, context);
33
+ await hook.onResult?.(result, context, meta);
32
34
  }
33
35
  return result;
34
36
  } catch (error) {
35
37
  for (const hook of hooks) {
36
- await hook.onError?.(error, context);
38
+ await hook.onError?.(error, context, meta);
37
39
  }
38
40
  throw error;
39
41
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lewebsimple/nuxt-graphql",
3
- "version": "0.7.10",
3
+ "version": "0.7.12",
4
4
  "description": "Opinionated Nuxt module for using GraphQL",
5
5
  "license": "AGPL-3.0-only",
6
6
  "repository": "lewebsimple/nuxt-graphql",