From b093cee72f23ae15e4086d15ccb5f4fa57884aea Mon Sep 17 00:00:00 2001 From: aadito123 Date: Mon, 25 Dec 2023 18:01:33 +0800 Subject: [PATCH 01/32] remove .forEach --- packages/form-core/src/FormApi.ts | 32 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/packages/form-core/src/FormApi.ts b/packages/form-core/src/FormApi.ts index f1c394bb2..338f54e63 100644 --- a/packages/form-core/src/FormApi.ts +++ b/packages/form-core/src/FormApi.ts @@ -179,10 +179,9 @@ export class FormApi< onUpdate: () => { let { state } = this.store // Computed state - const fieldMetaValues = Object.values(state.fieldMeta) as ( - | FieldMeta - | undefined - )[] + const fieldMetaValues = Object.values( + state.fieldMeta, + ) const isFieldsValidating = fieldMetaValues.some( (field) => field?.isValidating, @@ -307,23 +306,25 @@ export class FormApi< ) validateAllFields = async (cause: ValidationCause) => { - const fieldValidationPromises: Promise[] = [] as any + const fieldValidationPromises: Promise[] = [] this.store.batch(() => { - void ( - Object.values(this.fieldInfo) as FieldInfo[] - ).forEach((field) => { - Object.values(field.instances).forEach((instance) => { + const fieldInfoValues = Object.values>( + this.fieldInfo, + ) + for (const field of fieldInfoValues) { + const fieldInstances = Object.values(field.instances) + for (const instance of fieldInstances) { // Validate the field fieldValidationPromises.push( - Promise.resolve().then(() => instance.validate(cause)), + Promise.resolve(instance.validate(cause)), ) // If any fields are not touched if (!instance.state.meta.isTouched) { // Mark them as touched instance.setMeta((prev) => ({ ...prev, isTouched: true })) } - }) - }) + } + } }) const fieldErrorMapMap = await Promise.all(fieldValidationPromises) @@ -333,7 +334,7 @@ export class FormApi< // TODO: This code is copied from FieldApi, we should refactor to share validateSync = (cause: ValidationCause) => { const validates = getSyncValidatorArray(cause, this.options) - let hasErrored = false as boolean + let hasErrored = false this.store.batch(() => { for (const validateObj of validates) { @@ -453,10 +454,7 @@ export class FormApi< ) } - let results: ValidationError[] = [] - if (promises.length) { - results = await Promise.all(promises) - } + const results = promises.length > 0 ? await Promise.all(promises) : [] this.store.setState((prev) => ({ ...prev, From 4386ce5f5a87127f2538a665ca0525af803f9ee6 Mon Sep 17 00:00:00 2001 From: aadito123 Date: Mon, 25 Dec 2023 18:27:33 +0800 Subject: [PATCH 02/32] some react types --- packages/form-core/src/FormApi.ts | 3 ++- packages/react-form/src/useForm.tsx | 7 ++----- scripts/config.ts | 4 ++++ 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/packages/form-core/src/FormApi.ts b/packages/form-core/src/FormApi.ts index 338f54e63..458fbc839 100644 --- a/packages/form-core/src/FormApi.ts +++ b/packages/form-core/src/FormApi.ts @@ -69,6 +69,7 @@ export type FormOptions< TFormData, TFormValidator extends Validator | undefined = undefined, > = { + persistKey?: string defaultValues?: TFormData defaultState?: Partial> asyncAlways?: boolean @@ -334,7 +335,7 @@ export class FormApi< // TODO: This code is copied from FieldApi, we should refactor to share validateSync = (cause: ValidationCause) => { const validates = getSyncValidatorArray(cause, this.options) - let hasErrored = false + let hasErrored = false as boolean this.store.batch(() => { for (const validateObj of validates) { diff --git a/packages/react-form/src/useForm.tsx b/packages/react-form/src/useForm.tsx index 43a02e434..bbe0fa67f 100644 --- a/packages/react-form/src/useForm.tsx +++ b/packages/react-form/src/useForm.tsx @@ -41,12 +41,9 @@ export function useForm< } api.Field = Field as any api.useField = useField as any - api.useStore = ( - // @ts-ignore - selector, - ) => { + api.useStore = (selector) => { // eslint-disable-next-line react-hooks/rules-of-hooks - return useStore(api.store as any, selector as any) as any + return useStore(api.store, selector) } api.Subscribe = ( // @ts-ignore diff --git a/scripts/config.ts b/scripts/config.ts index ea2ad6fcb..1c33f3be6 100644 --- a/scripts/config.ts +++ b/scripts/config.ts @@ -7,6 +7,10 @@ export const packages: Package[] = [ name: '@tanstack/form-core', packageDir: 'form-core', }, + { + name: '@tanstack/form-persist-core', + packageDir: 'form-persist-core', + }, { name: '@tanstack/react-form', packageDir: 'react-form', From 68f6b035ca9284dbf85394ba6e0521067cb3c886 Mon Sep 17 00:00:00 2001 From: aadito123 Date: Tue, 26 Dec 2023 23:18:00 +0800 Subject: [PATCH 03/32] add persist core + some changes to core --- packages/form-core/src/FormApi.ts | 27 ++++++-- packages/form-core/src/utils.ts | 2 + packages/form-persist-core/.eslintrc.cjs | 11 +++ packages/form-persist-core/package.json | 61 ++++++++++++++++ packages/form-persist-core/src/index.ts | 69 +++++++++++++++++++ .../form-persist-core/tsconfig.eslint.json | 7 ++ packages/form-persist-core/tsconfig.json | 9 +++ packages/form-persist-core/tsup.config.js | 9 +++ packages/form-persist-core/vitest.config.ts | 12 ++++ packages/react-form/src/useForm.tsx | 14 ++-- pnpm-lock.yaml | 6 ++ 11 files changed, 213 insertions(+), 14 deletions(-) create mode 100644 packages/form-persist-core/.eslintrc.cjs create mode 100644 packages/form-persist-core/package.json create mode 100644 packages/form-persist-core/src/index.ts create mode 100644 packages/form-persist-core/tsconfig.eslint.json create mode 100644 packages/form-persist-core/tsconfig.json create mode 100644 packages/form-persist-core/tsup.config.js create mode 100644 packages/form-persist-core/vitest.config.ts diff --git a/packages/form-core/src/FormApi.ts b/packages/form-core/src/FormApi.ts index 458fbc839..559fec463 100644 --- a/packages/form-core/src/FormApi.ts +++ b/packages/form-core/src/FormApi.ts @@ -1,5 +1,5 @@ import { Store } from '@tanstack/store' -import type { DeepKeys, DeepValue, Updater } from './utils' +import type { DeepKeys, DeepValue, MaybePromise, Updater } from './utils' import { getAsyncValidatorArray, getSyncValidatorArray, @@ -65,11 +65,10 @@ export interface FormValidators< onSubmitAsyncDebounceMs?: number } -export type FormOptions< +export interface FormOptions< TFormData, TFormValidator extends Validator | undefined = undefined, -> = { - persistKey?: string +> { defaultValues?: TFormData defaultState?: Partial> asyncAlways?: boolean @@ -84,6 +83,13 @@ export type FormOptions< value: TFormData formApi: FormApi }) => void + persister?: Persister +} + +export type Persister = { + persistForm(formState: FormState): MaybePromise + restoreForm(): MaybePromise | null> + deleteForm(): MaybePromise } export type ValidationMeta = { @@ -218,15 +224,24 @@ export class FormApi< this.store.state = state this.state = state + opts?.persister?.persistForm(state) }, }, ) + this.restore() this.state = this.store.state this.update(opts || {}) } + restore = async () => { + if (!this.options.persister) return + const restoredState = await this.options.persister.restoreForm() + if (!restoredState) return + this.store.setState(() => restoredState) + } + runValidator< TValue extends { value: TFormData; formApi: FormApi }, TType extends 'validate' | 'validateAsync', @@ -298,13 +313,15 @@ export class FormApi< this.options = options } - reset = () => + reset = () => { + this.options.persister?.deleteForm() this.store.setState(() => getDefaultFormState({ ...(this.options.defaultState as any), values: this.options.defaultValues ?? this.options.defaultState?.values, }), ) + } validateAllFields = async (cause: ValidationCause) => { const fieldValidationPromises: Promise[] = [] diff --git a/packages/form-core/src/utils.ts b/packages/form-core/src/utils.ts index 9b35ca975..6d0d93ebc 100644 --- a/packages/form-core/src/utils.ts +++ b/packages/form-core/src/utils.ts @@ -2,6 +2,8 @@ import type { ValidationCause, Validator } from './types' import type { FormValidators } from './FormApi' import type { FieldValidators } from './FieldApi' +export type MaybePromise = T | Promise + export type UpdaterFn = (input: TInput) => TOutput export type Updater = diff --git a/packages/form-persist-core/.eslintrc.cjs b/packages/form-persist-core/.eslintrc.cjs new file mode 100644 index 000000000..52b44816b --- /dev/null +++ b/packages/form-persist-core/.eslintrc.cjs @@ -0,0 +1,11 @@ +// @ts-check + +/** @type {import('eslint').Linter.Config} */ +const config = { + parserOptions: { + tsconfigRootDir: __dirname, + project: './tsconfig.eslint.json', + }, +} + +module.exports = config diff --git a/packages/form-persist-core/package.json b/packages/form-persist-core/package.json new file mode 100644 index 000000000..33fd6d4cc --- /dev/null +++ b/packages/form-persist-core/package.json @@ -0,0 +1,61 @@ +{ + "name": "@tanstack/form-persist-core", + "version": "0.11.0", + "description": "Persistence for Tanstack Form.", + "author": "tannerlinsley", + "license": "MIT", + "repository": "tanstack/form", + "homepage": "https://tanstack.com/form", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "type": "module", + "types": "build/legacy/index.d.ts", + "main": "build/legacy/index.cjs", + "module": "build/legacy/index.js", + "exports": { + ".": { + "import": { + "types": "./build/modern/index.d.ts", + "default": "./build/modern/index.js" + }, + "require": { + "types": "./build/modern/index.d.cts", + "default": "./build/modern/index.cjs" + } + }, + "./package.json": "./package.json" + }, + "sideEffects": false, + "files": [ + "build", + "src" + ], + "nx": { + "targets": { + "test:build": { + "dependsOn": [ + "build" + ] + } + } + }, + "scripts": { + "clean": "rimraf ./build && rimraf ./coverage", + "test:eslint": "eslint --ext .ts,.tsx ./src", + "test:types:versions48": "../../node_modules/typescript48/bin/tsc --noEmit", + "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" + }, + "dependencies": { + "@tanstack/form-core": "workspace:*" + } +} \ No newline at end of file diff --git a/packages/form-persist-core/src/index.ts b/packages/form-persist-core/src/index.ts new file mode 100644 index 000000000..a7e966afc --- /dev/null +++ b/packages/form-persist-core/src/index.ts @@ -0,0 +1,69 @@ +import type { Persister } from '@tanstack/form-core' + +export type MaybePromise = T | Promise + +export interface AsyncStorage { + getItem: (key: string) => MaybePromise + setItem: (key: string, value: string) => MaybePromise + removeItem: (key: string) => MaybePromise +} + +export interface StoragePersisterOptions { + /** The storage client used for setting and retrieving items from cache. + * For SSR pass in `undefined`. + */ + storage: AsyncStorage | undefined | null + /** + * A unique string that can be used to forcefully invalidate existing caches, + * if they do not share the same buster string + */ + buster?: string + /** + * The max-allowed age of the cache in milliseconds. + * If a persisted cache is found that is older than this + * time, it will be discarded + * @default 24 hours + */ + maxAge?: number + /** + * Prefix to be used for storage key. + * Storage key is a combination of prefix and persistKey in a form of `prefix-persistKey`. + * @default 'tanstack-form' + */ + prefix?: string +} + +type AddKeyStringArgument any>> = { + [Key in keyof T]: ( + keyString: string, + ...args: Parameters + ) => ReturnType +} + +const makeKey = (prefix: string = 'tanstack-form', persistKey: string) => + `${prefix}-${persistKey}` + +export function createPersister( + options: StoragePersisterOptions, +): AddKeyStringArgument> { + return { + async persistForm(persistKey, formState) { + await options.storage?.setItem( + makeKey(options.prefix, persistKey), + JSON.stringify({ + buster: options.buster ?? '', + state: formState, + }), + ) + }, + async restoreForm(persistKey) { + const deserialized = + (await options.storage?.getItem(makeKey(options.prefix, persistKey))) ?? + 'null' + return JSON.parse(deserialized) + }, + deleteForm(persistKey) { + return options.storage?.removeItem(makeKey(options.prefix, persistKey)) + }, + } +} diff --git a/packages/form-persist-core/tsconfig.eslint.json b/packages/form-persist-core/tsconfig.eslint.json new file mode 100644 index 000000000..e3d796435 --- /dev/null +++ b/packages/form-persist-core/tsconfig.eslint.json @@ -0,0 +1,7 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "noEmit": true + }, + "include": ["**/*.ts", "**/*.tsx", ".eslintrc.cjs", "tsup.config.js"] +} diff --git a/packages/form-persist-core/tsconfig.json b/packages/form-persist-core/tsconfig.json new file mode 100644 index 000000000..8cb149f1d --- /dev/null +++ b/packages/form-persist-core/tsconfig.json @@ -0,0 +1,9 @@ +{ + "composite": true, + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "outDir": "./build/lib", + "types": ["vitest/globals"] + }, + "include": ["src"] +} diff --git a/packages/form-persist-core/tsup.config.js b/packages/form-persist-core/tsup.config.js new file mode 100644 index 000000000..7b19f5f87 --- /dev/null +++ b/packages/form-persist-core/tsup.config.js @@ -0,0 +1,9 @@ +// @ts-check + +import { defineConfig } from 'tsup' +import { legacyConfig, modernConfig } from '../../getTsupConfig.js' + +export default defineConfig([ + modernConfig({ entry: ['src/*.ts'] }), + legacyConfig({ entry: ['src/*.ts'] }), +]) diff --git a/packages/form-persist-core/vitest.config.ts b/packages/form-persist-core/vitest.config.ts new file mode 100644 index 000000000..fa0fbffb2 --- /dev/null +++ b/packages/form-persist-core/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineConfig } from 'vitest/config' + +export default defineConfig({ + test: { + name: 'form-persist-core', + dir: './src', + watch: false, + environment: 'jsdom', + globals: true, + coverage: { provider: 'istanbul' }, + }, +}) diff --git a/packages/react-form/src/useForm.tsx b/packages/react-form/src/useForm.tsx index bbe0fa67f..667742c98 100644 --- a/packages/react-form/src/useForm.tsx +++ b/packages/react-form/src/useForm.tsx @@ -1,10 +1,10 @@ -import type { FormState, FormOptions, Validator } from '@tanstack/form-core' +import type { FormOptions, FormState, Validator } from '@tanstack/form-core' import { FormApi, functionalUpdate } from '@tanstack/form-core' import type { NoInfer } from '@tanstack/react-store' import { useStore } from '@tanstack/react-store' -import React, { type PropsWithChildren, type ReactNode, useState } from 'react' -import { type UseField, type FieldComponent, Field, useField } from './useField' +import React, { useState, type PropsWithChildren, type ReactNode } from 'react' import { formContext } from './formContext' +import { Field, useField, type FieldComponent, type UseField } from './useField' import { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect' declare module '@tanstack/form-core' { @@ -30,7 +30,6 @@ export function useForm< opts?: FormOptions, ): FormApi { const [formApi] = useState(() => { - // @ts-ignore const api = new FormApi(opts) api.Provider = function Provider(props) { @@ -45,14 +44,11 @@ export function useForm< // eslint-disable-next-line react-hooks/rules-of-hooks return useStore(api.store, selector) } - api.Subscribe = ( - // @ts-ignore - props, - ) => { + api.Subscribe = (props) => { return functionalUpdate( props.children, // eslint-disable-next-line react-hooks/rules-of-hooks - useStore(api.store as any, props.selector as any), + useStore(api.store, props.selector), ) as any } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1d2b6c5bd..062878765 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -734,6 +734,12 @@ importers: specifier: 0.1.3 version: 0.1.3 + packages/form-persist-core: + dependencies: + '@tanstack/form-core': + specifier: workspace:* + version: link:../form-core + packages/react-form: dependencies: '@tanstack/form-core': From 778a30c5c3737eea089ae50962e4b118d3f097ae Mon Sep 17 00:00:00 2001 From: aadito123 Date: Fri, 29 Dec 2023 18:23:33 +0800 Subject: [PATCH 04/32] adding tests --- packages/form-core/src/FormApi.ts | 26 ++++++++++++++++-------- packages/form-persist-core/src/index.ts | 9 +++++--- packages/form-persist-core/tsconfig.json | 2 +- 3 files changed, 25 insertions(+), 12 deletions(-) diff --git a/packages/form-core/src/FormApi.ts b/packages/form-core/src/FormApi.ts index 559fec463..93a8557b8 100644 --- a/packages/form-core/src/FormApi.ts +++ b/packages/form-core/src/FormApi.ts @@ -88,7 +88,7 @@ export interface FormOptions< export type Persister = { persistForm(formState: FormState): MaybePromise - restoreForm(): MaybePromise | null> + restoreForm(): MaybePromise | undefined> deleteForm(): MaybePromise } @@ -176,6 +176,7 @@ export class FormApi< {} as any constructor(opts?: FormOptions) { + let firstUpdateCycleOccurred = false this.store = new Store>( getDefaultFormState({ ...(opts?.defaultState as any), @@ -224,22 +225,31 @@ export class FormApi< this.store.state = state this.state = state - opts?.persister?.persistForm(state) + if (firstUpdateCycleOccurred) { + if (opts?.persister) { + opts.persister.persistForm(state) + } else if (this.options.persister) { + this.options.persister.persistForm(state) + } + } + firstUpdateCycleOccurred = true }, }, ) - this.restore() this.state = this.store.state - this.update(opts || {}) + this.restore(opts) } - restore = async () => { - if (!this.options.persister) return - const restoredState = await this.options.persister.restoreForm() + restore = async (opts?: FormOptions) => { + if (!opts?.persister) return + const restoredState = await opts.persister.restoreForm() if (!restoredState) return - this.store.setState(() => restoredState) + this.state = restoredState + this.store.batch(() => { + this.store.setState(() => restoredState) + }) } runValidator< diff --git a/packages/form-persist-core/src/index.ts b/packages/form-persist-core/src/index.ts index a7e966afc..655eb8eee 100644 --- a/packages/form-persist-core/src/index.ts +++ b/packages/form-persist-core/src/index.ts @@ -43,9 +43,9 @@ type AddKeyStringArgument any>> = { const makeKey = (prefix: string = 'tanstack-form', persistKey: string) => `${prefix}-${persistKey}` -export function createPersister( +export function createPersister( options: StoragePersisterOptions, -): AddKeyStringArgument> { +): AddKeyStringArgument> { return { async persistForm(persistKey, formState) { await options.storage?.setItem( @@ -60,7 +60,10 @@ export function createPersister( const deserialized = (await options.storage?.getItem(makeKey(options.prefix, persistKey))) ?? 'null' - return JSON.parse(deserialized) + const state = JSON.parse(deserialized) + if (!state || state.buster !== (options.buster ?? '')) + return this.deleteForm(persistKey) + return state.state }, deleteForm(persistKey) { return options.storage?.removeItem(makeKey(options.prefix, persistKey)) diff --git a/packages/form-persist-core/tsconfig.json b/packages/form-persist-core/tsconfig.json index 8cb149f1d..62c218599 100644 --- a/packages/form-persist-core/tsconfig.json +++ b/packages/form-persist-core/tsconfig.json @@ -1,6 +1,6 @@ { "composite": true, - "extends": "../../tsconfig.base.json", + "extends": "../../tsconfig.json", "compilerOptions": { "outDir": "./build/lib", "types": ["vitest/globals"] From 9ca34641f3add1b403f015f36f024dad20cbd6f3 Mon Sep 17 00:00:00 2001 From: aadito123 Date: Tue, 2 Jan 2024 14:08:26 +0800 Subject: [PATCH 05/32] forgot to add files --- .../src/tests/persister.spec.ts | 90 +++++++++++++++++++ packages/form-persist-core/src/tests/utils.ts | 5 ++ 2 files changed, 95 insertions(+) create mode 100644 packages/form-persist-core/src/tests/persister.spec.ts create mode 100644 packages/form-persist-core/src/tests/utils.ts diff --git a/packages/form-persist-core/src/tests/persister.spec.ts b/packages/form-persist-core/src/tests/persister.spec.ts new file mode 100644 index 000000000..4c8293802 --- /dev/null +++ b/packages/form-persist-core/src/tests/persister.spec.ts @@ -0,0 +1,90 @@ +import { FormApi } from '@tanstack/form-core' +import { createPersister } from '..' +import type { StoragePersisterOptions } from '..' +import { sleep } from './utils' + +const mapHolder: Record> = {} +const getPersister = ( + idKey: string, + opts?: Omit, +) => { + const persistMap = mapHolder[idKey] || new Map() + mapHolder[idKey] = persistMap + return createPersister({ + storage: { + getItem(key) { + return persistMap.get(key) + }, + setItem(key, val) { + console.log('setting: ', key, val) + return persistMap.set(key, val) + }, + removeItem(key) { + persistMap.delete(key) + }, + }, + ...opts, + }) +} + +const getFormApiPersister = (id: string, formKey: string) => { + const persister = getPersister(id) + return { + persistForm: persister.persistForm.bind(null, formKey), + deleteForm: persister.deleteForm.bind(null, formKey), + restoreForm: persister.restoreForm.bind(null, formKey), + } +} + +let id_ = 0 +const getId = () => `id-${id_++}` +const getKey = () => `key-${id_++}` + +describe('persister', () => { + it('should persist state manually', async () => { + const id = getId() + const persister = getPersister(id) + const formApi = new FormApi({ defaultValues: { hi: 'there' } }) + await persister.persistForm(id, formApi.state) + const persistedForm = await persister.restoreForm(id) + expect(persistedForm).toEqual(formApi.state) + }) + + it('should persist with new persister', async () => { + const id = getId() + let persister = getPersister(id, { buster: 'hi' }) + const formApi = new FormApi({ defaultValues: { hi: 'there' } }) + await persister.persistForm(id, formApi.state) + persister = getPersister(id, { buster: 'hi' }) + const persistedForm = await persister.restoreForm(id) + expect(persistedForm).toEqual(formApi.state) + }) + + it('should delete when busted', async () => { + const id = getId() + let persister = getPersister(id, { buster: 'hi' }) + const formApi = new FormApi({ defaultValues: { hi: 'there' } }) + await persister.persistForm(id, formApi.state) + persister = getPersister(id, { buster: 'bye' }) + const persistedForm = await persister.restoreForm(id) + expect(persistedForm).toEqual(undefined) + }) + + it('should persist automatically', async () => { + const formKey = getKey(), + id = getId() + const getFormApi = () => + new FormApi({ + defaultValues: { hi: 'there' }, + persister: getFormApiPersister<{ hi: string }>(id, formKey), + }) + let formApi = getFormApi() + const oldState = structuredClone(formApi.state) + formApi.setFieldValue('hi', 'bye') + await sleep(10) + formApi = getFormApi() + await sleep(10) + console.log('old', oldState), console.log('new', formApi.state) + expect(formApi.state).toEqual(oldState) + }) +}) diff --git a/packages/form-persist-core/src/tests/utils.ts b/packages/form-persist-core/src/tests/utils.ts new file mode 100644 index 000000000..5e4d0305e --- /dev/null +++ b/packages/form-persist-core/src/tests/utils.ts @@ -0,0 +1,5 @@ +export function sleep(timeout: number): Promise { + return new Promise((resolve) => { + setTimeout(resolve, timeout) + }) +} From 5961a22913cfb03dcf8757b36a0d0f804ae9ba7c Mon Sep 17 00:00:00 2001 From: aadito123 Date: Fri, 5 Jan 2024 00:30:35 +0800 Subject: [PATCH 06/32] missing vite config for form persist --- packages/form-persist-core/vite.config.ts | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 packages/form-persist-core/vite.config.ts diff --git a/packages/form-persist-core/vite.config.ts b/packages/form-persist-core/vite.config.ts new file mode 100644 index 000000000..2d01612cf --- /dev/null +++ b/packages/form-persist-core/vite.config.ts @@ -0,0 +1,23 @@ +import { defineConfig, mergeConfig } from 'vitest/config' +import { tanstackBuildConfig } from '@tanstack/config/build' + +const config = defineConfig({ + test: { + name: 'form-core', + dir: './src', + watch: false, + environment: 'jsdom', + globals: true, + coverage: { enabled: true, provider: 'istanbul', include: ['src/**/*'] }, + typecheck: { enabled: true }, + }, +}) + +export default mergeConfig( + config, + tanstackBuildConfig({ + entry: './src/index.ts', + srcDir: './src', + exclude: ['./src/tests'], + }), +) From 311f31174dffa523c90dcba00e0db2e503eb9dc7 Mon Sep 17 00:00:00 2001 From: aadito123 Date: Fri, 5 Jan 2024 00:40:54 +0800 Subject: [PATCH 07/32] misc stuff --- packages/form-core/src/FormApi.ts | 4 +++- packages/form-persist-core/src/index.ts | 9 +++++---- packages/form-persist-core/src/tests/persister.spec.ts | 2 -- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/packages/form-core/src/FormApi.ts b/packages/form-core/src/FormApi.ts index 4afbaf2ed..5953a4753 100644 --- a/packages/form-core/src/FormApi.ts +++ b/packages/form-core/src/FormApi.ts @@ -238,7 +238,9 @@ export class FormApi< this.state = state this.store.state = this.state - + if (opts?.persister) { + opts.persister.persistForm(state) + } // Only run transform if state has shallowly changed - IE how React.useEffect works const transformArray = this.options.transform?.deps ?? [] const shouldTransform = diff --git a/packages/form-persist-core/src/index.ts b/packages/form-persist-core/src/index.ts index 655eb8eee..31e18a2c1 100644 --- a/packages/form-persist-core/src/index.ts +++ b/packages/form-persist-core/src/index.ts @@ -46,6 +46,9 @@ const makeKey = (prefix: string = 'tanstack-form', persistKey: string) => export function createPersister( options: StoragePersisterOptions, ): AddKeyStringArgument> { + const deleteForm = (persistKey: string) => { + return options.storage?.removeItem(makeKey(options.prefix, persistKey)) + } return { async persistForm(persistKey, formState) { await options.storage?.setItem( @@ -62,11 +65,9 @@ export function createPersister( 'null' const state = JSON.parse(deserialized) if (!state || state.buster !== (options.buster ?? '')) - return this.deleteForm(persistKey) + return deleteForm(persistKey) return state.state }, - deleteForm(persistKey) { - return options.storage?.removeItem(makeKey(options.prefix, persistKey)) - }, + deleteForm, } } diff --git a/packages/form-persist-core/src/tests/persister.spec.ts b/packages/form-persist-core/src/tests/persister.spec.ts index 4c8293802..e1ae57fdc 100644 --- a/packages/form-persist-core/src/tests/persister.spec.ts +++ b/packages/form-persist-core/src/tests/persister.spec.ts @@ -16,7 +16,6 @@ const getPersister = ( return persistMap.get(key) }, setItem(key, val) { - console.log('setting: ', key, val) return persistMap.set(key, val) }, removeItem(key) { @@ -84,7 +83,6 @@ describe('persister', () => { await sleep(10) formApi = getFormApi() await sleep(10) - console.log('old', oldState), console.log('new', formApi.state) expect(formApi.state).toEqual(oldState) }) }) From ce62fb2849b8258cbca2df1ecf4aeec74b11473d Mon Sep 17 00:00:00 2001 From: aadito123 Date: Sun, 7 Jan 2024 19:04:24 +0800 Subject: [PATCH 08/32] persistence test case passing --- packages/form-core/src/FormApi.ts | 51 +++++++++++++++---- packages/form-core/src/tests/FormApi.spec.ts | 17 ++++++- packages/form-persist-core/src/index.ts | 10 ++++ .../src/tests/persister.spec.ts | 13 +++-- 4 files changed, 74 insertions(+), 17 deletions(-) diff --git a/packages/form-core/src/FormApi.ts b/packages/form-core/src/FormApi.ts index 5953a4753..49dd9bfbc 100644 --- a/packages/form-core/src/FormApi.ts +++ b/packages/form-core/src/FormApi.ts @@ -143,6 +143,9 @@ export type FormState = { isValid: boolean canSubmit: boolean submissionAttempts: number + // Form Persistence + isRestored: boolean + isRestoring: boolean } function getDefaultFormState( @@ -171,6 +174,8 @@ function getDefaultFormState( onMount: undefined, onServer: undefined, }, + isRestored: false, + isRestoring: false, } } @@ -188,6 +193,7 @@ export class FormApi< {} as any prevTransformArray: unknown[] = [] + restorePromise: Promise = Promise.resolve() constructor(opts?: FormOptions) { this.store = new Store>( @@ -238,9 +244,7 @@ export class FormApi< this.state = state this.store.state = this.state - if (opts?.persister) { - opts.persister.persistForm(state) - } + // Only run transform if state has shallowly changed - IE how React.useEffect works const transformArray = this.options.transform?.deps ?? [] const shouldTransform = @@ -253,23 +257,44 @@ export class FormApi< this.store.state = this.state this.prevTransformArray = transformArray } + + if (opts?.persister && !this.state.isRestoring) { + opts.persister.persistForm(this.state) + } }, }, ) this.state = this.store.state - this.update(opts || {}) - this.restore(opts) + this.update(opts) } restore = async (opts?: FormOptions) => { if (!opts?.persister) return + let restorePromiseResolve: () => void + this.restorePromise = new Promise( + (res) => (restorePromiseResolve = res), + ) + this.store.setState((oldState) => ({ + ...oldState, + isRestored: false, + isRestoring: true, + })) const restoredState = await opts.persister.restoreForm() - if (!restoredState) return + if (!restoredState) { + return this.store.setState((oldState) => ({ + ...oldState, + isRestored: true, + isRestoring: false, + })) + } this.state = restoredState - this.store.batch(() => { - this.store.setState(() => restoredState) - }) + this.store.batch(() => + this.store.setState(() => { + restorePromiseResolve() + return restoredState + }), + ) } runValidator< @@ -317,15 +342,19 @@ export class FormApi< // 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.restore(options) + this.store.batch(() => { const shouldUpdateValues = options.defaultValues && options.defaultValues !== oldOptions.defaultValues && - !this.state.isTouched + !this.state.isTouched && + !this.state.isRestoring const shouldUpdateState = options.defaultState !== oldOptions.defaultState && - !this.state.isTouched + !this.state.isTouched && + !this.state.isRestoring this.store.setState(() => getDefaultFormState( diff --git a/packages/form-core/src/tests/FormApi.spec.ts b/packages/form-core/src/tests/FormApi.spec.ts index d11450d1e..f23e95b0b 100644 --- a/packages/form-core/src/tests/FormApi.spec.ts +++ b/packages/form-core/src/tests/FormApi.spec.ts @@ -12,22 +12,25 @@ describe('form api', () => { values: {}, fieldMeta: {}, canSubmit: true, - isFieldsValid: true, + isFieldsValid: false, isFieldsValidating: false, isFormValid: true, isFormValidating: false, isSubmitted: false, errors: [], errorMap: {}, + isRestored: false, + isRestoring: false, isSubmitting: false, isTouched: false, - isValid: true, + isValid: false, isValidating: false, submissionAttempts: 0, validationMetaMap: { onChange: undefined, onBlur: undefined, onSubmit: undefined, + onServer: undefined, onMount: undefined, }, }) @@ -57,6 +60,8 @@ describe('form api', () => { isTouched: false, isValid: true, isValidating: false, + isRestored: false, + isRestoring: false, submissionAttempts: 0, validationMetaMap: { onChange: undefined, @@ -83,6 +88,8 @@ describe('form api', () => { isFieldsValid: true, isFieldsValidating: false, isFormValid: true, + isRestored: false, + isRestoring: false, isFormValidating: false, isSubmitted: false, isSubmitting: false, @@ -95,6 +102,7 @@ describe('form api', () => { onBlur: undefined, onSubmit: undefined, onMount: undefined, + onServer: undefined, }, }) }) @@ -131,6 +139,8 @@ describe('form api', () => { isSubmitting: false, isTouched: false, isValid: true, + isRestored: false, + isRestoring: false, isValidating: false, submissionAttempts: 300, validationMetaMap: { @@ -172,10 +182,13 @@ describe('form api', () => { isTouched: false, isValid: true, isValidating: false, + isRestored: false, + isRestoring: false, submissionAttempts: 0, validationMetaMap: { onChange: undefined, onBlur: undefined, + onServer: undefined, onSubmit: undefined, onMount: undefined, }, diff --git a/packages/form-persist-core/src/index.ts b/packages/form-persist-core/src/index.ts index 31e18a2c1..bef080fdd 100644 --- a/packages/form-persist-core/src/index.ts +++ b/packages/form-persist-core/src/index.ts @@ -66,6 +66,16 @@ export function createPersister( const state = JSON.parse(deserialized) if (!state || state.buster !== (options.buster ?? '')) return deleteForm(persistKey) + state.state.isRestored = true + state.state.isRestoring = false + // ensures that this object is not empty + state.state.validationMetaMap = { + onChange: state.state.validationMetaMap.onChange, + onBlur: state.state.validationMetaMap.onBlur, + onSubmit: state.state.validationMetaMap.onSubmit, + onMount: state.state.validationMetaMap.onMount, + onServer: state.state.validationMetaMap.onServer, + } return state.state }, deleteForm, diff --git a/packages/form-persist-core/src/tests/persister.spec.ts b/packages/form-persist-core/src/tests/persister.spec.ts index e1ae57fdc..ad7e7faf3 100644 --- a/packages/form-persist-core/src/tests/persister.spec.ts +++ b/packages/form-persist-core/src/tests/persister.spec.ts @@ -16,6 +16,7 @@ const getPersister = ( return persistMap.get(key) }, setItem(key, val) { + // console.log('setting', key, JSON.parse(val).state.values) return persistMap.set(key, val) }, removeItem(key) { @@ -46,7 +47,7 @@ describe('persister', () => { const formApi = new FormApi({ defaultValues: { hi: 'there' } }) await persister.persistForm(id, formApi.state) const persistedForm = await persister.restoreForm(id) - expect(persistedForm).toEqual(formApi.state) + expect(persistedForm).toEqual({ ...formApi.state, isRestored: true }) }) it('should persist with new persister', async () => { @@ -56,7 +57,7 @@ describe('persister', () => { await persister.persistForm(id, formApi.state) persister = getPersister(id, { buster: 'hi' }) const persistedForm = await persister.restoreForm(id) - expect(persistedForm).toEqual(formApi.state) + expect(persistedForm).toEqual({ ...formApi.state, isRestored: true }) }) it('should delete when busted', async () => { @@ -82,7 +83,11 @@ describe('persister', () => { formApi.setFieldValue('hi', 'bye') await sleep(10) formApi = getFormApi() - await sleep(10) - expect(formApi.state).toEqual(oldState) + await formApi.restorePromise + expect(formApi.state).toEqual({ + ...oldState, + values: { hi: 'bye' }, + isRestored: true, + }) }) }) From bf9b0d5acf7f157599a870e6ee2f338928660b33 Mon Sep 17 00:00:00 2001 From: aadito123 Date: Mon, 8 Jan 2024 22:31:04 +0800 Subject: [PATCH 09/32] change types --- packages/form-persist-core/src/index.ts | 32 +++++++++++++++---------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/packages/form-persist-core/src/index.ts b/packages/form-persist-core/src/index.ts index bef080fdd..452023583 100644 --- a/packages/form-persist-core/src/index.ts +++ b/packages/form-persist-core/src/index.ts @@ -1,18 +1,21 @@ -import type { Persister } from '@tanstack/form-core' +import type { FormState, Persister } from '@tanstack/form-core' -export type MaybePromise = T | Promise - -export interface AsyncStorage { - getItem: (key: string) => MaybePromise - setItem: (key: string, value: string) => MaybePromise - removeItem: (key: string) => MaybePromise +export type SyncFormStorage = { + getItem: (key: string) => string | undefined | null + setItem: (key: string, value: string) => unknown + removeItem: (key: string) => void +} +export type AsyncFormStorage = { + [Method in keyof SyncFormStorage]: ( + ...args: Parameters + ) => Promise> } export interface StoragePersisterOptions { /** The storage client used for setting and retrieving items from cache. * For SSR pass in `undefined`. */ - storage: AsyncStorage | undefined | null + storage: AsyncFormStorage | SyncFormStorage | undefined | null /** * A unique string that can be used to forcefully invalidate existing caches, * if they do not share the same buster string @@ -63,12 +66,17 @@ export function createPersister( const deserialized = (await options.storage?.getItem(makeKey(options.prefix, persistKey))) ?? 'null' - const state = JSON.parse(deserialized) - if (!state || state.buster !== (options.buster ?? '')) - return deleteForm(persistKey) + const state = JSON.parse(deserialized) as { + buster: string + state: FormState + } | null + if (!state || state.buster !== (options.buster ?? '')) { + deleteForm(persistKey) + return + } state.state.isRestored = true state.state.isRestoring = false - // ensures that this object is not empty + // ensures that this object is not empty (JSON.parse('{hi: undefined}') => {}) state.state.validationMetaMap = { onChange: state.state.validationMetaMap.onChange, onBlur: state.state.validationMetaMap.onBlur, From f9b248a23a5a5700c15b9bee3c3bb4b91efc8ba2 Mon Sep 17 00:00:00 2001 From: aadito123 Date: Mon, 8 Jan 2024 22:56:08 +0800 Subject: [PATCH 10/32] make persister a class --- packages/form-persist-core/src/index.ts | 95 +++++++++++++------------ 1 file changed, 48 insertions(+), 47 deletions(-) diff --git a/packages/form-persist-core/src/index.ts b/packages/form-persist-core/src/index.ts index 452023583..eb9430c9a 100644 --- a/packages/form-persist-core/src/index.ts +++ b/packages/form-persist-core/src/index.ts @@ -36,56 +36,57 @@ export interface StoragePersisterOptions { prefix?: string } -type AddKeyStringArgument any>> = { - [Key in keyof T]: ( - keyString: string, - ...args: Parameters - ) => ReturnType -} - const makeKey = (prefix: string = 'tanstack-form', persistKey: string) => `${prefix}-${persistKey}` -export function createPersister( - options: StoragePersisterOptions, -): AddKeyStringArgument> { - const deleteForm = (persistKey: string) => { - return options.storage?.removeItem(makeKey(options.prefix, persistKey)) +class PersisterAPI { + options: StoragePersisterOptions + constructor(opts: StoragePersisterOptions) { + this.options = opts + } + + persistForm = async (persistKey: string, formState: FormState) => { + await this.options.storage?.setItem( + makeKey(this.options.prefix, persistKey), + JSON.stringify({ + buster: this.options.buster ?? '', + state: formState, + }), + ) } - return { - async persistForm(persistKey, formState) { - await options.storage?.setItem( - makeKey(options.prefix, persistKey), - JSON.stringify({ - buster: options.buster ?? '', - state: formState, - }), - ) - }, - async restoreForm(persistKey) { - const deserialized = - (await options.storage?.getItem(makeKey(options.prefix, persistKey))) ?? - 'null' - const state = JSON.parse(deserialized) as { - buster: string - state: FormState - } | null - if (!state || state.buster !== (options.buster ?? '')) { - deleteForm(persistKey) - return - } - state.state.isRestored = true - state.state.isRestoring = false - // ensures that this object is not empty (JSON.parse('{hi: undefined}') => {}) - state.state.validationMetaMap = { - onChange: state.state.validationMetaMap.onChange, - onBlur: state.state.validationMetaMap.onBlur, - onSubmit: state.state.validationMetaMap.onSubmit, - onMount: state.state.validationMetaMap.onMount, - onServer: state.state.validationMetaMap.onServer, - } - return state.state - }, - deleteForm, + restoreForm = async (persistKey: string) => { + const deserialized = + (await this.options.storage?.getItem( + makeKey(this.options.prefix, persistKey), + )) ?? 'null' + const state = JSON.parse(deserialized) as { + buster: string + state: FormState + } | null + if (!state || state.buster !== (this.options.buster ?? '')) { + this.deleteForm(persistKey) + return + } + state.state.isRestored = true + state.state.isRestoring = false + // ensures that this object is not empty (JSON.parse('{hi: undefined}') => {}) + state.state.validationMetaMap = { + onChange: state.state.validationMetaMap.onChange, + onBlur: state.state.validationMetaMap.onBlur, + onSubmit: state.state.validationMetaMap.onSubmit, + onMount: state.state.validationMetaMap.onMount, + onServer: state.state.validationMetaMap.onServer, + } + return state.state } + + deleteForm = (persistKey: string) => { + return this.options.storage?.removeItem( + makeKey(this.options.prefix, persistKey), + ) + } +} + +export function createPersister(options: StoragePersisterOptions) { + return new PersisterAPI(options) } From 8ebcda599fde6d6b2bf903e7430328450d21cb29 Mon Sep 17 00:00:00 2001 From: aadito123 Date: Mon, 8 Jan 2024 23:20:00 +0800 Subject: [PATCH 11/32] complete API revamp --- packages/form-persist-core/src/index.ts | 14 +++++++++++--- .../form-persist-core/src/tests/persister.spec.ts | 10 +++------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/packages/form-persist-core/src/index.ts b/packages/form-persist-core/src/index.ts index eb9430c9a..1c52b79d7 100644 --- a/packages/form-persist-core/src/index.ts +++ b/packages/form-persist-core/src/index.ts @@ -39,7 +39,7 @@ export interface StoragePersisterOptions { const makeKey = (prefix: string = 'tanstack-form', persistKey: string) => `${prefix}-${persistKey}` -class PersisterAPI { +export class PersisterAPI { options: StoragePersisterOptions constructor(opts: StoragePersisterOptions) { this.options = opts @@ -87,6 +87,14 @@ class PersisterAPI { } } -export function createPersister(options: StoragePersisterOptions) { - return new PersisterAPI(options) +export function createFormPersister( + persisterAPI: PersisterAPI, + formKey: string, +): Persister { + return { + deleteForm: () => persisterAPI.deleteForm(formKey), + restoreForm: () => persisterAPI.restoreForm(formKey), + persistForm: (state: FormState) => + persisterAPI.persistForm(formKey, state), + } } diff --git a/packages/form-persist-core/src/tests/persister.spec.ts b/packages/form-persist-core/src/tests/persister.spec.ts index ad7e7faf3..cfb20eda7 100644 --- a/packages/form-persist-core/src/tests/persister.spec.ts +++ b/packages/form-persist-core/src/tests/persister.spec.ts @@ -1,5 +1,5 @@ import { FormApi } from '@tanstack/form-core' -import { createPersister } from '..' +import { PersisterAPI, createFormPersister } from '..' import type { StoragePersisterOptions } from '..' import { sleep } from './utils' @@ -10,7 +10,7 @@ const getPersister = ( ) => { const persistMap = mapHolder[idKey] || new Map() mapHolder[idKey] = persistMap - return createPersister({ + return new PersisterAPI({ storage: { getItem(key) { return persistMap.get(key) @@ -29,11 +29,7 @@ const getPersister = ( const getFormApiPersister = (id: string, formKey: string) => { const persister = getPersister(id) - return { - persistForm: persister.persistForm.bind(null, formKey), - deleteForm: persister.deleteForm.bind(null, formKey), - restoreForm: persister.restoreForm.bind(null, formKey), - } + return createFormPersister(persister, formKey) } let id_ = 0 From e647c6fae1f9dd886c4dc6c1365635c1188ca75a Mon Sep 17 00:00:00 2001 From: aadito123 Date: Mon, 8 Jan 2024 23:42:15 +0800 Subject: [PATCH 12/32] removed console.log --- packages/form-core/src/FieldApi.ts | 1 - packages/form-core/src/FormApi.ts | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/form-core/src/FieldApi.ts b/packages/form-core/src/FieldApi.ts index c4e469763..48fd116ee 100644 --- a/packages/form-core/src/FieldApi.ts +++ b/packages/form-core/src/FieldApi.ts @@ -505,7 +505,6 @@ export class FieldApi< validateSync = (value = this.state.value, cause: ValidationCause) => { const validates = getSyncValidatorArray(cause, this.options) - if (this.name === 'firstName' && cause === 'submit') console.log(validates) // Needs type cast as eslint errantly believes this is always falsy let hasErrored = false as boolean diff --git a/packages/form-core/src/FormApi.ts b/packages/form-core/src/FormApi.ts index 49dd9bfbc..8129c1348 100644 --- a/packages/form-core/src/FormApi.ts +++ b/packages/form-core/src/FormApi.ts @@ -94,6 +94,7 @@ export interface FormOptions< formApi: FormApi }) => void transform?: FormTransform + // checkout @tanstack/form-persistence-core persister?: Persister } From 1ff49e97ec725c74430db634da65f79cff9b1d83 Mon Sep 17 00:00:00 2001 From: aadito123 Date: Mon, 8 Jan 2024 23:44:20 +0800 Subject: [PATCH 13/32] make prettier happy --- packages/form-persist-core/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/form-persist-core/package.json b/packages/form-persist-core/package.json index e0d33e110..1a28b30a0 100644 --- a/packages/form-persist-core/package.json +++ b/packages/form-persist-core/package.json @@ -57,4 +57,4 @@ "dependencies": { "@tanstack/form-core": "workspace:*" } -} \ No newline at end of file +} From 02636a25107e718609aeb2fe3894c6f697d88ffd Mon Sep 17 00:00:00 2001 From: aadito123 Date: Tue, 9 Jan 2024 09:56:24 +0800 Subject: [PATCH 14/32] add legacy tsconfig --- packages/form-persist-core/package.json | 4 ++-- packages/form-persist-core/tsconfig.legacy.json | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) create mode 100644 packages/form-persist-core/tsconfig.legacy.json diff --git a/packages/form-persist-core/package.json b/packages/form-persist-core/package.json index 1a28b30a0..b11f89583 100644 --- a/packages/form-persist-core/package.json +++ b/packages/form-persist-core/package.json @@ -44,7 +44,7 @@ "scripts": { "clean": "rimraf ./build && rimraf ./coverage", "test:eslint": "eslint --ext .ts,.tsx ./src", - "test:types:versions49": "../../node_modules/typescript49/bin/tsc --noEmit", + "test:types:versions49": "../../node_modules/typescript49/bin/tsc --project tsconfig.legacy.json --noEmit", "test:types:versions50": "../../node_modules/typescript50/bin/tsc --noEmit", "test:types:versions51": "../../node_modules/typescript51/bin/tsc --noEmit", "test:types:versions52": "tsc --noEmit", @@ -57,4 +57,4 @@ "dependencies": { "@tanstack/form-core": "workspace:*" } -} +} \ No newline at end of file diff --git a/packages/form-persist-core/tsconfig.legacy.json b/packages/form-persist-core/tsconfig.legacy.json new file mode 100644 index 000000000..8ba4eb48e --- /dev/null +++ b/packages/form-persist-core/tsconfig.legacy.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "moduleResolution": "Node" + }, + "include": ["src/**/*.ts", "src/**/*.tsx"], + "exclude": ["src/tests/**"] +} From 00287224631608bacd94981d1d40b88f0e03e09e Mon Sep 17 00:00:00 2001 From: aadito123 Date: Tue, 9 Jan 2024 10:11:57 +0800 Subject: [PATCH 15/32] fix format + typecheck command --- packages/form-persist-core/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/form-persist-core/package.json b/packages/form-persist-core/package.json index b11f89583..653abf3d4 100644 --- a/packages/form-persist-core/package.json +++ b/packages/form-persist-core/package.json @@ -48,7 +48,7 @@ "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:types": "pnpm run \"/^test:types:versions.*/\" && vitest --typecheck.only", "test:lib": "vitest run --coverage", "test:lib:dev": "pnpm run test:lib --watch", "test:build": "publint --strict", @@ -57,4 +57,4 @@ "dependencies": { "@tanstack/form-core": "workspace:*" } -} \ No newline at end of file +} From 2fd73f6b7a06ecd7398195fe2ba0f7b8e32b6fcb Mon Sep 17 00:00:00 2001 From: aadito123 Date: Fri, 26 Jan 2024 18:37:47 +0800 Subject: [PATCH 16/32] custom serializer --- packages/form-persist-core/src/index.ts | 71 +++++++++++++++++-------- 1 file changed, 50 insertions(+), 21 deletions(-) diff --git a/packages/form-persist-core/src/index.ts b/packages/form-persist-core/src/index.ts index 1c52b79d7..d8d098709 100644 --- a/packages/form-persist-core/src/index.ts +++ b/packages/form-persist-core/src/index.ts @@ -1,21 +1,30 @@ -import type { FormState, Persister } from '@tanstack/form-core' +import type { FormState, MaybePromise, Persister } from '@tanstack/form-core' -export type SyncFormStorage = { - getItem: (key: string) => string | undefined | null - setItem: (key: string, value: string) => unknown +export type SyncFormStorage = { + getItem: (key: string) => TStorageValue | undefined | null + setItem: (key: string, value: TStorageValue) => unknown removeItem: (key: string) => void } -export type AsyncFormStorage = { - [Method in keyof SyncFormStorage]: ( - ...args: Parameters - ) => Promise> +export type AsyncFormStorage = { + [Method in keyof SyncFormStorage]: ( + ...args: Parameters[Method]> + ) => Promise[Method]>> } -export interface StoragePersisterOptions { +type PersistedFormState = { + buster: string + state: FormState +} + +export interface StoragePersisterOptions { /** The storage client used for setting and retrieving items from cache. * For SSR pass in `undefined`. */ - storage: AsyncFormStorage | SyncFormStorage | undefined | null + storage: + | AsyncFormStorage + | SyncFormStorage + | undefined + | null /** * A unique string that can be used to forcefully invalidate existing caches, * if they do not share the same buster string @@ -34,32 +43,52 @@ export interface StoragePersisterOptions { * @default 'tanstack-form' */ prefix?: string + /** + * How to serialize the data to storage. + * @default `JSON.stringify` + */ + serializer?: ( + persistedForm: PersistedFormState, + ) => MaybePromise + /** + * How to deserialize the data from storage. + * @default `JSON.parse` + */ + deserializer?: ( + cachedValue: TStorageValue, + ) => MaybePromise } const makeKey = (prefix: string = 'tanstack-form', persistKey: string) => `${prefix}-${persistKey}` -export class PersisterAPI { - options: StoragePersisterOptions - constructor(opts: StoragePersisterOptions) { +export class PersisterAPI { + options: StoragePersisterOptions + constructor(opts: StoragePersisterOptions) { this.options = opts } persistForm = async (persistKey: string, formState: FormState) => { + const serialized = await (this.options.serializer ?? JSON.stringify)({ + buster: this.options.buster ?? '', + state: formState, + }) await this.options.storage?.setItem( makeKey(this.options.prefix, persistKey), - JSON.stringify({ - buster: this.options.buster ?? '', - state: formState, - }), + serialized as TStorageValue, ) } restoreForm = async (persistKey: string) => { - const deserialized = + const persistedValue = (await this.options.storage?.getItem( makeKey(this.options.prefix, persistKey), )) ?? 'null' - const state = JSON.parse(deserialized) as { + const state = ( + this.options.deserializer ?? + (JSON.parse as Required< + StoragePersisterOptions + >['deserializer']) + )(persistedValue as TStorageValue) as { buster: string state: FormState } | null @@ -87,8 +116,8 @@ export class PersisterAPI { } } -export function createFormPersister( - persisterAPI: PersisterAPI, +export function createFormPersister( + persisterAPI: PersisterAPI, formKey: string, ): Persister { return { From 4eff9b8dbcc206ff576881d7ae332e62ec95da9b Mon Sep 17 00:00:00 2001 From: aadito123 Date: Fri, 26 Jan 2024 19:11:22 +0800 Subject: [PATCH 17/32] fine-grained persistense (omitKeys) --- packages/form-persist-core/src/index.ts | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/packages/form-persist-core/src/index.ts b/packages/form-persist-core/src/index.ts index d8d098709..5c3653680 100644 --- a/packages/form-persist-core/src/index.ts +++ b/packages/form-persist-core/src/index.ts @@ -116,14 +116,34 @@ export class PersisterAPI { } } +type CreateFormPersisterOptions = { + omitFields: (keyof TFormData)[] | ((fieldName: keyof TFormData) => boolean) +} + export function createFormPersister( persisterAPI: PersisterAPI, formKey: string, + opts?: CreateFormPersisterOptions, ): Persister { return { deleteForm: () => persisterAPI.deleteForm(formKey), restoreForm: () => persisterAPI.restoreForm(formKey), - persistForm: (state: FormState) => - persisterAPI.persistForm(formKey, state), + persistForm: (state: FormState) => { + // this makes ts happy when we modify the state + const modifiedState: Omit & { + fieldMeta: any + values: any + } = structuredClone(state) // deep cloning to make sure we dont modify state that is referenced inside the form + if (typeof opts?.omitFields === 'function') { + for (const key of Object.keys(modifiedState.values)) + if (opts.omitFields(key as keyof TFormData)) { + delete modifiedState.fieldMeta[key] + delete modifiedState.values[key] + } + } else if (typeof opts?.omitFields === 'object') { + for (const key of opts.omitFields) delete modifiedState.fieldMeta[key] + } + return persisterAPI.persistForm(formKey, modifiedState) + }, } } From 215335f8cd372bbbe2764314afb5fac179f00ec1 Mon Sep 17 00:00:00 2001 From: aadito123 Date: Thu, 8 Feb 2024 17:43:01 +0800 Subject: [PATCH 18/32] delete keys from .values --- packages/form-persist-core/src/index.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/form-persist-core/src/index.ts b/packages/form-persist-core/src/index.ts index 5c3653680..111661590 100644 --- a/packages/form-persist-core/src/index.ts +++ b/packages/form-persist-core/src/index.ts @@ -141,7 +141,10 @@ export function createFormPersister( delete modifiedState.values[key] } } else if (typeof opts?.omitFields === 'object') { - for (const key of opts.omitFields) delete modifiedState.fieldMeta[key] + for (const key of opts.omitFields) { + delete modifiedState.fieldMeta[key] + delete modifiedState.values[key] + } } return persisterAPI.persistForm(formKey, modifiedState) }, From 72f2edeac684be172a09a2ff07054e8ef0415b9e Mon Sep 17 00:00:00 2001 From: aadito123 Date: Fri, 9 Feb 2024 11:13:28 +0800 Subject: [PATCH 19/32] form-persist react adapter --- packages/form-persist-core/package.json | 18 ++--- packages/form-persist-core/src/index.ts | 15 ++-- .../src/tests/persister.spec.ts | 11 +-- packages/form-persist-core/vite.config.ts | 2 +- packages/react-form-persist/.eslintrc.cjs | 13 ++++ packages/react-form-persist/README.md | 35 +++++++++ packages/react-form-persist/package.json | 73 ++++++++++++++++++ packages/react-form-persist/src/index.ts | 20 +++++ .../src/tests/useFormPersister.test.tsx | 74 +++++++++++++++++++ packages/react-form-persist/tsconfig.json | 9 +++ .../react-form-persist/tsconfig.legacy.json | 9 +++ packages/react-form-persist/vite.config.ts | 25 +++++++ pnpm-lock.yaml | 35 ++++++++- scripts/config.ts | 4 + 14 files changed, 319 insertions(+), 24 deletions(-) create mode 100644 packages/react-form-persist/.eslintrc.cjs create mode 100644 packages/react-form-persist/README.md create mode 100644 packages/react-form-persist/package.json create mode 100644 packages/react-form-persist/src/index.ts create mode 100644 packages/react-form-persist/src/tests/useFormPersister.test.tsx create mode 100644 packages/react-form-persist/tsconfig.json create mode 100644 packages/react-form-persist/tsconfig.legacy.json create mode 100644 packages/react-form-persist/vite.config.ts diff --git a/packages/form-persist-core/package.json b/packages/form-persist-core/package.json index 653abf3d4..84935ce18 100644 --- a/packages/form-persist-core/package.json +++ b/packages/form-persist-core/package.json @@ -11,25 +11,25 @@ "url": "https://github.com/sponsors/tannerlinsley" }, "type": "module", - "types": "build/legacy/index.d.ts", - "main": "build/legacy/index.cjs", - "module": "build/legacy/index.js", + "types": "dist/esm/index.d.ts", + "main": "dist/cjs/index.cjs", + "module": "dist/esm/index.js", "exports": { ".": { "import": { - "types": "./build/modern/index.d.ts", - "default": "./build/modern/index.js" + "types": "./dist/esm/index.d.ts", + "default": "./dist/esm/index.js" }, "require": { - "types": "./build/modern/index.d.cts", - "default": "./build/modern/index.cjs" + "types": "./dist/cjs/index.d.cts", + "default": "./dist/cjs/index.cjs" } }, "./package.json": "./package.json" }, "sideEffects": false, "files": [ - "build", + "dist", "src" ], "nx": { @@ -57,4 +57,4 @@ "dependencies": { "@tanstack/form-core": "workspace:*" } -} +} \ No newline at end of file diff --git a/packages/form-persist-core/src/index.ts b/packages/form-persist-core/src/index.ts index 111661590..cee04db78 100644 --- a/packages/form-persist-core/src/index.ts +++ b/packages/form-persist-core/src/index.ts @@ -62,13 +62,13 @@ export interface StoragePersisterOptions { const makeKey = (prefix: string = 'tanstack-form', persistKey: string) => `${prefix}-${persistKey}` -export class PersisterAPI { +export class PersisterAPI { options: StoragePersisterOptions constructor(opts: StoragePersisterOptions) { this.options = opts } - persistForm = async (persistKey: string, formState: FormState) => { + persistForm = async (persistKey: string, formState: FormState) => { const serialized = await (this.options.serializer ?? JSON.stringify)({ buster: this.options.buster ?? '', state: formState, @@ -90,7 +90,7 @@ export class PersisterAPI { >['deserializer']) )(persistedValue as TStorageValue) as { buster: string - state: FormState + state: FormState } | null if (!state || state.buster !== (this.options.buster ?? '')) { this.deleteForm(persistKey) @@ -116,18 +116,19 @@ export class PersisterAPI { } } -type CreateFormPersisterOptions = { - omitFields: (keyof TFormData)[] | ((fieldName: keyof TFormData) => boolean) +export type CreateFormPersisterOptions = { + omitFields?: (keyof TFormData)[] | ((fieldName: keyof TFormData) => boolean) } export function createFormPersister( - persisterAPI: PersisterAPI, + persisterAPI: PersisterAPI, formKey: string, opts?: CreateFormPersisterOptions, ): Persister { return { deleteForm: () => persisterAPI.deleteForm(formKey), - restoreForm: () => persisterAPI.restoreForm(formKey), + restoreForm: () => + persisterAPI.restoreForm(formKey) as Promise>, persistForm: (state: FormState) => { // this makes ts happy when we modify the state const modifiedState: Omit & { diff --git a/packages/form-persist-core/src/tests/persister.spec.ts b/packages/form-persist-core/src/tests/persister.spec.ts index cfb20eda7..be299d110 100644 --- a/packages/form-persist-core/src/tests/persister.spec.ts +++ b/packages/form-persist-core/src/tests/persister.spec.ts @@ -1,16 +1,17 @@ import { FormApi } from '@tanstack/form-core' import { PersisterAPI, createFormPersister } from '..' -import type { StoragePersisterOptions } from '..' import { sleep } from './utils' +import type { StoragePersisterOptions } from '..' + const mapHolder: Record> = {} -const getPersister = ( +const getPersister = ( idKey: string, opts?: Omit, ) => { const persistMap = mapHolder[idKey] || new Map() mapHolder[idKey] = persistMap - return new PersisterAPI({ + return new PersisterAPI({ storage: { getItem(key) { return persistMap.get(key) @@ -28,8 +29,8 @@ const getPersister = ( } const getFormApiPersister = (id: string, formKey: string) => { - const persister = getPersister(id) - return createFormPersister(persister, formKey) + const persister = getPersister(id) + return createFormPersister(persister, formKey) } let id_ = 0 diff --git a/packages/form-persist-core/vite.config.ts b/packages/form-persist-core/vite.config.ts index 2d01612cf..5384a9a79 100644 --- a/packages/form-persist-core/vite.config.ts +++ b/packages/form-persist-core/vite.config.ts @@ -3,7 +3,7 @@ import { tanstackBuildConfig } from '@tanstack/config/build' const config = defineConfig({ test: { - name: 'form-core', + name: 'form-persist-core', dir: './src', watch: false, environment: 'jsdom', diff --git a/packages/react-form-persist/.eslintrc.cjs b/packages/react-form-persist/.eslintrc.cjs new file mode 100644 index 000000000..5f504cf4c --- /dev/null +++ b/packages/react-form-persist/.eslintrc.cjs @@ -0,0 +1,13 @@ +// @ts-check + +/** @type {import('eslint').Linter.Config} */ +const config = { + extends: ['plugin:react/recommended', 'plugin:react-hooks/recommended'], + rules: { + 'react/jsx-key': ['error', { checkFragmentShorthand: true }], + 'react-hooks/exhaustive-deps': 'error', + 'react/no-children-prop': 'off', + }, +} + +module.exports = config diff --git a/packages/react-form-persist/README.md b/packages/react-form-persist/README.md new file mode 100644 index 000000000..936b5c6cf --- /dev/null +++ b/packages/react-form-persist/README.md @@ -0,0 +1,35 @@ + + +![TanStack Form Header](https://github.com/TanStack/form/raw/beta/media/repo-header.png) + +Hooks for managing form state in React + + + #TanStack + + + + + + + + + + semantic-release + + Join the discussion on Github +Best of JS + + + + + Gitpod Ready-to-Code + + +Enjoy this library? Try the entire [TanStack](https://tanstack.com)! [TanStack Table](https://github.com/TanStack/table), [TanStack Router](https://github.com/tanstack/router), [TanStack Virtual](https://github.com/tanstack/virtual), [React Charts](https://github.com/TanStack/react-charts), [React Ranger](https://github.com/TanStack/ranger) + +## Visit [tanstack.com/form](https://tanstack.com/form) for docs, guides, API and more! + +### [Become a Sponsor!](https://github.com/sponsors/tannerlinsley/) + + diff --git a/packages/react-form-persist/package.json b/packages/react-form-persist/package.json new file mode 100644 index 000000000..b2d41eed3 --- /dev/null +++ b/packages/react-form-persist/package.json @@ -0,0 +1,73 @@ +{ + "name": "@tanstack/react-form-persist", + "version": "0.13.5", + "description": "Persistence for Tanstack React Form.", + "author": "tannerlinsley", + "license": "MIT", + "repository": "tanstack/form", + "homepage": "https://tanstack.com/form", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "sideEffects": false, + "scripts": { + "clean": "rimraf ./dist && rimraf ./coverage", + "test:eslint": "eslint --ext .ts,.tsx ./src", + "test:types:versions49": "node ../../node_modules/typescript49/lib/tsc.js --project tsconfig.legacy.json", + "test:types:versions50": "node ../../node_modules/typescript50/lib/tsc.js", + "test:types:versions51": "node ../../node_modules/typescript51/lib/tsc.js", + "test:types:versions52": "tsc", + "test:types": "pnpm run \"/^test:types:versions.*/\"", + "test:lib": "vitest", + "test:lib:dev": "pnpm run test:lib --watch", + "test:build": "publint --strict", + "build": "vite build" + }, + "files": [ + "dist", + "src" + ], + "type": "module", + "types": "dist/esm/index.d.ts", + "main": "dist/cjs/index.cjs", + "module": "dist/esm/index.js", + "exports": { + ".": { + "import": { + "types": "./dist/esm/index.d.ts", + "default": "./dist/esm/index.js" + }, + "require": { + "types": "./dist/cjs/index.d.cts", + "default": "./dist/cjs/index.cjs" + } + }, + "./package.json": "./package.json" + }, + "devDependencies": { + "@types/react": "^18.2.45", + "@types/react-dom": "^18.0.5", + "@types/use-sync-external-store": "^0.0.3", + "@vitejs/plugin-react": "^4.2.1", + "react": "^18.2.0", + "react-dom": "^18.2.0" + }, + "dependencies": { + "@tanstack/form-persist-core": "workspace:*" + }, + "peerDependencies": { + "@tanstack/react-form": "workspace:*", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0", + "react-native": "*" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + } + } +} \ No newline at end of file diff --git a/packages/react-form-persist/src/index.ts b/packages/react-form-persist/src/index.ts new file mode 100644 index 000000000..9ca76d430 --- /dev/null +++ b/packages/react-form-persist/src/index.ts @@ -0,0 +1,20 @@ +import { PersisterAPI, createFormPersister } from '@tanstack/form-persist-core' +import { createContext, useContext, useEffect, useMemo, useState } from 'react' +import type { CreateFormPersisterOptions } from '@tanstack/form-persist-core' + +export { PersisterAPI } + +const persisterApiContext = createContext(null!) + +export const FormPersisterProvider = persisterApiContext.Provider + +export function useFormPersister( + opts: CreateFormPersisterOptions & { formKey: string }, +) { + const persisterApi = useContext(persisterApiContext) + if (!persisterApi) throw new Error('No persisterAPI found') + const [persister] = useState(() => + createFormPersister(persisterApi, opts.formKey, opts), + ) + return persister +} diff --git a/packages/react-form-persist/src/tests/useFormPersister.test.tsx b/packages/react-form-persist/src/tests/useFormPersister.test.tsx new file mode 100644 index 000000000..848d0742f --- /dev/null +++ b/packages/react-form-persist/src/tests/useFormPersister.test.tsx @@ -0,0 +1,74 @@ +/// +import '@testing-library/jest-dom' +import { render, waitFor } from '@testing-library/react' +import userEvent from '@testing-library/user-event' +import * as React from 'react' +import { useForm } from '@tanstack/react-form' + +import { FormPersisterProvider, PersisterAPI, useFormPersister } from '..' +import type { SyncFormStorage } from '@tanstack/form-persist-core' + +const storageMap = new Map() +const storage: SyncFormStorage = { + getItem(key) { + return storageMap.get(key) + }, + setItem(key, value) { + return storageMap.set(key, value) + }, + removeItem(key) { + storageMap.delete(key) + }, +} + +describe('useForm', () => { + it('value should be persisted after re-mount', async () => { + type Person = { + firstName: string + lastName: string + } + + function Comp() { + const form = useForm({ + persister: useFormPersister({ formKey: 'Person' }), + }) + + return ( + + { + return ( + field.handleChange(e.target.value)} + /> + ) + }} + /> + + ) + } + + const renderPage = () => + render( + + + , + ) + + const firstRender = renderPage() + let input = firstRender.getByTestId('fieldinput') + expect(firstRender.queryByText('FirstName')).not.toBeInTheDocument() + await userEvent.type(input, 'FirstName') + expect(input).toHaveValue('FirstName') + firstRender.unmount() + + const secondRender = renderPage() + input = secondRender.getByTestId('fieldinput') + waitFor(() => expect(input).toHaveValue('FirstName')) + }) +}) diff --git a/packages/react-form-persist/tsconfig.json b/packages/react-form-persist/tsconfig.json new file mode 100644 index 000000000..eb996e62e --- /dev/null +++ b/packages/react-form-persist/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "jsx": "react", + "moduleResolution": "Bundler", + "types": ["vitest/globals"] + }, + "include": ["src/**/*.ts", "src/**/*.tsx", ".eslintrc.cjs", "vite.config.ts"] +} diff --git a/packages/react-form-persist/tsconfig.legacy.json b/packages/react-form-persist/tsconfig.legacy.json new file mode 100644 index 000000000..8748cd003 --- /dev/null +++ b/packages/react-form-persist/tsconfig.legacy.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "jsx": "react", + "moduleResolution": "Node" + }, + "include": ["src/**/*.ts", "src/**/*.tsx"], + "exclude": ["src/tests/**"] +} diff --git a/packages/react-form-persist/vite.config.ts b/packages/react-form-persist/vite.config.ts new file mode 100644 index 000000000..8c1350135 --- /dev/null +++ b/packages/react-form-persist/vite.config.ts @@ -0,0 +1,25 @@ +import { defineConfig, mergeConfig } from 'vitest/config' +import { tanstackBuildConfig } from '@tanstack/config/build' +import react from '@vitejs/plugin-react' + +const config = defineConfig({ + plugins: [react()], + test: { + name: 'react-form-persist', + dir: './src', + watch: false, + environment: 'jsdom', + globals: true, + coverage: { enabled: true, provider: 'istanbul', include: ['src/**/*'] }, + typecheck: { enabled: true }, + }, +}) + +export default mergeConfig( + config, + tanstackBuildConfig({ + entry: './src/index.ts', + srcDir: './src', + exclude: ['./src/tests'], + }), +) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4aab9e8b5..7f19276de 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -567,6 +567,37 @@ importers: specifier: ^18.2.0 version: 18.2.0(react@18.2.0) + packages/react-form-persist: + dependencies: + '@tanstack/form-persist-core': + specifier: workspace:* + version: link:../form-persist-core + '@tanstack/react-form': + specifier: workspace:* + version: link:../react-form + react-native: + specifier: '*' + version: 0.72.6(@babel/core@7.23.7)(@babel/preset-env@7.21.5)(react@18.2.0) + devDependencies: + '@types/react': + specifier: ^18.2.45 + version: 18.2.46 + '@types/react-dom': + specifier: ^18.0.5 + version: 18.2.18 + '@types/use-sync-external-store': + specifier: ^0.0.3 + version: 0.0.3 + '@vitejs/plugin-react': + specifier: ^4.2.1 + version: 4.2.1(vite@5.0.12) + react: + specifier: ^18.2.0 + version: 18.2.0 + react-dom: + specifier: ^18.2.0 + version: 18.2.0(react@18.2.0) + packages/solid-form: dependencies: '@tanstack/form-core': @@ -8667,8 +8698,8 @@ packages: resolution: {integrity: sha512-Hh0ncPsHPVf6wXQSqJqB3K9Zbudht4aUtNpNXYXSxH+pteWqGAXnjtPsRAnCsCWl38wL0jYF0rJDdMajUI3BDw==} engines: {node: '>=16'} dependencies: - '@babel/traverse': 7.22.10 - '@babel/types': 7.22.15 + '@babel/traverse': 7.23.7 + '@babel/types': 7.23.6 invariant: 2.2.4 metro-symbolicate: 0.76.8 nullthrows: 1.1.1 diff --git a/scripts/config.ts b/scripts/config.ts index 1c33f3be6..8024ee742 100644 --- a/scripts/config.ts +++ b/scripts/config.ts @@ -7,6 +7,10 @@ export const packages: Package[] = [ name: '@tanstack/form-core', packageDir: 'form-core', }, + { + name: '@tanstack/form-persist-core', + packageDir: 'packages/form-persist-core', + }, { name: '@tanstack/form-persist-core', packageDir: 'form-persist-core', From 118e5e5d79300f48cb61533bbb5c9d9cbd340d53 Mon Sep 17 00:00:00 2001 From: aadito123 Date: Fri, 9 Feb 2024 11:19:19 +0800 Subject: [PATCH 20/32] format + eslint fixes --- packages/form-persist-core/package.json | 2 +- packages/react-form-persist/package.json | 2 +- packages/react-form-persist/src/index.ts | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/form-persist-core/package.json b/packages/form-persist-core/package.json index 84935ce18..4facc3a62 100644 --- a/packages/form-persist-core/package.json +++ b/packages/form-persist-core/package.json @@ -57,4 +57,4 @@ "dependencies": { "@tanstack/form-core": "workspace:*" } -} \ No newline at end of file +} diff --git a/packages/react-form-persist/package.json b/packages/react-form-persist/package.json index b2d41eed3..12281a17f 100644 --- a/packages/react-form-persist/package.json +++ b/packages/react-form-persist/package.json @@ -70,4 +70,4 @@ "optional": true } } -} \ No newline at end of file +} diff --git a/packages/react-form-persist/src/index.ts b/packages/react-form-persist/src/index.ts index 9ca76d430..d879a53ab 100644 --- a/packages/react-form-persist/src/index.ts +++ b/packages/react-form-persist/src/index.ts @@ -1,10 +1,10 @@ import { PersisterAPI, createFormPersister } from '@tanstack/form-persist-core' -import { createContext, useContext, useEffect, useMemo, useState } from 'react' +import { createContext, useContext, useState } from 'react' import type { CreateFormPersisterOptions } from '@tanstack/form-persist-core' export { PersisterAPI } -const persisterApiContext = createContext(null!) +const persisterApiContext = createContext(null) export const FormPersisterProvider = persisterApiContext.Provider From 4048f2483756724c1d2592ea8a011f9eaab15da5 Mon Sep 17 00:00:00 2001 From: aadito123 Date: Mon, 11 Mar 2024 22:29:00 +0800 Subject: [PATCH 21/32] solid-form-persist --- packages/solid-form-persist/.eslintrc.cjs | 6 ++ packages/solid-form-persist/README.md | 35 +++++++++ packages/solid-form-persist/package.json | 56 +++++++++++++++ packages/solid-form-persist/src/index.ts | 18 +++++ .../src/tests/useFormPersister.test.tsx | 72 +++++++++++++++++++ packages/solid-form-persist/test-setup.ts | 6 ++ packages/solid-form-persist/tsconfig.json | 19 +++++ .../solid-form-persist/tsconfig.legacy.json | 14 ++++ packages/solid-form-persist/vite.config.ts | 25 +++++++ 9 files changed, 251 insertions(+) create mode 100644 packages/solid-form-persist/.eslintrc.cjs create mode 100644 packages/solid-form-persist/README.md create mode 100644 packages/solid-form-persist/package.json create mode 100644 packages/solid-form-persist/src/index.ts create mode 100644 packages/solid-form-persist/src/tests/useFormPersister.test.tsx create mode 100644 packages/solid-form-persist/test-setup.ts create mode 100644 packages/solid-form-persist/tsconfig.json create mode 100644 packages/solid-form-persist/tsconfig.legacy.json create mode 100644 packages/solid-form-persist/vite.config.ts diff --git a/packages/solid-form-persist/.eslintrc.cjs b/packages/solid-form-persist/.eslintrc.cjs new file mode 100644 index 000000000..cca134ce1 --- /dev/null +++ b/packages/solid-form-persist/.eslintrc.cjs @@ -0,0 +1,6 @@ +// @ts-check + +/** @type {import('eslint').Linter.Config} */ +const config = {} + +module.exports = config diff --git a/packages/solid-form-persist/README.md b/packages/solid-form-persist/README.md new file mode 100644 index 000000000..a1b8c713e --- /dev/null +++ b/packages/solid-form-persist/README.md @@ -0,0 +1,35 @@ + + +![TanStack Form Header](https://github.com/TanStack/form/raw/beta/media/repo-header.png) + +Hooks for managing form state in Solid + + + #TanStack + + + + + + + + + + semantic-release + + Join the discussion on Github +Best of JS + + + + + Gitpod Ready-to-Code + + +Enjoy this library? Try the entire [TanStack](https://tanstack.com)! [TanStack Table](https://github.com/TanStack/table), [TanStack Router](https://github.com/tanstack/router), [TanStack Virtual](https://github.com/tanstack/virtual), [React Charts](https://github.com/TanStack/react-charts), [React Ranger](https://github.com/TanStack/ranger) + +## Visit [tanstack.com/form](https://tanstack.com/form) for docs, guides, API and more! + +### [Become a Sponsor!](https://github.com/sponsors/tannerlinsley/) + + diff --git a/packages/solid-form-persist/package.json b/packages/solid-form-persist/package.json new file mode 100644 index 000000000..b59bf1101 --- /dev/null +++ b/packages/solid-form-persist/package.json @@ -0,0 +1,56 @@ +{ + "name": "@tanstack/solid-form-persist", + "version": "0.13.7", + "description": "Persistence for Tanstack Solid Form.", + "author": "tannerlinsley", + "license": "MIT", + "repository": "tanstack/form", + "homepage": "https://tanstack.com/form", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "sideEffects": false, + "scripts": { + "clean": "rimraf ./dist && rimraf ./coverage", + "test:eslint": "eslint --ext .ts,.tsx ./src", + "test:types:versions49": "node ../../node_modules/typescript49/lib/tsc.js --project tsconfig.legacy.json", + "test:types:versions50": "node ../../node_modules/typescript50/lib/tsc.js", + "test:types:versions51": "node ../../node_modules/typescript51/lib/tsc.js", + "test:types:versions52": "tsc", + "test:types": "pnpm run \"/^test:types:versions.*/\"", + "test:lib": "vitest", + "test:lib:dev": "pnpm run test:lib --watch", + "test:build": "publint --strict", + "build": "vite build" + }, + "files": [ + "dist", + "src" + ], + "type": "module", + "types": "dist/esm/index.d.ts", + "main": "dist/cjs/index.cjs", + "module": "dist/esm/index.js", + "exports": { + ".": { + "import": { + "types": "./dist/esm/index.d.ts", + "default": "./dist/esm/index.js" + }, + "require": { + "types": "./dist/cjs/index.d.cts", + "default": "./dist/cjs/index.cjs" + } + }, + "./package.json": "./package.json" + }, + "devDependencies": { + "solid-js": "^1.7.8", + "vite-plugin-solid": "^2.10.1" + }, + "peerDependencies": { + "@tanstack/solid-form": "workspace:*", + "solid-js": "^1.6.0" + } +} \ No newline at end of file diff --git a/packages/solid-form-persist/src/index.ts b/packages/solid-form-persist/src/index.ts new file mode 100644 index 000000000..2b595b690 --- /dev/null +++ b/packages/solid-form-persist/src/index.ts @@ -0,0 +1,18 @@ +import { PersisterAPI, createFormPersister } from '@tanstack/form-persist-core' +import { createContext, useContext } from 'solid-js' +import type { CreateFormPersisterOptions } from '@tanstack/form-persist-core' + +export { PersisterAPI } + +const persisterApiContext = createContext(null) + +export const FormPersisterProvider = persisterApiContext.Provider + +export function useFormPersister( + opts: CreateFormPersisterOptions & { formKey: string }, +) { + const persisterApi = useContext(persisterApiContext) + if (!persisterApi) throw new Error('No persisterAPI found') + const persister = createFormPersister(persisterApi, opts.formKey, opts) + return persister +} diff --git a/packages/solid-form-persist/src/tests/useFormPersister.test.tsx b/packages/solid-form-persist/src/tests/useFormPersister.test.tsx new file mode 100644 index 000000000..ebf67a1c7 --- /dev/null +++ b/packages/solid-form-persist/src/tests/useFormPersister.test.tsx @@ -0,0 +1,72 @@ +import { render, waitFor } from '@solidjs/testing-library' +import { createForm } from '@tanstack/solid-form' +import { describe, expect, it } from 'vitest' +import userEvent from '@testing-library/user-event' + +import { FormPersisterProvider, PersisterAPI, useFormPersister } from '..' +import type { SyncFormStorage } from '@tanstack/form-persist-core' + +const storageMap = new Map() +const storage: SyncFormStorage = { + getItem(key) { + return storageMap.get(key) + }, + setItem(key, value) { + return storageMap.set(key, value) + }, + removeItem(key) { + storageMap.delete(key) + }, +} + +describe('useForm', () => { + it('value should be persisted after re-mount', async () => { + type Person = { + firstName: string + lastName: string + } + + function Comp() { + const form = createForm(() => ({ + persister: useFormPersister({ formKey: 'Person' }), + })) + + return ( + + { + return ( + field().handleChange(e.target.value)} + /> + ) + }} + /> + + ) + } + + const renderPage = () => + render(() => ( + + + + )) + + const firstRender = renderPage() + let input = firstRender.getByTestId('fieldinput') + expect(firstRender.queryByText('FirstName')).not.toBeInTheDocument() + await userEvent.type(input, 'FirstName') + expect(input).toHaveValue('FirstName') + firstRender.unmount() + + const secondRender = renderPage() + input = secondRender.getByTestId('fieldinput') + waitFor(() => expect(input).toHaveValue('FirstName')) + }) +}) diff --git a/packages/solid-form-persist/test-setup.ts b/packages/solid-form-persist/test-setup.ts new file mode 100644 index 000000000..c3055e4bd --- /dev/null +++ b/packages/solid-form-persist/test-setup.ts @@ -0,0 +1,6 @@ +import '@testing-library/jest-dom/vitest' +import { cleanup } from '@solidjs/testing-library' +import { afterEach } from 'vitest' + +// https://github.com/solidjs/solid-testing-library +afterEach(() => cleanup()) diff --git a/packages/solid-form-persist/tsconfig.json b/packages/solid-form-persist/tsconfig.json new file mode 100644 index 000000000..c608fa352 --- /dev/null +++ b/packages/solid-form-persist/tsconfig.json @@ -0,0 +1,19 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "jsx": "preserve", + "jsxImportSource": "solid-js", + "moduleResolution": "Bundler", + "paths": { + "@tanstack/solid-form": ["../solid-form/src"], + "@tanstack/form-persist-core": ["../form-persist-core/src"] + } + }, + "include": [ + "src/**/*.ts", + "src/**/*.tsx", + ".eslintrc.cjs", + "test-setup.ts", + "vite.config.ts" + ] +} diff --git a/packages/solid-form-persist/tsconfig.legacy.json b/packages/solid-form-persist/tsconfig.legacy.json new file mode 100644 index 000000000..a1fc5e3c7 --- /dev/null +++ b/packages/solid-form-persist/tsconfig.legacy.json @@ -0,0 +1,14 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "jsx": "preserve", + "jsxImportSource": "solid-js", + "moduleResolution": "Node", + "paths": { + "@tanstack/solid-form": ["../solid-form/src"], + "@tanstack/form-persist-core": ["../form-persist-core/src"] + } + }, + "include": ["src/**/*.ts", "src/**/*.tsx"], + "exclude": ["src/tests/**"] +} diff --git a/packages/solid-form-persist/vite.config.ts b/packages/solid-form-persist/vite.config.ts new file mode 100644 index 000000000..013a9a280 --- /dev/null +++ b/packages/solid-form-persist/vite.config.ts @@ -0,0 +1,25 @@ +import { defineConfig, mergeConfig } from 'vitest/config' +import { tanstackBuildConfig } from '@tanstack/config/build' +import solid from 'vite-plugin-solid' + +const config = defineConfig({ + plugins: [solid()], + test: { + name: 'solid-form', + dir: './src', + watch: false, + environment: 'jsdom', + setupFiles: ['test-setup.ts'], + coverage: { enabled: true, provider: 'istanbul', include: ['src/**/*'] }, + typecheck: { enabled: true }, + }, +}) + +export default mergeConfig( + config, + tanstackBuildConfig({ + entry: './src/index.ts', + srcDir: './src', + exclude: ['./src/tests'], + }), +) From 71bd83db6d7a2afaabde974a46981be557f51f86 Mon Sep 17 00:00:00 2001 From: aadito123 Date: Mon, 11 Mar 2024 22:34:10 +0800 Subject: [PATCH 22/32] add dependency --- packages/solid-form-persist/package.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/solid-form-persist/package.json b/packages/solid-form-persist/package.json index b59bf1101..ece73302d 100644 --- a/packages/solid-form-persist/package.json +++ b/packages/solid-form-persist/package.json @@ -49,6 +49,9 @@ "solid-js": "^1.7.8", "vite-plugin-solid": "^2.10.1" }, + "dependencies": { + "@tanstack/form-persist-core": "workspace:*" + }, "peerDependencies": { "@tanstack/solid-form": "workspace:*", "solid-js": "^1.6.0" From 13f63578484dd488b39f7bc361a62483090ab478 Mon Sep 17 00:00:00 2001 From: aadito123 Date: Mon, 11 Mar 2024 23:04:10 +0800 Subject: [PATCH 23/32] vue-form-persist --- packages/vue-form-persist/.eslintrc.cjs | 6 ++ packages/vue-form-persist/README.md | 35 ++++++++ packages/vue-form-persist/package.json | 60 ++++++++++++++ packages/vue-form-persist/src/index.ts | 21 +++++ .../src/tests/useFormPersister.test.tsx | 81 +++++++++++++++++++ packages/vue-form-persist/test-setup.ts | 6 ++ packages/vue-form-persist/tsconfig.json | 20 +++++ .../vue-form-persist/tsconfig.legacy.json | 15 ++++ packages/vue-form-persist/vite.config.ts | 29 +++++++ 9 files changed, 273 insertions(+) create mode 100644 packages/vue-form-persist/.eslintrc.cjs create mode 100644 packages/vue-form-persist/README.md create mode 100644 packages/vue-form-persist/package.json create mode 100644 packages/vue-form-persist/src/index.ts create mode 100644 packages/vue-form-persist/src/tests/useFormPersister.test.tsx create mode 100644 packages/vue-form-persist/test-setup.ts create mode 100644 packages/vue-form-persist/tsconfig.json create mode 100644 packages/vue-form-persist/tsconfig.legacy.json create mode 100644 packages/vue-form-persist/vite.config.ts diff --git a/packages/vue-form-persist/.eslintrc.cjs b/packages/vue-form-persist/.eslintrc.cjs new file mode 100644 index 000000000..cca134ce1 --- /dev/null +++ b/packages/vue-form-persist/.eslintrc.cjs @@ -0,0 +1,6 @@ +// @ts-check + +/** @type {import('eslint').Linter.Config} */ +const config = {} + +module.exports = config diff --git a/packages/vue-form-persist/README.md b/packages/vue-form-persist/README.md new file mode 100644 index 000000000..d5fd2fedb --- /dev/null +++ b/packages/vue-form-persist/README.md @@ -0,0 +1,35 @@ + + +![TanStack Form Header](https://github.com/TanStack/form/raw/main/media/repo-header.png) + +Hooks for managing form state in Vue + + + #TanStack + + + + + + + + + + semantic-release + + Join the discussion on Github +Best of JS + + + + + Gitpod Ready-to-Code + + +Enjoy this library? Try the entire [TanStack](https://tanstack.com)! [TanStack Table](https://github.com/TanStack/table), [TanStack Router](https://github.com/tanstack/router), [TanStack Virtual](https://github.com/tanstack/virtual), [React Charts](https://github.com/TanStack/react-charts), [React Ranger](https://github.com/TanStack/ranger) + +## Visit [tanstack.com/form](https://tanstack.com/form) for docs, guides, API and more! + +### [Become a Sponsor!](https://github.com/sponsors/tannerlinsley/) + + diff --git a/packages/vue-form-persist/package.json b/packages/vue-form-persist/package.json new file mode 100644 index 000000000..b54974dd4 --- /dev/null +++ b/packages/vue-form-persist/package.json @@ -0,0 +1,60 @@ +{ + "name": "@tanstack/vue-form", + "version": "0.13.7", + "description": "Powerful, type-safe forms for Vue.", + "author": "tannerlinsley", + "license": "MIT", + "repository": "tanstack/form", + "homepage": "https://tanstack.com/form", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "type": "module", + "types": "dist/esm/index.d.ts", + "main": "dist/cjs/index.cjs", + "module": "dist/esm/index.js", + "exports": { + ".": { + "import": { + "types": "./dist/esm/index.d.ts", + "default": "./dist/esm/index.js" + }, + "require": { + "types": "./dist/cjs/index.d.cts", + "default": "./dist/cjs/index.cjs" + } + }, + "./package.json": "./package.json" + }, + "sideEffects": false, + "scripts": { + "clean": "rimraf ./dist && rimraf ./coverage", + "test:eslint": "eslint --ext .ts,.tsx ./src", + "test:types:versions49": "node ../../node_modules/typescript49/lib/tsc.js --project tsconfig.legacy.json", + "test:types:versions50": "node ../../node_modules/typescript50/lib/tsc.js", + "test:types:versions51": "node ../../node_modules/typescript51/lib/tsc.js", + "test:types:versions52": "tsc", + "test:types": "pnpm run \"/^test:types:versions.*/\"", + "fixme:test:lib": "pnpm run test:2 && pnpm run test:2.7 && pnpm run test:3", + "test:lib": "vitest", + "test:lib:dev": "pnpm run test:lib --watch", + "test:build": "publint --strict", + "build": "vite build" + }, + "files": [ + "dist", + "src" + ], + "dependencies": { + "@tanstack/form-persist-core": "workspace:*" + }, + "devDependencies": { + "@vitejs/plugin-vue": "^5.0.4", + "vue": "^3.3.4" + }, + "peerDependencies": { + "@tanstack/vue-form": "workspace:*", + "vue": "^3.3.0" + } +} \ No newline at end of file diff --git a/packages/vue-form-persist/src/index.ts b/packages/vue-form-persist/src/index.ts new file mode 100644 index 000000000..f2ad0ae10 --- /dev/null +++ b/packages/vue-form-persist/src/index.ts @@ -0,0 +1,21 @@ +import { PersisterAPI, createFormPersister } from '@tanstack/form-persist-core' +import { inject, provide } from 'vue' +import type { CreateFormPersisterOptions } from '@tanstack/form-persist-core' + +export { PersisterAPI } + +const persisterApiContext = Symbol('PersisterContext') +//createContext(null) + +export function provideFormPersisterContext(api: PersisterAPI) { + provide(persisterApiContext, api) +} + +export function useFormPersister( + opts: CreateFormPersisterOptions & { formKey: string }, +) { + const persisterApi = inject(persisterApiContext) + if (!persisterApi) throw new Error('No persisterAPI found') + const persister = createFormPersister(persisterApi, opts.formKey, opts) + return persister +} diff --git a/packages/vue-form-persist/src/tests/useFormPersister.test.tsx b/packages/vue-form-persist/src/tests/useFormPersister.test.tsx new file mode 100644 index 000000000..d189cd55b --- /dev/null +++ b/packages/vue-form-persist/src/tests/useFormPersister.test.tsx @@ -0,0 +1,81 @@ +import { describe, expect, it, vi } from 'vitest' +import { defineComponent, h } from 'vue' +import { cleanup, render, waitFor } from '@testing-library/vue' +import { userEvent } from '@testing-library/user-event' +import { provideFormContext, useForm } from '@tanstack/vue-form' + +import { PersisterAPI, provideFormPersisterContext, useFormPersister } from '..' +import type { FieldApi } from '@tanstack/vue-form' +import type { SyncFormStorage } from '@tanstack/form-persist-core' + +const user = userEvent.setup() + +const storageMap = new Map() +const storage: SyncFormStorage = { + getItem(key) { + return storageMap.get(key) + }, + setItem(key, value) { + return storageMap.set(key, value) + }, + removeItem(key) { + storageMap.delete(key) + }, +} + +describe('useForm', () => { + it('value should be persisted after re-mount', async () => { + type Person = { + firstName: string + lastName: string + } + + const FieldComp = defineComponent(() => { + const form = useForm({ + persister: useFormPersister({ formKey: 'Person' }), + }) + + provideFormContext({ formApi: form }) + + return () => ( + + {({ + field, + }: { + field: FieldApi + }) => { + return ( + + field.handleChange((e.target as HTMLInputElement).value) + } + /> + ) + }} + + ) + }) + + const Comp = defineComponent(() => { + provideFormPersisterContext(new PersisterAPI({ storage })) + return () => + }) + + const renderPage = () => render(Comp) + + const firstRender = renderPage() + let input = firstRender.getByTestId('fieldinput') + expect(firstRender.queryByText('FirstName')).not.toBeInTheDocument() + await userEvent.type(input, 'FirstName') + expect(input).toHaveValue('FirstName') + cleanup() // additional cleanup since we are re-mounting + firstRender.unmount() + + const secondRender = renderPage() + input = secondRender.getByTestId('fieldinput') + waitFor(() => expect(input).toHaveValue('FirstName')) + }) +}) diff --git a/packages/vue-form-persist/test-setup.ts b/packages/vue-form-persist/test-setup.ts new file mode 100644 index 000000000..640dd8314 --- /dev/null +++ b/packages/vue-form-persist/test-setup.ts @@ -0,0 +1,6 @@ +import '@testing-library/jest-dom/vitest' +import { cleanup } from '@testing-library/vue' +import { afterEach } from 'vitest' + +// https://testing-library.com/docs/vue-testing-library/api#cleanup +afterEach(() => cleanup()) diff --git a/packages/vue-form-persist/tsconfig.json b/packages/vue-form-persist/tsconfig.json new file mode 100644 index 000000000..546a761f6 --- /dev/null +++ b/packages/vue-form-persist/tsconfig.json @@ -0,0 +1,20 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "jsx": "preserve", + "jsxImportSource": "vue", + "moduleResolution": "Bundler", + "types": ["vue/jsx"], + "paths": { + "@tanstack/vue-form": ["../vue-form/src"], + "@tanstack/form-persist-core": ["../form-persist-core/src"] + } + }, + "include": [ + "src/**/*.ts", + "src/**/*.tsx", + ".eslintrc.cjs", + "test-setup.ts", + "vite.config.ts" + ] +} diff --git a/packages/vue-form-persist/tsconfig.legacy.json b/packages/vue-form-persist/tsconfig.legacy.json new file mode 100644 index 000000000..4e11913be --- /dev/null +++ b/packages/vue-form-persist/tsconfig.legacy.json @@ -0,0 +1,15 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "jsx": "preserve", + "jsxImportSource": "vue", + "moduleResolution": "Node", + "types": ["vue/jsx"], + "paths": { + "@tanstack/vue-form": ["../vue-form/src"], + "@tanstack/form-persist-core": ["../form-persist-core/src"] + } + }, + "include": ["src/**/*.ts", "src/**/*.tsx"], + "exclude": ["src/tests/**"] +} diff --git a/packages/vue-form-persist/vite.config.ts b/packages/vue-form-persist/vite.config.ts new file mode 100644 index 000000000..e4018ebe0 --- /dev/null +++ b/packages/vue-form-persist/vite.config.ts @@ -0,0 +1,29 @@ +import { defineConfig, mergeConfig } from 'vitest/config' +import { tanstackBuildConfig } from '@tanstack/config/build' +import vue from '@vitejs/plugin-vue' + +const config = defineConfig({ + plugins: [vue()], + test: { + name: 'vue-query', + dir: './src', + watch: false, + environment: 'jsdom', + setupFiles: ['test-setup.ts'], + coverage: { enabled: true, provider: 'istanbul', include: ['src/**/*'] }, + typecheck: { enabled: true }, + }, + esbuild: { + jsxFactory: 'h', + jsxFragment: 'Fragment', + }, +}) + +export default mergeConfig( + config, + tanstackBuildConfig({ + entry: './src/index.ts', + srcDir: './src', + exclude: ['./src/tests'], + }), +) From 908d88bf5ae0e0bbc8714e6bde1a8b5feffc082a Mon Sep 17 00:00:00 2001 From: Corbin Crutchley Date: Mon, 11 Mar 2024 10:17:56 -0700 Subject: [PATCH 24/32] chore: fix config and package.json scripts --- packages/form-persist-core/package.json | 2 +- packages/react-form-persist/package.json | 2 +- packages/solid-form-persist/package.json | 4 +- packages/vue-form-persist/package.json | 6 +- pnpm-lock.yaml | 114 +++++++++++++++-------- scripts/config.js | 20 +++- scripts/config.ts | 75 --------------- 7 files changed, 96 insertions(+), 127 deletions(-) delete mode 100644 scripts/config.ts diff --git a/packages/form-persist-core/package.json b/packages/form-persist-core/package.json index 4facc3a62..bc877b911 100644 --- a/packages/form-persist-core/package.json +++ b/packages/form-persist-core/package.json @@ -1,7 +1,7 @@ { "name": "@tanstack/form-persist-core", "version": "0.11.0", - "description": "Persistence for Tanstack Form.", + "description": "Persistence for TanStack Form.", "author": "tannerlinsley", "license": "MIT", "repository": "tanstack/form", diff --git a/packages/react-form-persist/package.json b/packages/react-form-persist/package.json index 12281a17f..a50c9047d 100644 --- a/packages/react-form-persist/package.json +++ b/packages/react-form-persist/package.json @@ -1,7 +1,7 @@ { "name": "@tanstack/react-form-persist", "version": "0.13.5", - "description": "Persistence for Tanstack React Form.", + "description": "Persistence for TanStack React Form.", "author": "tannerlinsley", "license": "MIT", "repository": "tanstack/form", diff --git a/packages/solid-form-persist/package.json b/packages/solid-form-persist/package.json index ece73302d..6e7af17e2 100644 --- a/packages/solid-form-persist/package.json +++ b/packages/solid-form-persist/package.json @@ -1,7 +1,7 @@ { "name": "@tanstack/solid-form-persist", "version": "0.13.7", - "description": "Persistence for Tanstack Solid Form.", + "description": "Persistence for TanStack Solid Form.", "author": "tannerlinsley", "license": "MIT", "repository": "tanstack/form", @@ -56,4 +56,4 @@ "@tanstack/solid-form": "workspace:*", "solid-js": "^1.6.0" } -} \ No newline at end of file +} diff --git a/packages/vue-form-persist/package.json b/packages/vue-form-persist/package.json index b54974dd4..abe8b0d53 100644 --- a/packages/vue-form-persist/package.json +++ b/packages/vue-form-persist/package.json @@ -1,7 +1,7 @@ { - "name": "@tanstack/vue-form", + "name": "@tanstack/vue-form-persist", "version": "0.13.7", - "description": "Powerful, type-safe forms for Vue.", + "description": "Persistence for TanStack Vue Form.", "author": "tannerlinsley", "license": "MIT", "repository": "tanstack/form", @@ -57,4 +57,4 @@ "@tanstack/vue-form": "workspace:*", "vue": "^3.3.0" } -} \ No newline at end of file +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c87e4c5b4..b0a43fcdf 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -611,6 +611,22 @@ importers: specifier: ^2.10.1 version: 2.10.1(@testing-library/jest-dom@6.4.2)(solid-js@1.7.12)(vite@5.0.12) + packages/solid-form-persist: + dependencies: + '@tanstack/form-persist-core': + specifier: workspace:* + version: link:../form-persist-core + '@tanstack/solid-form': + specifier: workspace:* + version: link:../solid-form + devDependencies: + solid-js: + specifier: ^1.7.8 + version: 1.7.12 + vite-plugin-solid: + specifier: ^2.10.1 + version: 2.10.1(@testing-library/jest-dom@6.4.2)(solid-js@1.7.12)(vite@5.0.12) + packages/valibot-form-adapter: dependencies: '@tanstack/form-core': @@ -637,6 +653,22 @@ importers: specifier: ^3.3.4 version: 3.3.4 + packages/vue-form-persist: + dependencies: + '@tanstack/form-persist-core': + specifier: workspace:* + version: link:../form-persist-core + '@tanstack/vue-form': + specifier: workspace:* + version: link:../vue-form + devDependencies: + '@vitejs/plugin-vue': + specifier: ^5.0.4 + version: 5.0.4(vite@5.0.12)(vue@3.3.4) + vue: + specifier: ^3.3.4 + version: 3.3.4 + packages/yup-form-adapter: dependencies: '@tanstack/form-core': @@ -998,7 +1030,7 @@ packages: dependencies: '@babel/core': 7.23.7 '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-plugin-utils': 7.24.0 '@babel/helper-remap-async-to-generator': 7.22.20(@babel/core@7.23.7) '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.23.7) dev: false @@ -1012,7 +1044,7 @@ packages: dependencies: '@babel/core': 7.23.7 '@babel/helper-create-class-features-plugin': 7.24.0(@babel/core@7.23.7) - '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-plugin-utils': 7.24.0 dev: false /@babel/plugin-proposal-export-default-from@7.23.3(@babel/core@7.23.7): @@ -1022,7 +1054,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-plugin-utils': 7.24.0 '@babel/plugin-syntax-export-default-from': 7.23.3(@babel/core@7.23.7) dev: false @@ -1034,7 +1066,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-plugin-utils': 7.24.0 '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.23.7) dev: false @@ -1046,7 +1078,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-plugin-utils': 7.24.0 '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.23.7) dev: false @@ -1060,7 +1092,7 @@ packages: '@babel/compat-data': 7.23.5 '@babel/core': 7.23.7 '@babel/helper-compilation-targets': 7.23.6 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-plugin-utils': 7.24.0 '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.23.7) '@babel/plugin-transform-parameters': 7.23.3(@babel/core@7.23.7) dev: false @@ -1073,7 +1105,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-plugin-utils': 7.24.0 '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.23.7) dev: false @@ -1085,7 +1117,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-plugin-utils': 7.24.0 '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.23.7) dev: false @@ -1105,7 +1137,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-plugin-utils': 7.24.0 dev: false /@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.23.7): @@ -1133,7 +1165,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-plugin-utils': 7.24.0 dev: false /@babel/plugin-syntax-export-default-from@7.23.3(@babel/core@7.23.7): @@ -1143,7 +1175,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-plugin-utils': 7.24.0 dev: false /@babel/plugin-syntax-export-namespace-from@7.8.3(@babel/core@7.23.7): @@ -1162,7 +1194,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-plugin-utils': 7.24.0 dev: false /@babel/plugin-syntax-import-assertions@7.23.3(@babel/core@7.23.7): @@ -1227,7 +1259,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-plugin-utils': 7.24.0 dev: false /@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.23.7): @@ -1236,7 +1268,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-plugin-utils': 7.24.0 dev: false /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.23.7): @@ -1245,7 +1277,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-plugin-utils': 7.24.0 dev: false /@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.23.7): @@ -1254,7 +1286,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-plugin-utils': 7.24.0 dev: false /@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.23.7): @@ -1263,7 +1295,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-plugin-utils': 7.24.0 dev: false /@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.23.7): @@ -1273,7 +1305,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-plugin-utils': 7.24.0 dev: false /@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.23.7): @@ -1293,7 +1325,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-plugin-utils': 7.24.0 dev: false /@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.23.7): @@ -1314,7 +1346,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-plugin-utils': 7.24.0 dev: false /@babel/plugin-transform-async-generator-functions@7.23.9(@babel/core@7.23.7): @@ -1338,7 +1370,7 @@ packages: dependencies: '@babel/core': 7.23.7 '@babel/helper-module-imports': 7.22.15 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-plugin-utils': 7.24.0 '@babel/helper-remap-async-to-generator': 7.22.20(@babel/core@7.23.7) dev: false @@ -1359,7 +1391,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-plugin-utils': 7.24.0 dev: false /@babel/plugin-transform-class-properties@7.23.3(@babel/core@7.23.7): @@ -1396,7 +1428,7 @@ packages: '@babel/helper-compilation-targets': 7.23.6 '@babel/helper-environment-visitor': 7.22.20 '@babel/helper-function-name': 7.23.0 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-plugin-utils': 7.24.0 '@babel/helper-replace-supers': 7.22.20(@babel/core@7.23.7) '@babel/helper-split-export-declaration': 7.22.6 globals: 11.12.0 @@ -1409,7 +1441,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-plugin-utils': 7.24.0 '@babel/template': 7.22.15 dev: false @@ -1420,7 +1452,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-plugin-utils': 7.24.0 dev: false /@babel/plugin-transform-dotall-regex@7.23.3(@babel/core@7.23.7): @@ -1484,7 +1516,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-plugin-utils': 7.24.0 '@babel/plugin-syntax-flow': 7.23.3(@babel/core@7.23.7) dev: false @@ -1508,7 +1540,7 @@ packages: '@babel/core': 7.23.7 '@babel/helper-compilation-targets': 7.23.6 '@babel/helper-function-name': 7.23.0 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-plugin-utils': 7.24.0 dev: false /@babel/plugin-transform-json-strings@7.23.4(@babel/core@7.23.7): @@ -1529,7 +1561,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-plugin-utils': 7.24.0 dev: false /@babel/plugin-transform-logical-assignment-operators@7.23.4(@babel/core@7.23.7): @@ -1572,7 +1604,7 @@ packages: dependencies: '@babel/core': 7.23.7 '@babel/helper-module-transforms': 7.23.3(@babel/core@7.23.7) - '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-plugin-utils': 7.24.0 '@babel/helper-simple-access': 7.22.5 dev: false @@ -1608,7 +1640,7 @@ packages: dependencies: '@babel/core': 7.23.7 '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.23.7) - '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-plugin-utils': 7.24.0 dev: false /@babel/plugin-transform-new-target@7.23.3(@babel/core@7.23.7): @@ -1698,7 +1730,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-plugin-utils': 7.24.0 dev: false /@babel/plugin-transform-private-methods@7.23.3(@babel/core@7.23.7): @@ -1709,7 +1741,7 @@ packages: dependencies: '@babel/core': 7.23.7 '@babel/helper-create-class-features-plugin': 7.24.0(@babel/core@7.23.7) - '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-plugin-utils': 7.24.0 dev: false /@babel/plugin-transform-private-property-in-object@7.23.4(@babel/core@7.23.7): @@ -1721,7 +1753,7 @@ packages: '@babel/core': 7.23.7 '@babel/helper-annotate-as-pure': 7.22.5 '@babel/helper-create-class-features-plugin': 7.24.0(@babel/core@7.23.7) - '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-plugin-utils': 7.24.0 '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.23.7) dev: false @@ -1742,7 +1774,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-plugin-utils': 7.24.0 dev: false /@babel/plugin-transform-react-jsx-self@7.23.3(@babel/core@7.23.7): @@ -1772,7 +1804,7 @@ packages: '@babel/core': 7.23.7 '@babel/helper-annotate-as-pure': 7.22.5 '@babel/helper-module-imports': 7.22.15 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-plugin-utils': 7.24.0 '@babel/plugin-syntax-jsx': 7.23.3(@babel/core@7.23.7) '@babel/types': 7.23.6 dev: false @@ -1822,7 +1854,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-plugin-utils': 7.24.0 dev: false /@babel/plugin-transform-spread@7.23.3(@babel/core@7.23.7): @@ -1832,7 +1864,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-plugin-utils': 7.24.0 '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 dev: false @@ -1843,7 +1875,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-plugin-utils': 7.24.0 dev: false /@babel/plugin-transform-template-literals@7.23.3(@babel/core@7.23.7): @@ -1875,7 +1907,7 @@ packages: '@babel/core': 7.23.7 '@babel/helper-annotate-as-pure': 7.22.5 '@babel/helper-create-class-features-plugin': 7.24.0(@babel/core@7.23.7) - '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-plugin-utils': 7.24.0 '@babel/plugin-syntax-typescript': 7.23.3(@babel/core@7.23.7) dev: false @@ -1908,7 +1940,7 @@ packages: dependencies: '@babel/core': 7.23.7 '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.23.7) - '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-plugin-utils': 7.24.0 dev: false /@babel/plugin-transform-unicode-sets-regex@7.23.3(@babel/core@7.23.7): @@ -2043,7 +2075,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-plugin-utils': 7.24.0 '@babel/helper-validator-option': 7.23.5 '@babel/plugin-syntax-jsx': 7.23.3(@babel/core@7.23.7) '@babel/plugin-transform-modules-commonjs': 7.23.3(@babel/core@7.23.7) diff --git a/scripts/config.js b/scripts/config.js index f45a89235..779fd1d8f 100644 --- a/scripts/config.js +++ b/scripts/config.js @@ -36,10 +36,22 @@ export const packages = [ name: '@tanstack/solid-form', packageDir: 'packages/solid-form', }, - // { - // name: '@tanstack/svelte-form', - // packageDir: 'packages/svelte-form', - // }, + { + name: '@tanstack/form-persist-core', + packageDir: 'packages/form-persist-core', + }, + { + name: '@tanstack/react-form-persist', + packageDir: 'packages/react-form-persist', + }, + { + name: '@tanstack/solid-form-persist', + packageDir: 'packages/solid-form-persist', + }, + { + name: '@tanstack/vue-form-persist', + packageDir: 'packages/vue-form-persist', + }, ] /** diff --git a/scripts/config.ts b/scripts/config.ts deleted file mode 100644 index 8024ee742..000000000 --- a/scripts/config.ts +++ /dev/null @@ -1,75 +0,0 @@ -import path from 'path' -import { BranchConfig, Package } from './types' - -// TODO: List your npm packages here. -export const packages: Package[] = [ - { - name: '@tanstack/form-core', - packageDir: 'form-core', - }, - { - name: '@tanstack/form-persist-core', - packageDir: 'packages/form-persist-core', - }, - { - name: '@tanstack/form-persist-core', - packageDir: 'form-persist-core', - }, - { - name: '@tanstack/react-form', - packageDir: 'react-form', - }, - { - name: '@tanstack/vue-form', - packageDir: 'vue-form', - }, - { - name: '@tanstack/zod-form-adapter', - packageDir: 'zod-form-adapter', - }, - { - name: '@tanstack/yup-form-adapter', - packageDir: 'yup-form-adapter', - }, - { - name: '@tanstack/valibot-form-adapter', - packageDir: 'valibot-form-adapter', - }, - { - name: '@tanstack/solid-form', - packageDir: 'solid-form', - }, - // { - // name: '@tanstack/svelte-form', - // packageDir: 'svelte-form', - // }, -] - -export const latestBranch = 'main' - -export const branchConfigs: Record = { - main: { - prerelease: false, - ghRelease: true, - }, - next: { - prerelease: true, - ghRelease: true, - }, - beta: { - prerelease: true, - ghRelease: true, - }, - alpha: { - prerelease: true, - ghRelease: true, - }, -} - -export const rootDir = path.resolve(__dirname, '..') -export const examplesDirs = [ - 'examples/react', - 'examples/vue', - 'examples/solid', - // 'examples/svelte', -] From 5e252ab677dd8e4f5c7a372405fdf7c5058a515e Mon Sep 17 00:00:00 2001 From: aadito123 Date: Tue, 12 Mar 2024 10:12:06 +0800 Subject: [PATCH 25/32] fix fast-forward --- packages/react-form-persist/src/tests/useFormPersister.test.tsx | 2 +- packages/solid-form-persist/tsconfig.json | 2 +- packages/vue-form-persist/package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/react-form-persist/src/tests/useFormPersister.test.tsx b/packages/react-form-persist/src/tests/useFormPersister.test.tsx index 848d0742f..279e226c6 100644 --- a/packages/react-form-persist/src/tests/useFormPersister.test.tsx +++ b/packages/react-form-persist/src/tests/useFormPersister.test.tsx @@ -32,7 +32,7 @@ describe('useForm', () => { const form = useForm({ persister: useFormPersister({ formKey: 'Person' }), }) - + form.options.persister! return ( Date: Sun, 17 Mar 2024 20:12:06 +0800 Subject: [PATCH 26/32] pnpm-lock --- pnpm-lock.yaml | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8f62fbc81..a3714a190 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -616,6 +616,12 @@ importers: specifier: ^0.3.1 version: 0.3.1 + packages/form-persist-core: + dependencies: + '@tanstack/form-core': + specifier: workspace:* + version: link:../form-core + packages/lit-form: dependencies: '@tanstack/form-core': @@ -4507,10 +4513,34 @@ packages: resolution: {integrity: sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==} dev: true + /@types/stack-utils@2.0.3: + resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==} + dev: false + /@types/trusted-types@2.0.7: resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} dev: false + /@types/use-sync-external-store@0.0.3: + resolution: {integrity: sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==} + dev: true + + /@types/yargs-parser@21.0.3: + resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} + dev: false + + /@types/yargs@15.0.19: + resolution: {integrity: sha512-2XUaGVmyQjgyAZldf0D0c14vvo/yv0MhQBSTJcejMMaitsn3nxCB6TmH4G0ZQf+uxROOa9mpanoSm8h6SG/1ZA==} + dependencies: + '@types/yargs-parser': 21.0.3 + dev: false + + /@types/yargs@17.0.32: + resolution: {integrity: sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==} + dependencies: + '@types/yargs-parser': 21.0.3 + dev: false + /@typescript-eslint/eslint-plugin@6.20.0(@typescript-eslint/parser@6.20.0)(eslint@8.56.0)(typescript@5.2.2): resolution: {integrity: sha512-fTwGQUnjhoYHeSF6m5pWNkzmDDdsKELYrOBxhjMrofPqCkoC2k3B2wvGHFxa1CTIqkEn88nlW1HVMztjo2K8Hg==} engines: {node: ^16.0.0 || >=18.0.0} From b650bba6fea37268341fa9f533351b8eef4217db Mon Sep 17 00:00:00 2001 From: aadito123 Date: Fri, 22 Mar 2024 00:01:14 +0800 Subject: [PATCH 27/32] formatting + sherif fixes --- packages/form-core/src/tests/FormApi.spec.ts | 12 +++---- .../src/tests/persister.spec.ts | 4 +-- packages/react-form-persist/package.json | 7 ++-- .../src/tests/useFormPersister.test.tsx | 32 +++++++++---------- .../src/tests/useFormPersister.test.tsx | 32 +++++++++---------- packages/vue-form-persist/package.json | 2 +- .../src/tests/useFormPersister.test.tsx | 4 +-- scripts/config.js | 4 +-- 8 files changed, 44 insertions(+), 53 deletions(-) diff --git a/packages/form-core/src/tests/FormApi.spec.ts b/packages/form-core/src/tests/FormApi.spec.ts index 8fd2a7b37..52a5b9168 100644 --- a/packages/form-core/src/tests/FormApi.spec.ts +++ b/packages/form-core/src/tests/FormApi.spec.ts @@ -22,10 +22,10 @@ describe('form api', () => { isRestored: false, isRestoring: false, isSubmitting: false, - isTouched: false, + isTouched: false, isPristine: true, isDirty: false, - isValid: true, + isValid: false, isValidating: false, submissionAttempts: 0, validationMetaMap: { @@ -62,7 +62,7 @@ describe('form api', () => { isTouched: false, isPristine: true, isDirty: false, - isValid: true, + isValid: false, isValidating: false, isRestored: false, isRestoring: false, @@ -100,7 +100,7 @@ describe('form api', () => { isTouched: false, isPristine: true, isDirty: false, - isValid: true, + isValid: false, isValidating: false, submissionAttempts: 30, validationMetaMap: { @@ -146,7 +146,7 @@ describe('form api', () => { isTouched: false, isPristine: true, isDirty: false, - isValid: true, + isValid: false, isRestored: false, isRestoring: false, isValidating: false, @@ -190,7 +190,7 @@ describe('form api', () => { isTouched: false, isPristine: true, isDirty: false, - isValid: true, + isValid: false, isValidating: false, isRestored: false, isRestoring: false, diff --git a/packages/form-persist-core/src/tests/persister.spec.ts b/packages/form-persist-core/src/tests/persister.spec.ts index be299d110..fd88f8e51 100644 --- a/packages/form-persist-core/src/tests/persister.spec.ts +++ b/packages/form-persist-core/src/tests/persister.spec.ts @@ -1,8 +1,8 @@ import { FormApi } from '@tanstack/form-core' -import { PersisterAPI, createFormPersister } from '..' +import { PersisterAPI, createFormPersister } from '../index' import { sleep } from './utils' -import type { StoragePersisterOptions } from '..' +import type { StoragePersisterOptions } from '../index' const mapHolder: Record> = {} const getPersister = ( diff --git a/packages/react-form-persist/package.json b/packages/react-form-persist/package.json index a50c9047d..1707ba002 100644 --- a/packages/react-form-persist/package.json +++ b/packages/react-form-persist/package.json @@ -47,11 +47,8 @@ }, "devDependencies": { "@types/react": "^18.2.45", - "@types/react-dom": "^18.0.5", - "@types/use-sync-external-store": "^0.0.3", "@vitejs/plugin-react": "^4.2.1", - "react": "^18.2.0", - "react-dom": "^18.2.0" + "react": "^18.2.0" }, "dependencies": { "@tanstack/form-persist-core": "workspace:*" @@ -70,4 +67,4 @@ "optional": true } } -} +} \ No newline at end of file diff --git a/packages/react-form-persist/src/tests/useFormPersister.test.tsx b/packages/react-form-persist/src/tests/useFormPersister.test.tsx index 279e226c6..a57d183cd 100644 --- a/packages/react-form-persist/src/tests/useFormPersister.test.tsx +++ b/packages/react-form-persist/src/tests/useFormPersister.test.tsx @@ -5,7 +5,7 @@ import userEvent from '@testing-library/user-event' import * as React from 'react' import { useForm } from '@tanstack/react-form' -import { FormPersisterProvider, PersisterAPI, useFormPersister } from '..' +import { FormPersisterProvider, PersisterAPI, useFormPersister } from '../index' import type { SyncFormStorage } from '@tanstack/form-persist-core' const storageMap = new Map() @@ -34,22 +34,20 @@ describe('useForm', () => { }) form.options.persister! return ( - - { - return ( - field.handleChange(e.target.value)} - /> - ) - }} - /> - + { + return ( + field.handleChange(e.target.value)} + /> + ) + }} + /> ) } diff --git a/packages/solid-form-persist/src/tests/useFormPersister.test.tsx b/packages/solid-form-persist/src/tests/useFormPersister.test.tsx index ebf67a1c7..d920ba4c3 100644 --- a/packages/solid-form-persist/src/tests/useFormPersister.test.tsx +++ b/packages/solid-form-persist/src/tests/useFormPersister.test.tsx @@ -3,7 +3,7 @@ import { createForm } from '@tanstack/solid-form' import { describe, expect, it } from 'vitest' import userEvent from '@testing-library/user-event' -import { FormPersisterProvider, PersisterAPI, useFormPersister } from '..' +import { FormPersisterProvider, PersisterAPI, useFormPersister } from '../index' import type { SyncFormStorage } from '@tanstack/form-persist-core' const storageMap = new Map() @@ -32,22 +32,20 @@ describe('useForm', () => { })) return ( - - { - return ( - field().handleChange(e.target.value)} - /> - ) - }} - /> - + { + return ( + field().handleChange(e.target.value)} + /> + ) + }} + /> ) } diff --git a/packages/vue-form-persist/package.json b/packages/vue-form-persist/package.json index 4d162c50d..abe8b0d53 100644 --- a/packages/vue-form-persist/package.json +++ b/packages/vue-form-persist/package.json @@ -57,4 +57,4 @@ "@tanstack/vue-form": "workspace:*", "vue": "^3.3.0" } -} \ No newline at end of file +} diff --git a/packages/vue-form-persist/src/tests/useFormPersister.test.tsx b/packages/vue-form-persist/src/tests/useFormPersister.test.tsx index d189cd55b..a5a44e719 100644 --- a/packages/vue-form-persist/src/tests/useFormPersister.test.tsx +++ b/packages/vue-form-persist/src/tests/useFormPersister.test.tsx @@ -2,7 +2,7 @@ import { describe, expect, it, vi } from 'vitest' import { defineComponent, h } from 'vue' import { cleanup, render, waitFor } from '@testing-library/vue' import { userEvent } from '@testing-library/user-event' -import { provideFormContext, useForm } from '@tanstack/vue-form' +import { useForm } from '@tanstack/vue-form' import { PersisterAPI, provideFormPersisterContext, useFormPersister } from '..' import type { FieldApi } from '@tanstack/vue-form' @@ -35,8 +35,6 @@ describe('useForm', () => { persister: useFormPersister({ formKey: 'Person' }), }) - provideFormContext({ formApi: form }) - return () => ( {({ diff --git a/scripts/config.js b/scripts/config.js index 98e94131f..5f6312a94 100644 --- a/scripts/config.js +++ b/scripts/config.js @@ -39,7 +39,7 @@ export const packages = [ { name: '@tanstack/lit-form', packageDir: 'packages/lit-form', - }, + }, { name: '@tanstack/form-persist-core', packageDir: 'packages/form-persist-core', @@ -59,7 +59,7 @@ export const packages = [ // { // name: '@tanstack/svelte-form', // packageDir: 'packages/svelte-form', - // }, + // }, ] /** From c324206b8377e8fb84a257532f0e27f1dc9cdabf Mon Sep 17 00:00:00 2001 From: aadito123 Date: Fri, 22 Mar 2024 00:05:18 +0800 Subject: [PATCH 28/32] Revert "formatting + sherif fixes" This reverts commit b650bba6fea37268341fa9f533351b8eef4217db. --- packages/form-core/src/tests/FormApi.spec.ts | 12 +++---- .../src/tests/persister.spec.ts | 4 +-- packages/react-form-persist/package.json | 7 ++-- .../src/tests/useFormPersister.test.tsx | 32 ++++++++++--------- .../src/tests/useFormPersister.test.tsx | 32 ++++++++++--------- packages/vue-form-persist/package.json | 2 +- .../src/tests/useFormPersister.test.tsx | 4 ++- scripts/config.js | 4 +-- 8 files changed, 53 insertions(+), 44 deletions(-) diff --git a/packages/form-core/src/tests/FormApi.spec.ts b/packages/form-core/src/tests/FormApi.spec.ts index 52a5b9168..8fd2a7b37 100644 --- a/packages/form-core/src/tests/FormApi.spec.ts +++ b/packages/form-core/src/tests/FormApi.spec.ts @@ -22,10 +22,10 @@ describe('form api', () => { isRestored: false, isRestoring: false, isSubmitting: false, - isTouched: false, + isTouched: false, isPristine: true, isDirty: false, - isValid: false, + isValid: true, isValidating: false, submissionAttempts: 0, validationMetaMap: { @@ -62,7 +62,7 @@ describe('form api', () => { isTouched: false, isPristine: true, isDirty: false, - isValid: false, + isValid: true, isValidating: false, isRestored: false, isRestoring: false, @@ -100,7 +100,7 @@ describe('form api', () => { isTouched: false, isPristine: true, isDirty: false, - isValid: false, + isValid: true, isValidating: false, submissionAttempts: 30, validationMetaMap: { @@ -146,7 +146,7 @@ describe('form api', () => { isTouched: false, isPristine: true, isDirty: false, - isValid: false, + isValid: true, isRestored: false, isRestoring: false, isValidating: false, @@ -190,7 +190,7 @@ describe('form api', () => { isTouched: false, isPristine: true, isDirty: false, - isValid: false, + isValid: true, isValidating: false, isRestored: false, isRestoring: false, diff --git a/packages/form-persist-core/src/tests/persister.spec.ts b/packages/form-persist-core/src/tests/persister.spec.ts index fd88f8e51..be299d110 100644 --- a/packages/form-persist-core/src/tests/persister.spec.ts +++ b/packages/form-persist-core/src/tests/persister.spec.ts @@ -1,8 +1,8 @@ import { FormApi } from '@tanstack/form-core' -import { PersisterAPI, createFormPersister } from '../index' +import { PersisterAPI, createFormPersister } from '..' import { sleep } from './utils' -import type { StoragePersisterOptions } from '../index' +import type { StoragePersisterOptions } from '..' const mapHolder: Record> = {} const getPersister = ( diff --git a/packages/react-form-persist/package.json b/packages/react-form-persist/package.json index 1707ba002..a50c9047d 100644 --- a/packages/react-form-persist/package.json +++ b/packages/react-form-persist/package.json @@ -47,8 +47,11 @@ }, "devDependencies": { "@types/react": "^18.2.45", + "@types/react-dom": "^18.0.5", + "@types/use-sync-external-store": "^0.0.3", "@vitejs/plugin-react": "^4.2.1", - "react": "^18.2.0" + "react": "^18.2.0", + "react-dom": "^18.2.0" }, "dependencies": { "@tanstack/form-persist-core": "workspace:*" @@ -67,4 +70,4 @@ "optional": true } } -} \ No newline at end of file +} diff --git a/packages/react-form-persist/src/tests/useFormPersister.test.tsx b/packages/react-form-persist/src/tests/useFormPersister.test.tsx index a57d183cd..279e226c6 100644 --- a/packages/react-form-persist/src/tests/useFormPersister.test.tsx +++ b/packages/react-form-persist/src/tests/useFormPersister.test.tsx @@ -5,7 +5,7 @@ import userEvent from '@testing-library/user-event' import * as React from 'react' import { useForm } from '@tanstack/react-form' -import { FormPersisterProvider, PersisterAPI, useFormPersister } from '../index' +import { FormPersisterProvider, PersisterAPI, useFormPersister } from '..' import type { SyncFormStorage } from '@tanstack/form-persist-core' const storageMap = new Map() @@ -34,20 +34,22 @@ describe('useForm', () => { }) form.options.persister! return ( - { - return ( - field.handleChange(e.target.value)} - /> - ) - }} - /> + + { + return ( + field.handleChange(e.target.value)} + /> + ) + }} + /> + ) } diff --git a/packages/solid-form-persist/src/tests/useFormPersister.test.tsx b/packages/solid-form-persist/src/tests/useFormPersister.test.tsx index d920ba4c3..ebf67a1c7 100644 --- a/packages/solid-form-persist/src/tests/useFormPersister.test.tsx +++ b/packages/solid-form-persist/src/tests/useFormPersister.test.tsx @@ -3,7 +3,7 @@ import { createForm } from '@tanstack/solid-form' import { describe, expect, it } from 'vitest' import userEvent from '@testing-library/user-event' -import { FormPersisterProvider, PersisterAPI, useFormPersister } from '../index' +import { FormPersisterProvider, PersisterAPI, useFormPersister } from '..' import type { SyncFormStorage } from '@tanstack/form-persist-core' const storageMap = new Map() @@ -32,20 +32,22 @@ describe('useForm', () => { })) return ( - { - return ( - field().handleChange(e.target.value)} - /> - ) - }} - /> + + { + return ( + field().handleChange(e.target.value)} + /> + ) + }} + /> + ) } diff --git a/packages/vue-form-persist/package.json b/packages/vue-form-persist/package.json index abe8b0d53..4d162c50d 100644 --- a/packages/vue-form-persist/package.json +++ b/packages/vue-form-persist/package.json @@ -57,4 +57,4 @@ "@tanstack/vue-form": "workspace:*", "vue": "^3.3.0" } -} +} \ No newline at end of file diff --git a/packages/vue-form-persist/src/tests/useFormPersister.test.tsx b/packages/vue-form-persist/src/tests/useFormPersister.test.tsx index a5a44e719..d189cd55b 100644 --- a/packages/vue-form-persist/src/tests/useFormPersister.test.tsx +++ b/packages/vue-form-persist/src/tests/useFormPersister.test.tsx @@ -2,7 +2,7 @@ import { describe, expect, it, vi } from 'vitest' import { defineComponent, h } from 'vue' import { cleanup, render, waitFor } from '@testing-library/vue' import { userEvent } from '@testing-library/user-event' -import { useForm } from '@tanstack/vue-form' +import { provideFormContext, useForm } from '@tanstack/vue-form' import { PersisterAPI, provideFormPersisterContext, useFormPersister } from '..' import type { FieldApi } from '@tanstack/vue-form' @@ -35,6 +35,8 @@ describe('useForm', () => { persister: useFormPersister({ formKey: 'Person' }), }) + provideFormContext({ formApi: form }) + return () => ( {({ diff --git a/scripts/config.js b/scripts/config.js index 5f6312a94..98e94131f 100644 --- a/scripts/config.js +++ b/scripts/config.js @@ -39,7 +39,7 @@ export const packages = [ { name: '@tanstack/lit-form', packageDir: 'packages/lit-form', - }, + }, { name: '@tanstack/form-persist-core', packageDir: 'packages/form-persist-core', @@ -59,7 +59,7 @@ export const packages = [ // { // name: '@tanstack/svelte-form', // packageDir: 'packages/svelte-form', - // }, + // }, ] /** From 995a7fd88c14947051fcb731a9da0f8b9be4a033 Mon Sep 17 00:00:00 2001 From: aadito123 Date: Fri, 22 Mar 2024 00:10:53 +0800 Subject: [PATCH 29/32] remove .Provider + sherif + knip + prettier --- packages/form-core/src/tests/FormApi.spec.ts | 4 +-- .../src/tests/persister.spec.ts | 4 +-- packages/react-form-persist/package.json | 8 ++--- .../src/tests/useFormPersister.test.tsx | 32 +++++++++---------- .../src/tests/useFormPersister.test.tsx | 30 ++++++++--------- packages/vue-form-persist/package.json | 2 +- .../src/tests/useFormPersister.test.tsx | 4 +-- scripts/config.js | 4 +-- 8 files changed, 39 insertions(+), 49 deletions(-) diff --git a/packages/form-core/src/tests/FormApi.spec.ts b/packages/form-core/src/tests/FormApi.spec.ts index 8fd2a7b37..7282b27f6 100644 --- a/packages/form-core/src/tests/FormApi.spec.ts +++ b/packages/form-core/src/tests/FormApi.spec.ts @@ -22,10 +22,10 @@ describe('form api', () => { isRestored: false, isRestoring: false, isSubmitting: false, - isTouched: false, + isTouched: false, isPristine: true, isDirty: false, - isValid: true, + isValid: true, isValidating: false, submissionAttempts: 0, validationMetaMap: { diff --git a/packages/form-persist-core/src/tests/persister.spec.ts b/packages/form-persist-core/src/tests/persister.spec.ts index be299d110..fd88f8e51 100644 --- a/packages/form-persist-core/src/tests/persister.spec.ts +++ b/packages/form-persist-core/src/tests/persister.spec.ts @@ -1,8 +1,8 @@ import { FormApi } from '@tanstack/form-core' -import { PersisterAPI, createFormPersister } from '..' +import { PersisterAPI, createFormPersister } from '../index' import { sleep } from './utils' -import type { StoragePersisterOptions } from '..' +import type { StoragePersisterOptions } from '../index' const mapHolder: Record> = {} const getPersister = ( diff --git a/packages/react-form-persist/package.json b/packages/react-form-persist/package.json index a50c9047d..22ee3ea83 100644 --- a/packages/react-form-persist/package.json +++ b/packages/react-form-persist/package.json @@ -47,11 +47,8 @@ }, "devDependencies": { "@types/react": "^18.2.45", - "@types/react-dom": "^18.0.5", - "@types/use-sync-external-store": "^0.0.3", "@vitejs/plugin-react": "^4.2.1", - "react": "^18.2.0", - "react-dom": "^18.2.0" + "react": "^18.2.0" }, "dependencies": { "@tanstack/form-persist-core": "workspace:*" @@ -59,7 +56,6 @@ "peerDependencies": { "@tanstack/react-form": "workspace:*", "react": "^17.0.0 || ^18.0.0", - "react-dom": "^17.0.0 || ^18.0.0", "react-native": "*" }, "peerDependenciesMeta": { @@ -70,4 +66,4 @@ "optional": true } } -} +} \ No newline at end of file diff --git a/packages/react-form-persist/src/tests/useFormPersister.test.tsx b/packages/react-form-persist/src/tests/useFormPersister.test.tsx index 279e226c6..a57d183cd 100644 --- a/packages/react-form-persist/src/tests/useFormPersister.test.tsx +++ b/packages/react-form-persist/src/tests/useFormPersister.test.tsx @@ -5,7 +5,7 @@ import userEvent from '@testing-library/user-event' import * as React from 'react' import { useForm } from '@tanstack/react-form' -import { FormPersisterProvider, PersisterAPI, useFormPersister } from '..' +import { FormPersisterProvider, PersisterAPI, useFormPersister } from '../index' import type { SyncFormStorage } from '@tanstack/form-persist-core' const storageMap = new Map() @@ -34,22 +34,20 @@ describe('useForm', () => { }) form.options.persister! return ( - - { - return ( - field.handleChange(e.target.value)} - /> - ) - }} - /> - + { + return ( + field.handleChange(e.target.value)} + /> + ) + }} + /> ) } diff --git a/packages/solid-form-persist/src/tests/useFormPersister.test.tsx b/packages/solid-form-persist/src/tests/useFormPersister.test.tsx index ebf67a1c7..28e84e8b3 100644 --- a/packages/solid-form-persist/src/tests/useFormPersister.test.tsx +++ b/packages/solid-form-persist/src/tests/useFormPersister.test.tsx @@ -32,22 +32,20 @@ describe('useForm', () => { })) return ( - - { - return ( - field().handleChange(e.target.value)} - /> - ) - }} - /> - + { + return ( + field().handleChange(e.target.value)} + /> + ) + }} + /> ) } diff --git a/packages/vue-form-persist/package.json b/packages/vue-form-persist/package.json index 4d162c50d..abe8b0d53 100644 --- a/packages/vue-form-persist/package.json +++ b/packages/vue-form-persist/package.json @@ -57,4 +57,4 @@ "@tanstack/vue-form": "workspace:*", "vue": "^3.3.0" } -} \ No newline at end of file +} diff --git a/packages/vue-form-persist/src/tests/useFormPersister.test.tsx b/packages/vue-form-persist/src/tests/useFormPersister.test.tsx index d189cd55b..a5a44e719 100644 --- a/packages/vue-form-persist/src/tests/useFormPersister.test.tsx +++ b/packages/vue-form-persist/src/tests/useFormPersister.test.tsx @@ -2,7 +2,7 @@ import { describe, expect, it, vi } from 'vitest' import { defineComponent, h } from 'vue' import { cleanup, render, waitFor } from '@testing-library/vue' import { userEvent } from '@testing-library/user-event' -import { provideFormContext, useForm } from '@tanstack/vue-form' +import { useForm } from '@tanstack/vue-form' import { PersisterAPI, provideFormPersisterContext, useFormPersister } from '..' import type { FieldApi } from '@tanstack/vue-form' @@ -35,8 +35,6 @@ describe('useForm', () => { persister: useFormPersister({ formKey: 'Person' }), }) - provideFormContext({ formApi: form }) - return () => ( {({ diff --git a/scripts/config.js b/scripts/config.js index 98e94131f..5f6312a94 100644 --- a/scripts/config.js +++ b/scripts/config.js @@ -39,7 +39,7 @@ export const packages = [ { name: '@tanstack/lit-form', packageDir: 'packages/lit-form', - }, + }, { name: '@tanstack/form-persist-core', packageDir: 'packages/form-persist-core', @@ -59,7 +59,7 @@ export const packages = [ // { // name: '@tanstack/svelte-form', // packageDir: 'packages/svelte-form', - // }, + // }, ] /** From b552447015996f5634846aedd4c8ef6de8b03a41 Mon Sep 17 00:00:00 2001 From: aadito123 Date: Fri, 22 Mar 2024 00:28:30 +0800 Subject: [PATCH 30/32] form-core test fix --- packages/form-core/src/tests/FormApi.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/form-core/src/tests/FormApi.spec.ts b/packages/form-core/src/tests/FormApi.spec.ts index 7282b27f6..05a13d5d4 100644 --- a/packages/form-core/src/tests/FormApi.spec.ts +++ b/packages/form-core/src/tests/FormApi.spec.ts @@ -25,7 +25,7 @@ describe('form api', () => { isTouched: false, isPristine: true, isDirty: false, - isValid: true, + isValid: false, isValidating: false, submissionAttempts: 0, validationMetaMap: { From 3124b1013ed50b8f4b4e2987f88ea3326f2591d6 Mon Sep 17 00:00:00 2001 From: aadito123 Date: Fri, 22 Mar 2024 00:33:36 +0800 Subject: [PATCH 31/32] format + test fixes --- packages/form-persist-core/package.json | 2 +- packages/react-form-persist/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/form-persist-core/package.json b/packages/form-persist-core/package.json index bc877b911..8828bb58f 100644 --- a/packages/form-persist-core/package.json +++ b/packages/form-persist-core/package.json @@ -48,7 +48,7 @@ "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.only", + "test:types": "pnpm run \"/^test:types:versions.*/\"", "test:lib": "vitest run --coverage", "test:lib:dev": "pnpm run test:lib --watch", "test:build": "publint --strict", diff --git a/packages/react-form-persist/package.json b/packages/react-form-persist/package.json index 22ee3ea83..c77a795c1 100644 --- a/packages/react-form-persist/package.json +++ b/packages/react-form-persist/package.json @@ -66,4 +66,4 @@ "optional": true } } -} \ No newline at end of file +} From 0c24ff24fe5e715a0b01ef157a1a9d4009e99f70 Mon Sep 17 00:00:00 2001 From: aadito123 Date: Fri, 22 Mar 2024 00:36:14 +0800 Subject: [PATCH 32/32] lockfile update --- pnpm-lock.yaml | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 329d67906..d7223bbb0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -681,21 +681,12 @@ importers: '@types/react': specifier: ^18.2.45 version: 18.2.46 - '@types/react-dom': - specifier: ^18.0.5 - version: 18.2.19 - '@types/use-sync-external-store': - specifier: ^0.0.3 - version: 0.0.3 '@vitejs/plugin-react': specifier: ^4.2.1 version: 4.2.1(vite@5.0.12) react: specifier: ^18.2.0 version: 18.2.0 - react-dom: - specifier: ^18.2.0 - version: 18.2.0(react@18.2.0) packages/solid-form: dependencies: @@ -4521,10 +4512,6 @@ packages: resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} dev: false - /@types/use-sync-external-store@0.0.3: - resolution: {integrity: sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==} - dev: true - /@types/yargs-parser@21.0.3: resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} dev: false