web: Add custom concurrent Apollo link (#25236)

* Add custom concurrent Apollo link

* Fix apollo client version 3.4.7

* Fix search context integration tests

* Update global temporary settings mock
This commit is contained in:
Vova Kulikov 2021-10-20 17:36:32 +03:00 committed by GitHub
parent 54b08226b3
commit 98fcb441ef
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 275 additions and 73 deletions

View File

@ -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)

View File

@ -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<TData = any, TVariables = OperationVariables>
extends Omit<ApolloQueryHookOptions<TData, TVariables>, 'context'> {
/**
* Shared context information for apollo client. Since internal apollo
* types have context as Record<string, any> 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<TData = any, TVariables = OperationVariables>(
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<TData = any, TVariables = OperationVariables>(
query: RequestDocument,
options: QueryHookOptions<TData, TVariables>
@ -63,6 +66,16 @@ export function useLazyQuery<TData = any, TVariables = OperationVariables>(
return useApolloLazyQuery(documentNode, options)
}
interface MutationHookOptions<TData = any, TVariables = OperationVariables>
extends Omit<ApolloMutationHookOptions<TData, TVariables>, 'context'> {
/**
* Shared context information for apollo client. Since internal apollo
* types have context as Record<string, any> 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.

View File

@ -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<FetchResult>
observers: Observer<unknown>[]
currentSubscription?: ZenObservable.Subscription
}
interface RequestGroupQueues {
queue: OperationQueueEntry[]
activeQueue: OperationQueueEntry[]
}
export class ConcurrentRequestsLink extends ApolloLink {
private requests: Record<string, RequestGroupQueues> = {}
public request(operation: Operation, forward: NextLink): Observable<FetchResult> {
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<FetchResult>(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)
}
}

View File

@ -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
}
}

View File

@ -222,7 +222,12 @@ export const commonWebGraphQlResults: Partial<WebGraphQlOperations & SharedGraph
}),
GetTemporarySettings: () => ({
temporarySettings: {
contents: '{}',
__typename: 'TemporarySettings',
contents: JSON.stringify({
'user.daysActiveCount': 1,
'user.lastDayActive': new Date().toDateString(),
'search.usedNonGlobalContext': true,
}),
},
}),
EditTemporarySettings: () => ({

View File

@ -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: () => ({

View File

@ -72,6 +72,7 @@ describe('Search onboarding', () => {
}),
GetTemporarySettings: () => ({
temporarySettings: {
__typename: 'TemporarySettings',
contents: JSON.stringify({
'user.daysActiveCount': 1,
'user.lastDayActive': new Date().toDateString(),

View File

@ -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",

126
yarn.lock
View File

@ -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==