Releases: lawvs/fn-sphere
Releases · lawvs/fn-sphere
@fn-sphere/filter@1.3.0
@fn-sphere/core@1.3.0
@fn-sphere/filter@1.2.0
Minor Changes
4f62a4bThanks @lawvs! - Add ErrorBoundary component- Added
ErrorBoundarycomponent to the theme components for handling rendering errors in filter UI ErrorBoundarywrapsFilterGroupContainerandSingleFilterContainerto catch and handle errors gracefully- Provides delete functionality to remove error-causing filter rules or groups via
onDeletecallback - Displays user-friendly error fallback UI with error message and delete button
- Added
Patch Changes
@fn-sphere/core@1.2.0
Minor Changes
604b283Thanks @lawvs! - Add error handling support to filter predicates- Added
fallbackValueparameter to control behavior when filter rules are not available or errors occur (defaults totrue) - Added
errorHandlingoption withcatchErrorandlogErrorproperties for configurable error handling (defaults to{ catchError: true, logError: true }) - Renamed
createFilterPredicatetocreateUnsafeFilterPredicate(internal use) - New
createFilterPredicatenow safely handles errors by default - When
fallbackValueistrue, items are included in filtered results on error; whenfalse, items are excluded
- Added
@fn-sphere/filter@1.1.0
Minor Changes
- #185
7a93fcdThanks @lawvs! - Add support for Zod enum types in filter predicates and UI components.- Added
enumEqualsandenumNotEqualfilter functions for enum types - Extended
containsandnotContainsfunctions to work withz.enum()schemas - Added enum and enum array data input views for selecting enum values in the filter UI
- Enum filters are defined separately due to runtime type indistinguishability from strings
- Added
Patch Changes
- Updated dependencies [
7a93fcd]:- @fn-sphere/core@1.1.0
@fn-sphere/core@1.1.0
Minor Changes
- #185
7a93fcdThanks @lawvs! - Add support for Zod enum types in filter predicates and UI components.- Added
enumEqualsandenumNotEqualfilter functions for enum types - Extended
containsandnotContainsfunctions to work withz.enum()schemas - Added enum and enum array data input views for selecting enum values in the filter UI
- Enum filters are defined separately due to runtime type indistinguishability from strings
- Added
@fn-sphere/filter@1.0.0
Major Changes
-
15f2755Thanks @lawvs! - ## Migrate to Zod 4- Upgrade all filtering utilities to Zod 4, adopting the new
z.function({ input, output })factory. - Update tests, docs, and playground examples to reflect the revised function schema API.
- Surface tuple-based parameter metadata so filter UIs can materialise runtime validators without accessing private internals.
- Prepare downstream apps for the breaking changes required when upgrading filter definitions to Zod 4.
Migration guide
- Make sure your project is already on Zod 4 before consuming this release. Review the upstream changes at https://zod.dev/v4/changelog to plan any schema updates.
- Replace every
z.function().args(...).returns(...)with the new factory signature.
const equals = defineTypedFn({ name: "equals", - define: z.function().args(z.string(), z.string()).returns(z.boolean()), + define: z.function({ input: [z.string(), z.string()], output: z.boolean() }), implement: (value, target) => value === target, });getParametersExceptFirstnow returns a$ZodTuplerather than a plain array. Usetuple._zod.def.itemswhen you need to inspect or parse arguments at runtime.DataInputViewProps/DataInputViewSpecconsume tuple schemas instead of loose arrays:
// Before type DataInputViewProps = { rule: SingleFilter; requiredDataSchema: [] | [z.ZodTypeAny, ...z.ZodTypeAny[]]; updateInput: (...input: unknown[]) => void; }; type DataInputViewSpec = { name: string; match: | [] | [z.ZodTypeAny, ...z.ZodTypeAny[]] | (( parameterSchemas: [] | [z.ZodTypeAny, ...z.ZodTypeAny[]], fieldSchema?: z.ZodTypeAny, ) => boolean); view: ComponentType<DataInputViewProps>; }; // After type DataInputViewProps = { rule: SingleFilter; requiredDataSchema: $ZodTuple; updateInput: (...input: unknown[]) => void; }; type DataInputViewSpec = { name: string; match: | [] | [$ZodType, ...$ZodType[]] | $ZodTuple | ((parameterSchemas: $ZodTuple, fieldSchema?: $ZodType) => boolean); view: ComponentType<DataInputViewProps>; };
- Update all usages of
DataInputViewSpec.matchto handle the new tuple schema.
const literalUnionView: DataInputViewSpec = { name: "literal union", match: (parameterSchemas) => { - if (parameterSchemas.length !== 1) { + if (parameterSchemas._zod.def.items.length !== 1) { return false; } - const [item] = parameterSchemas; - const isUnion = item instanceof z.ZodUnion; + const theOnlyItem = parameterSchemas._zod.def.items.at(0); + const schemaDef = (theOnlyItem as $ZodTypes)._zod.def; + const isUnion = schemaDef.type === "union"; if (!isUnion) { return false; } - return item.options.every( - (option: unknown) => option instanceof z.ZodLiteral, + return schemaDef.options.every( + (option) => option._zod.def.type === "literal", + ); }, view: function View({ requiredDataSchema, rule, updateInput }) { const { Select } = useView("components"); const { getLocaleText } = useRootRule(); const options = useMemo(() => { - const unionSchema = requiredDataSchema[0] as z.ZodUnion< - [z.ZodLiteral<z.Primitive>] - >; + const unionSchema = requiredDataSchema._zod.def.items[0] as $ZodUnion< + $ZodLiteral[] + >; - return unionSchema.options.map((item: z.ZodLiteral<z.Primitive>) => ({ + return unionSchema._zod.def.options.map((item) => { const value = item._zod.def.values[0]; const meta = z.globalRegistry.get(item); const metaDesc = meta && meta.description ? meta.description : undefined; return { label: getLocaleText(metaDesc ?? String(value)), value, }; }); }, [getLocaleText, requiredDataSchema]); return ( <Select options={options} value={rule.args[0]} onChange={(value) => { updateInput(value); }} /> ); }, } - Upgrade all filtering utilities to Zod 4, adopting the new
Patch Changes
- Updated dependencies [
15f2755]:- @fn-sphere/core@1.0.0
@fn-sphere/core@1.0.0
Major Changes
-
15f2755Thanks @lawvs! - ## Migrate to Zod 4- Upgrade all filtering utilities to Zod 4, adopting the new
z.function({ input, output })factory. - Update tests, docs, and playground examples to reflect the revised function schema API.
- Surface tuple-based parameter metadata so filter UIs can materialise runtime validators without accessing private internals.
- Prepare downstream apps for the breaking changes required when upgrading filter definitions to Zod 4.
Migration guide
- Make sure your project is already on Zod 4 before consuming this release. Review the upstream changes at https://zod.dev/v4/changelog to plan any schema updates.
- Replace every
z.function().args(...).returns(...)with the new factory signature.
const equals = defineTypedFn({ name: "equals", - define: z.function().args(z.string(), z.string()).returns(z.boolean()), + define: z.function({ input: [z.string(), z.string()], output: z.boolean() }), implement: (value, target) => value === target, });getParametersExceptFirstnow returns a$ZodTuplerather than a plain array. Usetuple._zod.def.itemswhen you need to inspect or parse arguments at runtime.DataInputViewProps/DataInputViewSpecconsume tuple schemas instead of loose arrays:
// Before type DataInputViewProps = { rule: SingleFilter; requiredDataSchema: [] | [z.ZodTypeAny, ...z.ZodTypeAny[]]; updateInput: (...input: unknown[]) => void; }; type DataInputViewSpec = { name: string; match: | [] | [z.ZodTypeAny, ...z.ZodTypeAny[]] | (( parameterSchemas: [] | [z.ZodTypeAny, ...z.ZodTypeAny[]], fieldSchema?: z.ZodTypeAny, ) => boolean); view: ComponentType<DataInputViewProps>; }; // After type DataInputViewProps = { rule: SingleFilter; requiredDataSchema: $ZodTuple; updateInput: (...input: unknown[]) => void; }; type DataInputViewSpec = { name: string; match: | [] | [$ZodType, ...$ZodType[]] | $ZodTuple | ((parameterSchemas: $ZodTuple, fieldSchema?: $ZodType) => boolean); view: ComponentType<DataInputViewProps>; };
- Update all usages of
DataInputViewSpec.matchto handle the new tuple schema.
const literalUnionView: DataInputViewSpec = { name: "literal union", match: (parameterSchemas) => { - if (parameterSchemas.length !== 1) { + if (parameterSchemas._zod.def.items.length !== 1) { return false; } - const [item] = parameterSchemas; - const isUnion = item instanceof z.ZodUnion; + const theOnlyItem = parameterSchemas._zod.def.items.at(0); + const schemaDef = (theOnlyItem as $ZodTypes)._zod.def; + const isUnion = schemaDef.type === "union"; if (!isUnion) { return false; } - return item.options.every( - (option: unknown) => option instanceof z.ZodLiteral, + return schemaDef.options.every( + (option) => option._zod.def.type === "literal", + ); }, view: function View({ requiredDataSchema, rule, updateInput }) { const { Select } = useView("components"); const { getLocaleText } = useRootRule(); const options = useMemo(() => { - const unionSchema = requiredDataSchema[0] as z.ZodUnion< - [z.ZodLiteral<z.Primitive>] - >; + const unionSchema = requiredDataSchema._zod.def.items[0] as $ZodUnion< + $ZodLiteral[] + >; - return unionSchema.options.map((item: z.ZodLiteral<z.Primitive>) => ({ + return unionSchema._zod.def.options.map((item) => { const value = item._zod.def.values[0]; const meta = z.globalRegistry.get(item); const metaDesc = meta && meta.description ? meta.description : undefined; return { label: getLocaleText(metaDesc ?? String(value)), value, }; }); }, [getLocaleText, requiredDataSchema]); return ( <Select options={options} value={rule.args[0]} onChange={(value) => { updateInput(value); }} /> ); }, } - Upgrade all filtering utilities to Zod 4, adopting the new
@fn-sphere/theme-mui-material@0.1.3
@fn-sphere/filter@0.8.0
Minor Changes
-
a915a9aThanks @lawvs! - feat(filter)!: retain args by default when filter changes via tryRetainArgs- BREAKING: FieldSelect and FilterSelect now default
tryRetainArgs(andtryRetainFilterfor fields) totrue. Previously, leaving these props undefined defaulted to resettingargs. To restore the old behavior, explicitly passtryRetainArgs={false}(and/ortryRetainFilter={false}). - When switching filters within the same field, if the new filter's parameter schema is compatible, existing
argsare preserved. - Data input "literal union" options are memoized for stability.
This change improves UX by avoiding unnecessary argument resets when changing a filter, while still allowing users to opt out.
- BREAKING: FieldSelect and FilterSelect now default