@embeddables/forms 0.0.4 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"react.cjs","names":["useRef","useCallback","useSyncExternalStore","useEmbeddablesModule","useRef","useState","useCallback","initForms"],"sources":["../src/react/use-form-store.ts","../src/react/forms-registry.ts","../src/react/use-forms.ts","../src/react/use-form.ts","../src/react/use-form-errors.ts","../src/react/use-form-field.ts","../src/react/resolve-core-analytics.ts","../src/react/register-forms-client.ts","../src/react/forms-module.ts"],"sourcesContent":["import { useCallback, useRef, useSyncExternalStore } from 'react'\n\nimport type { FormSchema, FormValues } from '../core/config.js'\nimport type { FieldErrors, FormInstance } from '../core/form.js'\n\nexport type FormSnapshot<TSchema extends FormSchema> = Readonly<{\n values: Partial<FormValues<TSchema>>\n errors: FieldErrors<TSchema>\n}>\n\nconst EMPTY_SNAPSHOT: FormSnapshot<FormSchema> = Object.freeze({\n values: {},\n errors: {},\n})\n\nfunction createSnapshot<TSchema extends FormSchema>(\n form: FormInstance<TSchema>,\n): FormSnapshot<TSchema> {\n return Object.freeze({\n values: form.getAll(),\n errors: form.errors(),\n })\n}\n\ninterface CachedSnapshot<TSchema extends FormSchema> {\n readonly form: FormInstance<TSchema>\n readonly snapshot: FormSnapshot<TSchema>\n}\n\nexport function useFormSnapshot<TSchema extends FormSchema>(\n form: FormInstance<TSchema> | null,\n): FormSnapshot<TSchema> {\n const cachedRef = useRef<CachedSnapshot<TSchema> | null>(null)\n const emptyRef = useRef<FormSnapshot<TSchema>>(EMPTY_SNAPSHOT as FormSnapshot<TSchema>)\n\n const subscribe = useCallback(\n (listener: () => void) => {\n if (form === null) return () => undefined\n return form.subscribe(() => {\n cachedRef.current = { form, snapshot: createSnapshot(form) }\n listener()\n })\n },\n [form],\n )\n\n const getSnapshot = useCallback((): FormSnapshot<TSchema> => {\n if (form === null) {\n // * Otherwise a later A -> null -> mutate A -> A sequence would resurrect\n // * a snapshot cached before the detach, missing the mutation in between.\n cachedRef.current = null\n return emptyRef.current\n }\n // * A cached snapshot from a previous form instance must not survive a\n // * form change — recompute so switching forms without a mutation still\n // * returns the new form's values and errors.\n if (cachedRef.current === null || cachedRef.current.form !== form) {\n cachedRef.current = { form, snapshot: createSnapshot(form) }\n }\n return cachedRef.current.snapshot\n }, [form])\n\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot)\n}\n","import type { FormSchemaMap, FormsClient } from '../core/form.js'\n\nexport const FORMS_MODULE_KEY = 'forms'\n\n/**\n * Idempotence guard for `registerFormsClient` only — React reads the client\n * from provider context, not from here.\n */\nexport const formsByCore = new WeakMap<object, FormsClient<FormSchemaMap>>()\n","import { useEmbeddablesModule } from '@embeddables/core/react'\n\nimport { FORMS_MODULE_KEY } from './forms-registry.js'\n\nimport type { FormSchemaMap, FormsClient, InitFormsOptions } from '../core/form.js'\n\nexport type FormsReactOptions<TSchemas extends FormSchemaMap = FormSchemaMap> = Omit<\n InitFormsOptions<TSchemas>,\n 'core'\n>\n\n/** @internal Product hooks read the module client from provider context. */\nexport function useRegisteredFormsClient<\n TSchemas extends FormSchemaMap = FormSchemaMap,\n>(): FormsClient<TSchemas> | null {\n return useEmbeddablesModule<FormsClient<TSchemas>>({ key: FORMS_MODULE_KEY })\n}\n","import { useRef } from 'react'\n\nimport { useFormSnapshot } from './use-form-store.js'\nimport { useRegisteredFormsClient } from './use-forms.js'\n\nimport type { CustomValidationsFor, FormInstance, FormSchemaMap } from '../core/form.js'\nimport type { RegisteredSchemas } from './schema-registry.js'\n\n/**\n * Reactive binding for one declared form.\n *\n * Takes no type arguments: `TFormId` is inferred from `formId`, and the schema\n * map comes from the registry `em build` augments. Pass both explicitly\n * (`useForm<'signup', OtherSchemas>`) only to work against a map other than the\n * registered one.\n */\nexport function useForm<\n TFormId extends keyof TSchemas & string,\n TSchemas extends FormSchemaMap = RegisteredSchemas,\n>({\n formId,\n customValidations,\n}: {\n formId: TFormId\n customValidations?: CustomValidationsFor<TSchemas[TFormId]>\n}): {\n form: FormInstance<TSchemas[TFormId]> | null\n values: ReturnType<typeof useFormSnapshot<TSchemas[TFormId]>>['values']\n errors: ReturnType<typeof useFormSnapshot<TSchemas[TFormId]>>['errors']\n} {\n const client = useRegisteredFormsClient<TSchemas>()\n // * Held in a ref because only the first call for a form id builds the\n // * instance; a later render passing new validators must not look like a change.\n const customValidationsRef = useRef(customValidations)\n customValidationsRef.current = customValidations\n\n // * Safe to call on every render: the client returns one instance per form id.\n const form =\n client === null\n ? null\n : client.getForm({ formId, customValidations: customValidationsRef.current })\n const { values, errors } = useFormSnapshot(form)\n\n return { form, values, errors }\n}\n\n// prueba de la colisión\n","import { useFormSnapshot } from './use-form-store.js'\n\nimport type { FormSchema } from '../core/config.js'\nimport type { FieldErrors, FormInstance } from '../core/form.js'\n\nexport function useFormErrors<TSchema extends FormSchema>(\n form: FormInstance<TSchema> | null,\n): FieldErrors<TSchema> {\n const { errors } = useFormSnapshot(form)\n return errors\n}\n","import { useCallback, useEffect, useState } from 'react'\n\nimport { useFormSnapshot } from './use-form-store.js'\n\nimport type { FormFieldKey, FormSchema, FormValues } from '../core/config.js'\nimport type { FieldErrors, FormInstance, SetResult } from '../core/form.js'\n\nconst noopSetValue = async (): Promise<SetResult<FormSchema>> => ({\n ok: false,\n errors: {},\n})\n\nexport function useFormField<const TSchema extends FormSchema, K extends FormFieldKey<TSchema>>({\n form,\n key,\n}: {\n form: FormInstance<TSchema> | null\n key: K\n}): {\n value: FormValues<TSchema>[K] | undefined\n error: readonly string[] | undefined\n setValue: (value: FormValues<TSchema>[K]) => void\n onBlur: () => Promise<SetResult<TSchema>>\n} {\n const { values, errors } = useFormSnapshot(form)\n const committed = values[key]\n const [draft, setDraft] = useState<FormValues<TSchema>[K] | undefined>(committed)\n\n useEffect(() => {\n setDraft(committed)\n }, [form, key, committed])\n\n const setValue = useCallback((value: FormValues<TSchema>[K]) => {\n setDraft(value)\n }, [])\n\n const onBlur = useCallback(async (): Promise<SetResult<TSchema>> => {\n if (form === null) return noopSetValue()\n if (draft === committed) {\n return { ok: true, errors: {} as FieldErrors<TSchema> }\n }\n return form.set({ [key]: draft } as Partial<FormValues<TSchema>>)\n }, [committed, draft, form, key])\n\n if (form === null) {\n return {\n value: undefined,\n error: undefined,\n setValue: () => undefined,\n onBlur: async () => noopSetValue(),\n }\n }\n\n return {\n value: draft,\n error: errors[key],\n setValue,\n onBlur,\n }\n}\n","import type { AnalyticsInstance } from '@embeddables/core'\nimport type { EmbeddablesInstance } from '@embeddables/core'\n\nexport function resolveCoreAnalyticsInstance(\n core: EmbeddablesInstance,\n): AnalyticsInstance | undefined {\n if (typeof core.getAnalyticsInstance !== 'function') return undefined\n return core.getAnalyticsInstance() ?? undefined\n}\n","import { initForms } from '../core/form.js'\nimport { formsByCore } from './forms-registry.js'\nimport { resolveCoreAnalyticsInstance } from './resolve-core-analytics.js'\n\nimport type { FormSchemaMap, FormsClient, InitFormsOptions } from '../core/form.js'\n\nexport function registerFormsClient<const TSchemas extends FormSchemaMap>({\n core,\n ...options\n}: InitFormsOptions<TSchemas>): FormsClient<TSchemas> {\n const existing = formsByCore.get(core) as FormsClient<TSchemas> | undefined\n if (existing !== undefined) return existing\n\n const analyticsInstance = options.analyticsInstance ?? resolveCoreAnalyticsInstance(core)\n\n const client = initForms({ ...options, core, analyticsInstance })\n formsByCore.set(core, client as FormsClient<FormSchemaMap>)\n return client\n}\n","import type { EmbeddablesReactModule } from '@embeddables/core/react'\n\nimport { FORMS_MODULE_KEY } from './forms-registry.js'\nimport { registerFormsClient } from './register-forms-client.js'\n\nimport type { FormSchemaMap, FormsClient } from '../core/form.js'\nimport type { FormsReactOptions } from './use-forms.js'\n\nexport type { FormsReactOptions } from './use-forms.js'\n\nexport function forms<const TSchemas extends FormSchemaMap>(\n options: FormsReactOptions<TSchemas>,\n): EmbeddablesReactModule<FormsClient<TSchemas>> {\n return {\n key: FORMS_MODULE_KEY,\n init: (core) => registerFormsClient({ core, ...options }),\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"react.cjs","names":["useRef","useCallback","useSyncExternalStore","useEmbeddablesModule","useState","useCallback","initForms","FormsError"],"sources":["../src/react/use-form-store.ts","../src/react/forms-registry.ts","../src/react/use-forms.ts","../src/react/use-form.ts","../src/react/use-form-errors.ts","../src/react/use-form-field.ts","../src/react/resolve-core-analytics.ts","../src/react/register-forms-client.ts","../src/react/forms-module.ts"],"sourcesContent":["import { useCallback, useRef, useSyncExternalStore } from 'react'\n\nimport type { FormSchema, FormValues } from '../core/config.js'\nimport type { FieldErrors, FormInstance } from '../core/form.js'\n\nexport type FormSnapshot<TSchema extends FormSchema> = Readonly<{\n values: Partial<FormValues<TSchema>>\n errors: FieldErrors<TSchema>\n}>\n\nconst EMPTY_SNAPSHOT: FormSnapshot<FormSchema> = Object.freeze({\n values: {},\n errors: {},\n})\n\nfunction createSnapshot<TSchema extends FormSchema>(\n form: FormInstance<TSchema>,\n): FormSnapshot<TSchema> {\n return Object.freeze({\n values: form.getAll(),\n errors: form.errors(),\n })\n}\n\ninterface CachedSnapshot<TSchema extends FormSchema> {\n readonly form: FormInstance<TSchema>\n readonly snapshot: FormSnapshot<TSchema>\n}\n\nexport function useFormSnapshot<TSchema extends FormSchema>(\n form: FormInstance<TSchema> | null,\n): FormSnapshot<TSchema> {\n const cachedRef = useRef<CachedSnapshot<TSchema> | null>(null)\n const emptyRef = useRef<FormSnapshot<TSchema>>(EMPTY_SNAPSHOT as FormSnapshot<TSchema>)\n\n const subscribe = useCallback(\n (listener: () => void) => {\n if (form === null) return () => undefined\n return form.subscribe(() => {\n cachedRef.current = { form, snapshot: createSnapshot(form) }\n listener()\n })\n },\n [form],\n )\n\n const getSnapshot = useCallback((): FormSnapshot<TSchema> => {\n if (form === null) {\n // * Otherwise a later A -> null -> mutate A -> A sequence would resurrect\n // * a snapshot cached before the detach, missing the mutation in between.\n cachedRef.current = null\n return emptyRef.current\n }\n // * A cached snapshot from a previous form instance must not survive a\n // * form change — recompute so switching forms without a mutation still\n // * returns the new form's values and errors.\n if (cachedRef.current === null || cachedRef.current.form !== form) {\n cachedRef.current = { form, snapshot: createSnapshot(form) }\n }\n return cachedRef.current.snapshot\n }, [form])\n\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot)\n}\n","import type { FormSchemaMap, FormsClient } from '../core/form.js'\n\nexport const FORMS_MODULE_KEY = 'forms'\n\n/**\n * Idempotence guard for `registerFormsClient` only — React reads the client\n * from provider context, not from here.\n */\nexport const formsByCore = new WeakMap<object, FormsClient<FormSchemaMap>>()\n\nexport function getRegisteredFormsClient(core: object): FormsClient<FormSchemaMap> | undefined {\n return formsByCore.get(core)\n}\n","import { useEmbeddablesModule } from '@embeddables/core/react'\n\nimport { FORMS_MODULE_KEY } from './forms-registry.js'\n\nimport type { FormSchemaMap, FormsClient, InitFormsOptions } from '../core/form.js'\n\nexport type FormsReactOptions<TSchemas extends FormSchemaMap = FormSchemaMap> = Omit<\n InitFormsOptions<TSchemas>,\n 'core'\n>\n\n/** @internal Product hooks read the module client from provider context. */\nexport function useRegisteredFormsClient<\n TSchemas extends FormSchemaMap = FormSchemaMap,\n>(): FormsClient<TSchemas> | null {\n return useEmbeddablesModule<FormsClient<TSchemas>>({ key: FORMS_MODULE_KEY })\n}\n","import { useFormSnapshot } from './use-form-store.js'\nimport { useRegisteredFormsClient } from './use-forms.js'\n\nimport type { FormInstance, FormSchemaMap } from '../core/form.js'\nimport type { RegisteredSchemas } from './schema-registry.js'\n\n/**\n * Reactive binding for one declared form.\n *\n * Takes no type arguments: `TFormId` is inferred from `formId`, and the schema\n * map comes from the registry `em build` augments. Pass both explicitly\n * (`useForm<'signup', OtherSchemas>`) only to work against a map other than the\n * registered one.\n */\nexport function useForm<\n TFormId extends keyof TSchemas & string,\n TSchemas extends FormSchemaMap = RegisteredSchemas,\n>({\n formId,\n}: {\n formId: TFormId\n}): {\n form: FormInstance<TSchemas[TFormId]> | null\n values: ReturnType<typeof useFormSnapshot<TSchemas[TFormId]>>['values']\n errors: ReturnType<typeof useFormSnapshot<TSchemas[TFormId]>>['errors']\n} {\n const client = useRegisteredFormsClient<TSchemas>()\n\n // * Safe to call on every render: the client returns one instance per form id.\n const form = client === null ? null : client.getForm({ formId })\n const { values, errors } = useFormSnapshot(form)\n\n return { form, values, errors }\n}\n","import { useFormSnapshot } from './use-form-store.js'\n\nimport type { FormSchema } from '../core/config.js'\nimport type { FieldErrors, FormInstance } from '../core/form.js'\n\nexport function useFormErrors<TSchema extends FormSchema>(\n form: FormInstance<TSchema> | null,\n): FieldErrors<TSchema> {\n const { errors } = useFormSnapshot(form)\n return errors\n}\n","import { useCallback, useEffect, useState } from 'react'\n\nimport { useFormSnapshot } from './use-form-store.js'\n\nimport type { FormFieldKey, FormSchema, FormValues } from '../core/config.js'\nimport type { FieldErrors, FormInstance, SetResult } from '../core/form.js'\n\nconst noopSetValue = async (): Promise<SetResult<FormSchema>> => ({\n ok: false,\n errors: {},\n})\n\nexport function useFormField<const TSchema extends FormSchema, K extends FormFieldKey<TSchema>>({\n form,\n key,\n}: {\n form: FormInstance<TSchema> | null\n key: K\n}): {\n value: FormValues<TSchema>[K] | undefined\n error: readonly string[] | undefined\n setValue: (value: FormValues<TSchema>[K] | undefined) => void\n commit: (value: FormValues<TSchema>[K] | undefined) => Promise<SetResult<TSchema>>\n onBlur: () => Promise<SetResult<TSchema>>\n} {\n const { values, errors } = useFormSnapshot(form)\n const committed = values[key]\n const [draft, setDraft] = useState<FormValues<TSchema>[K] | undefined>(committed)\n\n useEffect(() => {\n setDraft(committed)\n }, [form, key, committed])\n\n const setValue = useCallback((value: FormValues<TSchema>[K] | undefined) => {\n setDraft(value)\n }, [])\n\n // * Takes the value as an argument rather than reading `draft`, so it is\n // * correct when called in the same tick as the change that produced it.\n // * `onBlur` cannot be: it compares the `draft`/`committed` pair captured in\n // * the current render, which a same-tick `setValue` has not updated yet.\n const commit = useCallback(\n (value: FormValues<TSchema>[K] | undefined): Promise<SetResult<TSchema>> => {\n if (form === null) return noopSetValue()\n // * Keeps the control responsive while `set` runs, and keeps a rejected\n // * value on screen next to its error instead of snapping back.\n setDraft(value)\n return form.set({ [key]: value } as Partial<FormValues<TSchema>>)\n },\n [form, key],\n )\n\n const onBlur = useCallback(async (): Promise<SetResult<TSchema>> => {\n if (form === null) return noopSetValue()\n if (draft === committed) {\n return { ok: true, errors: {} as FieldErrors<TSchema> }\n }\n return form.set({ [key]: draft } as Partial<FormValues<TSchema>>)\n }, [committed, draft, form, key])\n\n if (form === null) {\n return {\n value: undefined,\n error: undefined,\n setValue: () => undefined,\n commit: async () => noopSetValue(),\n onBlur: async () => noopSetValue(),\n }\n }\n\n return {\n value: draft,\n error: errors[key],\n setValue,\n commit,\n onBlur,\n }\n}\n","import type { AnalyticsInstance } from '@embeddables/core'\nimport type { EmbeddablesInstance } from '@embeddables/core'\n\nexport function resolveCoreAnalyticsInstance(\n core: EmbeddablesInstance,\n): AnalyticsInstance | undefined {\n if (typeof core.getAnalyticsInstance !== 'function') return undefined\n return core.getAnalyticsInstance() ?? undefined\n}\n","import { initForms } from '../core/form.js'\nimport { formsByCore } from './forms-registry.js'\nimport { resolveCoreAnalyticsInstance } from './resolve-core-analytics.js'\n\nimport type { FormsClient, InitFormsOptions } from '../core/form.js'\nimport type { RegisteredSchemas } from './schema-registry.js'\n\ninterface RegisterFormsModuleClientOptions extends InitFormsOptions<RegisteredSchemas> {\n /**\n * Set when `excludeAnalyticsInModules` names Forms. The exclusion is absolute:\n * it suppresses the Core-instance fallback as well as the injected client.\n */\n disableAnalyticsFallback?: boolean\n}\n\nfunction register({\n disableAnalyticsFallback,\n ...options\n}: RegisterFormsModuleClientOptions): FormsClient<RegisteredSchemas> {\n const { core } = options\n const existing = formsByCore.get(core)\n if (existing !== undefined) return existing\n\n const analyticsInstance = disableAnalyticsFallback\n ? undefined\n : (options.analyticsInstance ?? resolveCoreAnalyticsInstance(core))\n\n const client = initForms<RegisteredSchemas>({ ...options, core, analyticsInstance })\n formsByCore.set(core, client)\n return client\n}\n\nexport function registerFormsClient(\n options: InitFormsOptions<RegisteredSchemas>,\n): FormsClient<RegisteredSchemas> {\n return register(options)\n}\n\nexport function registerFormsModuleClient(\n options: RegisterFormsModuleClientOptions,\n): FormsClient<RegisteredSchemas> {\n return register(options)\n}\n","import type { EmbeddablesReactModule } from '@embeddables/core/react'\n\nimport { FormsError } from '../errors.js'\nimport { FORMS_MODULE_KEY } from './forms-registry.js'\nimport { registerFormsModuleClient } from './register-forms-client.js'\n\nimport type { AnalyticsInstance } from '../core/analytics.js'\nimport type { FormsClient } from '../core/form.js'\nimport type { RegisteredSchemas } from './schema-registry.js'\nimport type { FormsReactOptions } from './use-forms.js'\n\nexport type { FormsReactOptions } from './use-forms.js'\n\n/**\n * What `EmbeddablesProvider` accepts under its top-level `forms` prop.\n *\n * `analyticsInstance` is deliberately absent: the provider injects the\n * Analytics module client through module dependencies, so an app never wires\n * that instance by hand.\n */\nexport type FormsProviderOptions = Omit<FormsReactOptions<RegisteredSchemas>, 'analyticsInstance'>\n\ndeclare module '@embeddables/core/react' {\n interface EmbeddablesReactModuleParameters {\n readonly forms: FormsProviderOptions\n }\n}\n\nconst ANALYTICS_MODULE_KEY = 'analytics'\n\nfunction resolveInjectedAnalytics(value: unknown): AnalyticsInstance | undefined {\n if (value === undefined) return undefined\n if (typeof value !== 'object' || value === null) {\n throw new FormsError('Forms received an invalid Analytics module dependency.')\n }\n const candidate = value as Partial<AnalyticsInstance>\n if (\n typeof candidate.trackEvent !== 'function' ||\n typeof candidate.getAppUserId !== 'function' ||\n typeof candidate.getProjectId !== 'function'\n ) {\n throw new FormsError('Forms received an invalid Analytics module dependency.')\n }\n return candidate as AnalyticsInstance\n}\n\nexport function forms(\n options: FormsReactOptions<RegisteredSchemas> = {},\n): EmbeddablesReactModule<FormsClient<RegisteredSchemas>, FormsProviderOptions> {\n return {\n key: FORMS_MODULE_KEY,\n dependencies: [{ key: ANALYTICS_MODULE_KEY, optional: true }],\n init: (core, context) => {\n const analyticsInstance = context?.analyticsExcluded\n ? undefined\n : (options.analyticsInstance ??\n resolveInjectedAnalytics(context?.dependencies.get(ANALYTICS_MODULE_KEY)))\n\n return registerFormsModuleClient({\n core,\n customValidations: context?.parameters?.customValidations ?? options.customValidations,\n serverFormData: context?.parameters?.serverFormData ?? options.serverFormData,\n analyticsInstance,\n disableAnalyticsFallback: context?.analyticsExcluded,\n })\n },\n }\n}\n"],"mappings":"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"}
package/dist/react.d.ts CHANGED
@@ -1,4 +1,5 @@
1
- import { a as FormsClient, b as FormValues, i as FormSchemaMap, n as FieldErrors, o as InitFormsOptions, r as FormInstance, s as SetResult, t as CustomValidationsFor, v as FormFieldKey, y as FormSchema } from "./form-CbU5ezg7.js";
1
+ import "./index-BB698udY.js";
2
+ import { E as FormValues, T as FormSchema, a as FormSchemaMap, f as SetResult, i as FormInstance, l as InitFormsOptions, n as FieldErrors, s as FormsClient, w as FormFieldKey } from "./form-Br23yPDS.js";
2
3
  import { EmbeddablesReactModule } from "@embeddables/core/react";
3
4
  //#region src/react/use-form-store.d.ts
4
5
  type FormSnapshot<TSchema extends FormSchema> = Readonly<{
@@ -44,9 +45,8 @@ type RegisteredSchemas = EmbeddablesSchemaRegistry extends {
44
45
  * (`useForm<'signup', OtherSchemas>`) only to work against a map other than the
45
46
  * registered one.
46
47
  */
47
- declare function useForm<TFormId extends keyof TSchemas & string, TSchemas extends FormSchemaMap = RegisteredSchemas>({ formId, customValidations }: {
48
+ declare function useForm<TFormId extends keyof TSchemas & string, TSchemas extends FormSchemaMap = RegisteredSchemas>({ formId }: {
48
49
  formId: TFormId;
49
- customValidations?: CustomValidationsFor<TSchemas[TFormId]>;
50
50
  }): {
51
51
  form: FormInstance<TSchemas[TFormId]> | null;
52
52
  values: ReturnType<typeof useFormSnapshot<TSchemas[TFormId]>>['values'];
@@ -63,7 +63,8 @@ declare function useFormField<const TSchema extends FormSchema, K extends FormFi
63
63
  }): {
64
64
  value: FormValues<TSchema>[K] | undefined;
65
65
  error: readonly string[] | undefined;
66
- setValue: (value: FormValues<TSchema>[K]) => void;
66
+ setValue: (value: FormValues<TSchema>[K] | undefined) => void;
67
+ commit: (value: FormValues<TSchema>[K] | undefined) => Promise<SetResult<TSchema>>;
67
68
  onBlur: () => Promise<SetResult<TSchema>>;
68
69
  };
69
70
  //#endregion
@@ -71,10 +72,26 @@ declare function useFormField<const TSchema extends FormSchema, K extends FormFi
71
72
  type FormsReactOptions<TSchemas extends FormSchemaMap = FormSchemaMap> = Omit<InitFormsOptions<TSchemas>, 'core'>;
72
73
  //#endregion
73
74
  //#region src/react/forms-module.d.ts
74
- declare function forms<const TSchemas extends FormSchemaMap>(options: FormsReactOptions<TSchemas>): EmbeddablesReactModule<FormsClient<TSchemas>>;
75
+ /**
76
+ * What `EmbeddablesProvider` accepts under its top-level `forms` prop.
77
+ *
78
+ * `analyticsInstance` is deliberately absent: the provider injects the
79
+ * Analytics module client through module dependencies, so an app never wires
80
+ * that instance by hand.
81
+ */
82
+ type FormsProviderOptions = Omit<FormsReactOptions<RegisteredSchemas>, 'analyticsInstance'>;
83
+ declare module '@embeddables/core/react' {
84
+ interface EmbeddablesReactModuleParameters {
85
+ readonly forms: FormsProviderOptions;
86
+ }
87
+ }
88
+ declare function forms(options?: FormsReactOptions<RegisteredSchemas>): EmbeddablesReactModule<FormsClient<RegisteredSchemas>, FormsProviderOptions>;
75
89
  //#endregion
76
90
  //#region src/react/register-forms-client.d.ts
77
- declare function registerFormsClient<const TSchemas extends FormSchemaMap>({ core, ...options }: InitFormsOptions<TSchemas>): FormsClient<TSchemas>;
91
+ declare function registerFormsClient(options: InitFormsOptions<RegisteredSchemas>): FormsClient<RegisteredSchemas>;
92
+ //#endregion
93
+ //#region src/react/forms-registry.d.ts
94
+ declare function getRegisteredFormsClient(core: object): FormsClient<FormSchemaMap> | undefined;
78
95
  //#endregion
79
- export { type EmbeddablesSchemaRegistry, type FormsReactOptions, type RegisteredSchemas, forms, registerFormsClient, useForm, useFormErrors, useFormField };
96
+ export { type EmbeddablesSchemaRegistry, type FormsProviderOptions, type FormsReactOptions, type RegisteredSchemas, forms, getRegisteredFormsClient, registerFormsClient, useForm, useFormErrors, useFormField };
80
97
  //# sourceMappingURL=react.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"react.d.ts","names":[],"sources":["../src/react/use-form-store.ts","../src/react/schema-registry.ts","../src/react/use-form.ts","../src/react/use-form-errors.ts","../src/react/use-form-field.ts","../src/react/use-forms.ts","../src/react/forms-module.ts","../src/react/register-forms-client.ts"],"mappings":";;;KAKY,aAAa,gBAAgB,cAAc;EACrD,QAAQ,QAAQ,WAAW;EAC3B,QAAQ,YAAY;;iBAsBN,gBAAgB,gBAAgB,YAC9C,MAAM,aAAa,kBAClB,aAAa;;;;;;;;;;;;;;;;;;;;UCXC;;;;;;KAOL,oBAAoB;EAC9B,aAAa,iBAAiB;IAE5B,WACA;;;;;;;;;;;iBCfY,QACd,sBAAsB,mBACtB,iBAAiB,gBAAgB,qBAEjC,QACA;EAEA,QAAQ;EACR,oBAAoB,qBAAqB,SAAS;;EAElD,MAAM,aAAa,SAAS;EAC5B,QAAQ,kBAAkB,gBAAgB,SAAS;EACnD,QAAQ,kBAAkB,gBAAgB,SAAS;;;;iBCvBrC,cAAc,gBAAgB,YAC5C,MAAM,aAAa,kBAClB,YAAY;;;iBCKC,mBAAmB,gBAAgB,YAAY,UAAU,aAAa,YACpF,MACA;EAEA,MAAM,aAAa;EACnB,KAAK;;EAEL,OAAO,WAAW,SAAS;EAC3B;EACA,WAAW,OAAO,WAAW,SAAS;EACtC,cAAc,QAAQ,UAAU;;;;KChBtB,kBAAkB,iBAAiB,gBAAgB,iBAAiB,KAC9E,iBAAiB;;;iBCGH,YAAY,iBAAiB,eAC3C,SAAS,kBAAkB,YAC1B,uBAAuB,YAAY;;;iBCNtB,0BAA0B,iBAAiB,iBACzD,SACG,WACF,iBAAiB,YAAY,YAAY"}
1
+ {"version":3,"file":"react.d.ts","names":[],"sources":["../src/react/use-form-store.ts","../src/react/schema-registry.ts","../src/react/use-form.ts","../src/react/use-form-errors.ts","../src/react/use-form-field.ts","../src/react/use-forms.ts","../src/react/forms-module.ts","../src/react/register-forms-client.ts","../src/react/forms-registry.ts"],"mappings":";;;;KAKY,aAAa,gBAAgB,cAAc;EACrD,QAAQ,QAAQ,WAAW;EAC3B,QAAQ,YAAY;;iBAsBN,gBAAgB,gBAAgB,YAC9C,MAAM,aAAa,kBAClB,aAAa;;;;;;;;;;;;;;;;;;;;UCXC;;;;;;KAOL,oBAAoB;EAC9B,aAAa,iBAAiB;IAE5B,WACA;;;;;;;;;;;iBCjBY,QACd,sBAAsB,mBACtB,iBAAiB,gBAAgB,qBAEjC;EAEA,QAAQ;;EAER,MAAM,aAAa,SAAS;EAC5B,QAAQ,kBAAkB,gBAAgB,SAAS;EACnD,QAAQ,kBAAkB,gBAAgB,SAAS;;;;iBCnBrC,cAAc,gBAAgB,YAC5C,MAAM,aAAa,kBAClB,YAAY;;;iBCKC,mBAAmB,gBAAgB,YAAY,UAAU,aAAa,YACpF,MACA;EAEA,MAAM,aAAa;EACnB,KAAK;;EAEL,OAAO,WAAW,SAAS;EAC3B;EACA,WAAW,OAAO,WAAW,SAAS;EACtC,SAAS,OAAO,WAAW,SAAS,mBAAmB,QAAQ,UAAU;EACzE,cAAc,QAAQ,UAAU;;;;KCjBtB,kBAAkB,iBAAiB,gBAAgB,iBAAiB,KAC9E,iBAAiB;;;;;;;;;;KCaP,uBAAuB,KAAK,kBAAkB;;YAG9C;aACC,OAAO;;;iBAsBJ,MACd,UAAS,kBAAkB,qBAC1B,uBAAuB,YAAY,oBAAoB;;;iBChB1C,oBACd,SAAS,iBAAiB,qBACzB,YAAY;;;iBCxBC,yBAAyB,eAAe,YAAY"}
package/dist/react.js CHANGED
@@ -1,4 +1,4 @@
1
- import { t as initForms } from "./form-9Tp91g6a.js";
1
+ import { n as initForms, s as FormsError } from "./form-Bt5pwVP6.js";
2
2
  import { useCallback, useEffect, useRef, useState, useSyncExternalStore } from "react";
3
3
  import { useEmbeddablesModule } from "@embeddables/core/react";
4
4
  //#region src/react/use-form-store.ts
@@ -46,6 +46,9 @@ const FORMS_MODULE_KEY = "forms";
46
46
  * from provider context, not from here.
47
47
  */
48
48
  const formsByCore = /* @__PURE__ */ new WeakMap();
49
+ function getRegisteredFormsClient(core) {
50
+ return formsByCore.get(core);
51
+ }
49
52
  //#endregion
50
53
  //#region src/react/use-forms.ts
51
54
  /** @internal Product hooks read the module client from provider context. */
@@ -62,14 +65,9 @@ function useRegisteredFormsClient() {
62
65
  * (`useForm<'signup', OtherSchemas>`) only to work against a map other than the
63
66
  * registered one.
64
67
  */
65
- function useForm({ formId, customValidations }) {
68
+ function useForm({ formId }) {
66
69
  const client = useRegisteredFormsClient();
67
- const customValidationsRef = useRef(customValidations);
68
- customValidationsRef.current = customValidations;
69
- const form = client === null ? null : client.getForm({
70
- formId,
71
- customValidations: customValidationsRef.current
72
- });
70
+ const form = client === null ? null : client.getForm({ formId });
73
71
  const { values, errors } = useFormSnapshot(form);
74
72
  return {
75
73
  form,
@@ -103,6 +101,11 @@ function useFormField({ form, key }) {
103
101
  const setValue = useCallback((value) => {
104
102
  setDraft(value);
105
103
  }, []);
104
+ const commit = useCallback((value) => {
105
+ if (form === null) return noopSetValue();
106
+ setDraft(value);
107
+ return form.set({ [key]: value });
108
+ }, [form, key]);
106
109
  const onBlur = useCallback(async () => {
107
110
  if (form === null) return noopSetValue();
108
111
  if (draft === committed) return {
@@ -120,12 +123,14 @@ function useFormField({ form, key }) {
120
123
  value: void 0,
121
124
  error: void 0,
122
125
  setValue: () => void 0,
126
+ commit: async () => noopSetValue(),
123
127
  onBlur: async () => noopSetValue()
124
128
  };
125
129
  return {
126
130
  value: draft,
127
131
  error: errors[key],
128
132
  setValue,
133
+ commit,
129
134
  onBlur
130
135
  };
131
136
  }
@@ -137,10 +142,11 @@ function resolveCoreAnalyticsInstance(core) {
137
142
  }
138
143
  //#endregion
139
144
  //#region src/react/register-forms-client.ts
140
- function registerFormsClient({ core, ...options }) {
145
+ function register({ disableAnalyticsFallback, ...options }) {
146
+ const { core } = options;
141
147
  const existing = formsByCore.get(core);
142
148
  if (existing !== void 0) return existing;
143
- const analyticsInstance = options.analyticsInstance ?? resolveCoreAnalyticsInstance(core);
149
+ const analyticsInstance = disableAnalyticsFallback ? void 0 : options.analyticsInstance ?? resolveCoreAnalyticsInstance(core);
144
150
  const client = initForms({
145
151
  ...options,
146
152
  core,
@@ -149,18 +155,42 @@ function registerFormsClient({ core, ...options }) {
149
155
  formsByCore.set(core, client);
150
156
  return client;
151
157
  }
158
+ function registerFormsClient(options) {
159
+ return register(options);
160
+ }
161
+ function registerFormsModuleClient(options) {
162
+ return register(options);
163
+ }
152
164
  //#endregion
153
165
  //#region src/react/forms-module.ts
154
- function forms(options) {
166
+ const ANALYTICS_MODULE_KEY = "analytics";
167
+ function resolveInjectedAnalytics(value) {
168
+ if (value === void 0) return void 0;
169
+ if (typeof value !== "object" || value === null) throw new FormsError("Forms received an invalid Analytics module dependency.");
170
+ const candidate = value;
171
+ if (typeof candidate.trackEvent !== "function" || typeof candidate.getAppUserId !== "function" || typeof candidate.getProjectId !== "function") throw new FormsError("Forms received an invalid Analytics module dependency.");
172
+ return candidate;
173
+ }
174
+ function forms(options = {}) {
155
175
  return {
156
176
  key: FORMS_MODULE_KEY,
157
- init: (core) => registerFormsClient({
158
- core,
159
- ...options
160
- })
177
+ dependencies: [{
178
+ key: ANALYTICS_MODULE_KEY,
179
+ optional: true
180
+ }],
181
+ init: (core, context) => {
182
+ const analyticsInstance = context?.analyticsExcluded ? void 0 : options.analyticsInstance ?? resolveInjectedAnalytics(context?.dependencies.get(ANALYTICS_MODULE_KEY));
183
+ return registerFormsModuleClient({
184
+ core,
185
+ customValidations: context?.parameters?.customValidations ?? options.customValidations,
186
+ serverFormData: context?.parameters?.serverFormData ?? options.serverFormData,
187
+ analyticsInstance,
188
+ disableAnalyticsFallback: context?.analyticsExcluded
189
+ });
190
+ }
161
191
  };
162
192
  }
163
193
  //#endregion
164
- export { forms, registerFormsClient, useForm, useFormErrors, useFormField };
194
+ export { forms, getRegisteredFormsClient, registerFormsClient, useForm, useFormErrors, useFormField };
165
195
 
166
196
  //# sourceMappingURL=react.js.map
package/dist/react.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"react.js","names":[],"sources":["../src/react/use-form-store.ts","../src/react/forms-registry.ts","../src/react/use-forms.ts","../src/react/use-form.ts","../src/react/use-form-errors.ts","../src/react/use-form-field.ts","../src/react/resolve-core-analytics.ts","../src/react/register-forms-client.ts","../src/react/forms-module.ts"],"sourcesContent":["import { useCallback, useRef, useSyncExternalStore } from 'react'\n\nimport type { FormSchema, FormValues } from '../core/config.js'\nimport type { FieldErrors, FormInstance } from '../core/form.js'\n\nexport type FormSnapshot<TSchema extends FormSchema> = Readonly<{\n values: Partial<FormValues<TSchema>>\n errors: FieldErrors<TSchema>\n}>\n\nconst EMPTY_SNAPSHOT: FormSnapshot<FormSchema> = Object.freeze({\n values: {},\n errors: {},\n})\n\nfunction createSnapshot<TSchema extends FormSchema>(\n form: FormInstance<TSchema>,\n): FormSnapshot<TSchema> {\n return Object.freeze({\n values: form.getAll(),\n errors: form.errors(),\n })\n}\n\ninterface CachedSnapshot<TSchema extends FormSchema> {\n readonly form: FormInstance<TSchema>\n readonly snapshot: FormSnapshot<TSchema>\n}\n\nexport function useFormSnapshot<TSchema extends FormSchema>(\n form: FormInstance<TSchema> | null,\n): FormSnapshot<TSchema> {\n const cachedRef = useRef<CachedSnapshot<TSchema> | null>(null)\n const emptyRef = useRef<FormSnapshot<TSchema>>(EMPTY_SNAPSHOT as FormSnapshot<TSchema>)\n\n const subscribe = useCallback(\n (listener: () => void) => {\n if (form === null) return () => undefined\n return form.subscribe(() => {\n cachedRef.current = { form, snapshot: createSnapshot(form) }\n listener()\n })\n },\n [form],\n )\n\n const getSnapshot = useCallback((): FormSnapshot<TSchema> => {\n if (form === null) {\n // * Otherwise a later A -> null -> mutate A -> A sequence would resurrect\n // * a snapshot cached before the detach, missing the mutation in between.\n cachedRef.current = null\n return emptyRef.current\n }\n // * A cached snapshot from a previous form instance must not survive a\n // * form change — recompute so switching forms without a mutation still\n // * returns the new form's values and errors.\n if (cachedRef.current === null || cachedRef.current.form !== form) {\n cachedRef.current = { form, snapshot: createSnapshot(form) }\n }\n return cachedRef.current.snapshot\n }, [form])\n\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot)\n}\n","import type { FormSchemaMap, FormsClient } from '../core/form.js'\n\nexport const FORMS_MODULE_KEY = 'forms'\n\n/**\n * Idempotence guard for `registerFormsClient` only — React reads the client\n * from provider context, not from here.\n */\nexport const formsByCore = new WeakMap<object, FormsClient<FormSchemaMap>>()\n","import { useEmbeddablesModule } from '@embeddables/core/react'\n\nimport { FORMS_MODULE_KEY } from './forms-registry.js'\n\nimport type { FormSchemaMap, FormsClient, InitFormsOptions } from '../core/form.js'\n\nexport type FormsReactOptions<TSchemas extends FormSchemaMap = FormSchemaMap> = Omit<\n InitFormsOptions<TSchemas>,\n 'core'\n>\n\n/** @internal Product hooks read the module client from provider context. */\nexport function useRegisteredFormsClient<\n TSchemas extends FormSchemaMap = FormSchemaMap,\n>(): FormsClient<TSchemas> | null {\n return useEmbeddablesModule<FormsClient<TSchemas>>({ key: FORMS_MODULE_KEY })\n}\n","import { useRef } from 'react'\n\nimport { useFormSnapshot } from './use-form-store.js'\nimport { useRegisteredFormsClient } from './use-forms.js'\n\nimport type { CustomValidationsFor, FormInstance, FormSchemaMap } from '../core/form.js'\nimport type { RegisteredSchemas } from './schema-registry.js'\n\n/**\n * Reactive binding for one declared form.\n *\n * Takes no type arguments: `TFormId` is inferred from `formId`, and the schema\n * map comes from the registry `em build` augments. Pass both explicitly\n * (`useForm<'signup', OtherSchemas>`) only to work against a map other than the\n * registered one.\n */\nexport function useForm<\n TFormId extends keyof TSchemas & string,\n TSchemas extends FormSchemaMap = RegisteredSchemas,\n>({\n formId,\n customValidations,\n}: {\n formId: TFormId\n customValidations?: CustomValidationsFor<TSchemas[TFormId]>\n}): {\n form: FormInstance<TSchemas[TFormId]> | null\n values: ReturnType<typeof useFormSnapshot<TSchemas[TFormId]>>['values']\n errors: ReturnType<typeof useFormSnapshot<TSchemas[TFormId]>>['errors']\n} {\n const client = useRegisteredFormsClient<TSchemas>()\n // * Held in a ref because only the first call for a form id builds the\n // * instance; a later render passing new validators must not look like a change.\n const customValidationsRef = useRef(customValidations)\n customValidationsRef.current = customValidations\n\n // * Safe to call on every render: the client returns one instance per form id.\n const form =\n client === null\n ? null\n : client.getForm({ formId, customValidations: customValidationsRef.current })\n const { values, errors } = useFormSnapshot(form)\n\n return { form, values, errors }\n}\n\n// prueba de la colisión\n","import { useFormSnapshot } from './use-form-store.js'\n\nimport type { FormSchema } from '../core/config.js'\nimport type { FieldErrors, FormInstance } from '../core/form.js'\n\nexport function useFormErrors<TSchema extends FormSchema>(\n form: FormInstance<TSchema> | null,\n): FieldErrors<TSchema> {\n const { errors } = useFormSnapshot(form)\n return errors\n}\n","import { useCallback, useEffect, useState } from 'react'\n\nimport { useFormSnapshot } from './use-form-store.js'\n\nimport type { FormFieldKey, FormSchema, FormValues } from '../core/config.js'\nimport type { FieldErrors, FormInstance, SetResult } from '../core/form.js'\n\nconst noopSetValue = async (): Promise<SetResult<FormSchema>> => ({\n ok: false,\n errors: {},\n})\n\nexport function useFormField<const TSchema extends FormSchema, K extends FormFieldKey<TSchema>>({\n form,\n key,\n}: {\n form: FormInstance<TSchema> | null\n key: K\n}): {\n value: FormValues<TSchema>[K] | undefined\n error: readonly string[] | undefined\n setValue: (value: FormValues<TSchema>[K]) => void\n onBlur: () => Promise<SetResult<TSchema>>\n} {\n const { values, errors } = useFormSnapshot(form)\n const committed = values[key]\n const [draft, setDraft] = useState<FormValues<TSchema>[K] | undefined>(committed)\n\n useEffect(() => {\n setDraft(committed)\n }, [form, key, committed])\n\n const setValue = useCallback((value: FormValues<TSchema>[K]) => {\n setDraft(value)\n }, [])\n\n const onBlur = useCallback(async (): Promise<SetResult<TSchema>> => {\n if (form === null) return noopSetValue()\n if (draft === committed) {\n return { ok: true, errors: {} as FieldErrors<TSchema> }\n }\n return form.set({ [key]: draft } as Partial<FormValues<TSchema>>)\n }, [committed, draft, form, key])\n\n if (form === null) {\n return {\n value: undefined,\n error: undefined,\n setValue: () => undefined,\n onBlur: async () => noopSetValue(),\n }\n }\n\n return {\n value: draft,\n error: errors[key],\n setValue,\n onBlur,\n }\n}\n","import type { AnalyticsInstance } from '@embeddables/core'\nimport type { EmbeddablesInstance } from '@embeddables/core'\n\nexport function resolveCoreAnalyticsInstance(\n core: EmbeddablesInstance,\n): AnalyticsInstance | undefined {\n if (typeof core.getAnalyticsInstance !== 'function') return undefined\n return core.getAnalyticsInstance() ?? undefined\n}\n","import { initForms } from '../core/form.js'\nimport { formsByCore } from './forms-registry.js'\nimport { resolveCoreAnalyticsInstance } from './resolve-core-analytics.js'\n\nimport type { FormSchemaMap, FormsClient, InitFormsOptions } from '../core/form.js'\n\nexport function registerFormsClient<const TSchemas extends FormSchemaMap>({\n core,\n ...options\n}: InitFormsOptions<TSchemas>): FormsClient<TSchemas> {\n const existing = formsByCore.get(core) as FormsClient<TSchemas> | undefined\n if (existing !== undefined) return existing\n\n const analyticsInstance = options.analyticsInstance ?? resolveCoreAnalyticsInstance(core)\n\n const client = initForms({ ...options, core, analyticsInstance })\n formsByCore.set(core, client as FormsClient<FormSchemaMap>)\n return client\n}\n","import type { EmbeddablesReactModule } from '@embeddables/core/react'\n\nimport { FORMS_MODULE_KEY } from './forms-registry.js'\nimport { registerFormsClient } from './register-forms-client.js'\n\nimport type { FormSchemaMap, FormsClient } from '../core/form.js'\nimport type { FormsReactOptions } from './use-forms.js'\n\nexport type { FormsReactOptions } from './use-forms.js'\n\nexport function forms<const TSchemas extends FormSchemaMap>(\n options: FormsReactOptions<TSchemas>,\n): EmbeddablesReactModule<FormsClient<TSchemas>> {\n return {\n key: FORMS_MODULE_KEY,\n init: (core) => registerFormsClient({ core, ...options }),\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"react.js","names":[],"sources":["../src/react/use-form-store.ts","../src/react/forms-registry.ts","../src/react/use-forms.ts","../src/react/use-form.ts","../src/react/use-form-errors.ts","../src/react/use-form-field.ts","../src/react/resolve-core-analytics.ts","../src/react/register-forms-client.ts","../src/react/forms-module.ts"],"sourcesContent":["import { useCallback, useRef, useSyncExternalStore } from 'react'\n\nimport type { FormSchema, FormValues } from '../core/config.js'\nimport type { FieldErrors, FormInstance } from '../core/form.js'\n\nexport type FormSnapshot<TSchema extends FormSchema> = Readonly<{\n values: Partial<FormValues<TSchema>>\n errors: FieldErrors<TSchema>\n}>\n\nconst EMPTY_SNAPSHOT: FormSnapshot<FormSchema> = Object.freeze({\n values: {},\n errors: {},\n})\n\nfunction createSnapshot<TSchema extends FormSchema>(\n form: FormInstance<TSchema>,\n): FormSnapshot<TSchema> {\n return Object.freeze({\n values: form.getAll(),\n errors: form.errors(),\n })\n}\n\ninterface CachedSnapshot<TSchema extends FormSchema> {\n readonly form: FormInstance<TSchema>\n readonly snapshot: FormSnapshot<TSchema>\n}\n\nexport function useFormSnapshot<TSchema extends FormSchema>(\n form: FormInstance<TSchema> | null,\n): FormSnapshot<TSchema> {\n const cachedRef = useRef<CachedSnapshot<TSchema> | null>(null)\n const emptyRef = useRef<FormSnapshot<TSchema>>(EMPTY_SNAPSHOT as FormSnapshot<TSchema>)\n\n const subscribe = useCallback(\n (listener: () => void) => {\n if (form === null) return () => undefined\n return form.subscribe(() => {\n cachedRef.current = { form, snapshot: createSnapshot(form) }\n listener()\n })\n },\n [form],\n )\n\n const getSnapshot = useCallback((): FormSnapshot<TSchema> => {\n if (form === null) {\n // * Otherwise a later A -> null -> mutate A -> A sequence would resurrect\n // * a snapshot cached before the detach, missing the mutation in between.\n cachedRef.current = null\n return emptyRef.current\n }\n // * A cached snapshot from a previous form instance must not survive a\n // * form change — recompute so switching forms without a mutation still\n // * returns the new form's values and errors.\n if (cachedRef.current === null || cachedRef.current.form !== form) {\n cachedRef.current = { form, snapshot: createSnapshot(form) }\n }\n return cachedRef.current.snapshot\n }, [form])\n\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot)\n}\n","import type { FormSchemaMap, FormsClient } from '../core/form.js'\n\nexport const FORMS_MODULE_KEY = 'forms'\n\n/**\n * Idempotence guard for `registerFormsClient` only — React reads the client\n * from provider context, not from here.\n */\nexport const formsByCore = new WeakMap<object, FormsClient<FormSchemaMap>>()\n\nexport function getRegisteredFormsClient(core: object): FormsClient<FormSchemaMap> | undefined {\n return formsByCore.get(core)\n}\n","import { useEmbeddablesModule } from '@embeddables/core/react'\n\nimport { FORMS_MODULE_KEY } from './forms-registry.js'\n\nimport type { FormSchemaMap, FormsClient, InitFormsOptions } from '../core/form.js'\n\nexport type FormsReactOptions<TSchemas extends FormSchemaMap = FormSchemaMap> = Omit<\n InitFormsOptions<TSchemas>,\n 'core'\n>\n\n/** @internal Product hooks read the module client from provider context. */\nexport function useRegisteredFormsClient<\n TSchemas extends FormSchemaMap = FormSchemaMap,\n>(): FormsClient<TSchemas> | null {\n return useEmbeddablesModule<FormsClient<TSchemas>>({ key: FORMS_MODULE_KEY })\n}\n","import { useFormSnapshot } from './use-form-store.js'\nimport { useRegisteredFormsClient } from './use-forms.js'\n\nimport type { FormInstance, FormSchemaMap } from '../core/form.js'\nimport type { RegisteredSchemas } from './schema-registry.js'\n\n/**\n * Reactive binding for one declared form.\n *\n * Takes no type arguments: `TFormId` is inferred from `formId`, and the schema\n * map comes from the registry `em build` augments. Pass both explicitly\n * (`useForm<'signup', OtherSchemas>`) only to work against a map other than the\n * registered one.\n */\nexport function useForm<\n TFormId extends keyof TSchemas & string,\n TSchemas extends FormSchemaMap = RegisteredSchemas,\n>({\n formId,\n}: {\n formId: TFormId\n}): {\n form: FormInstance<TSchemas[TFormId]> | null\n values: ReturnType<typeof useFormSnapshot<TSchemas[TFormId]>>['values']\n errors: ReturnType<typeof useFormSnapshot<TSchemas[TFormId]>>['errors']\n} {\n const client = useRegisteredFormsClient<TSchemas>()\n\n // * Safe to call on every render: the client returns one instance per form id.\n const form = client === null ? null : client.getForm({ formId })\n const { values, errors } = useFormSnapshot(form)\n\n return { form, values, errors }\n}\n","import { useFormSnapshot } from './use-form-store.js'\n\nimport type { FormSchema } from '../core/config.js'\nimport type { FieldErrors, FormInstance } from '../core/form.js'\n\nexport function useFormErrors<TSchema extends FormSchema>(\n form: FormInstance<TSchema> | null,\n): FieldErrors<TSchema> {\n const { errors } = useFormSnapshot(form)\n return errors\n}\n","import { useCallback, useEffect, useState } from 'react'\n\nimport { useFormSnapshot } from './use-form-store.js'\n\nimport type { FormFieldKey, FormSchema, FormValues } from '../core/config.js'\nimport type { FieldErrors, FormInstance, SetResult } from '../core/form.js'\n\nconst noopSetValue = async (): Promise<SetResult<FormSchema>> => ({\n ok: false,\n errors: {},\n})\n\nexport function useFormField<const TSchema extends FormSchema, K extends FormFieldKey<TSchema>>({\n form,\n key,\n}: {\n form: FormInstance<TSchema> | null\n key: K\n}): {\n value: FormValues<TSchema>[K] | undefined\n error: readonly string[] | undefined\n setValue: (value: FormValues<TSchema>[K] | undefined) => void\n commit: (value: FormValues<TSchema>[K] | undefined) => Promise<SetResult<TSchema>>\n onBlur: () => Promise<SetResult<TSchema>>\n} {\n const { values, errors } = useFormSnapshot(form)\n const committed = values[key]\n const [draft, setDraft] = useState<FormValues<TSchema>[K] | undefined>(committed)\n\n useEffect(() => {\n setDraft(committed)\n }, [form, key, committed])\n\n const setValue = useCallback((value: FormValues<TSchema>[K] | undefined) => {\n setDraft(value)\n }, [])\n\n // * Takes the value as an argument rather than reading `draft`, so it is\n // * correct when called in the same tick as the change that produced it.\n // * `onBlur` cannot be: it compares the `draft`/`committed` pair captured in\n // * the current render, which a same-tick `setValue` has not updated yet.\n const commit = useCallback(\n (value: FormValues<TSchema>[K] | undefined): Promise<SetResult<TSchema>> => {\n if (form === null) return noopSetValue()\n // * Keeps the control responsive while `set` runs, and keeps a rejected\n // * value on screen next to its error instead of snapping back.\n setDraft(value)\n return form.set({ [key]: value } as Partial<FormValues<TSchema>>)\n },\n [form, key],\n )\n\n const onBlur = useCallback(async (): Promise<SetResult<TSchema>> => {\n if (form === null) return noopSetValue()\n if (draft === committed) {\n return { ok: true, errors: {} as FieldErrors<TSchema> }\n }\n return form.set({ [key]: draft } as Partial<FormValues<TSchema>>)\n }, [committed, draft, form, key])\n\n if (form === null) {\n return {\n value: undefined,\n error: undefined,\n setValue: () => undefined,\n commit: async () => noopSetValue(),\n onBlur: async () => noopSetValue(),\n }\n }\n\n return {\n value: draft,\n error: errors[key],\n setValue,\n commit,\n onBlur,\n }\n}\n","import type { AnalyticsInstance } from '@embeddables/core'\nimport type { EmbeddablesInstance } from '@embeddables/core'\n\nexport function resolveCoreAnalyticsInstance(\n core: EmbeddablesInstance,\n): AnalyticsInstance | undefined {\n if (typeof core.getAnalyticsInstance !== 'function') return undefined\n return core.getAnalyticsInstance() ?? undefined\n}\n","import { initForms } from '../core/form.js'\nimport { formsByCore } from './forms-registry.js'\nimport { resolveCoreAnalyticsInstance } from './resolve-core-analytics.js'\n\nimport type { FormsClient, InitFormsOptions } from '../core/form.js'\nimport type { RegisteredSchemas } from './schema-registry.js'\n\ninterface RegisterFormsModuleClientOptions extends InitFormsOptions<RegisteredSchemas> {\n /**\n * Set when `excludeAnalyticsInModules` names Forms. The exclusion is absolute:\n * it suppresses the Core-instance fallback as well as the injected client.\n */\n disableAnalyticsFallback?: boolean\n}\n\nfunction register({\n disableAnalyticsFallback,\n ...options\n}: RegisterFormsModuleClientOptions): FormsClient<RegisteredSchemas> {\n const { core } = options\n const existing = formsByCore.get(core)\n if (existing !== undefined) return existing\n\n const analyticsInstance = disableAnalyticsFallback\n ? undefined\n : (options.analyticsInstance ?? resolveCoreAnalyticsInstance(core))\n\n const client = initForms<RegisteredSchemas>({ ...options, core, analyticsInstance })\n formsByCore.set(core, client)\n return client\n}\n\nexport function registerFormsClient(\n options: InitFormsOptions<RegisteredSchemas>,\n): FormsClient<RegisteredSchemas> {\n return register(options)\n}\n\nexport function registerFormsModuleClient(\n options: RegisterFormsModuleClientOptions,\n): FormsClient<RegisteredSchemas> {\n return register(options)\n}\n","import type { EmbeddablesReactModule } from '@embeddables/core/react'\n\nimport { FormsError } from '../errors.js'\nimport { FORMS_MODULE_KEY } from './forms-registry.js'\nimport { registerFormsModuleClient } from './register-forms-client.js'\n\nimport type { AnalyticsInstance } from '../core/analytics.js'\nimport type { FormsClient } from '../core/form.js'\nimport type { RegisteredSchemas } from './schema-registry.js'\nimport type { FormsReactOptions } from './use-forms.js'\n\nexport type { FormsReactOptions } from './use-forms.js'\n\n/**\n * What `EmbeddablesProvider` accepts under its top-level `forms` prop.\n *\n * `analyticsInstance` is deliberately absent: the provider injects the\n * Analytics module client through module dependencies, so an app never wires\n * that instance by hand.\n */\nexport type FormsProviderOptions = Omit<FormsReactOptions<RegisteredSchemas>, 'analyticsInstance'>\n\ndeclare module '@embeddables/core/react' {\n interface EmbeddablesReactModuleParameters {\n readonly forms: FormsProviderOptions\n }\n}\n\nconst ANALYTICS_MODULE_KEY = 'analytics'\n\nfunction resolveInjectedAnalytics(value: unknown): AnalyticsInstance | undefined {\n if (value === undefined) return undefined\n if (typeof value !== 'object' || value === null) {\n throw new FormsError('Forms received an invalid Analytics module dependency.')\n }\n const candidate = value as Partial<AnalyticsInstance>\n if (\n typeof candidate.trackEvent !== 'function' ||\n typeof candidate.getAppUserId !== 'function' ||\n typeof candidate.getProjectId !== 'function'\n ) {\n throw new FormsError('Forms received an invalid Analytics module dependency.')\n }\n return candidate as AnalyticsInstance\n}\n\nexport function forms(\n options: FormsReactOptions<RegisteredSchemas> = {},\n): EmbeddablesReactModule<FormsClient<RegisteredSchemas>, FormsProviderOptions> {\n return {\n key: FORMS_MODULE_KEY,\n dependencies: [{ key: ANALYTICS_MODULE_KEY, optional: true }],\n init: (core, context) => {\n const analyticsInstance = context?.analyticsExcluded\n ? undefined\n : (options.analyticsInstance ??\n resolveInjectedAnalytics(context?.dependencies.get(ANALYTICS_MODULE_KEY)))\n\n return registerFormsModuleClient({\n core,\n customValidations: context?.parameters?.customValidations ?? options.customValidations,\n serverFormData: context?.parameters?.serverFormData ?? options.serverFormData,\n analyticsInstance,\n disableAnalyticsFallback: context?.analyticsExcluded,\n })\n },\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_form = require("./form-BOHdxeuO.cjs");
3
+ //#region src/core/server.ts
4
+ function toServerFormInstance(instance) {
5
+ return {
6
+ key: instance.key,
7
+ set: (patch) => instance.set(patch),
8
+ get: (key) => instance.get(key),
9
+ getAll: () => instance.getAll(),
10
+ getValueByProtocolFieldId: (protocolFieldId) => instance.getValueByProtocolFieldId(protocolFieldId)
11
+ };
12
+ }
13
+ function initFormsServer(options) {
14
+ const server = options.server;
15
+ if (typeof server.getProjectId !== "function" || typeof server.getAppUserId !== "function") throw new require_form.FormsError("initFormsServer requires an initialized Embeddables server instance.");
16
+ if (typeof server.getFormIds !== "function" || typeof server.getFormSchema !== "function") throw new require_form.FormsError("initFormsServer requires a Core instance with registered form schemas.");
17
+ const projectId = server.getProjectId();
18
+ const storage = require_form.createMemoryFormsStorage();
19
+ require_form.seedServerFormsStorageFromCookies({
20
+ storage,
21
+ projectId,
22
+ formIds: server.getFormIds(),
23
+ getFormSchema: (formId) => server.getFormSchema(formId),
24
+ getCookie: (key) => server.getCookie(key)
25
+ });
26
+ const client = require_form.createFormsClient({
27
+ core: server,
28
+ customValidations: options.customValidations,
29
+ analyticsInstance: options.analyticsInstance,
30
+ storage,
31
+ persistence: require_form.createNoopPersistence()
32
+ });
33
+ return {
34
+ getForm({ formId }) {
35
+ return toServerFormInstance(client.getForm({ formId }));
36
+ },
37
+ getServerFormData() {
38
+ const data = {};
39
+ for (const formId of server.getFormIds()) {
40
+ const key = formId;
41
+ data[key] = client.getForm({ formId: key }).getAll();
42
+ }
43
+ return data;
44
+ }
45
+ };
46
+ }
47
+ //#endregion
48
+ exports.initFormsServer = initFormsServer;
49
+
50
+ //# sourceMappingURL=server.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.cjs","names":["FormsError","createMemoryFormsStorage","createFormsClient","createNoopPersistence"],"sources":["../src/core/server.ts"],"sourcesContent":["import { FormsError } from '../errors.js'\nimport { seedServerFormsStorageFromCookies } from '../storage/cookie-form-data.js'\nimport { createNoopPersistence } from '../storage/persistence.js'\nimport { createMemoryFormsStorage } from '../storage/storage.js'\nimport { createFormsClient } from './form.js'\n\nimport type { FormSchema } from './config.js'\nimport type {\n FormInstance,\n FormSchemaMap,\n FormsClientOptions,\n FormsServerInitOptions,\n ServerFormDataByFormId,\n ServerFormInstance,\n} from './form.js'\n\nexport type { FormsServerInitOptions } from './form.js'\n\nexport interface FormsServerClient<TSchemas extends FormSchemaMap = FormSchemaMap> {\n getForm<K extends keyof TSchemas & string>(params: { formId: K }): ServerFormInstance<TSchemas[K]>\n /** Current values for every initialized form — pass to client `initForms` as `serverFormData`. */\n getServerFormData(): ServerFormDataByFormId<TSchemas>\n}\n\nfunction toServerFormInstance<TSchema extends FormSchema = FormSchema>(\n instance: FormInstance<TSchema>,\n): ServerFormInstance<TSchema> {\n return {\n key: instance.key,\n set: (patch) => instance.set(patch),\n get: (key) => instance.get(key),\n getAll: () => instance.getAll(),\n getValueByProtocolFieldId: (protocolFieldId) =>\n instance.getValueByProtocolFieldId(protocolFieldId),\n }\n}\n\nexport function initFormsServer<TSchemas extends FormSchemaMap = FormSchemaMap>(\n options: FormsServerInitOptions<TSchemas>,\n): FormsServerClient<TSchemas> {\n const server = options.server\n if (typeof server.getProjectId !== 'function' || typeof server.getAppUserId !== 'function') {\n throw new FormsError('initFormsServer requires an initialized Embeddables server instance.')\n }\n\n if (typeof server.getFormIds !== 'function' || typeof server.getFormSchema !== 'function') {\n throw new FormsError('initFormsServer requires a Core instance with registered form schemas.')\n }\n\n const projectId = server.getProjectId()\n const storage = createMemoryFormsStorage()\n seedServerFormsStorageFromCookies({\n storage,\n projectId,\n formIds: server.getFormIds(),\n getFormSchema: (formId) => server.getFormSchema(formId),\n getCookie: (key) => server.getCookie(key),\n })\n\n const client = createFormsClient<TSchemas>({\n core: server,\n customValidations: options.customValidations,\n analyticsInstance: options.analyticsInstance,\n storage,\n persistence: createNoopPersistence(),\n } satisfies FormsClientOptions)\n\n const serverClient = {\n getForm({ formId }: { formId: keyof TSchemas & string }) {\n return toServerFormInstance(client.getForm({ formId }))\n },\n getServerFormData() {\n const data: ServerFormDataByFormId<TSchemas> = {}\n for (const formId of server.getFormIds()) {\n const key = formId as keyof TSchemas & string\n data[key] = client.getForm({ formId: key }).getAll()\n }\n return data\n },\n } satisfies FormsServerClient<TSchemas>\n\n return serverClient\n}\n"],"mappings":";;;AAwBA,SAAS,qBACP,UAC6B;CAC7B,OAAO;EACL,KAAK,SAAS;EACd,MAAM,UAAU,SAAS,IAAI,KAAK;EAClC,MAAM,QAAQ,SAAS,IAAI,GAAG;EAC9B,cAAc,SAAS,OAAO;EAC9B,4BAA4B,oBAC1B,SAAS,0BAA0B,eAAe;CACtD;AACF;AAEA,SAAgB,gBACd,SAC6B;CAC7B,MAAM,SAAS,QAAQ;CACvB,IAAI,OAAO,OAAO,iBAAiB,cAAc,OAAO,OAAO,iBAAiB,YAC9E,MAAM,IAAIA,aAAAA,WAAW,sEAAsE;CAG7F,IAAI,OAAO,OAAO,eAAe,cAAc,OAAO,OAAO,kBAAkB,YAC7E,MAAM,IAAIA,aAAAA,WAAW,wEAAwE;CAG/F,MAAM,YAAY,OAAO,aAAa;CACtC,MAAM,UAAUC,aAAAA,yBAAyB;CACzC,aAAA,kCAAkC;EAChC;EACA;EACA,SAAS,OAAO,WAAW;EAC3B,gBAAgB,WAAW,OAAO,cAAc,MAAM;EACtD,YAAY,QAAQ,OAAO,UAAU,GAAG;CAC1C,CAAC;CAED,MAAM,SAASC,aAAAA,kBAA4B;EACzC,MAAM;EACN,mBAAmB,QAAQ;EAC3B,mBAAmB,QAAQ;EAC3B;EACA,aAAaC,aAAAA,sBAAsB;CACrC,CAA8B;CAgB9B,OAAO;EAbL,QAAQ,EAAE,UAA+C;GACvD,OAAO,qBAAqB,OAAO,QAAQ,EAAE,OAAO,CAAC,CAAC;EACxD;EACA,oBAAoB;GAClB,MAAM,OAAyC,CAAC;GAChD,KAAK,MAAM,UAAU,OAAO,WAAW,GAAG;IACxC,MAAM,MAAM;IACZ,KAAK,OAAO,OAAO,QAAQ,EAAE,QAAQ,IAAI,CAAC,CAAC,CAAC,OAAO;GACrD;GACA,OAAO;EACT;CAGgB;AACpB"}
@@ -0,0 +1,13 @@
1
+ import { a as FormSchemaMap, c as FormsServerInitOptions, d as ServerFormInstance, u as ServerFormDataByFormId } from "./form-Br23yPDS.js";
2
+ //#region src/core/server.d.ts
3
+ interface FormsServerClient<TSchemas extends FormSchemaMap = FormSchemaMap> {
4
+ getForm<K extends keyof TSchemas & string>(params: {
5
+ formId: K;
6
+ }): ServerFormInstance<TSchemas[K]>;
7
+ /** Current values for every initialized form — pass to client `initForms` as `serverFormData`. */
8
+ getServerFormData(): ServerFormDataByFormId<TSchemas>;
9
+ }
10
+ declare function initFormsServer<TSchemas extends FormSchemaMap = FormSchemaMap>(options: FormsServerInitOptions<TSchemas>): FormsServerClient<TSchemas>;
11
+ //#endregion
12
+ export { type FormsServerClient, type FormsServerInitOptions, type ServerFormDataByFormId, type ServerFormInstance, initFormsServer };
13
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","names":[],"sources":["../src/core/server.ts"],"mappings":";;UAkBiB,kBAAkB,iBAAiB,gBAAgB;EAClE,QAAQ,gBAAgB,mBAAmB;IAAU,QAAQ;MAAM,mBAAmB,SAAS;;EAE/F,qBAAqB,uBAAuB;;iBAgB9B,gBAAgB,iBAAiB,gBAAgB,eAC/D,SAAS,uBAAuB,YAC/B,kBAAkB"}
package/dist/server.js ADDED
@@ -0,0 +1,49 @@
1
+ import { i as seedServerFormsStorageFromCookies, o as createMemoryFormsStorage, r as createNoopPersistence, s as FormsError, t as createFormsClient } from "./form-Bt5pwVP6.js";
2
+ //#region src/core/server.ts
3
+ function toServerFormInstance(instance) {
4
+ return {
5
+ key: instance.key,
6
+ set: (patch) => instance.set(patch),
7
+ get: (key) => instance.get(key),
8
+ getAll: () => instance.getAll(),
9
+ getValueByProtocolFieldId: (protocolFieldId) => instance.getValueByProtocolFieldId(protocolFieldId)
10
+ };
11
+ }
12
+ function initFormsServer(options) {
13
+ const server = options.server;
14
+ if (typeof server.getProjectId !== "function" || typeof server.getAppUserId !== "function") throw new FormsError("initFormsServer requires an initialized Embeddables server instance.");
15
+ if (typeof server.getFormIds !== "function" || typeof server.getFormSchema !== "function") throw new FormsError("initFormsServer requires a Core instance with registered form schemas.");
16
+ const projectId = server.getProjectId();
17
+ const storage = createMemoryFormsStorage();
18
+ seedServerFormsStorageFromCookies({
19
+ storage,
20
+ projectId,
21
+ formIds: server.getFormIds(),
22
+ getFormSchema: (formId) => server.getFormSchema(formId),
23
+ getCookie: (key) => server.getCookie(key)
24
+ });
25
+ const client = createFormsClient({
26
+ core: server,
27
+ customValidations: options.customValidations,
28
+ analyticsInstance: options.analyticsInstance,
29
+ storage,
30
+ persistence: createNoopPersistence()
31
+ });
32
+ return {
33
+ getForm({ formId }) {
34
+ return toServerFormInstance(client.getForm({ formId }));
35
+ },
36
+ getServerFormData() {
37
+ const data = {};
38
+ for (const formId of server.getFormIds()) {
39
+ const key = formId;
40
+ data[key] = client.getForm({ formId: key }).getAll();
41
+ }
42
+ return data;
43
+ }
44
+ };
45
+ }
46
+ //#endregion
47
+ export { initFormsServer };
48
+
49
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","names":[],"sources":["../src/core/server.ts"],"sourcesContent":["import { FormsError } from '../errors.js'\nimport { seedServerFormsStorageFromCookies } from '../storage/cookie-form-data.js'\nimport { createNoopPersistence } from '../storage/persistence.js'\nimport { createMemoryFormsStorage } from '../storage/storage.js'\nimport { createFormsClient } from './form.js'\n\nimport type { FormSchema } from './config.js'\nimport type {\n FormInstance,\n FormSchemaMap,\n FormsClientOptions,\n FormsServerInitOptions,\n ServerFormDataByFormId,\n ServerFormInstance,\n} from './form.js'\n\nexport type { FormsServerInitOptions } from './form.js'\n\nexport interface FormsServerClient<TSchemas extends FormSchemaMap = FormSchemaMap> {\n getForm<K extends keyof TSchemas & string>(params: { formId: K }): ServerFormInstance<TSchemas[K]>\n /** Current values for every initialized form — pass to client `initForms` as `serverFormData`. */\n getServerFormData(): ServerFormDataByFormId<TSchemas>\n}\n\nfunction toServerFormInstance<TSchema extends FormSchema = FormSchema>(\n instance: FormInstance<TSchema>,\n): ServerFormInstance<TSchema> {\n return {\n key: instance.key,\n set: (patch) => instance.set(patch),\n get: (key) => instance.get(key),\n getAll: () => instance.getAll(),\n getValueByProtocolFieldId: (protocolFieldId) =>\n instance.getValueByProtocolFieldId(protocolFieldId),\n }\n}\n\nexport function initFormsServer<TSchemas extends FormSchemaMap = FormSchemaMap>(\n options: FormsServerInitOptions<TSchemas>,\n): FormsServerClient<TSchemas> {\n const server = options.server\n if (typeof server.getProjectId !== 'function' || typeof server.getAppUserId !== 'function') {\n throw new FormsError('initFormsServer requires an initialized Embeddables server instance.')\n }\n\n if (typeof server.getFormIds !== 'function' || typeof server.getFormSchema !== 'function') {\n throw new FormsError('initFormsServer requires a Core instance with registered form schemas.')\n }\n\n const projectId = server.getProjectId()\n const storage = createMemoryFormsStorage()\n seedServerFormsStorageFromCookies({\n storage,\n projectId,\n formIds: server.getFormIds(),\n getFormSchema: (formId) => server.getFormSchema(formId),\n getCookie: (key) => server.getCookie(key),\n })\n\n const client = createFormsClient<TSchemas>({\n core: server,\n customValidations: options.customValidations,\n analyticsInstance: options.analyticsInstance,\n storage,\n persistence: createNoopPersistence(),\n } satisfies FormsClientOptions)\n\n const serverClient = {\n getForm({ formId }: { formId: keyof TSchemas & string }) {\n return toServerFormInstance(client.getForm({ formId }))\n },\n getServerFormData() {\n const data: ServerFormDataByFormId<TSchemas> = {}\n for (const formId of server.getFormIds()) {\n const key = formId as keyof TSchemas & string\n data[key] = client.getForm({ formId: key }).getAll()\n }\n return data\n },\n } satisfies FormsServerClient<TSchemas>\n\n return serverClient\n}\n"],"mappings":";;AAwBA,SAAS,qBACP,UAC6B;CAC7B,OAAO;EACL,KAAK,SAAS;EACd,MAAM,UAAU,SAAS,IAAI,KAAK;EAClC,MAAM,QAAQ,SAAS,IAAI,GAAG;EAC9B,cAAc,SAAS,OAAO;EAC9B,4BAA4B,oBAC1B,SAAS,0BAA0B,eAAe;CACtD;AACF;AAEA,SAAgB,gBACd,SAC6B;CAC7B,MAAM,SAAS,QAAQ;CACvB,IAAI,OAAO,OAAO,iBAAiB,cAAc,OAAO,OAAO,iBAAiB,YAC9E,MAAM,IAAI,WAAW,sEAAsE;CAG7F,IAAI,OAAO,OAAO,eAAe,cAAc,OAAO,OAAO,kBAAkB,YAC7E,MAAM,IAAI,WAAW,wEAAwE;CAG/F,MAAM,YAAY,OAAO,aAAa;CACtC,MAAM,UAAU,yBAAyB;CACzC,kCAAkC;EAChC;EACA;EACA,SAAS,OAAO,WAAW;EAC3B,gBAAgB,WAAW,OAAO,cAAc,MAAM;EACtD,YAAY,QAAQ,OAAO,UAAU,GAAG;CAC1C,CAAC;CAED,MAAM,SAAS,kBAA4B;EACzC,MAAM;EACN,mBAAmB,QAAQ;EAC3B,mBAAmB,QAAQ;EAC3B;EACA,aAAa,sBAAsB;CACrC,CAA8B;CAgB9B,OAAO;EAbL,QAAQ,EAAE,UAA+C;GACvD,OAAO,qBAAqB,OAAO,QAAQ,EAAE,OAAO,CAAC,CAAC;EACxD;EACA,oBAAoB;GAClB,MAAM,OAAyC,CAAC;GAChD,KAAK,MAAM,UAAU,OAAO,WAAW,GAAG;IACxC,MAAM,MAAM;IACZ,KAAK,OAAO,OAAO,QAAQ,EAAE,QAAQ,IAAI,CAAC,CAAC,CAAC,OAAO;GACrD;GACA,OAAO;EACT;CAGgB;AACpB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@embeddables/forms",
3
- "version": "0.0.4",
3
+ "version": "0.2.0",
4
4
  "description": "Schema-driven form state, local persistence, and analytics events for Embeddables funnels.",
5
5
  "private": false,
6
6
  "type": "module",
@@ -26,6 +26,11 @@
26
26
  "types": "./dist/react.d.ts",
27
27
  "import": "./dist/react.js",
28
28
  "require": "./dist/react.cjs"
29
+ },
30
+ "./server": {
31
+ "types": "./dist/server.d.ts",
32
+ "import": "./dist/server.js",
33
+ "require": "./dist/server.cjs"
29
34
  }
30
35
  },
31
36
  "files": [
@@ -39,7 +44,7 @@
39
44
  "hono": "^4.12.25"
40
45
  },
41
46
  "peerDependencies": {
42
- "@embeddables/core": ">=0.0.3",
47
+ "@embeddables/core": ">=0.1.0",
43
48
  "react": ">=18"
44
49
  },
45
50
  "devDependencies": {
@@ -52,9 +57,9 @@
52
57
  "tsdown": "^0.22.14",
53
58
  "typescript": "~6.0.2",
54
59
  "vitest": "^4.1.9",
55
- "@embeddables/core": "0.0.4",
56
- "backend-worker": "1.0.0",
57
- "@embeddables/shared-types": "1.0.0"
60
+ "@embeddables/core": "0.1.0",
61
+ "@embeddables/shared-types": "1.0.0",
62
+ "backend-worker": "1.0.0"
58
63
  },
59
64
  "scripts": {
60
65
  "build": "tsdown",