Skip to content

Commit

Permalink
fix: fix union cache break default, fix koishijs/webui#158
Browse files Browse the repository at this point in the history
  • Loading branch information
shigma committed Sep 24, 2023
1 parent 0cec7ac commit a6b6f4f
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 44 deletions.
2 changes: 1 addition & 1 deletion packages/form/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "schemastery-vue",
"description": "Type driven schema validator",
"version": "7.0.1",
"version": "7.0.3",
"main": "src/index.ts",
"repository": {
"type": "git",
Expand Down
65 changes: 28 additions & 37 deletions packages/form/src/extensions/union.vue
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
import { computed, PropType, ref, watch, WatchStopHandle } from 'vue'
import { deepEqual, isNullable } from 'cosmokit'
import { useI18n } from 'vue-i18n'
import { check, getChoices, getFallback, Schema, useI18nText } from '../utils'
import { check, getChoices, getFallback, Schema, useModel, useI18nText } from '../utils'
import zhCN from '../locales/zh-CN.yml'
import enUS from '../locales/en-US.yml'
Expand All @@ -57,21 +57,13 @@ const props = defineProps({
extra: {} as PropType<any>,
})
const emit = defineEmits(['update:modelValue'])
defineEmits(['update:modelValue'])
const tt = useI18nText()
const config = ref()
const choices = ref<Schema[]>()
const cache = ref<any[]>()
const active = ref<Schema>()
let stop: WatchStopHandle
const doWatch = () => watch(config, (value) => {
const index = choices.value.indexOf(active.value)
if (index >= 0) cache.value[index] = value
emit('update:modelValue', deepEqual(value, props.schema.meta.default) ? null : value)
}, { deep: true })
watch(() => props.schema, (value) => {
choices.value = getChoices(props.schema)
Expand All @@ -81,36 +73,35 @@ watch(() => props.schema, (value) => {
})
}, { immediate: true })
watch(() => [props.modelValue, props.schema] as const, ([value, schema]) => {
stop?.()
config.value = value
value ??= schema.meta.default
active.value = null
let hasTransform = true, depth = 0
while (!active.value && hasTransform && ++depth < 10) {
hasTransform = false
for (const item of schema.list) {
if (item.meta.hidden) continue
if (!check(item, value)) continue
if (item.type === 'transform') {
if (!item.callback) continue
try {
value = item.callback(value)
} catch (error) {
console.error(error)
continue
const config = useModel({
input(value) {
active.value = null
let hasTransform = true, depth = 0
while (!active.value && hasTransform && ++depth < 10) {
hasTransform = false
for (const [index, item] of props.schema.list.entries()) {
if (item.meta.hidden) continue
if (!check(item, value)) continue
if (item.type === 'transform') {
if (!item.callback) continue
try {
value = item.callback(value)
} catch (error) {
console.error(error)
continue
}
hasTransform = true
value ??= getFallback(props.schema)
} else {
active.value = item
cache.value[index] = value
}
hasTransform = true
config.value = value
value ??= schema.meta.default
} else {
active.value = item
break
}
break
}
}
stop = doWatch()
}, { immediate: true, deep: true })
return value
},
})
const selectModel = computed({
get() {
Expand Down
12 changes: 6 additions & 6 deletions packages/form/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,8 @@ export function useDisabled() {

interface ConfigOptions<T> {
strict?: boolean
input(value: any): T
output(value: T): any
input?(value: any): T
output?(value: T): any
}

export function useModel<T = any>(options?: ConfigOptions<T>) {
Expand All @@ -101,21 +101,21 @@ export function useModel<T = any>(options?: ConfigOptions<T>) {

const doWatch = () => watch(config, (value) => {
try {
if (options) value = options.output(value)
if (options?.output) value = options.output(value)
} catch {
return
}
if (deepEqual(value, props.schema.meta.default, options?.strict)) value = null
emit('update:modelValue', value)
}, { deep: true })

watch([() => props.modelValue, () => props.schema], ([value, schema]) => {
watch(() => [props.modelValue, props.schema], ([value, schema]) => {
stop?.()
value ??= getFallback(schema)
if (options) value = options.input(value)
if (options?.input) value = options.input(value)
config.value = value
stop = doWatch()
}, { immediate: true })
}, { deep: true, immediate: true })

return config
}
Expand Down

0 comments on commit a6b6f4f

Please sign in to comment.