mirror of
https://github.com/Ku6epXBOCTuK/easy-png-tools.git
synced 2026-11-13 17:08:20 +00:00
fix: update field spec types
This commit is contained in:
@@ -166,13 +166,19 @@ round-семантика `clampByte` и trunc-семантика `clampInt` со
|
|||||||
`$bindable`, пропс `ontogglealign` удалён; `SchemaToolView` передаёт
|
`$bindable`, пропс `ontogglealign` удалён; `SchemaToolView` передаёт
|
||||||
`bind:aligned`.
|
`bind:aligned`.
|
||||||
|
|
||||||
### L4. Непроверяемые `as`-касты схемы
|
### L4. Непроверяемые `as`-касты схемы — СДЕЛАНО (2026-10)
|
||||||
|
|
||||||
`SchemaToolView.svelte:97,211`
|
- 14 field-контролов: `spec: FieldSpec` + `spec as XSpec` → точный тип спеки в
|
||||||
(`tool.schema as ToolSchema<Record<string, unknown>>`) и паттерн `spec as XSpec`
|
пропсах (`spec: ColorSpec` и т.д.); каст собран в одном месте — типизированный
|
||||||
в 14+ field-компонентах (`CheckboxControl.svelte:13`, `ColorControl.svelte:14`,
|
хелпер `controlFor<S>()` в `SchemaFields.svelte` (ключ kind в `FIELDS`
|
||||||
`GradientControl.svelte:16` и др.); двойной каст `as unknown as WorkerLike` в
|
гарантирует подтип спеки по `fieldSpecs`).
|
||||||
`executor/executor.ts:35`. Касты отключают проверку соответствия spec kind'у.
|
- `SchemaToolView`/`toolSchemaOf`: касты
|
||||||
|
`as ToolSchema<Record<string, unknown>>` удалены — дефолт дженерика
|
||||||
|
`Tool<P = Record<string, unknown>>` уже даёт нужный тип; `undefined`
|
||||||
|
обрабатывается гардами (`{#if stepSchema}` в разметке, `dims && stepSchema` в
|
||||||
|
`setStepValue`).
|
||||||
|
- `executor.ts` `as unknown as WorkerLike` оставлен намеренно: несовместимость
|
||||||
|
`onerror` (ErrorEvent vs Event) в типах lib.dom; добавлен комментарий-причина.
|
||||||
|
|
||||||
### L5. Хардкод slug-ов вне registry
|
### L5. Хардкод slug-ов вне registry
|
||||||
|
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { CheckboxSpec, FieldSpec } from "$lib/registry-schema";
|
import type { CheckboxSpec } from "$lib/registry-schema";
|
||||||
import Control from "./Control.svelte";
|
import Control from "./Control.svelte";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
label: string;
|
label: string;
|
||||||
value: unknown;
|
value: unknown;
|
||||||
spec: FieldSpec;
|
spec: CheckboxSpec;
|
||||||
onchange?: (value: boolean) => void;
|
onchange?: (value: boolean) => void;
|
||||||
}
|
}
|
||||||
let { label, value, spec, onchange }: Props = $props();
|
let { label, value, spec, onchange }: Props = $props();
|
||||||
|
|
||||||
const sp = $derived(spec as CheckboxSpec);
|
const sp = $derived(spec);
|
||||||
const current = $derived(
|
const current = $derived(
|
||||||
typeof value === "boolean" ? value : Boolean(sp.default),
|
typeof value === "boolean" ? value : Boolean(sp.default),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { ColorSpec, FieldSpec } from "$lib/registry-schema";
|
import type { ColorSpec } from "$lib/registry-schema";
|
||||||
import ColorSwatchInput from "./ColorSwatchInput.svelte";
|
import ColorSwatchInput from "./ColorSwatchInput.svelte";
|
||||||
import Control from "./Control.svelte";
|
import Control from "./Control.svelte";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
label: string;
|
label: string;
|
||||||
value: unknown;
|
value: unknown;
|
||||||
spec: FieldSpec;
|
spec: ColorSpec;
|
||||||
onchange?: (value: string) => void;
|
onchange?: (value: string) => void;
|
||||||
}
|
}
|
||||||
let { label, value, spec, onchange }: Props = $props();
|
let { label, value, spec, onchange }: Props = $props();
|
||||||
|
|
||||||
const sp = $derived(spec as ColorSpec);
|
const sp = $derived(spec);
|
||||||
const current = $derived(typeof value === "string" ? value : sp.default);
|
const current = $derived(typeof value === "string" ? value : sp.default);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -1,22 +1,18 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { t } from "$lib/i18n/t";
|
import { t } from "$lib/i18n/t";
|
||||||
import type {
|
import type { ColorPair, ColorPairSpec } from "$lib/registry-schema";
|
||||||
ColorPair,
|
|
||||||
ColorPairSpec,
|
|
||||||
FieldSpec,
|
|
||||||
} from "$lib/registry-schema";
|
|
||||||
import ColorSwatchInput from "./ColorSwatchInput.svelte";
|
import ColorSwatchInput from "./ColorSwatchInput.svelte";
|
||||||
import Control from "./Control.svelte";
|
import Control from "./Control.svelte";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
label: string;
|
label: string;
|
||||||
value: unknown;
|
value: unknown;
|
||||||
spec: FieldSpec;
|
spec: ColorPairSpec;
|
||||||
onchange?: (value: ColorPair) => void;
|
onchange?: (value: ColorPair) => void;
|
||||||
}
|
}
|
||||||
let { label, value, spec, onchange }: Props = $props();
|
let { label, value, spec, onchange }: Props = $props();
|
||||||
|
|
||||||
const sp = $derived(spec as ColorPairSpec);
|
const sp = $derived(spec);
|
||||||
const current = $derived.by(() => {
|
const current = $derived.by(() => {
|
||||||
const v = value as Partial<ColorPair> | undefined;
|
const v = value as Partial<ColorPair> | undefined;
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -3,22 +3,18 @@
|
|||||||
import Button from "$lib/components/ui/Button.svelte";
|
import Button from "$lib/components/ui/Button.svelte";
|
||||||
import IconButton from "$lib/components/ui/IconButton.svelte";
|
import IconButton from "$lib/components/ui/IconButton.svelte";
|
||||||
import { t } from "$lib/i18n/t";
|
import { t } from "$lib/i18n/t";
|
||||||
import type {
|
import type { ColorList, ColorListSpec } from "$lib/registry-schema";
|
||||||
ColorList,
|
|
||||||
ColorListSpec,
|
|
||||||
FieldSpec,
|
|
||||||
} from "$lib/registry-schema";
|
|
||||||
import Control from "./Control.svelte";
|
import Control from "./Control.svelte";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
label: string;
|
label: string;
|
||||||
value: unknown;
|
value: unknown;
|
||||||
spec: FieldSpec;
|
spec: ColorListSpec;
|
||||||
onchange?: (value: ColorList) => void;
|
onchange?: (value: ColorList) => void;
|
||||||
}
|
}
|
||||||
let { label, value, spec, onchange }: Props = $props();
|
let { label, value, spec, onchange }: Props = $props();
|
||||||
|
|
||||||
const sp = $derived(spec as ColorListSpec);
|
const sp = $derived(spec);
|
||||||
const current = $derived.by((): ColorList => {
|
const current = $derived.by((): ColorList => {
|
||||||
if (Array.isArray(value)) {
|
if (Array.isArray(value)) {
|
||||||
const valid = value.filter(
|
const valid = value.filter(
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
SIZE_PRESETS,
|
SIZE_PRESETS,
|
||||||
type Dimension,
|
type Dimension,
|
||||||
type DimensionSpec,
|
type DimensionSpec,
|
||||||
type FieldSpec,
|
|
||||||
} from "$lib/registry-schema";
|
} from "$lib/registry-schema";
|
||||||
import ChipButton from "$lib/components/ui/ChipButton.svelte";
|
import ChipButton from "$lib/components/ui/ChipButton.svelte";
|
||||||
import Control from "./Control.svelte";
|
import Control from "./Control.svelte";
|
||||||
@@ -12,7 +11,7 @@
|
|||||||
interface Props {
|
interface Props {
|
||||||
label: string;
|
label: string;
|
||||||
value: unknown;
|
value: unknown;
|
||||||
spec: FieldSpec;
|
spec: DimensionSpec;
|
||||||
/** Step input dimensions: axis cap for maxFromSource fields. */
|
/** Step input dimensions: axis cap for maxFromSource fields. */
|
||||||
sourceDims?: Dimension;
|
sourceDims?: Dimension;
|
||||||
onchange?: (value: Dimension, axis?: "width" | "height" | "both") => void;
|
onchange?: (value: Dimension, axis?: "width" | "height" | "both") => void;
|
||||||
@@ -25,7 +24,7 @@
|
|||||||
onchange,
|
onchange,
|
||||||
}: Props = $props();
|
}: Props = $props();
|
||||||
|
|
||||||
const sp = $derived(spec as DimensionSpec);
|
const sp = $derived(spec);
|
||||||
const maxW = $derived(
|
const maxW = $derived(
|
||||||
sp.maxFromSource && sourceDims ? sourceDims.width : sp.max,
|
sp.maxFromSource && sourceDims ? sourceDims.width : sp.max,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,23 +1,19 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { t } from "$lib/i18n/t";
|
import { t } from "$lib/i18n/t";
|
||||||
import type { TextFont } from "$lib/core/domText";
|
import type { TextFont } from "$lib/core/domText";
|
||||||
import type {
|
import type { FontStyle, FontStyleSpec } from "$lib/registry-schema";
|
||||||
FieldSpec,
|
|
||||||
FontStyle,
|
|
||||||
FontStyleSpec,
|
|
||||||
} from "$lib/registry-schema";
|
|
||||||
import ColorSwatchInput from "./ColorSwatchInput.svelte";
|
import ColorSwatchInput from "./ColorSwatchInput.svelte";
|
||||||
import Control from "./Control.svelte";
|
import Control from "./Control.svelte";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
label: string;
|
label: string;
|
||||||
value: unknown;
|
value: unknown;
|
||||||
spec: FieldSpec;
|
spec: FontStyleSpec;
|
||||||
onchange?: (value: FontStyle) => void;
|
onchange?: (value: FontStyle) => void;
|
||||||
}
|
}
|
||||||
let { label, value, spec, onchange }: Props = $props();
|
let { label, value, spec, onchange }: Props = $props();
|
||||||
|
|
||||||
const sp = $derived(spec as FontStyleSpec);
|
const sp = $derived(spec);
|
||||||
const current = $derived.by(() => {
|
const current = $derived.by(() => {
|
||||||
const v = value as Partial<FontStyle> | undefined;
|
const v = value as Partial<FontStyle> | undefined;
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -3,17 +3,17 @@
|
|||||||
import ColorSwatchInput from "./ColorSwatchInput.svelte";
|
import ColorSwatchInput from "./ColorSwatchInput.svelte";
|
||||||
import Control from "./Control.svelte";
|
import Control from "./Control.svelte";
|
||||||
import { t } from "$lib/i18n/t";
|
import { t } from "$lib/i18n/t";
|
||||||
import type { FieldSpec, Gradient, GradientSpec } from "$lib/registry-schema";
|
import type { Gradient, GradientSpec } from "$lib/registry-schema";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
label: string;
|
label: string;
|
||||||
value: unknown;
|
value: unknown;
|
||||||
spec: FieldSpec;
|
spec: GradientSpec;
|
||||||
onchange?: (value: Gradient) => void;
|
onchange?: (value: Gradient) => void;
|
||||||
}
|
}
|
||||||
let { label, value, spec, onchange }: Props = $props();
|
let { label, value, spec, onchange }: Props = $props();
|
||||||
|
|
||||||
const sp = $derived(spec as GradientSpec);
|
const sp = $derived(spec);
|
||||||
const current = $derived.by(() => {
|
const current = $derived.by(() => {
|
||||||
const v = value as Partial<Gradient> | undefined;
|
const v = value as Partial<Gradient> | undefined;
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { FieldSpec, Offset, OffsetSpec } from "$lib/registry-schema";
|
import type { Offset, OffsetSpec } from "$lib/registry-schema";
|
||||||
import Control from "./Control.svelte";
|
import Control from "./Control.svelte";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
label: string;
|
label: string;
|
||||||
value: unknown;
|
value: unknown;
|
||||||
spec: FieldSpec;
|
spec: OffsetSpec;
|
||||||
onchange?: (value: Offset) => void;
|
onchange?: (value: Offset) => void;
|
||||||
}
|
}
|
||||||
let { label, value, spec, onchange }: Props = $props();
|
let { label, value, spec, onchange }: Props = $props();
|
||||||
|
|
||||||
const sp = $derived(spec as OffsetSpec);
|
const sp = $derived(spec);
|
||||||
const current = $derived.by(() => {
|
const current = $derived.by(() => {
|
||||||
const v = value as Partial<Offset> | undefined;
|
const v = value as Partial<Offset> | undefined;
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { t } from "$lib/i18n/t";
|
import { t } from "$lib/i18n/t";
|
||||||
import type { FieldSpec, Plate, PlateSpec } from "$lib/registry-schema";
|
import type { Plate, PlateSpec } from "$lib/registry-schema";
|
||||||
import ColorSwatchInput from "./ColorSwatchInput.svelte";
|
import ColorSwatchInput from "./ColorSwatchInput.svelte";
|
||||||
import Control from "./Control.svelte";
|
import Control from "./Control.svelte";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
label: string;
|
label: string;
|
||||||
value: unknown;
|
value: unknown;
|
||||||
spec: FieldSpec;
|
spec: PlateSpec;
|
||||||
onchange?: (value: Plate) => void;
|
onchange?: (value: Plate) => void;
|
||||||
}
|
}
|
||||||
let { label, value, spec, onchange }: Props = $props();
|
let { label, value, spec, onchange }: Props = $props();
|
||||||
|
|
||||||
const sp = $derived(spec as PlateSpec);
|
const sp = $derived(spec);
|
||||||
const current = $derived.by(() => {
|
const current = $derived.by(() => {
|
||||||
const v = value as Partial<Plate> | undefined;
|
const v = value as Partial<Plate> | undefined;
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -1,21 +1,17 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { Position9 } from "$lib/core/textdraw";
|
import type { Position9 } from "$lib/core/textdraw";
|
||||||
import {
|
import { POSITION9_VALUES, type Position9Spec } from "$lib/registry-schema";
|
||||||
POSITION9_VALUES,
|
|
||||||
type FieldSpec,
|
|
||||||
type Position9Spec,
|
|
||||||
} from "$lib/registry-schema";
|
|
||||||
import Control from "./Control.svelte";
|
import Control from "./Control.svelte";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
label: string;
|
label: string;
|
||||||
value: unknown;
|
value: unknown;
|
||||||
spec: FieldSpec;
|
spec: Position9Spec;
|
||||||
onchange?: (value: Position9) => void;
|
onchange?: (value: Position9) => void;
|
||||||
}
|
}
|
||||||
let { label, value, spec, onchange }: Props = $props();
|
let { label, value, spec, onchange }: Props = $props();
|
||||||
|
|
||||||
const sp = $derived(spec as Position9Spec);
|
const sp = $derived(spec);
|
||||||
const current = $derived(
|
const current = $derived(
|
||||||
typeof value === "string" &&
|
typeof value === "string" &&
|
||||||
(POSITION9_VALUES as readonly string[]).includes(value)
|
(POSITION9_VALUES as readonly string[]).includes(value)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { FieldSpec, NumberSpec, SliderSpec } from "$lib/registry-schema";
|
import type { NumberSpec, SliderSpec } from "$lib/registry-schema";
|
||||||
import { t } from "$lib/i18n/t";
|
import { t } from "$lib/i18n/t";
|
||||||
import { Minus, Plus, RotateCcw } from "@lucide/svelte";
|
import { Minus, Plus, RotateCcw } from "@lucide/svelte";
|
||||||
import IconButton from "$lib/components/ui/IconButton.svelte";
|
import IconButton from "$lib/components/ui/IconButton.svelte";
|
||||||
@@ -8,12 +8,12 @@
|
|||||||
interface Props {
|
interface Props {
|
||||||
label: string;
|
label: string;
|
||||||
value: unknown;
|
value: unknown;
|
||||||
spec: FieldSpec;
|
spec: NumberSpec | SliderSpec;
|
||||||
onchange?: (value: number) => void;
|
onchange?: (value: number) => void;
|
||||||
}
|
}
|
||||||
let { label, value, spec, onchange }: Props = $props();
|
let { label, value, spec, onchange }: Props = $props();
|
||||||
|
|
||||||
const sp = $derived(spec as NumberSpec | SliderSpec);
|
const sp = $derived(spec);
|
||||||
const min = $derived(sp.min ?? 0);
|
const min = $derived(sp.min ?? 0);
|
||||||
const max = $derived(sp.max ?? 100);
|
const max = $derived(sp.max ?? 100);
|
||||||
const step = $derived(sp.step ?? 1);
|
const step = $derived(sp.step ?? 1);
|
||||||
|
|||||||
@@ -2,19 +2,19 @@
|
|||||||
import Control from "./Control.svelte";
|
import Control from "./Control.svelte";
|
||||||
import Segmented from "$lib/components/ui/Segmented.svelte";
|
import Segmented from "$lib/components/ui/Segmented.svelte";
|
||||||
import { optionLabel } from "$lib/i18n/schema-tool-strings";
|
import { optionLabel } from "$lib/i18n/schema-tool-strings";
|
||||||
import type { FieldSpec, SegmentedSpec } from "$lib/registry-schema";
|
import type { SegmentedSpec } from "$lib/registry-schema";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
label: string;
|
label: string;
|
||||||
value: unknown;
|
value: unknown;
|
||||||
spec: FieldSpec;
|
spec: SegmentedSpec;
|
||||||
toolId: string;
|
toolId: string;
|
||||||
fieldId: string;
|
fieldId: string;
|
||||||
onchange?: (value: string) => void;
|
onchange?: (value: string) => void;
|
||||||
}
|
}
|
||||||
let { label, value, spec, toolId, fieldId, onchange }: Props = $props();
|
let { label, value, spec, toolId, fieldId, onchange }: Props = $props();
|
||||||
|
|
||||||
const sp = $derived(spec as SegmentedSpec);
|
const sp = $derived(spec);
|
||||||
const current = $derived(
|
const current = $derived(
|
||||||
typeof value === "string" && sp.options.some((o) => o.value === value)
|
typeof value === "string" && sp.options.some((o) => o.value === value)
|
||||||
? value
|
? value
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { optionLabel } from "$lib/i18n/schema-tool-strings";
|
import { optionLabel } from "$lib/i18n/schema-tool-strings";
|
||||||
import type { FieldSpec, SelectSpec } from "$lib/registry-schema";
|
import type { SelectSpec } from "$lib/registry-schema";
|
||||||
import Control from "./Control.svelte";
|
import Control from "./Control.svelte";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
label: string;
|
label: string;
|
||||||
value: unknown;
|
value: unknown;
|
||||||
spec: FieldSpec;
|
spec: SelectSpec;
|
||||||
toolId: string;
|
toolId: string;
|
||||||
fieldId: string;
|
fieldId: string;
|
||||||
onchange?: (value: string) => void;
|
onchange?: (value: string) => void;
|
||||||
}
|
}
|
||||||
let { label, value, spec, toolId, fieldId, onchange }: Props = $props();
|
let { label, value, spec, toolId, fieldId, onchange }: Props = $props();
|
||||||
|
|
||||||
const sp = $derived(spec as SelectSpec);
|
const sp = $derived(spec);
|
||||||
const current = $derived(
|
const current = $derived(
|
||||||
typeof value === "string" && sp.options.some((o) => o.value === value)
|
typeof value === "string" && sp.options.some((o) => o.value === value)
|
||||||
? value
|
? value
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { FieldSpec, TextSpec } from "$lib/registry-schema";
|
import type { TextSpec } from "$lib/registry-schema";
|
||||||
import Control from "./Control.svelte";
|
import Control from "./Control.svelte";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
label: string;
|
label: string;
|
||||||
value: unknown;
|
value: unknown;
|
||||||
spec: FieldSpec;
|
spec: TextSpec;
|
||||||
onchange?: (value: string) => void;
|
onchange?: (value: string) => void;
|
||||||
}
|
}
|
||||||
let { label, value, spec, onchange }: Props = $props();
|
let { label, value, spec, onchange }: Props = $props();
|
||||||
|
|
||||||
const sp = $derived(spec as TextSpec);
|
const sp = $derived(spec);
|
||||||
const current = $derived(typeof value === "string" ? value : sp.default);
|
const current = $derived(typeof value === "string" ? value : sp.default);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,23 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type {
|
import type {
|
||||||
|
CheckboxSpec,
|
||||||
|
ColorListSpec,
|
||||||
|
ColorPairSpec,
|
||||||
|
ColorSpec,
|
||||||
Dimension,
|
Dimension,
|
||||||
|
DimensionSpec,
|
||||||
FieldSpec,
|
FieldSpec,
|
||||||
FieldSpecKind,
|
FieldSpecKind,
|
||||||
|
FontStyleSpec,
|
||||||
|
GradientSpec,
|
||||||
|
NumberSpec,
|
||||||
|
OffsetSpec,
|
||||||
|
PlateSpec,
|
||||||
|
Position9Spec,
|
||||||
|
SegmentedSpec,
|
||||||
|
SelectSpec,
|
||||||
|
SliderSpec,
|
||||||
|
TextSpec,
|
||||||
ToolSchema,
|
ToolSchema,
|
||||||
} from "$lib/registry-schema";
|
} from "$lib/registry-schema";
|
||||||
import { effectiveMax, resolveLayoutGroups } from "$lib/registry-schema";
|
import { effectiveMax, resolveLayoutGroups } from "$lib/registry-schema";
|
||||||
@@ -36,22 +51,34 @@
|
|||||||
onchange?: (value: unknown, axis?: "width" | "height" | "both") => void;
|
onchange?: (value: unknown, axis?: "width" | "height" | "both") => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The kind key of FIELDS guarantees the spec subtype at runtime (fieldSpecs
|
||||||
|
// map in registry-schema); the cast lives once here, so each control
|
||||||
|
// declares its exact spec type instead of casting internally.
|
||||||
|
type ControlFor<S extends FieldSpec> = Component<
|
||||||
|
Omit<FieldControlProps, "spec"> & { spec: S }
|
||||||
|
>;
|
||||||
|
function controlFor<S extends FieldSpec>(
|
||||||
|
c: ControlFor<S>,
|
||||||
|
): Component<FieldControlProps> {
|
||||||
|
return c as unknown as Component<FieldControlProps>;
|
||||||
|
}
|
||||||
|
|
||||||
const FIELDS: Record<FieldSpecKind, Component<FieldControlProps>> = {
|
const FIELDS: Record<FieldSpecKind, Component<FieldControlProps>> = {
|
||||||
number: RangeControl,
|
number: controlFor<NumberSpec | SliderSpec>(RangeControl),
|
||||||
slider: RangeControl,
|
slider: controlFor<NumberSpec | SliderSpec>(RangeControl),
|
||||||
color: ColorControl,
|
color: controlFor<ColorSpec>(ColorControl),
|
||||||
"color-pair": ColorPairControl,
|
"color-pair": controlFor<ColorPairSpec>(ColorPairControl),
|
||||||
colors: ColorsControl,
|
colors: controlFor<ColorListSpec>(ColorsControl),
|
||||||
select: SelectControl,
|
select: controlFor<SelectSpec>(SelectControl),
|
||||||
segmented: SegmentedControl,
|
segmented: controlFor<SegmentedSpec>(SegmentedControl),
|
||||||
checkbox: CheckboxControl,
|
checkbox: controlFor<CheckboxSpec>(CheckboxControl),
|
||||||
text: TextControl,
|
text: controlFor<TextSpec>(TextControl),
|
||||||
dimension: DimensionField,
|
dimension: controlFor<DimensionSpec>(DimensionField),
|
||||||
offset: OffsetControl,
|
offset: controlFor<OffsetSpec>(OffsetControl),
|
||||||
position9: PositionControl,
|
position9: controlFor<Position9Spec>(PositionControl),
|
||||||
"font-style": FontStyleControl,
|
"font-style": controlFor<FontStyleSpec>(FontStyleControl),
|
||||||
plate: PlateControl,
|
plate: controlFor<PlateSpec>(PlateControl),
|
||||||
gradient: GradientControl,
|
gradient: controlFor<GradientSpec>(GradientControl),
|
||||||
};
|
};
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
|
|||||||
@@ -42,7 +42,6 @@
|
|||||||
applySourceDefaults,
|
applySourceDefaults,
|
||||||
clampSourceAwareMaxes,
|
clampSourceAwareMaxes,
|
||||||
sanitizeSchemaParams,
|
sanitizeSchemaParams,
|
||||||
type ToolSchema,
|
|
||||||
} from "$lib/registry-schema";
|
} from "$lib/registry-schema";
|
||||||
import { onMount } from "svelte";
|
import { onMount } from "svelte";
|
||||||
import { SvelteSet } from "svelte/reactivity";
|
import { SvelteSet } from "svelte/reactivity";
|
||||||
@@ -65,9 +64,7 @@
|
|||||||
}
|
}
|
||||||
let { page, tool, chainId = undefined }: Props = $props();
|
let { page, tool, chainId = undefined }: Props = $props();
|
||||||
|
|
||||||
const schema = $derived(
|
const schema = $derived(tool.schema);
|
||||||
tool.schema as ToolSchema<Record<string, unknown>> | undefined,
|
|
||||||
);
|
|
||||||
|
|
||||||
const inputMode = $derived(tool.input);
|
const inputMode = $derived(tool.input);
|
||||||
|
|
||||||
@@ -471,14 +468,17 @@
|
|||||||
onadd={(id) => replaceStepTool(i, id)}
|
onadd={(id) => replaceStepTool(i, id)}
|
||||||
/>
|
/>
|
||||||
{/snippet}
|
{/snippet}
|
||||||
|
{@const stepSchema = toolSchemaOf(step)}
|
||||||
|
{#if stepSchema}
|
||||||
<SchemaFields
|
<SchemaFields
|
||||||
schema={toolSchemaOf(step)}
|
schema={stepSchema}
|
||||||
values={step.params}
|
values={step.params}
|
||||||
toolId={step.id}
|
toolId={step.id}
|
||||||
sourceDims={i === 0 ? (source ?? undefined) : stepDims[i - 1]}
|
sourceDims={i === 0 ? (source ?? undefined) : stepDims[i - 1]}
|
||||||
onchange={(id, v, axis) => setStepValue(i, id, v, axis)}
|
onchange={(id, v, axis) => setStepValue(i, id, v, axis)}
|
||||||
onreset={() => resetStep(i)}
|
onreset={() => resetStep(i)}
|
||||||
/>
|
/>
|
||||||
|
{/if}
|
||||||
</StepCard>
|
</StepCard>
|
||||||
{/snippet}
|
{/snippet}
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import {
|
|||||||
defaultSchemaParams,
|
defaultSchemaParams,
|
||||||
withAspectLock,
|
withAspectLock,
|
||||||
type Dimension,
|
type Dimension,
|
||||||
type ToolSchema,
|
|
||||||
} from "$lib/registry-schema";
|
} from "$lib/registry-schema";
|
||||||
import { SvelteMap, SvelteSet } from "svelte/reactivity";
|
import { SvelteMap, SvelteSet } from "svelte/reactivity";
|
||||||
|
|
||||||
@@ -28,7 +27,7 @@ interface StepsState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function toolSchemaOf(step: ChainStep) {
|
export function toolSchemaOf(step: ChainStep) {
|
||||||
return getTool(step.id)?.schema as ToolSchema<Record<string, unknown>>;
|
return getTool(step.id)?.schema;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setStepValue(
|
function setStepValue(
|
||||||
@@ -79,7 +78,8 @@ function setStepValue(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const clamped = dims ? clampSourceAwareMaxes(stepSchema, next, dims) : next;
|
const clamped =
|
||||||
|
dims && stepSchema ? clampSourceAwareMaxes(stepSchema, next, dims) : next;
|
||||||
s.steps = s.steps.with(index, { ...step, params: clamped });
|
s.steps = s.steps.with(index, { ...step, params: clamped });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,8 @@ type PendingRequest = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
function defaultWorkerFactory(): WorkerLike {
|
function defaultWorkerFactory(): WorkerLike {
|
||||||
|
// Worker's onerror is typed with ErrorEvent while WorkerLike expects Event;
|
||||||
|
// the DOM lib types are incompatible, hence the double cast.
|
||||||
return new Worker(new URL("./executor.worker.ts", import.meta.url), {
|
return new Worker(new URL("./executor.worker.ts", import.meta.url), {
|
||||||
type: "module",
|
type: "module",
|
||||||
}) as unknown as WorkerLike;
|
}) as unknown as WorkerLike;
|
||||||
|
|||||||
Reference in New Issue
Block a user