From c112de453fc476e666480e5fea7b1b3ae50b6843 Mon Sep 17 00:00:00 2001 From: Rupert Dunk Date: Thu, 24 Oct 2024 13:52:20 +0100 Subject: [PATCH] feat(visual-editing): add package version mismatch warning (#2040) * feat(comlink): add console.warn suppression option * feat(visual-editing): add package version mismatch warning --- packages/comlink/src/node.ts | 30 ++++++++++++------- packages/comlink/src/request.ts | 13 +++++--- packages/comlink/src/types.ts | 5 +++- .../visual-editing/src/ui/VisualEditing.tsx | 15 ++++++---- .../machines/createSharedListener.ts | 12 ++++++-- .../src/ui/schema/SchemaProvider.tsx | 4 +-- .../src/ui/usePerspectiveSync.tsx | 23 +++++++++++--- 7 files changed, 73 insertions(+), 29 deletions(-) diff --git a/packages/comlink/src/node.ts b/packages/comlink/src/node.ts index 4278f85a5..35ca4c8a2 100644 --- a/packages/comlink/src/node.ts +++ b/packages/comlink/src/node.ts @@ -62,7 +62,7 @@ export type Node = { actor: NodeActor fetch: >( data: U, - options?: {signal?: AbortSignal}, + options?: {signal?: AbortSignal; suppressWarnings?: boolean}, ) => S extends U ? (S['type'] extends T ? Promise : never) : never machine: NodeActorLogic on: >( @@ -97,7 +97,10 @@ export const createNodeMachine = < buffer: Array<{ data: V resolvable?: PromiseWithResolvers - signal?: AbortSignal + options?: { + signal?: AbortSignal + suppressWarnings?: boolean + } }> connectionId: string | null connectTo: string @@ -128,7 +131,10 @@ export const createNodeMachine = < type: 'post' data: V resolvable?: PromiseWithResolvers - signal?: AbortSignal + options?: { + signal?: AbortSignal + suppressWarning?: boolean + } } | {type: 'request.aborted'; requestId: string} | {type: 'request.failed'; requestId: string} @@ -161,7 +167,7 @@ export const createNodeMachine = < { data: event.data, resolvable: event.resolvable, - signal: event.signal, + options: event.options, }, ] }, @@ -191,11 +197,12 @@ export const createNodeMachine = < parentRef: self, resolvable: request.resolvable, responseTo: request.responseTo, + signal: request.options?.signal, sources: context.target!, + suppressWarnings: request.options?.suppressWarnings, targetOrigin: context.targetOrigin!, to: context.connectTo, type: request.type, - signal: request.signal, }, }) }) @@ -227,12 +234,12 @@ export const createNodeMachine = < 'flush buffer': enqueueActions(({enqueue}) => { enqueue.raise(({context}) => ({ type: 'request', - data: context.buffer.map(({data, resolvable, signal}) => ({ + data: context.buffer.map(({data, resolvable, options}) => ({ data: data.data, type: data.type, expectResponse: resolvable ? true : false, resolvable, - signal, + options, })), })) enqueue.emit(({context}) => { @@ -260,7 +267,7 @@ export const createNodeMachine = < expectResponse: event.resolvable ? true : false, type: event.data.type, resolvable: event.resolvable, - signal: event.signal, + options: event.options, }, } }), @@ -495,13 +502,16 @@ export const createNode = ( actor.send({type: 'post', data}) } - const fetch = (data: WithoutResponse, options?: {signal?: AbortSignal}) => { + const fetch = ( + data: WithoutResponse, + options?: {signal?: AbortSignal; suppressWarnings?: boolean}, + ) => { const resolvable = Promise.withResolvers() actor.send({ type: 'post', data, resolvable, - signal: options?.signal, + options, }) return resolvable.promise as never } diff --git a/packages/comlink/src/request.ts b/packages/comlink/src/request.ts index b92e5e6f7..8462351d7 100644 --- a/packages/comlink/src/request.ts +++ b/packages/comlink/src/request.ts @@ -36,6 +36,7 @@ export interface RequestMachineContext { response: S['response'] | null responseTo: string | undefined signal: AbortSignal | undefined + suppressWarnings: boolean | undefined sources: Set targetOrigin: string to: string @@ -84,6 +85,7 @@ export const createRequestMachine = < responseTo?: string signal?: AbortSignal sources: Set | MessageEventSource + suppressWarnings?: boolean targetOrigin: string to: string type: S['type'] @@ -151,10 +153,12 @@ export const createRequestMachine = < 'on fail': sendTo( ({context}) => context.parentRef, ({context, self}) => { - // eslint-disable-next-line no-console - console.warn( - `Received no response to message '${context.type}' on client '${context.from}' (ID: '${context.id}').`, - ) + if (!context.suppressWarnings) { + // eslint-disable-next-line no-console + console.warn( + `[@sanity/comlink] Received no response to message '${context.type}' on client '${context.from}' (ID: '${context.id}').`, + ) + } context.resolvable?.reject(new Error('No response received')) return {type: 'request.failed', requestId: self.id} }, @@ -190,6 +194,7 @@ export const createRequestMachine = < responseTo: input.responseTo, signal: input.signal, sources: input.sources instanceof Set ? input.sources : new Set([input.sources]), + suppressWarnings: input.suppressWarnings, targetOrigin: input.targetOrigin, to: input.to, type: input.type, diff --git a/packages/comlink/src/types.ts b/packages/comlink/src/types.ts index 74c21fafb..8f93daf1e 100644 --- a/packages/comlink/src/types.ts +++ b/packages/comlink/src/types.ts @@ -45,7 +45,10 @@ export interface RequestData { responseTo?: string type: MessageType resolvable?: PromiseWithResolvers - signal?: AbortSignal + options?: { + signal?: AbortSignal + suppressWarnings?: boolean + } } /** diff --git a/packages/visual-editing/src/ui/VisualEditing.tsx b/packages/visual-editing/src/ui/VisualEditing.tsx index 269bfdbca..bc84f6231 100644 --- a/packages/visual-editing/src/ui/VisualEditing.tsx +++ b/packages/visual-editing/src/ui/VisualEditing.tsx @@ -45,24 +45,29 @@ export const VisualEditing: FunctionComponent = (props) => }) // Fetch features to determine if optimistic updates are supported - const abortController = new AbortController() + const controller = new AbortController() comlink - .fetch({type: 'visual-editing/features', data: undefined}, {signal: abortController.signal}) + .fetch( + {type: 'visual-editing/features', data: undefined}, + {signal: controller.signal, suppressWarnings: true}, + ) .then((data) => { if (data.features['optimistic']) { setActor(actor) } }) .catch(() => { - // Fail silently as the app may be communicating with a version of - // Presentation that does not support this feature + // eslint-disable-next-line no-console + console.warn( + '[@sanity/visual-editing] Package version mismatch detected: Please update your Sanity studio to prevent potential compatibility issues.', + ) }) actor.start() comlink.start() return () => { - abortController.abort() + controller.abort() actor.stop() comlink.stop() } diff --git a/packages/visual-editing/src/ui/optimistic-state/machines/createSharedListener.ts b/packages/visual-editing/src/ui/optimistic-state/machines/createSharedListener.ts index 1c9becf51..fcfe6bafb 100644 --- a/packages/visual-editing/src/ui/optimistic-state/machines/createSharedListener.ts +++ b/packages/visual-editing/src/ui/optimistic-state/machines/createSharedListener.ts @@ -15,9 +15,15 @@ export function createSharedListener(comlink: VisualEditingNode): Observable(1) const incomingMutations$ = new Subject() - comlink.fetch({type: 'visual-editing/snapshot-welcome', data: undefined}).then((data) => { - incomingConnection$.next(data.event) - }) + comlink + .fetch({type: 'visual-editing/snapshot-welcome', data: undefined}, {suppressWarnings: true}) + .then((data) => { + incomingConnection$.next(data.event) + }) + .catch(() => { + // Fail silently as the app may be communicating with a version of + // Presentation that does not support this feature + }) comlink.on('presentation/snapshot-event', (data) => { // Welcome events are still emitted by Presentation for backwards diff --git a/packages/visual-editing/src/ui/schema/SchemaProvider.tsx b/packages/visual-editing/src/ui/schema/SchemaProvider.tsx index 54bb2b2d8..09732d820 100644 --- a/packages/visual-editing/src/ui/schema/SchemaProvider.tsx +++ b/packages/visual-editing/src/ui/schema/SchemaProvider.tsx @@ -82,7 +82,7 @@ export const SchemaProvider: FunctionComponent< type: 'visual-editing/schema', data: undefined, }, - {signal}, + {signal, suppressWarnings: true}, ) setSchema(response.schema) } catch (e) { @@ -110,7 +110,7 @@ export const SchemaProvider: FunctionComponent< type: 'visual-editing/schema-union-types', data: {paths}, }, - {signal}, + {signal, suppressWarnings: true}, ) setResolvedTypes(response.types) reportedPathsRef.current = paths diff --git a/packages/visual-editing/src/ui/usePerspectiveSync.tsx b/packages/visual-editing/src/ui/usePerspectiveSync.tsx index 1e17f6758..69a44664b 100644 --- a/packages/visual-editing/src/ui/usePerspectiveSync.tsx +++ b/packages/visual-editing/src/ui/usePerspectiveSync.tsx @@ -7,12 +7,27 @@ export function usePerspectiveSync( dispatch: (value: OverlayMsg | VisualEditingControllerMsg) => void, ): void { useEffect(() => { - comlink?.fetch({type: 'visual-editing/fetch-perspective', data: undefined}).then((data) => { - dispatch({type: 'presentation/perspective', data}) - }) + const controller = new AbortController() + comlink + ?.fetch( + {type: 'visual-editing/fetch-perspective', data: undefined}, + {signal: controller.signal, suppressWarnings: true}, + ) + .then((data) => { + dispatch({type: 'presentation/perspective', data}) + }) + .catch(() => { + // Fail silently as the app may be communicating with a version of + // Presentation that does not support this feature + }) - return comlink?.on('presentation/perspective', (data) => { + const unsub = comlink?.on('presentation/perspective', (data) => { dispatch({type: 'presentation/perspective', data}) }) + + return () => { + unsub?.() + controller.abort() + } }, [comlink, dispatch]) }