svelte 5 dispatch fixes (#5604)

* dispatchIfMounted

* fixed all warnings

* typo

* fix another infinite loop

* buggy date time input on runs page when changing search params
This commit is contained in:
Diego Imbert
2025-04-11 17:17:42 +02:00
committed by GitHub
parent 9ffa3e81ac
commit abb1cbb8ac
35 changed files with 129 additions and 70 deletions
+3 -1
View File
@@ -38,6 +38,7 @@
import type { Script } from '$lib/gen'
import type { SchemaDiff } from '$lib/components/schema/schemaUtils'
import type { ComponentCustomCSS } from './apps/types'
import { createDispatcherIfMounted } from '$lib/createDispatcherIfMounted'
export let label: string = ''
export let value: any
@@ -150,6 +151,7 @@
}
const dispatch = createEventDispatcher()
const dispatchIfMounted = createDispatcherIfMounted(dispatch)
let ignoreValueUndefined = false
let error: string = ''
@@ -388,7 +390,7 @@
function compareValues(value) {
if (!deepEqual(oldValue, value)) {
oldValue = value
dispatch('change')
dispatchIfMounted('change')
}
}
@@ -3,6 +3,7 @@
import { Button } from './common'
import { Clock, X } from 'lucide-svelte'
import { twMerge } from 'tailwind-merge'
import { createDispatcherIfMounted } from '$lib/createDispatcherIfMounted'
// import ToggleButtonGroup from './common/toggleButton-v2/ToggleButtonGroup.svelte'
// import ToggleButton from './common/toggleButton-v2/ToggleButton.svelte'
@@ -43,14 +44,13 @@
let initialTime = time
function parseDateAndTime(date: string | undefined, time: string | undefined) {
console.log(date, time)
if (date && time && (initialDate != date || initialTime != time)) {
let newDate = new Date(`${date}T${time}`)
if (newDate.toString() === 'Invalid Date') return
if (newDate.getFullYear() < 2000) return
value = newDate.toISOString()
dispatch('change', value)
dispatchIfMounted('change', value)
}
}
@@ -61,6 +61,7 @@
}
const dispatch = createEventDispatcher()
const dispatchIfMounted = createDispatcherIfMounted(dispatch)
function setTimeLater(mins: number) {
let newDate = new Date()
@@ -131,7 +131,7 @@
bind:this={diffDivEl}
class="{$$props.class} editor nonmain-editor"
bind:clientWidth={editorWidth}
/>
></div>
{#if showButtons}
<div
class="absolute flex flex-row gap-2 bottom-10 left-1/2 z-10 -translate-x-1/2 rounded-md p-1 w-full justify-center"
@@ -35,6 +35,7 @@
import PdfViewer from './display/PdfViewer.svelte'
import type { DisplayResultUi } from './custom_ui'
import { getContext, hasContext, createEventDispatcher, onDestroy } from 'svelte'
import { createDispatcherIfMounted } from '$lib/createDispatcherIfMounted'
export let result: any
export let requireHtmlApproval = false
@@ -57,6 +58,7 @@
const DISPLAY_MAX_SIZE = 100000
const dispatch = createEventDispatcher()
const dispatchIfMounted = createDispatcherIfMounted(dispatch)
let resultKind:
| 'json'
@@ -414,7 +416,7 @@
} else {
toolbarLocation = 'self'
}
dispatch('toolbar-location-changed', toolbarLocation)
dispatchIfMounted('toolbar-location-changed', toolbarLocation)
}
export function getToolbarLocation() {
@@ -24,6 +24,7 @@
import { tweened } from 'svelte/motion'
import type { SchemaDiff } from '$lib/components/schema/schemaUtils'
import type { EditableSchemaFormUi } from '$lib/components/custom_ui'
import { createDispatcherIfMounted } from '$lib/createDispatcherIfMounted'
export let schema: Schema | any
export let schemaSkippedValues: string[] = []
@@ -57,6 +58,7 @@
export let customUi: EditableSchemaFormUi | undefined = undefined
const dispatch = createEventDispatcher()
const dispatchIfMounted = createDispatcherIfMounted(dispatch)
let clazz: string = ''
export { clazz as class }
@@ -230,7 +232,7 @@
function updatePanelSizes(editSize: number, inputSize: number) {
editPanelSize = editSize
inputPanelSize = inputSize
dispatch('editPanelSizeChanged', editSize)
dispatchIfMounted('editPanelSizeChanged', editSize)
}
$: updatePanelSizes($editPanelSizeSmooth, $inputPanelSizeSmooth)
@@ -3,6 +3,7 @@
import SimpleEditor from '$lib/components/SimpleEditor.svelte'
import { createEventDispatcher } from 'svelte'
import { createDispatcherIfMounted } from '$lib/createDispatcherIfMounted'
export let code: string | undefined
export let value: any = undefined
export let error = ''
@@ -12,6 +13,7 @@
$: tooBig = code && code?.length > 1000000
const dispatch = createEventDispatcher()
const dispatchIfMounted = createDispatcherIfMounted(dispatch)
function parseJson() {
try {
@@ -21,7 +23,7 @@
return
}
value = JSON.parse(code ?? '')
dispatch('changeValue', value)
dispatchIfMounted('changeValue', value)
error = ''
} catch (e) {
error = e.message
@@ -10,8 +10,10 @@
import { Plus, Loader2, Link2Off } from 'lucide-svelte'
import type { AppViewerContext } from './apps/types'
import { sendUserToast } from '$lib/toast'
import { createDispatcherIfMounted } from '$lib/createDispatcherIfMounted'
const dispatch = createEventDispatcher()
const dispatchIfMounted = createDispatcherIfMounted(dispatch)
export let initialValue: string | undefined = undefined
export let value: string | undefined = initialValue
@@ -29,7 +31,7 @@
? {
value: value ?? initialValue,
label: value ?? initialValue
}
}
: undefined
let collection = [valueSelect]
@@ -64,7 +66,7 @@
$: $workspaceStore && loadResources(resourceType)
$: dispatch('change', value)
$: dispatchIfMounted('change', value)
let darkMode: boolean = false
@@ -18,6 +18,7 @@
import autosize from '$lib/autosize'
import GfmMarkdown from './GfmMarkdown.svelte'
import TestTriggerConnection from './triggers/TestTriggerConnection.svelte'
import { createDispatcherIfMounted } from '$lib/createDispatcherIfMounted'
export let canSave = true
export let resource_type: string | undefined = undefined
@@ -52,8 +53,9 @@
let viewJsonSchema = false
const dispatch = createEventDispatcher()
const dispatchIfMounted = createDispatcherIfMounted(dispatch)
$: watchChanges && dispatch('change', { path, args, description })
$: watchChanges && dispatchIfMounted('change', { path, args, description })
let rawCode: string | undefined = undefined
@@ -12,8 +12,10 @@
import DarkModeObserver from './DarkModeObserver.svelte'
import { Pen, Plus, RotateCw } from 'lucide-svelte'
import { sendUserToast } from '$lib/toast'
import { createDispatcherIfMounted } from '$lib/createDispatcherIfMounted'
const dispatch = createEventDispatcher()
const dispatchIfMounted = createDispatcherIfMounted(dispatch)
export let initialValue: string | undefined = undefined
export let value: string | undefined = initialValue
@@ -97,9 +99,7 @@
$: $workspaceStore && loadResources(resourceType)
let oldValue = value
$: (oldValue !== value) && dispatch('change', (oldValue = value))
$: dispatchIfMounted('change', value)
let appConnect: AppConnect
let resourceEditor: ResourceEditorDrawer
@@ -43,6 +43,7 @@
import HideButton from './apps/editor/settingsPanel/HideButton.svelte'
import { base } from '$lib/base'
import { SUPPORTED_CHAT_SCRIPT_LANGUAGES } from './copilot/chat/core'
import { createDispatcherIfMounted } from '$lib/createDispatcherIfMounted'
// Exported
export let schema: Schema | any = emptySchema()
@@ -87,10 +88,11 @@
}
const dispatch = createEventDispatcher()
const dispatchIfMounted = createDispatcherIfMounted(dispatch)
$: watchChanges &&
(code != undefined || schema != undefined) &&
dispatch('change', { code, schema })
dispatchIfMounted('change', { code, schema })
let width = 1200
@@ -78,10 +78,10 @@
? config
: {
worker_tags: []
}
}
: {
worker_tags: []
}
}
if (nconfig.priority_tags === undefined) {
nconfig.priority_tags = new Map<string, number>()
}
@@ -215,7 +215,7 @@
Workers can still have their WORKER_TAGS, INIT_SCRIPT and WHITELIST_ENVS passed as env.
Dedicated workers are an enterprise only feature.
</Alert>
<div class="pb-4" />
<div class="pb-4"></div>
{/if}
<ToggleButtonGroup
@@ -402,7 +402,7 @@
{/if}
</Section>
{#if nconfig !== undefined}
<div class="mt-8" />
<div class="mt-8"></div>
<Section label="Alerts" tooltip="Alert is sent to the configured critical error channels">
<Toggle
size="sm"
@@ -465,7 +465,7 @@
{/if}
{/if}
<div class="mt-8" />
<div class="mt-8"></div>
<Section
label="Python runtime settings"
collapsable={true}
@@ -576,7 +576,7 @@
</div>
</Section>
<div class="mt-8" />
<div class="mt-8"></div>
<Section
label="Environment variables passed to jobs"
@@ -716,7 +716,7 @@
</div>
{/if}
</Section>
<div class="mt-8" />
<div class="mt-8"></div>
<Section label="Autoscaling" collapsable>
<div slot="header" class="ml-4 flex flex-row gap-2 items-center">
@@ -731,7 +731,7 @@
bind:config={nconfig.autoscaling}
/>
</Section>
<div class="mt-8" />
<div class="mt-8"></div>
<Section
label="Init script"
@@ -22,6 +22,7 @@
import { deepEqual } from 'fast-equals'
import { deepMergeWithPriority, isCodeInjection } from '$lib/utils'
import sum from 'hash-sum'
import { createDispatcherIfMounted } from '$lib/createDispatcherIfMounted'
type T = string | number | boolean | Record<string | number, any> | undefined
@@ -76,8 +77,11 @@
debounceTemplate()
const dispatch = createEventDispatcher()
const dispatchIfMounted = createDispatcherIfMounted(dispatch)
if (input == undefined) {
// How did this ever do anything at the top level in svelte 4 if
// events were not being picked up before the component fully mounted?
dispatch('done')
}
@@ -244,7 +248,7 @@
}
await tick()
dispatch('done')
dispatchIfMounted('done')
}
function onEvalChange(previousValueKey: string) {
@@ -27,6 +27,7 @@
import { ctxRegex } from '../../utils'
import { computeWorkspaceS3FileInputPolicy } from '../../editor/appUtilsS3'
import SchemaForm from '$lib/components/SchemaForm.svelte'
import { createDispatcherIfMounted } from '$lib/createDispatcherIfMounted'
// Component props
export let id: string
@@ -88,6 +89,7 @@
const groupContext = getContext<GroupContext>('GroupContext')
const dispatch = createEventDispatcher()
const dispatchIfMounted = createDispatcherIfMounted(dispatch)
$runnableComponents = $runnableComponents
@@ -139,7 +141,7 @@
resultJobLoader &&
refreshIfAutoRefresh('arg changed')
$: runnableInputValues && dispatch('argsChanged')
$: runnableInputValues && dispatchIfMounted('argsChanged')
$: refreshOn =
runnable && runnable.type === 'runnableByName' ? (runnable.inlineScript?.refreshOn ?? []) : []
@@ -59,9 +59,6 @@
return Object.values(componentOptions).some((value) => value)
}
let connectingPopupHover = false
$: connectingPopupHover && dispatch('mouseover')
let hoverHeader = false
</script>
@@ -126,8 +123,8 @@
selected
? 'bg-blue-600/90 text-white'
: $connectingInput.opened
? 'bg-[#f8aa4b]/90 text-white'
: 'bg-blue-400/90 text-white'
? 'bg-[#f8aa4b]/90 text-white'
: 'bg-blue-400/90 text-white'
)}
>
<div
@@ -112,6 +112,7 @@
{#if componentIsDebugging}
<div class="flex flex-row items-center gap-2">
{`${isSmall ? '' : 'Debugging node'} ${nodes[$debuggingComponents[id] ?? 0]?.id}`}
<!-- svelte-ignore node_invalid_placement_ssr -->
<button
on:click={() => {
$componentControl?.[id]?.setTab?.(0)
@@ -18,6 +18,7 @@
import ToggleButton from '$lib/components/common/toggleButton-v2/ToggleButton.svelte'
import Popover from '$lib/components/Popover.svelte'
import { tailwindClasses } from './tailwindUtils'
import { createDispatcherIfMounted } from '$lib/createDispatcherIfMounted'
export let name: string
export let value: ComponentCssProperty = {}
@@ -33,9 +34,10 @@
export let wmClass: string | undefined = undefined
const dispatch = createEventDispatcher()
const dispatchIfMounted = createDispatcherIfMounted(dispatch)
let isQuickMenuOpen = false
$: dispatch('change', value)
$: dispatchIfMounted('change', value)
function toggleQuickMenu() {
try {
@@ -4,6 +4,7 @@
import { isOpenStore } from './store'
import { createEventDispatcher, onMount } from 'svelte'
import Tooltip from '$lib/components/Tooltip.svelte'
import { createDispatcherIfMounted } from '$lib/createDispatcherIfMounted'
export let title: string
export let prefix: string | undefined = undefined
@@ -17,11 +18,12 @@
export let subtitle: string | undefined = undefined
const dispatch = createEventDispatcher()
const dispatchIfMounted = createDispatcherIfMounted(dispatch)
$: storeTitle = prefix + title
$: isOpen = prefix ? $isOpenStore[storeTitle] : true
$: dispatch('open', isOpen)
$: dispatchIfMounted('open', isOpen)
onMount(() => {
if (prefix !== undefined && !(prefix + title in $isOpenStore)) {
@@ -58,9 +58,10 @@
current[s.prop.key] = convertValue(s.value)
})
const entries = Object.entries(current)
value = entries.reduce((style, [k, v]) => {
const newValue = entries.reduce((style, [k, v]) => {
return v ? `${style} ${k}: ${v}; `.trim() : style
}, '')
if (value !== newValue) value = newValue
}
function convertValue(value: any) {
@@ -11,12 +11,14 @@
type StyleStoreValue,
type StylePropertyValue
} from './quickStyleProperties'
import { createDispatcherIfMounted } from '$lib/createDispatcherIfMounted'
export let prop: StyleStoreValue['style'][number]['prop']
export let value: string | undefined
export let inline = false
const styleStore = getContext<StyleStore>(STYLE_STORE_KEY)
const dispatch = createEventDispatcher()
const dispatchIfMounted = createDispatcherIfMounted(dispatch)
const key = prop.key
const type = prop.value?.['type']
let unit: (typeof StylePropertyUnits)[number] = StylePropertyUnits[0]
@@ -35,7 +37,7 @@
return ''
}
$: internalValue = getInteralValue(value, prop.value as StylePropertyValue)
$: dispatch('change', value)
$: dispatchIfMounted('change', value)
function updateValue(next: number) {
value = next ? next + unit : ''
@@ -28,6 +28,7 @@
import { createEventDispatcher, getContext } from 'svelte'
import type { AppViewerContext } from '$lib/components/apps/types'
import { deleteGridItem } from '../../appUtils'
import { createDispatcherIfMounted } from '$lib/createDispatcherIfMounted'
export let nodes: DecisionTreeNode[]
export let paneWidth = 0
@@ -38,6 +39,7 @@
const edgesStore = writable<Edge[]>([])
const dispatch = createEventDispatcher()
const dispatchIfMounted = createDispatcherIfMounted(dispatch)
const { selectedNodeId } = getContext<{
selectedNodeId: Writable<string | undefined>
@@ -155,7 +157,7 @@
default:
break
}
dispatch('render')
dispatchIfMounted('render')
}
function graphBuilder(decisionTreeNodes: DecisionTreeNode[]) {
@@ -5,14 +5,16 @@
import { createPopperActions } from 'svelte-popperjs'
import { fade } from 'svelte/transition'
import { zIndexes } from '$lib/zIndexes'
import { createDispatcherIfMounted } from '$lib/createDispatcherIfMounted'
export let value: string = '#fff'
const dispatch = createEventDispatcher()
const dispatchIfMounted = createDispatcherIfMounted(dispatch)
const [popperRef, popperContent] = createPopperActions()
let isOpen = false
let width: number
$: dispatch('change', value)
$: dispatchIfMounted('change', value)
function open() {
isOpen = true
@@ -1,10 +1,11 @@
<script>
// @ts-nocheck
import { beforeUpdate, createEventDispatcher, onDestroy, onMount, tick } from 'svelte'
import { beforeUpdate, createEventDispatcher, onDestroy, onMount } from 'svelte'
import { offset, flip, shift } from '@floating-ui/dom'
import { createFloatingActions } from 'svelte-floating-ui'
const dispatch = createEventDispatcher()
// This component caused trouble with svelte 5 so better be extra safe
const dispatch = createDispatcherIfMounted(createEventDispatcher())
import _filter from './filter'
import _getItems from './get-items'
@@ -17,6 +18,7 @@
import { extractCustomProperties, truncate } from '$lib/utils'
import { twMerge } from 'tailwind-merge'
import { createDispatcherIfMounted } from '$lib/createDispatcherIfMounted'
export let portal = true
@@ -8,6 +8,7 @@
import { createTooltip } from '@melt-ui/svelte'
import type { Placement } from '@floating-ui/core'
import { conditionalMelt } from '$lib/utils'
import { createDispatcherIfMounted } from '$lib/createDispatcherIfMounted'
export let size: ButtonType.Size = 'md'
export let spacingSize: ButtonType.Size = size
@@ -72,6 +73,7 @@
}
const dispatch = createEventDispatcher()
const dispatchIfMounted = createDispatcherIfMounted(dispatch)
// Order of classes: border, border modifier, bg, bg modifier, text, text modifier, everything else
async function onClick(event: MouseEvent) {
@@ -150,7 +152,7 @@
}
$: tooltipPopover && openDelay !== undefined && ($openDelay = tooltipPopover?.openDelay) //This option is reactive
$: $open !== undefined && dispatch('tooltipOpen', $open)
$: $open !== undefined && dispatchIfMounted('tooltipOpen', $open)
</script>
<div
@@ -2,6 +2,7 @@
import { createEventDispatcher } from 'svelte'
import { fade } from 'svelte/transition'
import { X } from 'lucide-svelte'
import { createDispatcherIfMounted } from '$lib/createDispatcherIfMounted'
export let value: any = ''
export let placeholder = ''
@@ -10,10 +11,11 @@
export let wrapperClass = ''
export let buttonClass = ''
const dispatch = createEventDispatcher()
const dispatchIfMounted = createDispatcherIfMounted(dispatch)
let isHovered = false
$: isNumeric = ['number', 'range'].includes(type)
$: dispatch('change', value)
$: dispatchIfMounted('change', value)
function handleInput(e) {
value = isNumeric ? +e.target.value : e.target.value
@@ -3,6 +3,8 @@
</script>
<script lang="ts">
import { createDispatcherIfMounted } from '$lib/createDispatcherIfMounted'
import { zIndexes } from '$lib/zIndexes'
import { createEventDispatcher } from 'svelte'
@@ -50,6 +52,7 @@
}
const dispatch = createEventDispatcher()
const dispatchIfMounted = createDispatcherIfMounted(dispatch)
function handleClickAway(e) {
const last = openedDrawers[openedDrawers.length - 1]
@@ -81,7 +84,7 @@
$: zIndex = zIndexes.disposables + offset
$: open ? dispatch('open') : dispatch('close')
$: dispatchIfMounted(open ? 'open' : 'close')
</script>
<svelte:window on:keydown={onKeyDown} />
@@ -1,14 +1,10 @@
<script lang="ts">
import { createDispatcherIfMounted } from '$lib/createDispatcherIfMounted'
import { createEventDispatcher } from 'svelte'
const dispatch = createEventDispatcher()
const dispatchIfMounted = createDispatcherIfMounted(dispatch)
export let open: boolean = false
$: {
if (open) {
dispatch('open')
} else {
dispatch('close')
}
}
$: dispatchIfMounted(open ? 'open' : 'close')
</script>
@@ -11,8 +11,10 @@
import { writable, type Writable } from 'svelte/store'
import { createEventDispatcher } from 'svelte'
import { twMerge } from 'tailwind-merge'
import { createDispatcherIfMounted } from '$lib/createDispatcherIfMounted'
const dispatch = createEventDispatcher()
const dispatchIfMounted = createDispatcherIfMounted(dispatch)
export let selected: string
export let hideTabs = false
@@ -28,16 +30,7 @@
const selectedStore = writable(selected)
$: $selectedStore && onSelectedStoreChange()
let initial = true
function onSelectedStoreChange() {
if (initial) {
initial = false
return
}
dispatch('selected', $selectedStore)
}
$: $selectedStore && dispatchIfMounted('selected', $selectedStore)
$: hashValues = values ? values.map((x) => '#' + x) : undefined
setContext<TabsContext>('Tabs', {
@@ -14,6 +14,7 @@
import { yamlStringifyExceptKeys } from './utils'
import { copilotInfo, stepInputCompletionEnabled } from '$lib/stores'
import { twMerge } from 'tailwind-merge'
import { createDispatcherIfMounted } from '$lib/createDispatcherIfMounted'
let generatedContent = ''
let loading = false
@@ -96,6 +97,7 @@ Only output the expression, do not explain or discuss.`
}
const dispatch = createEventDispatcher()
const dispatchIfMounted = createDispatcherIfMounted(dispatch)
function automaticGeneration() {
if (empty) {
@@ -125,7 +127,7 @@ Only output the expression, do not explain or discuss.`
generatedContent = ''
}
$: dispatch('showExpr', generatedContent)
$: dispatchIfMounted('showExpr', generatedContent)
let out = true // hack to prevent regenerating answer when accepting the answer due to mouseenter on new icon
</script>
@@ -10,6 +10,7 @@
import type { FlowValue } from '$lib/gen'
import { yamlStringifyExceptKeys } from './utils'
import type { ChatCompletionMessageParam } from 'openai/resources/index.mjs'
import { createDispatcherIfMounted } from '$lib/createDispatcherIfMounted'
type PromptConfig = {
system: string
@@ -151,10 +152,9 @@ Generate a description for the flow below:
}
const dispatch = createEventDispatcher()
const dispatchIfMounted = createDispatcherIfMounted(dispatch)
$: if (content) {
dispatch('change', { content })
}
$: content && dispatchIfMounted('change', { content })
$: active =
$copilotInfo.enabled &&
@@ -17,6 +17,7 @@
import type { SchemaProperty } from '$lib/common'
import FlowCopilotInputsModal from './FlowCopilotInputsModal.svelte'
import { twMerge } from 'tailwind-merge'
import { createDispatcherIfMounted } from '$lib/createDispatcherIfMounted'
let generatedContent = ''
let loading = false
@@ -155,6 +156,7 @@ Only return the expression without any wrapper.`
}
const dispatch = createEventDispatcher()
const dispatchIfMounted = createDispatcherIfMounted(dispatch)
function cancel() {
abortController.abort()
@@ -184,9 +186,9 @@ Only return the expression without any wrapper.`
automaticGeneration()
}
$: dispatch('showExpr', generatedContent)
$: dispatchIfMounted('showExpr', generatedContent)
$: dispatch('showExpr', $generatedExprs?.[argName] || '')
$: dispatchIfMounted('showExpr', $generatedExprs?.[argName] || '')
let out = true // hack to prevent regenerating answer when accepting the answer due to mouseenter on new icon
let openInputsModal = false
@@ -238,8 +240,8 @@ Only return the expression without any wrapper.`
loading || ($stepInputsLoading && empty)
? Loader2
: generatedContent.length > 0
? Check
: Wand2,
? Check
: Wand2,
classes: loading || ($stepInputsLoading && empty) ? 'animate-spin' : ''
}}
on:focus={() => {
@@ -18,6 +18,7 @@
import { Pen, Plus, Trash2 } from 'lucide-svelte'
import Popover from '$lib/components/meltComponents/Popover.svelte'
import { deepEqual } from 'fast-equals'
import { createDispatcherIfMounted } from '$lib/createDispatcherIfMounted'
export let format: string | undefined = undefined
export let contentEncoding: 'base64' | 'binary' | undefined = undefined
@@ -92,6 +93,7 @@
$: orderUpdate(order)
const dispatch = createEventDispatcher()
const dispatchIfMounted = createDispatcherIfMounted(dispatch)
function getResourceTypesFromFormat(format: string | undefined): string[] {
if (format?.startsWith('resource-')) {
@@ -132,7 +134,7 @@
}
}
})
dispatch('schemaChange', { properties, order, requiredProperty, oneOf })
dispatchIfMounted('schemaChange', { properties, order, requiredProperty, oneOf })
}
}
@@ -15,6 +15,7 @@
import ToggleButtonGroup from '../common/toggleButton-v2/ToggleButtonGroup.svelte'
import ToggleButton from '../common/toggleButton-v2/ToggleButton.svelte'
import { createEventDispatcher, onMount } from 'svelte'
import { createDispatcherIfMounted } from '$lib/createDispatcherIfMounted'
export let description: string = ''
export let format: string | undefined = undefined
@@ -43,6 +44,7 @@
| undefined = undefined
const dispatch = createEventDispatcher()
const dispatchIfMounted = createDispatcherIfMounted(dispatch)
let el: HTMLTextAreaElement | undefined = undefined
let oneOfSelected: string | undefined =
@@ -102,7 +104,7 @@
if (!deepEqual(extra, initialExtra)) {
initialExtra = structuredClone(extra)
console.debug('property content updated')
dispatch('change')
dispatchIfMounted('change')
}
}
@@ -115,7 +117,7 @@
order
}
console.debug('property schema updated')
dispatch('change')
dispatchIfMounted('change')
}
}
</script>
@@ -10,6 +10,7 @@
import { ArrowDownIcon, ArrowLeftIcon, ArrowRightIcon, Loader2 } from 'lucide-svelte'
import { twMerge } from 'tailwind-merge'
import List from '$lib/components/common/layout/List.svelte'
import { createDispatcherIfMounted } from '$lib/createDispatcherIfMounted'
export let paginated: boolean = false
export let currentPage: number = 1
@@ -31,6 +32,7 @@
let footerHeight: number = 0
let tableHeight: number = 0
const dispatch = createEventDispatcher()
const dispatchIfMounted = createDispatcherIfMounted(dispatch)
let tableContainer: HTMLDivElement
export let loading = false
export let loadingMore = false
@@ -45,7 +47,7 @@
const hasScrollbar = tableContainer.scrollHeight > tableContainer.clientHeight
if (!hasScrollbar && hasMore) {
dispatch('loadMore')
dispatchIfMounted('loadMore')
}
}
@@ -0,0 +1,19 @@
import { onMount, type EventDispatcher } from 'svelte'
/**
* This wrapper emulates the behavior of an event dispatcher in Svelte 4
*
* A lot of svelte 4 code depended on events not being picked up when they
* were dispatched before being mounted. In svelte 5, these events are
* being reacted to which cause infinite loops.
*/
export function createDispatcherIfMounted<EventMap extends Record<string, any> = any>(
dispatch: EventDispatcher<EventMap>
): EventDispatcher<EventMap> {
let mounted = false
onMount(() => (mounted = true))
return ((...args: Parameters<typeof dispatch>) => {
if (!mounted) return false
return dispatch(...args)
}) as any
}
@@ -199,12 +199,14 @@
tag ||
graph ||
maxTs ||
minTs ||
allWorkspaces ||
allowWildcards ||
$workspaceStore) &&
setQuery(false)
$: minTs || setQuery(true)
$: maxTs || setQuery(true)
function setQuery(replaceState: boolean) {
let searchParams = new URLSearchParams()
@@ -330,7 +332,7 @@
$page.url.pathname != newUrl.split('?')[0]
) {
// replaceState(newUrl.toString(), $page.state)
goto(newUrl.toString(), { replaceState: replaceState })
goto(newUrl.toString(), { replaceState: replaceState, keepFocus: true })
}
}