@sanity/client
Advanced tools
Comparing version 6.17.3-canary.6 to 6.17.3-canary.7
{ | ||
"name": "@sanity/client", | ||
"version": "6.17.3-canary.6", | ||
"version": "6.17.3-canary.7", | ||
"description": "Client for retrieving, creating and patching data from Sanity.io", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
@@ -174,2 +174,6 @@ import {Observable} from 'rxjs' | ||
es = eventSource | ||
// Handle race condition where the observer is unsubscribed before the EventSource is set up | ||
if (unsubscribed) { | ||
unsubscribe() | ||
} | ||
} | ||
@@ -193,3 +197,3 @@ }) | ||
function parseEvent(event: Any) { | ||
function parseEvent(event: MessageEvent) { | ||
try { | ||
@@ -196,0 +200,0 @@ const data = (event.data && JSON.parse(event.data)) || {} |
@@ -20,6 +20,10 @@ import {Observable} from 'rxjs' | ||
const listenFor = ['restart', 'message'] | ||
const listenFor = ['restart', 'message'] as const | ||
return new Observable((observer) => { | ||
let es: InstanceType<typeof import('@sanity/eventsource')> | ||
let es: InstanceType<typeof EventSource> | undefined | ||
let reconnectTimer: NodeJS.Timeout | ||
let stopped = false | ||
// Unsubscribe differs from stopped in that we will never reopen. | ||
// Once it is`true`, it will never be `false` again. | ||
let unsubscribed = false | ||
@@ -29,10 +33,20 @@ | ||
function onError(evt: Any) { | ||
if (unsubscribed) { | ||
// EventSource will emit a regular event if it fails to connect, however the API will emit an `error` MessageEvent if the server goes down | ||
// So we need to handle both cases | ||
function onError(evt: MessageEvent | Event) { | ||
if (stopped) { | ||
return | ||
} | ||
observer.error(cooerceError(evt)) | ||
// If the event has a `data` property, then it`s a MessageEvent emitted by the API and we should forward the error and close the connection | ||
if ('data' in evt) { | ||
try { | ||
const event = parseEvent(evt) | ||
observer.error(new Error(event.message, {cause: event})) | ||
} catch (err) { | ||
observer.error(err) | ||
} | ||
} | ||
// Unless we've explicitly stopped the ES (in which case `unsubscribed` should be true), | ||
// Unless we've explicitly stopped the ES (in which case `stopped` should be true), | ||
// we should never be in a disconnected state. By default, EventSource will reconnect | ||
@@ -42,4 +56,6 @@ // automatically, in which case it sets readyState to `CONNECTING`, but in some cases | ||
// to explicitly reconnect. | ||
if (es.readyState === es.CLOSED) { | ||
if (es!.readyState === es!.CLOSED) { | ||
unsubscribe() | ||
clearTimeout(reconnectTimer) | ||
reconnectTimer = setTimeout(open, 100) | ||
} | ||
@@ -54,8 +70,7 @@ } | ||
function unsubscribe() { | ||
console.log('unsubscribe', {es, unsubscribed}) | ||
unsubscribed = true | ||
if (!es) return | ||
console.log('teardown and es.close') | ||
es.removeEventListener('error', onError) | ||
listenFor.forEach((type: string) => es.removeEventListener(type, onMessage)) | ||
for (const type of listenFor) { | ||
es.removeEventListener(type, onMessage) | ||
} | ||
es.close() | ||
@@ -65,7 +80,6 @@ } | ||
async function getEventSource() { | ||
console.log('getEventSource inner', {unsubscribed}) | ||
const EventSourceImplementation: typeof import('@sanity/eventsource') = | ||
const EventSourceImplementation: typeof EventSource = | ||
typeof EventSource === 'undefined' | ||
? (await import('@sanity/eventsource')).default | ||
: (globalThis.EventSource as unknown as Any) | ||
? ((await import('@sanity/eventsource')).default as typeof EventSource) | ||
: EventSource | ||
@@ -75,10 +89,10 @@ // If the listener has been unsubscribed from before we managed to load the module, | ||
if (unsubscribed) { | ||
console.log('unsubscribed, do not setup') | ||
return | ||
} | ||
console.log('starting EventSource', {url, unsubscribed, EventSourceImplementation}) | ||
const evs = new EventSourceImplementation(url.toString()) | ||
evs.addEventListener('error', onError) | ||
listenFor.forEach((type: string) => evs.addEventListener(type, onMessage)) | ||
for (const type of listenFor) { | ||
evs.addEventListener(type, onMessage) | ||
} | ||
return evs | ||
@@ -88,6 +102,4 @@ } | ||
function open() { | ||
console.log('open.getEventSource', {unsubscribed}) | ||
getEventSource() | ||
.then((eventSource) => { | ||
console.log('open.getEventSource.then', {eventSource, unsubscribed}) | ||
if (eventSource) { | ||
@@ -97,3 +109,2 @@ es = eventSource | ||
if (unsubscribed) { | ||
console.log('open.getEventSource.then.unsubscribed', {unsubscribed, es}) | ||
unsubscribe() | ||
@@ -109,3 +120,9 @@ } | ||
return unsubscribe | ||
function stop() { | ||
stopped = true | ||
unsubscribe() | ||
unsubscribed = true | ||
} | ||
return stop | ||
}) | ||
@@ -123,22 +140,1 @@ } | ||
} | ||
function cooerceError(err: Any) { | ||
if (err instanceof Error) { | ||
return err | ||
} | ||
const evt = parseEvent(err) | ||
return evt instanceof Error ? evt : new Error(extractErrorMessage(evt), {cause: evt}) | ||
} | ||
function extractErrorMessage(err: Any) { | ||
if (!err.error) { | ||
return err.message || 'Unknown listener error' | ||
} | ||
if (err.error.description) { | ||
return err.error.description | ||
} | ||
return typeof err.error === 'string' ? err.error : JSON.stringify(err.error, null, 2) | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
24451
2184144