@operato/graphql 10.29.69 → 10.29.76

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 CHANGED
@@ -3,6 +3,23 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ### [10.29.76](https://github.com/hatiolab/operato/compare/v10.29.75...v10.29.76) (2026-11-09)
7
+
8
+ **Note:** Version bump only for package @operato/graphql
9
+
10
+
11
+
12
+
13
+
14
+ ### [10.29.71](https://github.com/hatiolab/operato/compare/v10.29.70...v10.29.71) (2026-11-08)
15
+
16
+
17
+ ### :rocket: New Features
18
+
19
+ * **list-state, graphql, utils:** a failed refresh keeps the data shown and says when it was read ([5bb19d6](https://github.com/hatiolab/operato/commit/5bb19d6f3fb311eae31f183e5307cf45b94fe6bc))
20
+
21
+
22
+
6
23
  ### [10.29.69](https://github.com/hatiolab/operato/compare/v10.29.68...v10.29.69) (2026-11-07)
7
24
 
8
25
 
@@ -34,7 +34,10 @@ export declare class QueryController<D = any, V extends OperationVariables = Ope
34
34
  get data(): D | undefined;
35
35
  get loading(): boolean;
36
36
  get error(): unknown;
37
- /** When the answer shown arrived - a screen that says when it read. */
37
+ /**
38
+ * When the data shown arrived - a screen that says when it read. A failed read leaves it: a refresh that failed while
39
+ * the previous answer is kept still says when that answer was read.
40
+ */
38
41
  get answeredAt(): Date | undefined;
39
42
  private watched?;
40
43
  private subscription?;
@@ -35,7 +35,10 @@ export class QueryController {
35
35
  get error() {
36
36
  return this.none || this.stale ? undefined : this._error;
37
37
  }
38
- /** When the answer shown arrived - a screen that says when it read. */
38
+ /**
39
+ * When the data shown arrived - a screen that says when it read. A failed read leaves it: a refresh that failed while
40
+ * the previous answer is kept still says when that answer was read.
41
+ */
39
42
  get answeredAt() {
40
43
  return this.none || (this.stale && !this.options.keepPrevious) ? undefined : this._answeredAt;
41
44
  }
@@ -110,9 +113,11 @@ export class QueryController {
110
113
  return;
111
114
  this._loading = result.loading;
112
115
  if (!result.loading) {
113
- if (result.data || !this.options.keepPrevious)
116
+ /* `answeredAt` is when the data shown arrived: a failure that keeps the previous answer keeps its time too. */
117
+ if (result.data || !this.options.keepPrevious) {
114
118
  this._data = (_a = result.data) !== null && _a !== void 0 ? _a : undefined;
115
- this._answeredAt = new Date();
119
+ this._answeredAt = result.data ? new Date() : undefined;
120
+ }
116
121
  this.shown = key;
117
122
  this._error =
118
123
  (_b = result.error) !== null && _b !== void 0 ? _b : (((_c = result.errors) === null || _c === void 0 ? void 0 : _c.length) ? new ApolloError({ graphQLErrors: result.errors }) : undefined);
@@ -1 +1 @@
1
- {"version":3,"file":"query-controller.js","sourceRoot":"","sources":["../../src/query-controller.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ReactiveController, ReactiveControllerHost } from 'lit'\nimport {\n ApolloError,\n type ApolloQueryResult,\n type DocumentNode,\n type ObservableQuery,\n type ObservableSubscription,\n type OperationVariables,\n type WatchQueryFetchPolicy\n} from '@apollo/client/core/index.js'\n\nimport { client } from './graphql-client.js'\n\nexport type QueryControllerOptions<V> = {\n /** The variables the screen shows now - read again whenever they change. `undefined` reads nothing. */\n variables?: () => V | undefined\n fetchPolicy?: WatchQueryFetchPolicy\n context?: Record<string, unknown>\n /**\n * While new variables are read, `data` stays the previous answer (with `loading`); a failure keeps it too and sets\n * `error`. For a screen that keeps drawing what it showed - filters drawn inside the data, a forecast re-run.\n */\n keepPrevious?: boolean\n}\n\n/** Dispatched on a controller's host, not bubbling, each time its query answered. */\nexport const QUERY_ANSWERED = 'query-answered'\n\n/** No variables are watched: the host left, or has not drawn yet. Unlike `undefined` - variables that read nothing. */\nconst UNWATCHED = Symbol('unwatched')\n\n/** Every controller on a connected host, so a page refresh reads again what the page shows (ADR-0174). */\nconst live = new Set<QueryController<any, any>>()\n\n/**\n * What a screen reads, declared once (ADR-0190): the query and the variables it depends on. The controller reads, reads\n * again when the variables change - an answer for the variables before is never delivered - and keeps `data`, `loading`\n * and `error` for the variables shown now. A host that leaves the document stops watching; one that comes back reads\n * the same variables again.\n */\nexport class QueryController<D = any, V extends OperationVariables = OperationVariables> implements ReactiveController {\n private _data?: D\n private _loading = false\n private _error?: unknown\n private _answeredAt?: Date\n\n /*\n * What the controller says belongs to the variables the host shows now. Lit runs a host's `willUpdate` before its\n * controllers' `hostUpdate`, so a host deriving state there asks before new variables are watched: for variables\n * not watched yet the controller says loading, with no data (the previous with `keepPrevious`) and no error.\n */\n private get stale(): boolean {\n return this.keyOf(this.variablesNow()) !== this.asked\n }\n\n /** Variables that read nothing: no answer, nothing loading, no error - whatever was read before. */\n private get none(): boolean {\n return this.variablesNow() === undefined\n }\n\n /** The answer for the variables shown now - undefined while they are read (the previous with `keepPrevious`). */\n get data(): D | undefined {\n return this.none || (this.stale && !this.options.keepPrevious) ? undefined : this._data\n }\n\n get loading(): boolean {\n return this.none ? false : this.stale || this._loading\n }\n\n get error(): unknown {\n return this.none || this.stale ? undefined : this._error\n }\n\n /** When the answer shown arrived - a screen that says when it read. */\n get answeredAt(): Date | undefined {\n return this.none || (this.stale && !this.options.keepPrevious) ? undefined : this._answeredAt\n }\n\n private watched?: ObservableQuery<D, V>\n private subscription?: ObservableSubscription\n /** The variables `data` belongs to, and the ones being watched. */\n private shown?: string\n private asked: string | undefined | typeof UNWATCHED = UNWATCHED\n\n constructor(\n readonly host: ReactiveControllerHost & EventTarget,\n private query: DocumentNode,\n private options: QueryControllerOptions<V> = {}\n ) {\n host.addController(this)\n }\n\n hostConnected() {\n live.add(this)\n this.follow()\n }\n\n hostUpdate() {\n this.follow()\n }\n\n hostDisconnected() {\n live.delete(this)\n this.stop()\n }\n\n /** Reads the variables shown now again: after a save, or a page refresh. */\n async refetch(): Promise<void> {\n if (!this.subscription || !this.watched) {\n this.asked = UNWATCHED\n this.follow()\n return\n }\n this._loading = true\n this._error = undefined\n this.host.requestUpdate()\n await this.watched.refetch().catch(() => {})\n }\n\n private variablesNow(): V | undefined {\n return this.options.variables ? this.options.variables() : ({} as V)\n }\n\n private keyOf(variables: V | undefined): string | undefined {\n return variables === undefined ? undefined : JSON.stringify(variables)\n }\n\n private follow() {\n const variables = this.variablesNow()\n const key = this.keyOf(variables)\n /* The same variables: watched already, or failed - only refetch() asks a failed read again. */\n if (key === this.asked) return\n\n this.stop()\n this.asked = key\n /* Another answer is coming, or none: what was read for other variables goes (kept only while new ones are read). */\n if (key === undefined || (key !== this.shown && !this.options.keepPrevious)) this._data = this._answeredAt = undefined\n this._error = undefined\n if (key === undefined) {\n this.shown = undefined\n this._loading = false\n return\n }\n\n this._loading = true\n const watched = (this.watched = client.watchQuery<D, V>({\n query: this.query,\n variables: variables as V,\n fetchPolicy: this.options.fetchPolicy ?? 'no-cache',\n errorPolicy: 'all',\n notifyOnNetworkStatusChange: true,\n ...(this.options.context ? { context: this.options.context } : {})\n }))\n this.subscription = watched.subscribe({\n next: (result: ApolloQueryResult<D>) => {\n if (watched !== this.watched) return\n this._loading = result.loading\n if (!result.loading) {\n if (result.data || !this.options.keepPrevious) this._data = result.data ?? undefined\n this._answeredAt = new Date()\n this.shown = key\n this._error =\n result.error ?? (result.errors?.length ? new ApolloError({ graphQLErrors: result.errors }) : undefined)\n }\n this.host.requestUpdate()\n /* A page whose title or actions come from what it read says them again (PageView). */\n if (!result.loading) this.host.dispatchEvent(new Event(QUERY_ANSWERED))\n },\n error: error => {\n if (watched !== this.watched) return\n /* A network failure ends the watch: the next refetch watches again. */\n this.subscription = undefined\n this._loading = false\n this._error = error\n this.host.requestUpdate()\n }\n })\n }\n\n private stop() {\n this.subscription?.unsubscribe()\n this.subscription = undefined\n this.watched = undefined\n this.asked = UNWATCHED\n }\n}\n\n/** Reads again every query shown inside `root` - the page refresh (ADR-0174) of a page and the sections in it. */\nexport async function refetchWithin(root: Node): Promise<void> {\n const within = (node: Node | null): boolean => {\n for (; node; node = node.parentNode ?? (node as ShadowRoot).host ?? null) if (node === root) return true\n return false\n }\n await Promise.all([...live].filter(one => within(one.host as unknown as Node)).map(one => one.refetch()))\n}\n"]}
1
+ {"version":3,"file":"query-controller.js","sourceRoot":"","sources":["../../src/query-controller.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ReactiveController, ReactiveControllerHost } from 'lit'\nimport {\n ApolloError,\n type ApolloQueryResult,\n type DocumentNode,\n type ObservableQuery,\n type ObservableSubscription,\n type OperationVariables,\n type WatchQueryFetchPolicy\n} from '@apollo/client/core/index.js'\n\nimport { client } from './graphql-client.js'\n\nexport type QueryControllerOptions<V> = {\n /** The variables the screen shows now - read again whenever they change. `undefined` reads nothing. */\n variables?: () => V | undefined\n fetchPolicy?: WatchQueryFetchPolicy\n context?: Record<string, unknown>\n /**\n * While new variables are read, `data` stays the previous answer (with `loading`); a failure keeps it too and sets\n * `error`. For a screen that keeps drawing what it showed - filters drawn inside the data, a forecast re-run.\n */\n keepPrevious?: boolean\n}\n\n/** Dispatched on a controller's host, not bubbling, each time its query answered. */\nexport const QUERY_ANSWERED = 'query-answered'\n\n/** No variables are watched: the host left, or has not drawn yet. Unlike `undefined` - variables that read nothing. */\nconst UNWATCHED = Symbol('unwatched')\n\n/** Every controller on a connected host, so a page refresh reads again what the page shows (ADR-0174). */\nconst live = new Set<QueryController<any, any>>()\n\n/**\n * What a screen reads, declared once (ADR-0190): the query and the variables it depends on. The controller reads, reads\n * again when the variables change - an answer for the variables before is never delivered - and keeps `data`, `loading`\n * and `error` for the variables shown now. A host that leaves the document stops watching; one that comes back reads\n * the same variables again.\n */\nexport class QueryController<D = any, V extends OperationVariables = OperationVariables> implements ReactiveController {\n private _data?: D\n private _loading = false\n private _error?: unknown\n private _answeredAt?: Date\n\n /*\n * What the controller says belongs to the variables the host shows now. Lit runs a host's `willUpdate` before its\n * controllers' `hostUpdate`, so a host deriving state there asks before new variables are watched: for variables\n * not watched yet the controller says loading, with no data (the previous with `keepPrevious`) and no error.\n */\n private get stale(): boolean {\n return this.keyOf(this.variablesNow()) !== this.asked\n }\n\n /** Variables that read nothing: no answer, nothing loading, no error - whatever was read before. */\n private get none(): boolean {\n return this.variablesNow() === undefined\n }\n\n /** The answer for the variables shown now - undefined while they are read (the previous with `keepPrevious`). */\n get data(): D | undefined {\n return this.none || (this.stale && !this.options.keepPrevious) ? undefined : this._data\n }\n\n get loading(): boolean {\n return this.none ? false : this.stale || this._loading\n }\n\n get error(): unknown {\n return this.none || this.stale ? undefined : this._error\n }\n\n /**\n * When the data shown arrived - a screen that says when it read. A failed read leaves it: a refresh that failed while\n * the previous answer is kept still says when that answer was read.\n */\n get answeredAt(): Date | undefined {\n return this.none || (this.stale && !this.options.keepPrevious) ? undefined : this._answeredAt\n }\n\n private watched?: ObservableQuery<D, V>\n private subscription?: ObservableSubscription\n /** The variables `data` belongs to, and the ones being watched. */\n private shown?: string\n private asked: string | undefined | typeof UNWATCHED = UNWATCHED\n\n constructor(\n readonly host: ReactiveControllerHost & EventTarget,\n private query: DocumentNode,\n private options: QueryControllerOptions<V> = {}\n ) {\n host.addController(this)\n }\n\n hostConnected() {\n live.add(this)\n this.follow()\n }\n\n hostUpdate() {\n this.follow()\n }\n\n hostDisconnected() {\n live.delete(this)\n this.stop()\n }\n\n /** Reads the variables shown now again: after a save, or a page refresh. */\n async refetch(): Promise<void> {\n if (!this.subscription || !this.watched) {\n this.asked = UNWATCHED\n this.follow()\n return\n }\n this._loading = true\n this._error = undefined\n this.host.requestUpdate()\n await this.watched.refetch().catch(() => {})\n }\n\n private variablesNow(): V | undefined {\n return this.options.variables ? this.options.variables() : ({} as V)\n }\n\n private keyOf(variables: V | undefined): string | undefined {\n return variables === undefined ? undefined : JSON.stringify(variables)\n }\n\n private follow() {\n const variables = this.variablesNow()\n const key = this.keyOf(variables)\n /* The same variables: watched already, or failed - only refetch() asks a failed read again. */\n if (key === this.asked) return\n\n this.stop()\n this.asked = key\n /* Another answer is coming, or none: what was read for other variables goes (kept only while new ones are read). */\n if (key === undefined || (key !== this.shown && !this.options.keepPrevious)) this._data = this._answeredAt = undefined\n this._error = undefined\n if (key === undefined) {\n this.shown = undefined\n this._loading = false\n return\n }\n\n this._loading = true\n const watched = (this.watched = client.watchQuery<D, V>({\n query: this.query,\n variables: variables as V,\n fetchPolicy: this.options.fetchPolicy ?? 'no-cache',\n errorPolicy: 'all',\n notifyOnNetworkStatusChange: true,\n ...(this.options.context ? { context: this.options.context } : {})\n }))\n this.subscription = watched.subscribe({\n next: (result: ApolloQueryResult<D>) => {\n if (watched !== this.watched) return\n this._loading = result.loading\n if (!result.loading) {\n /* `answeredAt` is when the data shown arrived: a failure that keeps the previous answer keeps its time too. */\n if (result.data || !this.options.keepPrevious) {\n this._data = result.data ?? undefined\n this._answeredAt = result.data ? new Date() : undefined\n }\n this.shown = key\n this._error =\n result.error ?? (result.errors?.length ? new ApolloError({ graphQLErrors: result.errors }) : undefined)\n }\n this.host.requestUpdate()\n /* A page whose title or actions come from what it read says them again (PageView). */\n if (!result.loading) this.host.dispatchEvent(new Event(QUERY_ANSWERED))\n },\n error: error => {\n if (watched !== this.watched) return\n /* A network failure ends the watch: the next refetch watches again. */\n this.subscription = undefined\n this._loading = false\n this._error = error\n this.host.requestUpdate()\n }\n })\n }\n\n private stop() {\n this.subscription?.unsubscribe()\n this.subscription = undefined\n this.watched = undefined\n this.asked = UNWATCHED\n }\n}\n\n/** Reads again every query shown inside `root` - the page refresh (ADR-0174) of a page and the sections in it. */\nexport async function refetchWithin(root: Node): Promise<void> {\n const within = (node: Node | null): boolean => {\n for (; node; node = node.parentNode ?? (node as ShadowRoot).host ?? null) if (node === root) return true\n return false\n }\n await Promise.all([...live].filter(one => within(one.host as unknown as Node)).map(one => one.refetch()))\n}\n"]}