Files
speckle-server/packages/frontend-2/lib/common/composables/reactiveCookie.ts
T
Kristaps Fabians Geikins 83d8035dc2 chore: upgrade to eslint 9 (#2348)
* root + server

* frontend

* frontend-2

* dui3

* dui3

* tailwind theme

* ui-components

* preview service

* viewer

* viewer-sandbox

* fileimport-service

* webhook service

* objectloader

* shared

* ui-components-nuxt

* WIP full config

* WIP full linter

* eslint projectwide util

* minor fix

* removing redundant ci

* clean up test errors

* fixed prettier formatting

* CI improvements

* TSC lint fix

* 'buildBatch' needs to be async since some batch types (like Text) require it. Removed a disabled liniting rule from ObjLoader

* removed unnecessary void

---------

Co-authored-by: AlexandruPopovici <alexandrupopoviciioan@gmail.com>
2024-06-12 14:38:02 +03:00

67 lines
2.2 KiB
TypeScript

/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable @typescript-eslint/no-unsafe-argument */
import type { CookieOptions } from 'nuxt/dist/app/composables/cookie'
import dayjs from 'dayjs'
import { useScopedState } from '~~/lib/common/composables/scopedState'
import { isUndefined } from 'lodash-es'
import { isBraveOrSafari } from '@speckle/shared'
import { abortControllerManager, isAbortError } from '~/lib/common/utils/requests'
const aborts = abortControllerManager()
/**
* Makes useCookie() synchronized across the app so that a change to it from one place
* will also update other references elsewhere.
*
* Defaults to an expiration date of 1 year
*/
export const useSynchronizedCookie = <CookieValue = string>(
name: string,
opts?: CookieOptions<CookieValue>
) =>
useScopedState(`synchronizedCookiesState-${name}`, () => {
const finalOpts: CookieOptions<CookieValue> = {
expires: dayjs().add(1, 'year').toDate(),
...(opts || {}),
readonly: false,
default: undefined
}
// something's off with nuxt's types here, have to use any
const cookie = useCookie<CookieValue>(name, finalOpts as any)
// Hack to resolve Safari & Brave limiting client-side cookies to 7 days - set temporary cookie to be read from server-side where it'll be fixed
if (import.meta.client && isBraveOrSafari()) {
const tmpCookie = useCookie(`tmp-${name}`, finalOpts as any)
watch(cookie, (newVal) => {
if (newVal) {
tmpCookie.value = JSON.stringify({
expires: finalOpts.expires?.toISOString(),
maxAge: finalOpts.maxAge
})
} else {
tmpCookie.value = undefined
}
// Fetch w/ abort of previous call, if any
const controller = aborts.popOnlyInCSR()
void fetch('/web-api/cookie-fix', {
signal: controller?.signal
}).catch((e) => {
if (!isAbortError(e)) {
throw e
}
})
})
}
// there's a bug in nuxt where a default value doesn't get set if useCookie is only invoked in CSR
// TODO: https://github.com/nuxt/nuxt/issues/26701
if (isUndefined(cookie.value) && opts?.default) {
cookie.value = unref(opts.default())
}
return cookie
})