diff --git a/client/shared/src/graphql/apollo/client.ts b/client/shared/src/graphql/apollo/client.ts index 0ef0aa338de..849e22e12f5 100644 --- a/client/shared/src/graphql/apollo/client.ts +++ b/client/shared/src/graphql/apollo/client.ts @@ -1,8 +1,9 @@ -import { ApolloClient, createHttpLink, NormalizedCacheObject } from '@apollo/client' +import { ApolloClient, createHttpLink, from, NormalizedCacheObject } from '@apollo/client' import { LocalStorageWrapper, CachePersistor } from 'apollo3-cache-persist' import { once } from 'lodash' import { GRAPHQL_URI } from '../constants' +import { ConcurrentRequestsLink } from '../links/concurrent-requests-link' import { cache } from './cache' import { persistenceMapper } from './persistenceMapper' @@ -66,10 +67,13 @@ export const getGraphQLClient = once( fetchPolicy: 'network-only', }, }, - link: createHttpLink({ - uri: ({ operationName }) => `${uri}?${operationName}`, - headers, - }), + link: from([ + new ConcurrentRequestsLink(), + createHttpLink({ + uri: ({ operationName }) => `${uri}?${operationName}`, + headers, + }), + ]), }) return Promise.resolve(apolloClient) diff --git a/client/shared/src/graphql/apollo/hooks.ts b/client/shared/src/graphql/apollo/hooks.ts index 2edb309fca1..9b92ec8b39d 100644 --- a/client/shared/src/graphql/apollo/hooks.ts +++ b/client/shared/src/graphql/apollo/hooks.ts @@ -5,14 +5,16 @@ import { useLazyQuery as useApolloLazyQuery, DocumentNode, OperationVariables, - QueryHookOptions, + QueryHookOptions as ApolloQueryHookOptions, QueryResult, - MutationHookOptions, + MutationHookOptions as ApolloMutationHookOptions, MutationTuple, QueryTuple, } from '@apollo/client' import { useMemo } from 'react' +import { ApolloContext } from '../types' + type RequestDocument = string | DocumentNode /** @@ -31,6 +33,16 @@ export const getDocumentNode = (document: RequestDocument): DocumentNode => { const useDocumentNode = (document: RequestDocument): DocumentNode => useMemo(() => getDocumentNode(document), [document]) +export interface QueryHookOptions + extends Omit, 'context'> { + /** + * Shared context information for apollo client. Since internal apollo + * types have context as Record we have to set this type + * directly. + */ + context?: ApolloContext +} + /** * Send a query to GraphQL and respond to updates. * Wrapper around Apollo `useQuery` that supports `DocumentNode` and `string` types. @@ -46,15 +58,6 @@ export function useQuery( const documentNode = useDocumentNode(query) return useApolloQuery(documentNode, options) } - -/** - * Unlike with `useQuery`, when you call `useLazyQuery`, it does not immediately execute its associated query. - * Wrapper around Apollo `useLazyQuery` that supports `DocumentNode` and `string` types. - * - * @param query GraphQL operation payload. - * @param options Operation variables and request configuration. - * @returns returns a query function in its result tuple that you call whenever you're ready to execute the query. - */ export function useLazyQuery( query: RequestDocument, options: QueryHookOptions @@ -63,6 +66,16 @@ export function useLazyQuery( return useApolloLazyQuery(documentNode, options) } +interface MutationHookOptions + extends Omit, 'context'> { + /** + * Shared context information for apollo client. Since internal apollo + * types have context as Record we have to set this type + * directly. + */ + context?: ApolloContext +} + /** * Send a mutation to GraphQL and respond to updates. * Wrapper around Apollo `useMutation` that supports `DocumentNode` and `string` types. diff --git a/client/shared/src/graphql/links/concurrent-requests-link.ts b/client/shared/src/graphql/links/concurrent-requests-link.ts new file mode 100644 index 00000000000..3bc94547a1e --- /dev/null +++ b/client/shared/src/graphql/links/concurrent-requests-link.ts @@ -0,0 +1,141 @@ +import { ApolloLink, FetchResult, NextLink, Operation, Observable, Observer } from '@apollo/client' + +import { ApolloContext } from '../types' + +const DEFAULT_PARALLEL_CONCURRENT_REQUESTS = 3 + +interface OperationQueueEntry { + operation: Operation + forward: NextLink + groupKey: string + limit: number + observable: Observable + observers: Observer[] + currentSubscription?: ZenObservable.Subscription +} + +interface RequestGroupQueues { + queue: OperationQueueEntry[] + activeQueue: OperationQueueEntry[] +} + +export class ConcurrentRequestsLink extends ApolloLink { + private requests: Record = {} + + public request(operation: Operation, forward: NextLink): Observable { + const context = (operation.getContext() ?? {}) as ApolloContext + + // Ignore and pass further all operations that don't required being run + // in parallel concurrent mode. + if (!context.concurrentRequests) { + return forward(operation) + } + + const { key = '', limit } = context.concurrentRequests + + const event: OperationQueueEntry = { + operation, + forward, + observers: [], + groupKey: key, + limit: limit ?? DEFAULT_PARALLEL_CONCURRENT_REQUESTS, + observable: new Observable(observer => { + // Called for each subscriber, so need to save all listeners(next, error, complete) + event.observers.push(observer) + + return () => { + this.cancelOperation(event) + } + }), + } + + this.addOperations(event) + + return event.observable + } + + private addOperations(operation: OperationQueueEntry): void { + if (!this.requests[operation.groupKey]) { + this.requests[operation.groupKey] = { + queue: [], + activeQueue: [], + } + } + + this.requests[operation.groupKey].queue.push(operation) + this.scheduleOperations(operation.groupKey) + } + + private cancelOperation(event: OperationQueueEntry): void { + const { queue, activeQueue } = this.requests[event.groupKey] + const possibleQueuedEventIndex = queue.indexOf(event) + + if (possibleQueuedEventIndex !== -1) { + this.requests[event.groupKey].queue = queue.filter(queuedEvent => queuedEvent !== event) + event.currentSubscription?.unsubscribe() + + return + } + + const possibleOnGoingEventIndex = activeQueue.indexOf(event) + + if (possibleOnGoingEventIndex !== -1) { + this.requests[event.groupKey].activeQueue = activeQueue.filter(operation => operation !== event) + event.currentSubscription?.unsubscribe() + + this.scheduleOperations(event.groupKey) + } + } + + private scheduleOperations(groupKey: string): void { + const { activeQueue, queue } = this.requests[groupKey] + const maxParallelRequests = Math.max(...queue.map(event => event.limit)) + + while (activeQueue.length < maxParallelRequests && queue.length > 0) { + const event = queue.shift() + + if (event) { + activeQueue.push(event) + + event.currentSubscription = event.forward(event.operation).subscribe({ + next: value => this.onNext(value, event), + error: error => this.onErrorLink(error, event), + complete: () => this.onComplete(event), + }) + } + } + } + + private onNext(value: unknown, event: OperationQueueEntry): void { + for (const observer of event.observers) { + observer.next?.(value) + } + } + + private onErrorLink(error: unknown, event: OperationQueueEntry): void { + for (const observer of event.observers) { + observer.error?.(error) + } + + this.finishEventExecution(event) + } + + private onComplete(event: OperationQueueEntry): void { + for (const observer of event.observers) { + observer.complete?.() + } + + this.finishEventExecution(event) + } + + private finishEventExecution(event: OperationQueueEntry): void { + const { activeQueue } = this.requests[event.groupKey] + + // Delete completed event from the active queue in order to run other + // queued events. + this.requests[event.groupKey].activeQueue = activeQueue.filter(operation => operation !== event) + + // Run queued events + this.scheduleOperations(event.groupKey) + } +} diff --git a/client/shared/src/graphql/types.ts b/client/shared/src/graphql/types.ts new file mode 100644 index 00000000000..77dc8f436df --- /dev/null +++ b/client/shared/src/graphql/types.ts @@ -0,0 +1,17 @@ +/** + * Shared global Apollo context is used in hooks to specify some context properties + * and read in apollo links to turn on/off some internal apollo request logic. + */ +export interface ApolloContext { + /** + * Turns on/off concurrent/parallel requests apollo link. + * See `./links/concurrent-requests-link.ts` for more details. + */ + concurrentRequests?: { + /** Group requests by this key and run them concurrently/in parallel */ + key?: string + + /** The size of parallel requests queue for particular group of requests */ + limit?: number + } +} diff --git a/client/web/src/integration/graphQlResults.ts b/client/web/src/integration/graphQlResults.ts index 6994103f083..a30444c7dd3 100644 --- a/client/web/src/integration/graphQlResults.ts +++ b/client/web/src/integration/graphQlResults.ts @@ -222,7 +222,12 @@ export const commonWebGraphQlResults: Partial ({ temporarySettings: { - contents: '{}', + __typename: 'TemporarySettings', + contents: JSON.stringify({ + 'user.daysActiveCount': 1, + 'user.lastDayActive': new Date().toDateString(), + 'search.usedNonGlobalContext': true, + }), }, }), EditTemporarySettings: () => ({ diff --git a/client/web/src/integration/insights/utils/override-insights-graphql.ts b/client/web/src/integration/insights/utils/override-insights-graphql.ts index 56cf83453ad..d7c289bebd7 100644 --- a/client/web/src/integration/insights/utils/override-insights-graphql.ts +++ b/client/web/src/integration/insights/utils/override-insights-graphql.ts @@ -51,7 +51,10 @@ export function overrideGraphQLExtensions(props: OverrideGraphQLExtensionsProps) // Mock temporary settings cause code insights beta modal UI relies on this handler to show/hide // modal UI on all code insights related pages. GetTemporarySettings: () => ({ - temporarySettings: { contents: JSON.stringify({ 'insights.freeBetaAccepted': true }) }, + temporarySettings: { + __typename: 'TemporarySettings', + contents: JSON.stringify({ 'insights.freeBetaAccepted': true }), + }, }), Insights: () => ({ insights: { nodes: [] } }), CurrentAuthState: () => ({ diff --git a/client/web/src/integration/search-onboarding.test.ts b/client/web/src/integration/search-onboarding.test.ts index 5d2bac7fd24..18e27316e9e 100644 --- a/client/web/src/integration/search-onboarding.test.ts +++ b/client/web/src/integration/search-onboarding.test.ts @@ -72,6 +72,7 @@ describe('Search onboarding', () => { }), GetTemporarySettings: () => ({ temporarySettings: { + __typename: 'TemporarySettings', contents: JSON.stringify({ 'user.daysActiveCount': 1, 'user.lastDayActive': new Date().toDateString(), diff --git a/package.json b/package.json index 04f273ed5b5..0f2814cc854 100644 --- a/package.json +++ b/package.json @@ -324,7 +324,7 @@ "yarn-deduplicate": "^3.1.0" }, "dependencies": { - "@apollo/client": "^3.3.20", + "@apollo/client": "3.4.7", "@reach/accordion": "^0.10.2", "@reach/combobox": "^0.15.2", "@reach/dialog": "^0.11.2", diff --git a/yarn.lock b/yarn.lock index 40d1565e49e..5a1a4b39669 100644 --- a/yarn.lock +++ b/yarn.lock @@ -38,24 +38,23 @@ call-me-maybe "^1.0.1" js-yaml "^3.13.1" -"@apollo/client@^3.3.20": - version "3.3.20" - resolved "https://registry.npmjs.org/@apollo/client/-/client-3.3.20.tgz#8f0935fa991857e9cf2e73c9bd378ad7ec97caf8" - integrity sha512-hS7UmBwJweudw/J3M0RAcusMHNiRuGqkRH6g91PM2ev8cXScIMdXr/++9jo7wD1nAITMCMF4HQQ3LFaw/Or0Bw== +"@apollo/client@3.4.7": + version "3.4.7" + resolved "https://registry.npmjs.org/@apollo/client/-/client-3.4.7.tgz#63d7c3539cc45fe44ac9cb093a27641479a8d1ad" + integrity sha512-EmqGxXD8hr05cIFWJFwtGXifc+Lo8hTCEuiaQMtKknHszJfqIFXSxqP+H+eJnjfuoxH74aTSsZKtJlnE83Vt6w== dependencies: "@graphql-typed-document-node/core" "^3.0.0" - "@types/zen-observable" "^0.8.0" "@wry/context" "^0.6.0" "@wry/equality" "^0.5.0" - fast-json-stable-stringify "^2.0.0" - graphql-tag "^2.12.0" + "@wry/trie" "^0.3.0" + graphql-tag "^2.12.3" hoist-non-react-statics "^3.3.2" - optimism "^0.16.0" + optimism "^0.16.1" prop-types "^15.7.2" symbol-observable "^4.0.0" - ts-invariant "^0.7.0" - tslib "^1.10.0" - zen-observable "^0.8.14" + ts-invariant "^0.9.0" + tslib "^2.3.0" + zen-observable-ts "^1.1.0" "@ardatan/aggregate-error@0.0.1": version "0.0.1" @@ -4876,9 +4875,9 @@ integrity sha512-NaIeSIBiFgSC6IGUBjZWcscUJEq7vpVu7KthHN8eieTV9d9MqkSOZLH4chq1PmcKy06PNe3axLeKmRIyxJ+PZQ== "@types/d3-random@^2.2.0": - version "2.2.0" - resolved "https://registry.npmjs.org/@types/d3-random/-/d3-random-2.2.0.tgz#fc44cabb966917459490b758f31f5359adeabe5b" - integrity sha512-Hjfj9m68NmYZzushzEG7etPvKH/nj9b9s9+qtkNG3/dbRBjQZQg1XS6nRuHJcCASTjxXlyXZnKu2gDxyQIIu9A== + version "2.2.1" + resolved "https://registry.npmjs.org/@types/d3-random/-/d3-random-2.2.1.tgz#551edbb71cb317dea2cf9c76ebe059d311eefacb" + integrity sha512-5vvxn6//poNeOxt1ZwC7QU//dG9QqABjy1T7fP/xmFHY95GnaOw3yABf29hiu5SR1Oo34XcpyHFbzod+vemQjA== "@types/d3-scale@2.2.0": version "2.2.0" @@ -4887,12 +4886,12 @@ dependencies: "@types/d3-time" "*" -"@types/d3-scale@^3.2.1": - version "3.2.2" - resolved "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-3.2.2.tgz#5e28d0b1c599328aaec6094219f10a2570be6d74" - integrity sha512-qpQe8G02tzUwt9sdWX1h8A/W0Q1+N48wMnYXVOkrzeLUkCfvzJYV9Ee3aORCS4dN4ONRLFmMvaXdziQ29XGLjQ== +"@types/d3-scale@^3.2.1", "@types/d3-scale@^3.3.0": + version "3.3.2" + resolved "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-3.3.2.tgz#18c94e90f4f1c6b1ee14a70f14bfca2bd1c61d06" + integrity sha512-gGqr7x1ost9px3FvIfUMi5XA/F/yAf4UkUDtdQhpH92XCT0Oa7zkkRzY61gPVJq+DxpHn/btouw5ohWkbBsCzQ== dependencies: - "@types/d3-time" "*" + "@types/d3-time" "^2" "@types/d3-selection@*", "@types/d3-selection@1.4.1": version "1.4.1" @@ -4911,7 +4910,12 @@ resolved "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-3.0.0.tgz#913e984362a59792dc8d8b122dd17625991eade2" integrity sha512-UpLg1mn/8PLyjr+J/JwdQJM/GzysMvv2CS8y+WYAL5K0+wbvXv/pPSLEfdNaprCZsGcXTxPsFMy8QtkYv9ueew== -"@types/d3-time@*", "@types/d3-time@^1.0.10": +"@types/d3-time@*", "@types/d3-time@^2", "@types/d3-time@^2.0.0": + version "2.1.1" + resolved "https://registry.npmjs.org/@types/d3-time/-/d3-time-2.1.1.tgz#743fdc821c81f86537cbfece07093ac39b4bc342" + integrity sha512-9MVYlmIgmRR31C5b4FVSWtuMmBHh2mOWQYfl7XAYOa8dsnb7iEmUmRSWSFgXFtkjxO65d7hTUHQC+RhR/9IWFg== + +"@types/d3-time@^1.0.10": version "1.1.1" resolved "https://registry.npmjs.org/@types/d3-time/-/d3-time-1.1.1.tgz#6cf3a4242c3bbac00440dfb8ba7884f16bedfcbf" integrity sha512-ULX7LoqXTCYtM+tLYOaeAJK7IwCT+4Gxlm2MaH0ErKLi07R5lh8NHCAyWcDkCCmx1AfRcBEV6H9QE9R25uP7jw== @@ -5826,10 +5830,10 @@ dependencies: "@types/node" "*" -"@types/zen-observable@^0.8.0": - version "0.8.2" - resolved "https://registry.npmjs.org/@types/zen-observable/-/zen-observable-0.8.2.tgz#808c9fa7e4517274ed555fa158f2de4b4f468e71" - integrity sha512-HrCIVMLjE1MOozVoD86622S7aunluLb2PJdPfb3nYiEtohm8mIB/vyv0Fd37AdeMFrTUQXEunw78YloMA3Qilg== +"@types/zen-observable@0.8.3": + version "0.8.3" + resolved "https://registry.npmjs.org/@types/zen-observable/-/zen-observable-0.8.3.tgz#781d360c282436494b32fe7d9f7f8e64b3118aa3" + integrity sha512-fbF6oTd4sGGy0xjHPKAt+eS2CrxJ3+6gQ3FGcBoIJR2TLAyCkCyI8JqZNy+FeON0AhVgNJoUumVoZQjBFUqHkw== "@typescript-eslint/eslint-plugin@^4.28.3": version "4.28.3" @@ -6017,13 +6021,12 @@ d3-random "^2.2.2" "@visx/pattern@^1.7.0": - version "1.7.0" - resolved "https://registry.npmjs.org/@visx/pattern/-/pattern-1.7.0.tgz#4b4392b976f57592d836b2055dc606aa7b0192d9" - integrity sha512-uIrGDtm7NqDfZZneRZ/DRdZA0nli/13sIUcxQ0oRL70b6ul+epNGiBVR8pvrgMhZ+SW3b05xhfEDnfnl2CqFQw== + version "1.17.1" + resolved "https://registry.npmjs.org/@visx/pattern/-/pattern-1.17.1.tgz#2be0b35584eaedfa0e4cdbf7fd7ae036480805ac" + integrity sha512-lPlkSHr9a/+3je6D35mIq6tNZ0BBWU5FExX0EroNRYPl9KxKtQv4C8PlAiTdmMuAXwYLnxls04y5iHwDRXH6Cw== dependencies: - "@types/classnames" "^2.2.9" "@types/react" "*" - classnames "^2.2.5" + classnames "^2.3.1" prop-types "^15.5.10" "@visx/point@1.7.0": @@ -8495,10 +8498,10 @@ class-utils@^0.3.5: isobject "^3.0.0" static-extend "^0.1.1" -classnames@2.x, classnames@^2.2.3, classnames@^2.2.5, classnames@^2.2.6: - version "2.2.6" - resolved "https://registry.npmjs.org/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce" - integrity sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q== +classnames@2.x, classnames@^2.2.3, classnames@^2.2.5, classnames@^2.2.6, classnames@^2.3.1: + version "2.3.1" + resolved "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz#dfcfa3891e306ec1dad105d0e88f4417b8535e8e" + integrity sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA== clean-css@^4.2.3: version "4.2.3" @@ -9578,18 +9581,18 @@ currently-unhandled@^0.4.1: dependencies: array-find-index "^1.0.1" -d3-array@^1.2.0: - version "1.2.4" - resolved "https://registry.npmjs.org/d3-array/-/d3-array-1.2.4.tgz#635ce4d5eea759f6f605863dbcfc30edc737f71f" - integrity sha512-KHW6M86R+FUPYGb3R5XiYjXPq7VzwxZ22buHhAEVG5ztoEcZZMLov530mmccaqA1GghZArjQV46fuc8kUqhhHw== - -d3-array@^2.3.0, d3-array@^2.6.0: +d3-array@2, d3-array@^2.3.0, d3-array@^2.6.0: version "2.12.1" resolved "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz#e20b41aafcdffdf5d50928004ececf815a465e81" integrity sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ== dependencies: internmap "^1.0.0" +d3-array@^1.2.0: + version "1.2.4" + resolved "https://registry.npmjs.org/d3-array/-/d3-array-1.2.4.tgz#635ce4d5eea759f6f605863dbcfc30edc737f71f" + integrity sha512-KHW6M86R+FUPYGb3R5XiYjXPq7VzwxZ22buHhAEVG5ztoEcZZMLov530mmccaqA1GghZArjQV46fuc8kUqhhHw== + d3-axis@^1.0.12: version "1.0.12" resolved "https://registry.npmjs.org/d3-axis/-/d3-axis-1.0.12.tgz#cdf20ba210cfbb43795af33756886fb3638daac9" @@ -9649,15 +9652,15 @@ d3-scale@^2.1.0: d3-time "1" d3-time-format "2" -d3-scale@^3.2.1, d3-scale@^3.2.3: - version "3.2.4" - resolved "https://registry.npmjs.org/d3-scale/-/d3-scale-3.2.4.tgz#13d758d7cf4e4f1fc40196a63597d01f3ed81765" - integrity sha512-PG6gtpbPCFqKbvdBEswQcJcTzHC8VEd/XzezF5e68KlkT4/ggELw/nR1tv863jY6ufKTvDlzCMZvhe06codbbA== +d3-scale@^3.2.1, d3-scale@^3.2.3, d3-scale@^3.3.0: + version "3.3.0" + resolved "https://registry.npmjs.org/d3-scale/-/d3-scale-3.3.0.tgz#28c600b29f47e5b9cd2df9749c206727966203f3" + integrity sha512-1JGp44NQCt5d1g+Yy+GeOnZP7xHo0ii8zsQp6PGzd+C1/dl0KGsp9A7Mxwp+1D1o4unbTTxVdU/ZOIEBoeZPbQ== dependencies: d3-array "^2.3.0" d3-format "1 - 2" d3-interpolate "1.2.0 - 2" - d3-time "1 - 2" + d3-time "^2.1.1" d3-time-format "2 - 3" d3-selection@^1.4.1: @@ -9698,6 +9701,13 @@ d3-time@1, "d3-time@1 - 2", d3-time@^1.1.0: resolved "https://registry.npmjs.org/d3-time/-/d3-time-1.1.0.tgz#b1e19d307dae9c900b7e5b25ffc5dcc249a8a0f1" integrity sha512-Xh0isrZ5rPYYdqhAVk8VLnMEidhz5aP7htAADH6MfzgmmicPkTo8LhkLxci61/lCB7n7UmE3bN0leRt+qvkLxA== +d3-time@^2.1.1: + version "2.1.1" + resolved "https://registry.npmjs.org/d3-time/-/d3-time-2.1.1.tgz#e9d8a8a88691f4548e68ca085e5ff956724a6682" + integrity sha512-/eIQe/eR4kCQwq7yxi7z4c6qEXf2IYGcjoWB5OOQy4Tq9Uv39/947qlDcN2TLkiTzQWzvnsuYPB9TrWaNfipKQ== + dependencies: + d3-array "2" + d3-voronoi@^1.1.2: version "1.1.4" resolved "https://registry.npmjs.org/d3-voronoi/-/d3-voronoi-1.1.4.tgz#dd3c78d7653d2bb359284ae478645d95944c8297" @@ -13048,10 +13058,10 @@ graphql-schema-linter@^2.0.1: glob "^7.1.2" graphql "^15.0.0" -graphql-tag@^2.11.0, graphql-tag@^2.12.0: - version "2.12.4" - resolved "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.12.4.tgz#d34066688a4f09e72d6f4663c74211e9b4b7c4bf" - integrity sha512-VV1U4O+9x99EkNpNmCUV5RZwq6MnK4+pGbRYWG+lA/m3uo7TSqJF81OkcOP148gFP6fzdl7JWYBrwWVTS9jXww== +graphql-tag@^2.11.0, graphql-tag@^2.12.3: + version "2.12.5" + resolved "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.12.5.tgz#5cff974a67b417747d05c8d9f5f3cb4495d0db8f" + integrity sha512-5xNhP4063d16Pz3HBtKprutsPrmHZi5IdUGOWRxA2B6VF7BIRGOHZ5WQvDmJXZuPcBg7rYwaFxvQYjqkSdR3TQ== dependencies: tslib "^2.1.0" @@ -17787,7 +17797,7 @@ openurl@^1.1.1: resolved "https://registry.npmjs.org/openurl/-/openurl-1.1.1.tgz#3875b4b0ef7a52c156f0db41d4609dbb0f94b387" integrity sha1-OHW0sO96UsFW8NtB1GCduw+Us4c= -optimism@^0.16.0: +optimism@^0.16.1: version "0.16.1" resolved "https://registry.npmjs.org/optimism/-/optimism-0.16.1.tgz#7c8efc1f3179f18307b887e18c15c5b7133f6e7d" integrity sha512-64i+Uw3otrndfq5kaoGNoY7pvOhSsjFEN4bdEFh80MWVk/dbgJfMv7VFDeCT8LxNAlEVhQmdVEbfE7X2nWNIIg== @@ -22893,10 +22903,10 @@ ts-essentials@^7.0.3: resolved "https://registry.npmjs.org/ts-essentials/-/ts-essentials-7.0.3.tgz#686fd155a02133eedcc5362dc8b5056cde3e5a38" integrity sha512-8+gr5+lqO3G84KdiTSMRLtuyJ+nTBVRKuCrK4lidMPdVeEp0uqC875uE5NMcaA7YYMN7XsNiFQuMvasF8HT/xQ== -ts-invariant@^0.7.0: - version "0.7.5" - resolved "https://registry.npmjs.org/ts-invariant/-/ts-invariant-0.7.5.tgz#f9658719f9a7737b117d09820d952aacf6263f9c" - integrity sha512-qfVyqTYWEqADMtncLqwpUdMjMSXnsqOeqGtj1LeJNFDjz8oqZ1YxLEp29YCOq65z0LgEiERqQ8ThVjnfibJNpg== +ts-invariant@^0.9.0: + version "0.9.3" + resolved "https://registry.npmjs.org/ts-invariant/-/ts-invariant-0.9.3.tgz#4b41e0a80c2530a56ce4b8fd4e14183aaac0efa8" + integrity sha512-HinBlTbFslQI0OHP07JLsSXPibSegec6r9ai5xxq/qHYCsIQbzpymLpDhAUsnXcSrDEcd0L62L8vsOEdzM0qlA== dependencies: tslib "^2.1.0" @@ -24800,7 +24810,15 @@ yocto-queue@^0.1.0: resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== -zen-observable@^0.8.14: +zen-observable-ts@^1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/zen-observable-ts/-/zen-observable-ts-1.1.0.tgz#2d1aa9d79b87058e9b75698b92791c1838551f83" + integrity sha512-1h4zlLSqI2cRLPJUHJFL8bCWHhkpuXkF+dbGkRaWjgDIG26DmzyshUMrdV/rL3UnR+mhaX4fRq8LPouq0MYYIA== + dependencies: + "@types/zen-observable" "0.8.3" + zen-observable "0.8.15" + +zen-observable@0.8.15: version "0.8.15" resolved "https://registry.npmjs.org/zen-observable/-/zen-observable-0.8.15.tgz#96415c512d8e3ffd920afd3889604e30b9eaac15" integrity sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ==