New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@tanstack/form-core

Package Overview
Dependencies
Maintainers
2
Versions
129
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@tanstack/form-core - npm Package Compare versions

Comparing version 0.11.0 to 0.12.0

dist/cjs/FieldApi.d.ts

37

package.json
{
"name": "@tanstack/form-core",
"version": "0.11.0",
"version": "0.12.0",
"description": "Powerful, type-safe, framework agnostic forms.",

@@ -14,14 +14,14 @@ "author": "tannerlinsley",

"type": "module",
"types": "build/legacy/index.d.ts",
"main": "build/legacy/index.cjs",
"module": "build/legacy/index.js",
"types": "dist/mjs/index.d.mts",
"main": "dist/cjs/index.cjs",
"module": "dist/mjs/index.mjs",
"exports": {
".": {
"import": {
"types": "./build/modern/index.d.ts",
"default": "./build/modern/index.js"
"types": "./dist/mjs/index.d.mts",
"default": "./dist/mjs/index.mjs"
},
"require": {
"types": "./build/modern/index.d.cts",
"default": "./build/modern/index.cjs"
"types": "./dist/cjs/index.d.cts",
"default": "./dist/cjs/index.cjs"
}

@@ -33,14 +33,5 @@ },

"files": [
"build",
"dist",
"src"
],
"nx": {
"targets": {
"test:build": {
"dependsOn": [
"build"
]
}
}
},
"dependencies": {

@@ -50,10 +41,14 @@ "@tanstack/store": "0.1.3"

"scripts": {
"clean": "rimraf ./build && rimraf ./coverage",
"clean": "rimraf ./dist && rimraf ./coverage",
"test:eslint": "eslint --ext .ts,.tsx ./src",
"test:types": "tsc --noEmit && vitest typecheck",
"test:types:versions49": "../../node_modules/typescript49/bin/tsc --noEmit",
"test:types:versions50": "../../node_modules/typescript50/bin/tsc --noEmit",
"test:types:versions51": "../../node_modules/typescript51/bin/tsc --noEmit",
"test:types:versions52": "tsc --noEmit",
"test:types": "pnpm run \"/^test:types:versions.*/\" && vitest typecheck",
"test:lib": "vitest run --coverage",
"test:lib:dev": "pnpm run test:lib --watch",
"test:build": "publint --strict",
"build": "tsup"
"build": "vite build"
}
}

@@ -48,12 +48,18 @@ import { Store } from '@tanstack/store'

: TFormValidator extends Validator<TParentData, infer FFN>
?
| FFN
| FieldValidateFn<
TParentData,
TName,
TFieldValidator,
TFormValidator,
TData
>
: FieldValidateFn<TParentData, TName, TFieldValidator, TFormValidator, TData>
?
| FFN
| FieldValidateFn<
TParentData,
TName,
TFieldValidator,
TFormValidator,
TData
>
: FieldValidateFn<
TParentData,
TName,
TFieldValidator,
TFormValidator,
TData
>

@@ -97,18 +103,18 @@ export type FieldValidateAsyncFn<

: TFormValidator extends Validator<TParentData, infer FFN>
?
| FFN
| FieldValidateAsyncFn<
TParentData,
TName,
TFieldValidator,
TFormValidator,
TData
>
: FieldValidateAsyncFn<
TParentData,
TName,
TFieldValidator,
TFormValidator,
TData
>
?
| FFN
| FieldValidateAsyncFn<
TParentData,
TName,
TFieldValidator,
TFormValidator,
TData
>
: FieldValidateAsyncFn<
TParentData,
TName,
TFieldValidator,
TFormValidator,
TData
>

@@ -575,4 +581,2 @@ export interface FieldValidators<

fieldValidatorMeta?.lastAbortController.abort()
// Sorry Safari 12
// eslint-disable-next-line compat/compat
const controller = new AbortController()

@@ -589,11 +593,19 @@

rawError = await new Promise((rawResolve, rawReject) => {
setTimeout(() => {
setTimeout(async () => {
if (controller.signal.aborted) return rawResolve(undefined)
this.runValidator({
validate: validateObj.validate,
value: { value, fieldApi: this, signal: controller.signal },
type: 'validateAsync',
})
.then(rawResolve)
.catch(rawReject)
try {
rawResolve(
await this.runValidator({
validate: validateObj.validate,
value: {
value,
fieldApi: this,
signal: controller.signal,
},
type: 'validateAsync',
}),
)
} catch (e) {
rawReject(e)
}
}, validateObj.debounceMs)

@@ -682,4 +694,2 @@ })

return 'onSubmit'
case 'change':
return 'onChange'
case 'blur':

@@ -689,3 +699,8 @@ return 'onBlur'

return 'onMount'
case 'server':
return 'onServer'
case 'change':
default:
return 'onChange'
}
}

@@ -68,6 +68,16 @@ import { Store } from '@tanstack/store'

export type FormOptions<
export interface FormTransform<
TFormData,
TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,
> = {
> {
fn: (
formBase: FormApi<TFormData, TFormValidator>,
) => FormApi<TFormData, TFormValidator>
deps: unknown[]
}
export interface FormOptions<
TFormData,
TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,
> {
defaultValues?: TFormData

@@ -87,2 +97,3 @@ defaultState?: Partial<FormState<TFormData>>

}) => void
transform?: FormTransform<TFormData, TFormValidator>
}

@@ -156,2 +167,3 @@

onMount: undefined,
onServer: undefined,
},

@@ -174,2 +186,4 @@ }

prevTransformArray: unknown[] = []
constructor(opts?: FormOptions<TFormData, TFormValidator>) {

@@ -223,4 +237,17 @@ this.store = new Store<FormState<TFormData>>(

this.store.state = state
this.state = state
this.store.state = this.state
// Only run transform if state has shallowly changed - IE how React.useEffect works
const transformArray = this.options.transform?.deps ?? []
const shouldTransform =
transformArray.length !== this.prevTransformArray.length ||
transformArray.some((val, i) => val !== this.prevTransformArray[i])
if (shouldTransform) {
// This mutates the state
this.options.transform?.fn(this)
this.store.state = this.state
this.prevTransformArray = transformArray
}
},

@@ -275,10 +302,15 @@ },

const oldOptions = this.options
// Options need to be updated first so that when the store is updated, the state is correct for the derived state
this.options = options
this.store.batch(() => {
const shouldUpdateValues =
options.defaultValues &&
options.defaultValues !== this.options.defaultValues &&
options.defaultValues !== oldOptions.defaultValues &&
!this.state.isTouched
const shouldUpdateState =
options.defaultState !== this.options.defaultState &&
options.defaultState !== oldOptions.defaultState &&
!this.state.isTouched

@@ -303,4 +335,2 @@

})
this.options = options
}

@@ -418,4 +448,2 @@

fieldValidatorMeta?.lastAbortController.abort()
// Sorry Safari 12
// eslint-disable-next-line compat/compat
const controller = new AbortController()

@@ -432,15 +460,19 @@

rawError = await new Promise((rawResolve, rawReject) => {
setTimeout(() => {
setTimeout(async () => {
if (controller.signal.aborted) return rawResolve(undefined)
this.runValidator({
validate: validateObj.validate!,
value: {
value: this.state.values,
formApi: this,
signal: controller.signal,
},
type: 'validateAsync',
})
.then(rawResolve)
.catch(rawReject)
try {
rawResolve(
await this.runValidator({
validate: validateObj.validate!,
value: {
value: this.state.values,
formApi: this,
signal: controller.signal,
},
type: 'validateAsync',
}),
)
} catch (e) {
rawReject(e)
}
}, validateObj.debounceMs)

@@ -575,2 +607,3 @@ })

onMount: undefined,
onServer: undefined,
},

@@ -707,4 +740,2 @@ })

return 'onSubmit'
case 'change':
return 'onChange'
case 'blur':

@@ -714,3 +745,8 @@ return 'onBlur'

return 'onMount'
case 'server':
return 'onServer'
case 'change':
default:
return 'onChange'
}
}

@@ -5,1 +5,2 @@ export * from './FormApi'

export * from './types'
export * from './mergeForm'

@@ -141,2 +141,3 @@ import { expect } from 'vitest'

onMount: undefined,
onServer: undefined,
},

@@ -143,0 +144,0 @@ })

@@ -9,3 +9,4 @@ export type ValidationError = undefined | false | null | string

export type ValidationCause = 'change' | 'blur' | 'submit' | 'mount'
// "server" is only intended for SSR/SSG validation and should not execute anything
export type ValidationCause = 'change' | 'blur' | 'submit' | 'mount' | 'server'

@@ -12,0 +13,0 @@ export type ValidationErrorMapKeys = `on${Capitalize<ValidationCause>}`

@@ -167,6 +167,8 @@ import type { ValidationCause, Validator } from './types'

: T extends FormValidators<any, any>
? Array<
AsyncValidator<T['onChangeAsync'] | T['onBlurAsync'] | T['onSubmitAsync']>
>
: never {
? Array<
AsyncValidator<
T['onChangeAsync'] | T['onBlurAsync'] | T['onSubmitAsync']
>
>
: never {
const { asyncDebounceMs } = options

@@ -207,2 +209,4 @@ const {

return [changeValidator, blurValidator, submitValidator] as never
case 'server':
return [] as never
case 'blur':

@@ -231,4 +235,4 @@ return [blurValidator] as never

: T extends FormValidators<any, any>
? Array<SyncValidator<T['onChange'] | T['onBlur'] | T['onSubmit']>>
: never {
? Array<SyncValidator<T['onChange'] | T['onBlur'] | T['onSubmit']>>
: never {
const { onChange, onBlur, onSubmit } = (options.validators || {}) as

@@ -242,10 +246,23 @@ | FieldValidators<any, any>

// Allows us to clear onServer errors
const serverValidator = {
cause: 'server',
validate: () => undefined,
} as const
switch (cause) {
case 'submit':
return [changeValidator, blurValidator, submitValidator] as never
return [
changeValidator,
blurValidator,
submitValidator,
serverValidator,
] as never
case 'server':
return [serverValidator] as never
case 'blur':
return [blurValidator] as never
return [blurValidator, serverValidator] as never
case 'change':
default:
return [changeValidator] as never
return [changeValidator, serverValidator] as never
}

@@ -279,4 +296,4 @@ }

: Tuple extends readonly [infer _, ...infer Tail]
? AllowedIndexes<Tail, Keys | Tail['length']>
: Keys
? AllowedIndexes<Tail, Keys | Tail['length']>
: Keys

@@ -286,14 +303,14 @@ export type DeepKeys<T, TDepth extends any[] = []> = TDepth['length'] extends 5

: unknown extends T
? string
: object extends T
? string
: T extends readonly any[] & IsTuple<T>
? AllowedIndexes<T> | DeepKeysPrefix<T, AllowedIndexes<T>, TDepth>
: T extends any[]
? DeepKeys<T[number], [...TDepth, any]>
: T extends Date
? never
: T extends object
? (keyof T & string) | DeepKeysPrefix<T, keyof T, TDepth>
: never
? string
: object extends T
? string
: T extends readonly any[] & IsTuple<T>
? AllowedIndexes<T> | DeepKeysPrefix<T, AllowedIndexes<T>, TDepth>
: T extends any[]
? DeepKeys<T[number], [...TDepth, any]>
: T extends Date
? never
: T extends object
? (keyof T & string) | DeepKeysPrefix<T, keyof T, TDepth>
: never

@@ -300,0 +317,0 @@ type DeepKeysPrefix<

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc