@jayalfredprufrock/mobx-toolbox 0.6.0 → 0.6.2

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.
package/dist/dialog.d.mts CHANGED
@@ -1,6 +1,4 @@
1
- import * as _$react from "react";
2
1
  import { FC } from "react";
3
- import * as _$react_jsx_runtime0 from "react/jsx-runtime";
4
2
 
5
3
  //#region src/dialog/dialog.types.d.ts
6
4
  type DialogState = "opening" | "opened" | "closing" | "closed";
@@ -48,7 +46,7 @@ interface MobxDialogsProps {
48
46
  }
49
47
  declare const MobxDialogs: (({
50
48
  store
51
- }: MobxDialogsProps) => _$react_jsx_runtime0.JSX.Element) & {
49
+ }: MobxDialogsProps) => import("react/jsx-runtime").JSX.Element) & {
52
50
  displayName: string;
53
51
  };
54
52
  interface MobxDialogProps {
@@ -56,18 +54,18 @@ interface MobxDialogProps {
56
54
  }
57
55
  declare const MobxDialog: (({
58
56
  dialog
59
- }: MobxDialogProps) => _$react_jsx_runtime0.JSX.Element) & {
57
+ }: MobxDialogProps) => import("react/jsx-runtime").JSX.Element) & {
60
58
  displayName: string;
61
59
  };
62
60
  //#endregion
63
61
  //#region src/dialog/dialog.context.d.ts
64
- declare const dialogStoreContext: _$react.Context<DialogStore | undefined>;
62
+ declare const dialogStoreContext: import("react").Context<DialogStore | undefined>;
65
63
  declare const useDialogStore: () => DialogStore;
66
- declare const DialogStoreProvider: _$react.Provider<DialogStore | undefined>;
67
- declare const dialogContext: _$react.Context<DialogModel | undefined>;
64
+ declare const DialogStoreProvider: import("react").Provider<DialogStore | undefined>;
65
+ declare const dialogContext: import("react").Context<DialogModel | undefined>;
68
66
  declare const useDialogContext: () => DialogModel;
69
67
  declare const useDialogContextIfAvailable: () => DialogModel | undefined;
70
- declare const DialogProvider: _$react.Provider<DialogModel | undefined>;
68
+ declare const DialogProvider: import("react").Provider<DialogModel | undefined>;
71
69
  //#endregion
72
70
  //#region src/dialog/use-dialogs.d.ts
73
71
  declare const useDialogs: (store?: DialogStore) => DialogStore;
@@ -1 +1 @@
1
- {"version":3,"file":"dialog.d.mts","names":[],"sources":["../src/dialog/dialog.types.ts","../src/dialog/dialog.store.ts","../src/dialog/dialog.model.ts","../src/dialog/components/dialogs.tsx","../src/dialog/dialog.context.ts","../src/dialog/use-dialogs.ts"],"mappings":";;;;;KAEY,WAAA;AAAA,KAEP,YAAA,oBAAgC,CAAA,gBAAiB,IAAA,CAAK,CAAA,EAAG,CAAA,YAAa,CAAA,SAAU,CAAA;AAAA,KAEzE,YAAA,GAAe,EAAA;AAAA,KAEf,uBAAA,WAAkC,YAAA,MAAkB,UAAA,CAAW,CAAA,QACzE,YAAA,CAAa,CAAA,mBAAoB,CAAA,EAAG,CAAA,MAAO,CAAA,EAAG,CAAA;AAAA,UAE/B,iBAAA;EACf,EAAA;EACA,SAAA,EAAW,YAAA;EACX,KAAA,GAAQ,KAAA,CAAM,cAAA,CAAe,YAAA;EAC7B,cAAA;EACA,YAAA,GAAe,WAAA;AAAA;;;cCZJ,WAAA;EACX,OAAA,EAAO,GAAA,SAAA,WAAA;EAAA,IAEH,WAAA,CAAA,GAAe,WAAA;EAAA,IAMf,YAAA,CAAA,GAAgB,WAAA;EAIpB,WAAA,CAAA;EAIA,GAAA,CAAI,MAAA,EAAQ,iBAAA,GAAoB,WAAA;EAMhC,IAAA,WAAe,YAAA,CAAA,CAAA,GAAiB,IAAA,EAAM,uBAAA,CAAwB,CAAA,IAAK,WAAA;EAUnE,KAAA,CAAM,gBAAA;AAAA;;;cCjCK,WAAA;EAAA,SAWA,KAAA,EAAO,WAAA;EAAA,SACP,MAAA,EAAQ,iBAAA;EAAA,SAXV,EAAA;EAAA,SACA,SAAA,EAAW,YAAA;EAAA,SACX,KAAA,GAAQ,KAAA,CAAM,cAAA,CAAe,YAAA;EAEtC,QAAA;EACA,wBAAA,EAA0B,WAAA;EAE1B,KAAA,EAAQ,WAAA;EAER,WAAA,CACW,KAAA,EAAO,WAAA,EACP,MAAA,EAAQ,iBAAA;EAiBnB,KAAA,CAAM,gBAAA;EAIN,IAAA,CAAK,eAAA;EAIL,QAAA,CAAS,KAAA,EAAO,WAAA;AAAA;;;UCnCD,gBAAA;EACf,KAAA,GAAQ,WAAA;AAAA;AAAA,cAGG,WAAA;EAAW;AAAA,GAAwB,gBAAA,KAAgB,oBAAA,CAAA,GAAA,CAAA,OAAA;;;UAY/C,eAAA;EACf,MAAA,EAAQ,WAAA;AAAA;AAAA,cAGG,UAAA;EAAU;AAAA,GAAyB,eAAA,KAAe,oBAAA,CAAA,GAAA,CAAA,OAAA;;;;;cCtBlD,kBAAA,EAAkB,OAAA,CAAA,OAAA,CAAA,WAAA;AAAA,cAClB,cAAA,QAAc,WAAA;AAAA,cAQd,mBAAA,EAAmB,OAAA,CAAA,QAAA,CAAA,WAAA;AAAA,cAEnB,aAAA,EAAa,OAAA,CAAA,OAAA,CAAA,WAAA;AAAA,cACb,gBAAA,QAAgB,WAAA;AAAA,cAQhB,2BAAA,QAA2B,WAAA;AAAA,cAE3B,cAAA,EAAc,OAAA,CAAA,QAAA,CAAA,WAAA;;;cCvBd,UAAA,GAAU,KAAA,GAAY,WAAA,KAAc,WAAA"}
1
+ {"version":3,"file":"dialog.d.mts","names":[],"sources":["../src/dialog/dialog.types.ts","../src/dialog/dialog.store.ts","../src/dialog/dialog.model.ts","../src/dialog/components/dialogs.tsx","../src/dialog/dialog.context.ts","../src/dialog/use-dialogs.ts"],"mappings":";;;KAEY,WAAA;AAAA,KAEP,YAAA,oBAAgC,CAAA,gBAAiB,IAAA,CAAK,CAAA,EAAG,CAAA,YAAa,CAAA,SAAU,CAAA;AAAA,KAEzE,YAAA,GAAe,EAAE;AAAA,KAEjB,uBAAA,WAAkC,YAAA,MAAkB,UAAA,CAAW,CAAA,QACzE,YAAA,CAAa,CAAA,mBAAoB,CAAA,EAAG,CAAA,MAAO,CAAA,EAAG,CAAA;AAAA,UAE/B,iBAAA;EACf,EAAA;EACA,SAAA,EAAW,YAAA;EACX,KAAA,GAAQ,KAAA,CAAM,cAAA,CAAe,YAAA;EAC7B,cAAA;EACA,YAAA,GAAe,WAAA;AAAA;;;cCZJ,WAAA;EACX,OAAA,EAAO,GAAA,SAAA,WAAA;EAAA,IAEH,WAAA,IAAe,WAAA;EAAA,IAMf,YAAA,IAAgB,WAAA;EAIpB,WAAA;EAIA,GAAA,CAAI,MAAA,EAAQ,iBAAA,GAAoB,WAAA;EAMhC,IAAA,WAAe,YAAA,KAAiB,IAAA,EAAM,uBAAA,CAAwB,CAAA,IAAK,WAAA;EAUnE,KAAA,CAAM,gBAAA;AAAA;;;cCjCK,WAAA;EAAA,SAWA,KAAA,EAAO,WAAA;EAAA,SACP,MAAA,EAAQ,iBAAA;EAAA,SAXV,EAAA;EAAA,SACA,SAAA,EAAW,YAAA;EAAA,SACX,KAAA,GAAQ,KAAA,CAAM,cAAA,CAAe,YAAA;EAEtC,QAAA;EACA,wBAAA,EAA0B,WAAA;EAE1B,KAAA,EAAQ,WAAA;EAER,WAAA,CACW,KAAA,EAAO,WAAA,EACP,MAAA,EAAQ,iBAAA;EAiBnB,KAAA,CAAM,gBAAA;EAIN,IAAA,CAAK,eAAA;EAIL,QAAA,CAAS,KAAA,EAAO,WAAA;AAAA;;;UCnCD,gBAAA;EACf,KAAA,GAAQ,WAAW;AAAA;AAAA,cAGR,WAAA;EAAW;AAAA,GAAwB,gBAAgB,iCAAA,GAAA,CAAA,OAAA;;;UAY/C,eAAA;EACf,MAAA,EAAQ,WAAW;AAAA;AAAA,cAGR,UAAA;EAAU;AAAA,GAAyB,eAAe,iCAAA,GAAA,CAAA,OAAA;;;;;cCtBlD,kBAAA,kBAAkB,OAAA,CAAA,WAAA;AAAA,cAClB,cAAA,QAAc,WAM1B;AAAA,cAEY,mBAAA,kBAAmB,QAAA,CAAA,WAAA;AAAA,cAEnB,aAAA,kBAAa,OAAA,CAAA,WAAA;AAAA,cACb,gBAAA,QAAgB,WAM5B;AAAA,cAEY,2BAAA,QAA2B,WAAA;AAAA,cAE3B,cAAA,kBAAc,QAAA,CAAA,WAAA;;;cCvBd,UAAA,GAAU,KAAA,GAAY,WAAA,KAAc,WAMhD"}
package/dist/dialog.mjs CHANGED
@@ -23,6 +23,8 @@ const DialogProvider = dialogContext.Provider;
23
23
  //#endregion
24
24
  //#region src/dialog/dialog.model.ts
25
25
  var DialogModel = class {
26
+ store;
27
+ config;
26
28
  id;
27
29
  component;
28
30
  props;
@@ -1 +1 @@
1
- {"version":3,"file":"dialog.mjs","names":[],"sources":["../src/dialog/dialog.context.ts","../src/dialog/dialog.model.ts","../src/dialog/dialog.store.ts","../src/dialog/use-dialogs.ts","../src/dialog/components/dialogs.tsx"],"sourcesContent":["import { createContext, useContext } from \"react\";\nimport type { DialogModel } from \"./dialog.model\";\nimport type { DialogStore } from \"./dialog.store\";\n\nexport const dialogStoreContext = createContext<DialogStore | undefined>(undefined);\nexport const useDialogStore = () => {\n const context = useContext(dialogStoreContext);\n if (!context) {\n throw new Error(\"Dialog store context not available. Are you using the <Dialogs /> component?\");\n }\n return context;\n};\n\nexport const DialogStoreProvider = dialogStoreContext.Provider;\n\nexport const dialogContext = createContext<DialogModel | undefined>(undefined);\nexport const useDialogContext = () => {\n const context = useContext(dialogContext);\n if (!context) {\n throw new Error(\"Dialog context not available. Are you using <DialogProvider /> ?\");\n }\n return context;\n};\n\nexport const useDialogContextIfAvailable = () => useContext(dialogContext);\n\nexport const DialogProvider = dialogContext.Provider;\n","import { makeAutoObservable } from \"mobx\";\nimport type { DialogStore } from \"./dialog.store\";\nimport type { AnyComponent, DialogModelConfig, DialogState } from \"./dialog.types\";\n\nexport class DialogModel {\n readonly id: string;\n readonly component: AnyComponent;\n readonly props?: React.ComponentProps<AnyComponent>;\n\n openedAt = 0;\n previouslyFocusedElement: HTMLElement | null = null;\n\n state!: DialogState;\n\n constructor(\n readonly store: DialogStore,\n readonly config: DialogModelConfig,\n ) {\n this.id = config.id ?? btoa(Math.random().toString()).substring(3, 12);\n this.component = config.component;\n this.props = config.props;\n\n this.setState(config.initialState ?? \"closed\");\n\n makeAutoObservable(this, {\n id: false,\n component: false,\n props: false,\n openedAt: false,\n previouslyFocusedElement: false,\n });\n }\n\n close(closeImmediately?: boolean): void {\n this.setState(closeImmediately ? \"closed\" : \"closing\");\n }\n\n open(openImmediately?: boolean): void {\n this.setState(openImmediately ? \"opened\" : \"opening\");\n }\n\n setState(state: DialogState): void {\n if (this.state === state) return;\n\n this.state = state;\n if (state === \"opened\" || state === \"opening\") {\n this.openedAt = Date.now();\n if (state === \"opening\") {\n this.previouslyFocusedElement =\n document.activeElement instanceof HTMLElement ? document.activeElement : null;\n }\n } else if (state === \"closed\") {\n this.previouslyFocusedElement?.focus();\n if (this.config.removeOnClosed) {\n this.store.dialogs.delete(this.id);\n }\n this.previouslyFocusedElement = null;\n }\n }\n}\n","import { makeAutoObservable } from \"mobx\";\nimport { DialogModel } from \"./dialog.model\";\nimport type { AnyComponent, DialogComponentAndProps, DialogModelConfig } from \"./dialog.types\";\n\nexport class DialogStore {\n dialogs = new Map<string, DialogModel>();\n\n get openDialogs(): DialogModel[] {\n return [...this.dialogs.values()]\n .filter((d) => d.state !== \"closed\")\n .sort((d1, d2) => d1.openedAt - d2.openedAt);\n }\n\n get activeDialog(): DialogModel | undefined {\n return this.openDialogs.at(-1);\n }\n\n constructor() {\n makeAutoObservable(this);\n }\n\n add(config: DialogModelConfig): DialogModel {\n const dialogModel = new DialogModel(this, config);\n this.dialogs.set(dialogModel.id, dialogModel);\n return dialogModel;\n }\n\n open<C extends AnyComponent>(...args: DialogComponentAndProps<C>): DialogModel {\n const [component, props] = args;\n return this.add({\n component,\n props,\n removeOnClosed: true,\n initialState: \"opening\",\n });\n }\n\n close(closeImmediately?: boolean): void {\n this.activeDialog?.close(closeImmediately);\n }\n}\n","import { useRef } from \"react\";\nimport { DialogStore } from \"./dialog.store\";\n\nexport const useDialogs = (store?: DialogStore): DialogStore => {\n const storeRef = useRef<DialogStore | undefined>(store);\n if (!storeRef.current) {\n storeRef.current = new DialogStore();\n }\n return storeRef.current;\n};\n","import { observer } from \"mobx-react-lite\";\nimport { DialogProvider, DialogStoreProvider } from \"../dialog.context\";\nimport type { DialogModel } from \"../dialog.model\";\nimport type { DialogStore } from \"../dialog.store\";\nimport { useDialogs } from \"../use-dialogs\";\n\nexport interface MobxDialogsProps {\n store?: DialogStore;\n}\n\nexport const MobxDialogs = observer(({ store }: MobxDialogsProps) => {\n const dialogStore = useDialogs(store);\n\n return (\n <DialogStoreProvider value={dialogStore}>\n {dialogStore.openDialogs.map((dialog) => {\n return <MobxDialog key={dialog.id} dialog={dialog} />;\n })}\n </DialogStoreProvider>\n );\n});\n\nexport interface MobxDialogProps {\n dialog: DialogModel;\n}\n\nexport const MobxDialog = observer(({ dialog }: MobxDialogProps) => {\n const { component: DialogComponent, props: dialogProps } = dialog;\n return (\n <DialogProvider value={dialog}>\n <DialogComponent {...dialogProps} />\n </DialogProvider>\n );\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"dialog.mjs","names":[],"sources":["../src/dialog/dialog.context.ts","../src/dialog/dialog.model.ts","../src/dialog/dialog.store.ts","../src/dialog/use-dialogs.ts","../src/dialog/components/dialogs.tsx"],"sourcesContent":["import { createContext, useContext } from \"react\";\nimport type { DialogModel } from \"./dialog.model\";\nimport type { DialogStore } from \"./dialog.store\";\n\nexport const dialogStoreContext = createContext<DialogStore | undefined>(undefined);\nexport const useDialogStore = () => {\n const context = useContext(dialogStoreContext);\n if (!context) {\n throw new Error(\"Dialog store context not available. Are you using the <Dialogs /> component?\");\n }\n return context;\n};\n\nexport const DialogStoreProvider = dialogStoreContext.Provider;\n\nexport const dialogContext = createContext<DialogModel | undefined>(undefined);\nexport const useDialogContext = () => {\n const context = useContext(dialogContext);\n if (!context) {\n throw new Error(\"Dialog context not available. Are you using <DialogProvider /> ?\");\n }\n return context;\n};\n\nexport const useDialogContextIfAvailable = () => useContext(dialogContext);\n\nexport const DialogProvider = dialogContext.Provider;\n","import { makeAutoObservable } from \"mobx\";\nimport type { DialogStore } from \"./dialog.store\";\nimport type { AnyComponent, DialogModelConfig, DialogState } from \"./dialog.types\";\n\nexport class DialogModel {\n readonly id: string;\n readonly component: AnyComponent;\n readonly props?: React.ComponentProps<AnyComponent>;\n\n openedAt = 0;\n previouslyFocusedElement: HTMLElement | null = null;\n\n state!: DialogState;\n\n constructor(\n readonly store: DialogStore,\n readonly config: DialogModelConfig,\n ) {\n this.id = config.id ?? btoa(Math.random().toString()).substring(3, 12);\n this.component = config.component;\n this.props = config.props;\n\n this.setState(config.initialState ?? \"closed\");\n\n makeAutoObservable(this, {\n id: false,\n component: false,\n props: false,\n openedAt: false,\n previouslyFocusedElement: false,\n });\n }\n\n close(closeImmediately?: boolean): void {\n this.setState(closeImmediately ? \"closed\" : \"closing\");\n }\n\n open(openImmediately?: boolean): void {\n this.setState(openImmediately ? \"opened\" : \"opening\");\n }\n\n setState(state: DialogState): void {\n if (this.state === state) return;\n\n this.state = state;\n if (state === \"opened\" || state === \"opening\") {\n this.openedAt = Date.now();\n if (state === \"opening\") {\n this.previouslyFocusedElement =\n document.activeElement instanceof HTMLElement ? document.activeElement : null;\n }\n } else if (state === \"closed\") {\n this.previouslyFocusedElement?.focus();\n if (this.config.removeOnClosed) {\n this.store.dialogs.delete(this.id);\n }\n this.previouslyFocusedElement = null;\n }\n }\n}\n","import { makeAutoObservable } from \"mobx\";\nimport { DialogModel } from \"./dialog.model\";\nimport type { AnyComponent, DialogComponentAndProps, DialogModelConfig } from \"./dialog.types\";\n\nexport class DialogStore {\n dialogs = new Map<string, DialogModel>();\n\n get openDialogs(): DialogModel[] {\n return [...this.dialogs.values()]\n .filter((d) => d.state !== \"closed\")\n .sort((d1, d2) => d1.openedAt - d2.openedAt);\n }\n\n get activeDialog(): DialogModel | undefined {\n return this.openDialogs.at(-1);\n }\n\n constructor() {\n makeAutoObservable(this);\n }\n\n add(config: DialogModelConfig): DialogModel {\n const dialogModel = new DialogModel(this, config);\n this.dialogs.set(dialogModel.id, dialogModel);\n return dialogModel;\n }\n\n open<C extends AnyComponent>(...args: DialogComponentAndProps<C>): DialogModel {\n const [component, props] = args;\n return this.add({\n component,\n props,\n removeOnClosed: true,\n initialState: \"opening\",\n });\n }\n\n close(closeImmediately?: boolean): void {\n this.activeDialog?.close(closeImmediately);\n }\n}\n","import { useRef } from \"react\";\nimport { DialogStore } from \"./dialog.store\";\n\nexport const useDialogs = (store?: DialogStore): DialogStore => {\n const storeRef = useRef<DialogStore | undefined>(store);\n if (!storeRef.current) {\n storeRef.current = new DialogStore();\n }\n return storeRef.current;\n};\n","import { observer } from \"mobx-react-lite\";\nimport { DialogProvider, DialogStoreProvider } from \"../dialog.context\";\nimport type { DialogModel } from \"../dialog.model\";\nimport type { DialogStore } from \"../dialog.store\";\nimport { useDialogs } from \"../use-dialogs\";\n\nexport interface MobxDialogsProps {\n store?: DialogStore;\n}\n\nexport const MobxDialogs = observer(({ store }: MobxDialogsProps) => {\n const dialogStore = useDialogs(store);\n\n return (\n <DialogStoreProvider value={dialogStore}>\n {dialogStore.openDialogs.map((dialog) => {\n return <MobxDialog key={dialog.id} dialog={dialog} />;\n })}\n </DialogStoreProvider>\n );\n});\n\nexport interface MobxDialogProps {\n dialog: DialogModel;\n}\n\nexport const MobxDialog = observer(({ dialog }: MobxDialogProps) => {\n const { component: DialogComponent, props: dialogProps } = dialog;\n return (\n <DialogProvider value={dialog}>\n <DialogComponent {...dialogProps} />\n </DialogProvider>\n );\n});\n"],"mappings":"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"}
package/dist/form.d.mts CHANGED
@@ -1,7 +1,4 @@
1
- import * as _$react from "react";
2
- import * as _$react_jsx_runtime0 from "react/jsx-runtime";
3
1
  import { Validator } from "typebox/schema";
4
- import * as _$typebox from "typebox";
5
2
  import { Static, TLiteral, TObject, TSchema, TUnion } from "typebox";
6
3
 
7
4
  //#region src/form/form-field.model.d.ts
@@ -86,7 +83,7 @@ declare class FormModel<T extends FormSchema = TObject> {
86
83
  interface MobxFormProps extends Omit<React.HTMLProps<HTMLFormElement>, "form" | "action" | "method"> {
87
84
  form: FormModel<any>;
88
85
  }
89
- declare const MobxForm: _$react.ForwardRefExoticComponent<Omit<MobxFormProps, "ref"> & _$react.RefAttributes<unknown>>;
86
+ declare const MobxForm: import("react").ForwardRefExoticComponent<Omit<MobxFormProps, "ref"> & import("react").RefAttributes<unknown>>;
90
87
  //#endregion
91
88
  //#region src/form/components/form-when.d.ts
92
89
  interface FormWhenProps<T extends TUnion, D extends DiscriminatorKeys<T>, V extends string> {
@@ -108,13 +105,13 @@ declare function FormWhen<T extends TUnion, D extends DiscriminatorKeys<T>, V ex
108
105
  field,
109
106
  value,
110
107
  children
111
- }: FormWhenProps<T, D, V>): _$react_jsx_runtime0.JSX.Element;
108
+ }: FormWhenProps<T, D, V>): import("react/jsx-runtime").JSX.Element;
112
109
  //#endregion
113
110
  //#region src/form/form.context.d.ts
114
- declare const formContext: _$react.Context<FormModel<_$typebox.TObject<_$typebox.TProperties>> | undefined>;
115
- declare const useFormContext: () => FormModel<_$typebox.TObject<_$typebox.TProperties>>;
116
- declare const FormProvider: _$react.Provider<FormModel<_$typebox.TObject<_$typebox.TProperties>> | undefined>;
117
- declare const useFormContextIfAvailable: () => FormModel<_$typebox.TObject<_$typebox.TProperties>> | undefined;
111
+ declare const formContext: import("react").Context<FormModel<import("typebox").TObject<import("typebox").TProperties>> | undefined>;
112
+ declare const useFormContext: () => FormModel<import("typebox").TObject<import("typebox").TProperties>>;
113
+ declare const FormProvider: import("react").Provider<FormModel<import("typebox").TObject<import("typebox").TProperties>> | undefined>;
114
+ declare const useFormContextIfAvailable: () => FormModel<import("typebox").TObject<import("typebox").TProperties>> | undefined;
118
115
  //#endregion
119
116
  //#region src/form/use-form.d.ts
120
117
  declare const useForm: <T extends FormSchema = TObject>(schema: T, config: FormConfig<T>) => FormModel<T>;
@@ -1 +1 @@
1
- {"version":3,"file":"form.d.mts","names":[],"sources":["../src/form/form-field.model.ts","../src/form/form.types.ts","../src/form/form.model.ts","../src/form/components/form.tsx","../src/form/components/form-when.tsx","../src/form/form.context.ts","../src/form/use-form.ts"],"mappings":";;;;;;;cAUa,cAAA,WAAyB,CAAA,CAAE,OAAA,GAAU,CAAA,CAAE,OAAA;EAAA,SACzC,IAAA;EAAA,SACA,MAAA,EAAQ,CAAA;EAAA,SACR,MAAA,EAAQ,eAAA,CAAgB,CAAA;EAAA,SACxB,SAAA,EAAW,SAAA,CAAU,CAAA;EAE9B,KAAA,EAAO,CAAA,CAAE,MAAA,CAAO,CAAA;EAChB,OAAA;EAAA,IAEI,KAAA,CAAA;EAAA,IAKA,YAAA,CAAA;EA2BJ,WAAA,CAAY,MAAA,EAAQ,eAAA,CAAgB,CAAA;EAepC,QAAA,CAAS,KAAA,GAAQ,CAAA,CAAE,MAAA,CAAO,CAAA;EAM1B,UAAA,CAAW,OAAA;EAIX,KAAA,CAAA;EAQA,KAAA,CAAA;EAWA,MAAA,CAAA,GAAU,CAAA,CAAE,MAAA,CAAO,CAAA;AAAA;;;KC5FT,UAAA,GAAa,OAAA,GAAU,MAAA;AAAA,UAElB,UAAA,WAAqB,UAAA,GAAa,OAAA;EACjD,YAAA,GAAe,IAAA,EAAM,MAAA,CAAO,CAAA,MAAO,OAAA;EAEnC,aAAA,GAAgB,iBAAA,CAAkB,CAAA;AAAA;AAAA,UAGnB,eAAA,WAA0B,OAAA,GAAU,OAAA;EACnD,IAAA;EACA,MAAA,EAAQ,CAAA;EACR,YAAA,GAAe,MAAA,CAAO,CAAA;AAAA;AAAA,KAGnB,mBAAA,OAA0B,CAAA,oBAAqB,CAAA,EAAG,CAAA,6BACrD,CAAA,sBAEE,CAAA;;KAIC,WAAA,MAAiB,CAAA,SAAU,OAAA,SAAgB,CAAA;;KAG3C,UAAA,MACH,mBAAA,CAAoB,CAAA,SAAU,OAAA;EAAY,CAAA,QAAS,CAAA;AAAA;EACjD,CAAA,kBAAmB,WAAA;AAAA,IAEjB,CAAA;;KAID,aAAA,cAA2B,WAAA,IAAe,CAAA,SAAU,OAAA,GACrD,CAAA,eAAgB,CAAA,iBACd,CAAA,eAAgB,CAAA;;KAKjB,YAAA,cAA0B,WAAA,IAAe,CAAA,SAAU,OAAA,GACpD,CAAA,eAAgB,CAAA,iBACd,MAAA,CAAO,CAAA,eAAgB,CAAA;AAAA,KAMjB,UAAA,WAAqB,UAAA,GAAa,OAAA,IAC5C,CAAA,SAAU,MAAA,oBACE,UAAA,CAAW,CAAA,YAAa,cAAA,CAAe,aAAA,CAAc,CAAA,UAAW,CAAA,OACxE,CAAA,SAAU,OAAA,iBACM,CAAA,iBAAkB,cAAA,CAAe,CAAA,eAAgB,CAAA;AAAA,KAK3D,aAAA,WAAwB,UAAA,GAAa,OAAA,IAC/C,CAAA,SAAU,MAAA,oBACE,WAAA,CAAY,CAAA,YAAa,cAAA,CAAe,aAAA,CAAc,CAAA,UAAW,CAAA,OACzE,CAAA,SAAU,OAAA,iBACM,CAAA,iBAAkB,cAAA,CAAe,CAAA,eAAgB,CAAA;AAAA,KAIlE,iBAAA,WAA4B,UAAA,IAC/B,CAAA,SAAU,MAAA,oBACE,WAAA,CAAY,CAAA,aAAc,YAAA,CAAa,CAAA,UAAW,CAAA,MAC1D,CAAA,SAAU,OAAA,GACR,OAAA,CAAQ,MAAA,CAAO,CAAA;;KAMX,iBAAA,WAA4B,MAAA,IACtC,CAAA,SAAU,MAAA,YAAkB,WAAA,CAAY,CAAA;AAAA,KAErC,WAAA,MAAiB,CAAA,SAAU,OAAA,iBAEd,CAAA,iBAAkB,CAAA,eAAgB,CAAA,UAAW,QAAA,GAAW,CAAA,iBAC9D,CAAA;;KAIA,kBAAA,WAA6B,MAAA,YAAkB,WAAA,IACzD,CAAA,SAAU,MAAA,YAAkB,YAAA,CAAa,CAAA,UAAW,CAAA;AAAA,KAEjD,YAAA,cAA0B,WAAA,IAAe,CAAA,SAAU,OAAA,GACpD,CAAA,eAAgB,CAAA,iBACd,CAAA,eAAgB,CAAA,UAAW,QAAA,YACzB,CAAA;;KAMI,YAAA,WAAuB,MAAA,YAAkB,WAAA,OACnD,CAAA,SAAU,MAAA,eAAqB,UAAA,CAAW,IAAA,UAAc,CAAA,EAAG,CAAA;AAAA,KAExD,UAAA,cAAwB,WAAA,OAAkB,CAAA,SAAU,OAAA,GACrD,CAAA,eAAgB,CAAA,iBACd,CAAA,eAAgB,CAAA,UAAW,QAAA,YACzB,CAAA,SAAU,CAAA,GACR,CAAA;;;cChEG,SAAA,WAAoB,UAAA,GAAa,OAAA;;WAEnC,MAAA,EAAQ,UAAA,CAAW,CAAA;;WAEnB,SAAA,EAAW,aAAA,CAAc,CAAA;EAAA,SACzB,MAAA,EAAQ,UAAA,CAAW,CAAA;EAAA,SACnB,MAAA,EAAQ,CAAA;EAAA,SACR,SAAA,EAAW,SAAA,CAAU,CAAA;EAG9B,UAAA;EACA,SAAA;EAGA,WAAA;EAEA,WAAA,CAAY,MAAA,EAAQ,CAAA,EAAG,MAAA,EAAQ,UAAA,CAAW,CAAA;EAAA,IAgCtC,KAAA,CAAA;EASJ,KAAA,CAAA;EA4BA,cAAA,CAAe,KAAA;EAAA,UAIL,aAAA,CAAc,UAAA;EAAA,UAId,YAAA,CAAa,SAAA;EAIvB,KAAA,CAAA;EAOA,QAAA,CAAA;EAOA,MAAA,CAAA,GAAU,OAAA,CAAQ,MAAA,CAAO,CAAA;AAAA;;;UCrJV,aAAA,SAAsB,IAAA,CACrC,KAAA,CAAM,SAAA,CAAU,eAAA;EAGhB,IAAA,EAAM,SAAA;AAAA;AAAA,cAGK,QAAA,EAAQ,OAAA,CAAA,yBAAA,CAAA,IAAA,CAAA,aAAA,WAAA,OAAA,CAAA,aAAA;;;UCAJ,aAAA,WAAwB,MAAA,YAAkB,iBAAA,CAAkB,CAAA;EAC3E,IAAA,EAAM,SAAA,CAAU,CAAA;;EAEhB,KAAA,EAAO,CAAA;EJJI;EIMX,KAAA,EAAO,CAAA,GAAI,kBAAA,CAAmB,CAAA,EAAG,CAAA;EJNR;EIQzB,QAAA,GAAW,MAAA,EAAQ,UAAA,CAAW,YAAA,CAAa,CAAA,EAAG,CAAA,EAAG,CAAA,OAAQ,KAAA,CAAM,SAAA;AAAA;;;;;;iBAQjD,QAAA,WAAmB,MAAA,YAAkB,iBAAA,CAAkB,CAAA,oBAAA,CAAA;EACrE,IAAA;EACA,KAAA;EACA,KAAA;EACA;AAAA,GACC,aAAA,CAAc,CAAA,EAAG,CAAA,EAAG,CAAA,IAAE,oBAAA,CAAA,GAAA,CAAA,OAAA;;;cC5BZ,WAAA,EAAW,OAAA,CAAA,OAAA,CAAA,SAAA,CAAA,SAAA,CAAA,OAAA,CAAkD,SAAA,CAAlD,WAAA;AAAA,cACX,cAAA,QAAc,SAAA,CAAA,SAAA,CAAA,OAAA,CAQ1B,SAAA,CAR0B,WAAA;AAAA,cAUd,YAAA,EAAY,OAAA,CAAA,QAAA,CAAA,SAAA,CAAA,SAAA,CAAA,OAAA,CAAuB,SAAA,CAAvB,WAAA;AAAA,cAEZ,yBAAA,QAAyB,SAAA,CAAA,SAAA,CAAA,OAAA,CAAgC,SAAA,CAAhC,WAAA;;;cCXzB,OAAA,aAAqB,UAAA,GAAa,OAAA,EAAO,MAAA,EAC5C,CAAA,EAAC,MAAA,EACD,UAAA,CAAW,CAAA,MAClB,SAAA,CAAU,CAAA"}
1
+ {"version":3,"file":"form.d.mts","names":[],"sources":["../src/form/form-field.model.ts","../src/form/form.types.ts","../src/form/form.model.ts","../src/form/components/form.tsx","../src/form/components/form-when.tsx","../src/form/form.context.ts","../src/form/use-form.ts"],"mappings":"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"}
package/dist/form.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"form.mjs","names":[],"sources":["../src/form/form.context.ts","../src/form/components/form.tsx","../src/form/components/form-when.tsx","../src/form/form-field.model.ts","../src/form/form.model.ts","../src/form/use-form.ts"],"sourcesContent":["import { createContext, useContext } from \"react\";\nimport type { FormModel } from \"./form.model\";\n\nexport const formContext = createContext<FormModel | undefined>(undefined);\nexport const useFormContext = () => {\n const context = useContext(formContext);\n if (!context) {\n throw new Error(\n \"Form context not available. Make sure you are within the <Form> component or providing the form context manually.\",\n );\n }\n return context;\n};\n\nexport const FormProvider = formContext.Provider;\n\nexport const useFormContextIfAvailable = () => useContext(formContext);\n","import { forwardRef } from \"react\";\nimport { FormProvider } from \"../form.context\";\nimport type { FormModel } from \"../form.model\";\n\nexport interface MobxFormProps extends Omit<\n React.HTMLProps<HTMLFormElement>,\n \"form\" | \"action\" | \"method\"\n> {\n form: FormModel<any>;\n}\n\nexport const MobxForm = forwardRef(function MobxForm(\n { form, children, ...formProps }: MobxFormProps,\n ref,\n) {\n return (\n <FormProvider value={form}>\n <form noValidate {...formProps} ref={ref} {...form.props()}>\n {children}\n </form>\n </FormProvider>\n );\n});\n","import type { TUnion } from \"typebox\";\nimport { Observer } from \"mobx-react-lite\";\nimport type { FormModel } from \"../form.model\";\nimport type { FormFieldModel } from \"../form-field.model\";\nimport type {\n DiscriminatorKeys,\n DiscriminatorValue,\n FormFields,\n MatchVariant,\n} from \"../form.types\";\n\nexport interface FormWhenProps<T extends TUnion, D extends DiscriminatorKeys<T>, V extends string> {\n form: FormModel<T>;\n /** The discriminator field name. */\n field: D;\n /** Render the children only while the discriminator field equals this value. */\n value: V & DiscriminatorValue<T, D>;\n /** Receives the matching variant's fields. The form itself is already in scope. */\n children: (fields: FormFields<MatchVariant<T, D, V>>) => React.ReactNode;\n}\n\n/**\n * Renders its children only when the form's discriminator field currently holds\n * `value`, passing the fields narrowed to that variant. Stack one per variant to\n * lay out a discriminated-union form without manual conditionals or casts.\n */\nexport function FormWhen<T extends TUnion, D extends DiscriminatorKeys<T>, V extends string>({\n form,\n field,\n value,\n children,\n}: FormWhenProps<T, D, V>) {\n return (\n <Observer>\n {() => {\n const fields = form.rawFields as Record<string, FormFieldModel>;\n if (fields[field as string]?.value !== value) return null;\n return <>{children(fields as unknown as FormFields<MatchVariant<T, D, V>>)}</>;\n }}\n </Observer>\n );\n}\n","import Schema, { Validator } from \"typebox/schema\";\nimport * as Value from \"typebox/value\";\nimport * as T from \"typebox\";\nimport { makeAutoObservable, toJS } from \"mobx\";\nimport type { FormFieldConfig } from \"./form.types\";\n\n// TODO: should infer required prop\n// TODO: should also allow for \"id\", defaulting to name\n// TODO: probably shouldn't assume value is of correct type, maybe unknown?\n\nexport class FormFieldModel<T extends T.TSchema = T.TSchema> {\n readonly name: string;\n readonly schema: T;\n readonly config: FormFieldConfig<T>;\n readonly validator: Validator<T>;\n\n value: T.Static<T> | undefined;\n touched = false;\n\n get valid(): boolean {\n if (this.value === undefined && T.IsOptional(this.schema)) return true;\n return this.validator.Check(this.value);\n }\n\n get errorMessage(): string {\n if (this.valid || !this.touched) return \"\";\n // TODO: revisit this, now that .Errors returns success/fail\n const [_, errors] = this.validator.Errors(this.value);\n const error = errors.at(0);\n\n if (!error) return \"\";\n\n if (!T.IsOptional(this.schema) && (this.value === undefined || this.value === \"\")) {\n return \"This field is required.\";\n }\n\n if (\"errorMessage\" in this.schema) {\n if (typeof this.schema.errorMessage === \"string\") {\n return this.schema.errorMessage;\n } else if (typeof this.schema.errorMessage === \"function\") {\n return this.schema.errorMessage(this.value, this.schema);\n }\n }\n\n if (T.IsString(this.schema) && \"format\" in this.schema) {\n return `Please enter a valid ${String(this.schema.format)}`;\n }\n\n return error.message;\n }\n\n constructor(config: FormFieldConfig<T>) {\n this.config = config;\n this.name = config.name;\n this.schema = config.schema;\n this.validator = Schema.Compile(this.schema);\n this.value = Value.Convert(this.schema, config.initialValue) as T.Static<T>;\n\n makeAutoObservable(this, {\n name: false,\n schema: false,\n config: false,\n validator: false,\n });\n }\n\n setValue(value?: T.Static<T>) {\n // TODO: does this still make sense? If value is invalid,\n // then type will be wrong...revisit this\n this.value = Value.Convert(this.schema, value) as T.Static<T>;\n }\n\n setTouched(touched: boolean) {\n this.touched = touched;\n }\n\n reset() {\n this.setTouched(false);\n this.setValue(this.config.initialValue);\n }\n\n // TODO: this any type is dangerous, need to figure out a good way\n // to make this work OTTB for most form controls, while allowing\n // some kind of escape hatch for special cases\n props(): any {\n return {\n name: this.name,\n onChange: (v?: T.Static<T>) => this.setValue(v),\n value: this.value,\n onBlur: () => {\n this.setTouched(true);\n },\n };\n }\n\n toJSON(): T.Static<T> | undefined {\n return toJS(this.value);\n }\n}\n","import * as Format from \"typebox/format\";\nimport * as Value from \"typebox/value\";\nimport Schema, { type Validator } from \"typebox/schema\";\nimport { IsUnion, Union, type Static, type TObject, type TSchema } from \"typebox\";\nimport { makeAutoObservable } from \"mobx\";\nimport type { FormConfig, FormFields, FormSchema, RawFormFields } from \"./form.types\";\nimport { FormFieldModel } from \"./form-field.model\";\n\n// should these be here?\nFormat.Set(\"password\", () => true);\nFormat.Set(\"phone\", () => true);\n\n// Flatten a schema's fields into a single property map. For a discriminated\n// union this merges the properties of every variant, unioning the schemas of\n// any field that appears in more than one variant (which naturally turns the\n// discriminator into a union of its literals).\nfunction resolveProperties(schema: FormSchema): Record<string, TSchema> {\n if (!IsUnion(schema)) return schema.properties;\n\n const groups: Record<string, TSchema[]> = {};\n for (const variant of schema.anyOf) {\n for (const [key, propSchema] of Object.entries((variant as TObject).properties)) {\n (groups[key] ??= []).push(propSchema as TSchema);\n }\n }\n\n const merged: Record<string, TSchema> = {};\n for (const [key, schemas] of Object.entries(groups)) {\n const distinct = [...new Map(schemas.map((s) => [JSON.stringify(s), s])).values()];\n merged[key] = distinct.length === 1 ? distinct[0]! : Union(distinct);\n }\n return merged;\n}\n\n// consider using enumerable to allow spreading of\n// field model instead of calling props() unless we need\n// to pass data to props...\n\n// TODO:\n// handleSubmit should catch a special MobxFormError\n// that can set field-level errors from an API response\n\nexport class FormModel<T extends FormSchema = TObject> {\n /** Shared fields only (for unions); every field for a plain object schema. */\n readonly fields: FormFields<T>;\n /** Every field across all variants — escape hatch for reaching variant fields. */\n readonly rawFields: RawFormFields<T>;\n readonly config: FormConfig<T>;\n readonly schema: T;\n readonly validator: Validator<T>;\n\n // TODO: maybe refactor into a \"state\" property?\n submitting = false;\n submitted = false;\n\n // TODO: what should this type be? should it be generic?\n submitError: any;\n\n constructor(schema: T, config: FormConfig<T>) {\n this.schema = schema;\n this.config = config;\n this.validator = Schema.Compile(schema);\n\n makeAutoObservable(this, {\n fields: false,\n rawFields: false,\n schema: false,\n config: false,\n validator: false,\n });\n\n const initialValues = config?.initialValues as Record<string, unknown> | undefined;\n const fields = Object.entries(resolveProperties(schema)).reduce(\n (fields, [fieldName, fieldSchema]) => {\n fields[fieldName] = new FormFieldModel({\n name: fieldName,\n schema: fieldSchema,\n initialValue: initialValues?.[fieldName],\n });\n return fields;\n },\n {} as Record<string, FormFieldModel<TSchema>>,\n );\n\n // `fields` and `rawFields` are the same object; the types differ so that a\n // union form only surfaces shared fields by default.\n this.rawFields = fields as unknown as RawFormFields<T>;\n this.fields = fields as unknown as FormFields<T>;\n }\n\n get valid(): boolean {\n // A union form can't be validated field-by-field — fields belonging to the\n // inactive variant would fail — so validate the assembled object instead.\n if (IsUnion(this.schema)) {\n return this.validator.Check(this.toJSON());\n }\n return Object.values(this.fields).every((field) => field.valid);\n }\n\n props(): any {\n return {\n onSubmit: (e: React.FormEvent<HTMLFormElement>) => {\n e.preventDefault();\n\n this.setSubmitError(undefined);\n\n if (!this.validate()) {\n return;\n }\n\n this.setSubmitting(true);\n this.config\n .handleSubmit(this.toJSON() as Static<T>)\n .then((resp) => {\n this.setSubmitted(true);\n return resp;\n })\n .catch((e) => {\n this.setSubmitError(e);\n })\n .finally(() => {\n this.setSubmitting(false);\n });\n },\n };\n }\n\n setSubmitError(error: any): void {\n this.submitError = error;\n }\n\n protected setSubmitting(submitting: boolean): void {\n this.submitting = submitting;\n }\n\n protected setSubmitted(submitted: boolean): void {\n this.submitted = submitted;\n }\n\n reset(): void {\n this.setSubmitError(undefined);\n for (const field of Object.values(this.fields)) {\n field.reset();\n }\n }\n\n validate(): boolean {\n for (const field of Object.values(this.fields)) {\n field.setTouched(true);\n }\n return this.valid;\n }\n\n toJSON(): Partial<Static<T>> {\n const data = Object.values(this.fields).reduce(\n (fields, field) => {\n fields[field.name] = field.toJSON();\n return fields;\n },\n {} as Record<string, unknown>,\n );\n\n // Drop fields belonging to the inactive variant so submitted data matches\n // the selected member of the union exactly.\n if (IsUnion(this.schema)) {\n return Value.Clean(this.schema, data) as Partial<Static<T>>;\n }\n return data as Partial<Static<T>>;\n }\n}\n","import type { TObject } from \"typebox\";\nimport { useRef } from \"react\";\nimport { FormModel } from \"./form.model\";\nimport type { FormConfig, FormSchema } from \"./form.types\";\n\nexport const useForm = <T extends FormSchema = TObject>(\n schema: T,\n config: FormConfig<T>,\n): FormModel<T> => {\n const formRef = useRef<FormModel<T>>(undefined);\n if (formRef.current) {\n Object.assign(formRef.current.config, config);\n } else {\n formRef.current = new FormModel<T>(schema, config);\n }\n\n return formRef.current;\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"form.mjs","names":[],"sources":["../src/form/form.context.ts","../src/form/components/form.tsx","../src/form/components/form-when.tsx","../src/form/form-field.model.ts","../src/form/form.model.ts","../src/form/use-form.ts"],"sourcesContent":["import { createContext, useContext } from \"react\";\nimport type { FormModel } from \"./form.model\";\n\nexport const formContext = createContext<FormModel | undefined>(undefined);\nexport const useFormContext = () => {\n const context = useContext(formContext);\n if (!context) {\n throw new Error(\n \"Form context not available. Make sure you are within the <Form> component or providing the form context manually.\",\n );\n }\n return context;\n};\n\nexport const FormProvider = formContext.Provider;\n\nexport const useFormContextIfAvailable = () => useContext(formContext);\n","import { forwardRef } from \"react\";\nimport { FormProvider } from \"../form.context\";\nimport type { FormModel } from \"../form.model\";\n\nexport interface MobxFormProps extends Omit<\n React.HTMLProps<HTMLFormElement>,\n \"form\" | \"action\" | \"method\"\n> {\n form: FormModel<any>;\n}\n\nexport const MobxForm = forwardRef(function MobxForm(\n { form, children, ...formProps }: MobxFormProps,\n ref,\n) {\n return (\n <FormProvider value={form}>\n <form noValidate {...formProps} ref={ref} {...form.props()}>\n {children}\n </form>\n </FormProvider>\n );\n});\n","import type { TUnion } from \"typebox\";\nimport { Observer } from \"mobx-react-lite\";\nimport type { FormModel } from \"../form.model\";\nimport type { FormFieldModel } from \"../form-field.model\";\nimport type {\n DiscriminatorKeys,\n DiscriminatorValue,\n FormFields,\n MatchVariant,\n} from \"../form.types\";\n\nexport interface FormWhenProps<T extends TUnion, D extends DiscriminatorKeys<T>, V extends string> {\n form: FormModel<T>;\n /** The discriminator field name. */\n field: D;\n /** Render the children only while the discriminator field equals this value. */\n value: V & DiscriminatorValue<T, D>;\n /** Receives the matching variant's fields. The form itself is already in scope. */\n children: (fields: FormFields<MatchVariant<T, D, V>>) => React.ReactNode;\n}\n\n/**\n * Renders its children only when the form's discriminator field currently holds\n * `value`, passing the fields narrowed to that variant. Stack one per variant to\n * lay out a discriminated-union form without manual conditionals or casts.\n */\nexport function FormWhen<T extends TUnion, D extends DiscriminatorKeys<T>, V extends string>({\n form,\n field,\n value,\n children,\n}: FormWhenProps<T, D, V>) {\n return (\n <Observer>\n {() => {\n const fields = form.rawFields as Record<string, FormFieldModel>;\n if (fields[field as string]?.value !== value) return null;\n return <>{children(fields as unknown as FormFields<MatchVariant<T, D, V>>)}</>;\n }}\n </Observer>\n );\n}\n","import Schema, { Validator } from \"typebox/schema\";\nimport * as Value from \"typebox/value\";\nimport * as T from \"typebox\";\nimport { makeAutoObservable, toJS } from \"mobx\";\nimport type { FormFieldConfig } from \"./form.types\";\n\n// TODO: should infer required prop\n// TODO: should also allow for \"id\", defaulting to name\n// TODO: probably shouldn't assume value is of correct type, maybe unknown?\n\nexport class FormFieldModel<T extends T.TSchema = T.TSchema> {\n readonly name: string;\n readonly schema: T;\n readonly config: FormFieldConfig<T>;\n readonly validator: Validator<T>;\n\n value: T.Static<T> | undefined;\n touched = false;\n\n get valid(): boolean {\n if (this.value === undefined && T.IsOptional(this.schema)) return true;\n return this.validator.Check(this.value);\n }\n\n get errorMessage(): string {\n if (this.valid || !this.touched) return \"\";\n // TODO: revisit this, now that .Errors returns success/fail\n const [_, errors] = this.validator.Errors(this.value);\n const error = errors.at(0);\n\n if (!error) return \"\";\n\n if (!T.IsOptional(this.schema) && (this.value === undefined || this.value === \"\")) {\n return \"This field is required.\";\n }\n\n if (\"errorMessage\" in this.schema) {\n if (typeof this.schema.errorMessage === \"string\") {\n return this.schema.errorMessage;\n } else if (typeof this.schema.errorMessage === \"function\") {\n return this.schema.errorMessage(this.value, this.schema);\n }\n }\n\n if (T.IsString(this.schema) && \"format\" in this.schema) {\n return `Please enter a valid ${String(this.schema.format)}`;\n }\n\n return error.message;\n }\n\n constructor(config: FormFieldConfig<T>) {\n this.config = config;\n this.name = config.name;\n this.schema = config.schema;\n this.validator = Schema.Compile(this.schema);\n this.value = Value.Convert(this.schema, config.initialValue) as T.Static<T>;\n\n makeAutoObservable(this, {\n name: false,\n schema: false,\n config: false,\n validator: false,\n });\n }\n\n setValue(value?: T.Static<T>) {\n // TODO: does this still make sense? If value is invalid,\n // then type will be wrong...revisit this\n this.value = Value.Convert(this.schema, value) as T.Static<T>;\n }\n\n setTouched(touched: boolean) {\n this.touched = touched;\n }\n\n reset() {\n this.setTouched(false);\n this.setValue(this.config.initialValue);\n }\n\n // TODO: this any type is dangerous, need to figure out a good way\n // to make this work OTTB for most form controls, while allowing\n // some kind of escape hatch for special cases\n props(): any {\n return {\n name: this.name,\n onChange: (v?: T.Static<T>) => this.setValue(v),\n value: this.value,\n onBlur: () => {\n this.setTouched(true);\n },\n };\n }\n\n toJSON(): T.Static<T> | undefined {\n return toJS(this.value);\n }\n}\n","import * as Format from \"typebox/format\";\nimport * as Value from \"typebox/value\";\nimport Schema, { type Validator } from \"typebox/schema\";\nimport { IsUnion, Union, type Static, type TObject, type TSchema } from \"typebox\";\nimport { makeAutoObservable } from \"mobx\";\nimport type { FormConfig, FormFields, FormSchema, RawFormFields } from \"./form.types\";\nimport { FormFieldModel } from \"./form-field.model\";\n\n// should these be here?\nFormat.Set(\"password\", () => true);\nFormat.Set(\"phone\", () => true);\n\n// Flatten a schema's fields into a single property map. For a discriminated\n// union this merges the properties of every variant, unioning the schemas of\n// any field that appears in more than one variant (which naturally turns the\n// discriminator into a union of its literals).\nfunction resolveProperties(schema: FormSchema): Record<string, TSchema> {\n if (!IsUnion(schema)) return schema.properties;\n\n const groups: Record<string, TSchema[]> = {};\n for (const variant of schema.anyOf) {\n for (const [key, propSchema] of Object.entries((variant as TObject).properties)) {\n (groups[key] ??= []).push(propSchema as TSchema);\n }\n }\n\n const merged: Record<string, TSchema> = {};\n for (const [key, schemas] of Object.entries(groups)) {\n const distinct = [...new Map(schemas.map((s) => [JSON.stringify(s), s])).values()];\n merged[key] = distinct.length === 1 ? distinct[0]! : Union(distinct);\n }\n return merged;\n}\n\n// consider using enumerable to allow spreading of\n// field model instead of calling props() unless we need\n// to pass data to props...\n\n// TODO:\n// handleSubmit should catch a special MobxFormError\n// that can set field-level errors from an API response\n\nexport class FormModel<T extends FormSchema = TObject> {\n /** Shared fields only (for unions); every field for a plain object schema. */\n readonly fields: FormFields<T>;\n /** Every field across all variants — escape hatch for reaching variant fields. */\n readonly rawFields: RawFormFields<T>;\n readonly config: FormConfig<T>;\n readonly schema: T;\n readonly validator: Validator<T>;\n\n // TODO: maybe refactor into a \"state\" property?\n submitting = false;\n submitted = false;\n\n // TODO: what should this type be? should it be generic?\n submitError: any;\n\n constructor(schema: T, config: FormConfig<T>) {\n this.schema = schema;\n this.config = config;\n this.validator = Schema.Compile(schema);\n\n makeAutoObservable(this, {\n fields: false,\n rawFields: false,\n schema: false,\n config: false,\n validator: false,\n });\n\n const initialValues = config?.initialValues as Record<string, unknown> | undefined;\n const fields = Object.entries(resolveProperties(schema)).reduce(\n (fields, [fieldName, fieldSchema]) => {\n fields[fieldName] = new FormFieldModel({\n name: fieldName,\n schema: fieldSchema,\n initialValue: initialValues?.[fieldName],\n });\n return fields;\n },\n {} as Record<string, FormFieldModel<TSchema>>,\n );\n\n // `fields` and `rawFields` are the same object; the types differ so that a\n // union form only surfaces shared fields by default.\n this.rawFields = fields as unknown as RawFormFields<T>;\n this.fields = fields as unknown as FormFields<T>;\n }\n\n get valid(): boolean {\n // A union form can't be validated field-by-field — fields belonging to the\n // inactive variant would fail — so validate the assembled object instead.\n if (IsUnion(this.schema)) {\n return this.validator.Check(this.toJSON());\n }\n return Object.values(this.fields).every((field) => field.valid);\n }\n\n props(): any {\n return {\n onSubmit: (e: React.FormEvent<HTMLFormElement>) => {\n e.preventDefault();\n\n this.setSubmitError(undefined);\n\n if (!this.validate()) {\n return;\n }\n\n this.setSubmitting(true);\n this.config\n .handleSubmit(this.toJSON() as Static<T>)\n .then((resp) => {\n this.setSubmitted(true);\n return resp;\n })\n .catch((e) => {\n this.setSubmitError(e);\n })\n .finally(() => {\n this.setSubmitting(false);\n });\n },\n };\n }\n\n setSubmitError(error: any): void {\n this.submitError = error;\n }\n\n protected setSubmitting(submitting: boolean): void {\n this.submitting = submitting;\n }\n\n protected setSubmitted(submitted: boolean): void {\n this.submitted = submitted;\n }\n\n reset(): void {\n this.setSubmitError(undefined);\n for (const field of Object.values(this.fields)) {\n field.reset();\n }\n }\n\n validate(): boolean {\n for (const field of Object.values(this.fields)) {\n field.setTouched(true);\n }\n return this.valid;\n }\n\n toJSON(): Partial<Static<T>> {\n const data = Object.values(this.fields).reduce(\n (fields, field) => {\n fields[field.name] = field.toJSON();\n return fields;\n },\n {} as Record<string, unknown>,\n );\n\n // Drop fields belonging to the inactive variant so submitted data matches\n // the selected member of the union exactly.\n if (IsUnion(this.schema)) {\n return Value.Clean(this.schema, data) as Partial<Static<T>>;\n }\n return data as Partial<Static<T>>;\n }\n}\n","import type { TObject } from \"typebox\";\nimport { useRef } from \"react\";\nimport { FormModel } from \"./form.model\";\nimport type { FormConfig, FormSchema } from \"./form.types\";\n\nexport const useForm = <T extends FormSchema = TObject>(\n schema: T,\n config: FormConfig<T>,\n): FormModel<T> => {\n const formRef = useRef<FormModel<T>>(undefined);\n if (formRef.current) {\n Object.assign(formRef.current.config, config);\n } else {\n formRef.current = new FormModel<T>(schema, config);\n }\n\n return formRef.current;\n};\n"],"mappings":"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"}
@@ -33,4 +33,4 @@ declare function lazyObservableArray<T>(fetch: () => Promise<T[]>, options?: Laz
33
33
  type InferLazyObservable<O> = O extends LazyObservableArray<infer T> ? T[] : O extends LazyObservable<infer T> ? T : never;
34
34
  //#endregion
35
35
  export { LazyObservableOptions as a, lazyObservableArray as c, LazyObservableArrayOptions as i, LazyObservable as n, LazyObservableOptionsWithInitialValue as o, LazyObservableArray as r, lazyObservable as s, InferLazyObservable as t };
36
- //# sourceMappingURL=lazy-observable-DA4DIMbc.d.mts.map
36
+ //# sourceMappingURL=lazy-observable-Bx58qmfb.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lazy-observable-Bx58qmfb.d.mts","names":[],"sources":["../src/lazy-observable/lazy-observable.ts"],"mappings":";;;UAUiB,cAAA,0BAAwC,CAAA;EACvD,KAAA,EAAO,aAAA;EACP,KAAA,IAAS,aAAA;EACT,SAAA,IAAa,OAAA,CAAQ,CAAA;EACrB,GAAA,CAAI,KAAA,EAAO,CAAA;EACX,MAAA,IAAU,OAAA,CAAQ,CAAA;EAClB,MAAA;EACA,KAAA;EACA,OAAA;EACA,MAAA;AAAA;AAAA,UAGe,qBAAA;EACf,OAAA;EACA,iBAAA;EACA,SAAA;AAAA;AAAA,UAGe,qCAAA,wBAEP,qBAAqB;EAC7B,YAAA,GAAe,aAAA;AAAA;AAAA,iBAGD,cAAA,IAAkB,KAAA,QAAa,OAAA,CAAQ,CAAA,IAAK,cAAA,CAAe,CAAA;AAAA,iBAC3D,cAAA,IACd,KAAA,QAAa,OAAA,CAAQ,CAAA,GACrB,OAAA,EAAS,qBAAA,GACR,cAAA,CAAe,CAAA;AAAA,iBACF,cAAA,mBACd,KAAA,QAAa,OAAA,CAAQ,CAAA,GACrB,OAAA,EAAS,qCAAA,CAAsC,aAAA,IAC9C,cAAA,CAAe,CAAA,EAAG,aAAA;AAAA,UAkLJ,mBAAA,kBAAqC,IAAA,CACpD,cAAA,CAAe,gBAAA,CAAiB,CAAA;EAGhC,GAAA,CAAI,KAAA,EAAO,CAAA;AAAA;AAAA,UAGI,0BAAA,YAAsC,qBAAqB;EAC1E,YAAA,GAAe,CAAA;AAAA;AAAA,iBAGD,mBAAA,IACd,KAAA,QAAa,OAAA,CAAQ,CAAA,KACrB,OAAA,GAAU,0BAAA,CAA2B,CAAA,IACpC,mBAAA,CAAoB,CAAA;AAAA,KAIX,mBAAA,MACV,CAAA,SAAU,mBAAA,YAA+B,CAAA,KAAM,CAAA,SAAU,cAAA,YAA0B,CAAA"}
@@ -138,4 +138,4 @@ function lazyObservableArray(fetch, options) {
138
138
 
139
139
  //#endregion
140
140
  export { lazyObservableArray as n, lazyObservable as t };
141
- //# sourceMappingURL=lazy-observable-CdHXpUkk.mjs.map
141
+ //# sourceMappingURL=lazy-observable-Ce5e1Izm.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"lazy-observable-CdHXpUkk.mjs","names":[],"sources":["../src/lazy-observable/lazy-observable.ts"],"sourcesContent":["import {\n _allowStateChanges,\n autorun,\n type IObservableArray,\n type IReactionDisposer,\n observable,\n onBecomeObserved,\n onBecomeUnobserved,\n} from \"mobx\";\n\nexport interface LazyObservable<T = any, TInitialValue = T | undefined> {\n value: TInitialValue;\n reset(): TInitialValue;\n getOrLoad(): Promise<T>;\n set(value: T): void;\n reload(): Promise<T>;\n status: \"init\" | \"loading\" | \"loaded\" | \"error\";\n error: unknown;\n loading: boolean;\n loaded: boolean;\n}\n\nexport interface LazyObservableOptions {\n shallow?: boolean;\n resetOnUnobserved?: \"never\" | \"always\" | number;\n debugName?: string;\n}\n\nexport interface LazyObservableOptionsWithInitialValue<\n TInitialValue,\n> extends LazyObservableOptions {\n initialValue?: TInitialValue;\n}\n\nexport function lazyObservable<T>(fetch: () => Promise<T>): LazyObservable<T>;\nexport function lazyObservable<T>(\n fetch: () => Promise<T>,\n options: LazyObservableOptions,\n): LazyObservable<T>;\nexport function lazyObservable<T, TInitialValue>(\n fetch: () => Promise<T>,\n options: LazyObservableOptionsWithInitialValue<TInitialValue>,\n): LazyObservable<T, TInitialValue>;\n\nexport function lazyObservable<T>(\n fetch: () => Promise<T>,\n options?: LazyObservableOptionsWithInitialValue<T>,\n): LazyObservable<T> {\n const value = observable.box<T>(options?.initialValue, { deep: !options?.shallow });\n const status = observable.box<LazyObservable<T>[\"status\"]>(\"init\");\n const error = observable.box<unknown>(undefined);\n\n let resetTimer: NodeJS.Timeout;\n let autorunDisposer: IReactionDisposer;\n\n let promise: Promise<T> | undefined;\n let promiseResolve: ((value: T) => void) | undefined;\n let promiseReject: ((value: unknown) => void) | undefined;\n\n const getOrCreatePromise = () => {\n if (promise && status.get() !== \"loaded\" && status.get() !== \"error\") {\n return promise;\n }\n promise = new Promise<T>((resolve, reject) => {\n promiseResolve = resolve;\n promiseReject = reject;\n });\n return promise;\n };\n\n const reset = () => {\n clearTimeout(resetTimer);\n autorunDisposer?.();\n _allowStateChanges(true, () => {\n value.set(options?.initialValue);\n status.set(\"init\");\n error.set(undefined);\n });\n return options?.initialValue;\n };\n\n const load = (): void => {\n if (status.get() === \"loading\") return;\n clearTimeout(resetTimer);\n\n // TODO: this disposer is unreliable while we are using\n // babel to convert all async function to generators\n autorunDisposer?.();\n autorunDisposer = autorun(() => {\n _allowStateChanges(true, () => {\n status.set(\"loading\");\n error.set(undefined);\n });\n\n let fetchPromise: Promise<T>;\n try {\n fetchPromise = fetch();\n } catch (e) {\n _allowStateChanges(true, () => {\n error.set(e);\n status.set(\"error\");\n promiseReject?.(e);\n });\n return;\n }\n\n fetchPromise\n .then((newValue) => {\n _allowStateChanges(true, () => {\n value.set(newValue);\n status.set(\"loaded\");\n promiseResolve?.(newValue);\n });\n })\n .catch((e) => {\n _allowStateChanges(true, () => {\n error.set(e);\n status.set(\"error\");\n promiseReject?.(e);\n });\n });\n });\n };\n\n // TODO: should this resolve any promises?\n const set = (val: T): void => {\n _allowStateChanges(true, () => {\n value.set(val);\n status.set(\"loaded\");\n });\n };\n\n let observedCount = 0;\n\n const onObserved = () => {\n observedCount = Math.min(2, observedCount + 1);\n\n // only consider observed the first time this handler gets called\n if (observedCount !== 1) return;\n\n if (options?.debugName) {\n console.log(`lazyObservable ${options.debugName}`, \"observed\");\n }\n clearTimeout(resetTimer);\n if (status.get() === \"error\" || status.get() === \"init\") {\n load();\n }\n };\n\n const onUnobserved = () => {\n observedCount = Math.max(0, observedCount - 1);\n\n // only consider unobserved when count reaches zero\n if (observedCount) return;\n\n if (options?.debugName) {\n console.log(`lazyObservable ${options.debugName}`, \"unobserved\");\n }\n\n // Errors are never cached regardless of resetOnUnobserved — failure state\n // shouldn't persist across mounts, only successfully loaded values should.\n if (status.get() === \"error\") {\n _allowStateChanges(true, () => {\n status.set(\"init\");\n error.set(undefined);\n });\n return;\n }\n\n if (options?.resetOnUnobserved === \"never\") {\n return;\n } else if (typeof options?.resetOnUnobserved === \"number\") {\n resetTimer = setTimeout(() => {\n reset();\n }, options?.resetOnUnobserved);\n } else {\n reset();\n }\n };\n\n onBecomeObserved(value, onObserved);\n onBecomeObserved(status, onObserved);\n onBecomeObserved(error, onObserved);\n\n onBecomeUnobserved(value, onUnobserved);\n onBecomeUnobserved(status, onUnobserved);\n onBecomeUnobserved(error, onUnobserved);\n\n return {\n get value() {\n return value.get();\n },\n get status() {\n return status.get();\n },\n get error() {\n return error.get();\n },\n get loading() {\n return status.get() === \"loading\";\n },\n get loaded() {\n return status.get() === \"loaded\";\n },\n reload() {\n const promise = getOrCreatePromise();\n load();\n return promise;\n },\n getOrLoad() {\n // TODO: this assertion shouldn't be necessary\n // consider fixing box/value type\n if (this.loaded) return Promise.resolve(value.get() as Promise<T>);\n return this.reload();\n },\n set,\n reset,\n };\n}\n\nexport interface LazyObservableArray<T = any> extends Omit<\n LazyObservable<IObservableArray<T>>,\n \"set\"\n> {\n set(value: T[]): void;\n}\n\nexport interface LazyObservableArrayOptions<T> extends LazyObservableOptions {\n initialValue?: T[];\n}\n\nexport function lazyObservableArray<T>(\n fetch: () => Promise<T[]>,\n options?: LazyObservableArrayOptions<T>,\n): LazyObservableArray<T> {\n return lazyObservable(fetch, { initialValue: [], ...options }) as LazyObservableArray<T>;\n}\n\nexport type InferLazyObservable<O> =\n O extends LazyObservableArray<infer T> ? T[] : O extends LazyObservable<infer T> ? T : never;\n"],"mappings":"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"}
1
+ {"version":3,"file":"lazy-observable-Ce5e1Izm.mjs","names":[],"sources":["../src/lazy-observable/lazy-observable.ts"],"sourcesContent":["import {\n _allowStateChanges,\n autorun,\n type IObservableArray,\n type IReactionDisposer,\n observable,\n onBecomeObserved,\n onBecomeUnobserved,\n} from \"mobx\";\n\nexport interface LazyObservable<T = any, TInitialValue = T | undefined> {\n value: TInitialValue;\n reset(): TInitialValue;\n getOrLoad(): Promise<T>;\n set(value: T): void;\n reload(): Promise<T>;\n status: \"init\" | \"loading\" | \"loaded\" | \"error\";\n error: unknown;\n loading: boolean;\n loaded: boolean;\n}\n\nexport interface LazyObservableOptions {\n shallow?: boolean;\n resetOnUnobserved?: \"never\" | \"always\" | number;\n debugName?: string;\n}\n\nexport interface LazyObservableOptionsWithInitialValue<\n TInitialValue,\n> extends LazyObservableOptions {\n initialValue?: TInitialValue;\n}\n\nexport function lazyObservable<T>(fetch: () => Promise<T>): LazyObservable<T>;\nexport function lazyObservable<T>(\n fetch: () => Promise<T>,\n options: LazyObservableOptions,\n): LazyObservable<T>;\nexport function lazyObservable<T, TInitialValue>(\n fetch: () => Promise<T>,\n options: LazyObservableOptionsWithInitialValue<TInitialValue>,\n): LazyObservable<T, TInitialValue>;\n\nexport function lazyObservable<T>(\n fetch: () => Promise<T>,\n options?: LazyObservableOptionsWithInitialValue<T>,\n): LazyObservable<T> {\n const value = observable.box<T>(options?.initialValue, { deep: !options?.shallow });\n const status = observable.box<LazyObservable<T>[\"status\"]>(\"init\");\n const error = observable.box<unknown>(undefined);\n\n let resetTimer: NodeJS.Timeout;\n let autorunDisposer: IReactionDisposer;\n\n let promise: Promise<T> | undefined;\n let promiseResolve: ((value: T) => void) | undefined;\n let promiseReject: ((value: unknown) => void) | undefined;\n\n const getOrCreatePromise = () => {\n if (promise && status.get() !== \"loaded\" && status.get() !== \"error\") {\n return promise;\n }\n promise = new Promise<T>((resolve, reject) => {\n promiseResolve = resolve;\n promiseReject = reject;\n });\n return promise;\n };\n\n const reset = () => {\n clearTimeout(resetTimer);\n autorunDisposer?.();\n _allowStateChanges(true, () => {\n value.set(options?.initialValue);\n status.set(\"init\");\n error.set(undefined);\n });\n return options?.initialValue;\n };\n\n const load = (): void => {\n if (status.get() === \"loading\") return;\n clearTimeout(resetTimer);\n\n // TODO: this disposer is unreliable while we are using\n // babel to convert all async function to generators\n autorunDisposer?.();\n autorunDisposer = autorun(() => {\n _allowStateChanges(true, () => {\n status.set(\"loading\");\n error.set(undefined);\n });\n\n let fetchPromise: Promise<T>;\n try {\n fetchPromise = fetch();\n } catch (e) {\n _allowStateChanges(true, () => {\n error.set(e);\n status.set(\"error\");\n promiseReject?.(e);\n });\n return;\n }\n\n fetchPromise\n .then((newValue) => {\n _allowStateChanges(true, () => {\n value.set(newValue);\n status.set(\"loaded\");\n promiseResolve?.(newValue);\n });\n })\n .catch((e) => {\n _allowStateChanges(true, () => {\n error.set(e);\n status.set(\"error\");\n promiseReject?.(e);\n });\n });\n });\n };\n\n // TODO: should this resolve any promises?\n const set = (val: T): void => {\n _allowStateChanges(true, () => {\n value.set(val);\n status.set(\"loaded\");\n });\n };\n\n let observedCount = 0;\n\n const onObserved = () => {\n observedCount = Math.min(2, observedCount + 1);\n\n // only consider observed the first time this handler gets called\n if (observedCount !== 1) return;\n\n if (options?.debugName) {\n console.log(`lazyObservable ${options.debugName}`, \"observed\");\n }\n clearTimeout(resetTimer);\n if (status.get() === \"error\" || status.get() === \"init\") {\n load();\n }\n };\n\n const onUnobserved = () => {\n observedCount = Math.max(0, observedCount - 1);\n\n // only consider unobserved when count reaches zero\n if (observedCount) return;\n\n if (options?.debugName) {\n console.log(`lazyObservable ${options.debugName}`, \"unobserved\");\n }\n\n // Errors are never cached regardless of resetOnUnobserved — failure state\n // shouldn't persist across mounts, only successfully loaded values should.\n if (status.get() === \"error\") {\n _allowStateChanges(true, () => {\n status.set(\"init\");\n error.set(undefined);\n });\n return;\n }\n\n if (options?.resetOnUnobserved === \"never\") {\n return;\n } else if (typeof options?.resetOnUnobserved === \"number\") {\n resetTimer = setTimeout(() => {\n reset();\n }, options?.resetOnUnobserved);\n } else {\n reset();\n }\n };\n\n onBecomeObserved(value, onObserved);\n onBecomeObserved(status, onObserved);\n onBecomeObserved(error, onObserved);\n\n onBecomeUnobserved(value, onUnobserved);\n onBecomeUnobserved(status, onUnobserved);\n onBecomeUnobserved(error, onUnobserved);\n\n return {\n get value() {\n return value.get();\n },\n get status() {\n return status.get();\n },\n get error() {\n return error.get();\n },\n get loading() {\n return status.get() === \"loading\";\n },\n get loaded() {\n return status.get() === \"loaded\";\n },\n reload() {\n const promise = getOrCreatePromise();\n load();\n return promise;\n },\n getOrLoad() {\n // TODO: this assertion shouldn't be necessary\n // consider fixing box/value type\n if (this.loaded) return Promise.resolve(value.get() as Promise<T>);\n return this.reload();\n },\n set,\n reset,\n };\n}\n\nexport interface LazyObservableArray<T = any> extends Omit<\n LazyObservable<IObservableArray<T>>,\n \"set\"\n> {\n set(value: T[]): void;\n}\n\nexport interface LazyObservableArrayOptions<T> extends LazyObservableOptions {\n initialValue?: T[];\n}\n\nexport function lazyObservableArray<T>(\n fetch: () => Promise<T[]>,\n options?: LazyObservableArrayOptions<T>,\n): LazyObservableArray<T> {\n return lazyObservable(fetch, { initialValue: [], ...options }) as LazyObservableArray<T>;\n}\n\nexport type InferLazyObservable<O> =\n O extends LazyObservableArray<infer T> ? T[] : O extends LazyObservable<infer T> ? T : never;\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { a as LazyObservableOptions, c as lazyObservableArray, i as LazyObservableArrayOptions, n as LazyObservable, o as LazyObservableOptionsWithInitialValue, r as LazyObservableArray, s as lazyObservable, t as InferLazyObservable } from "./lazy-observable-DA4DIMbc.mjs";
1
+ import { a as LazyObservableOptions, c as lazyObservableArray, i as LazyObservableArrayOptions, n as LazyObservable, o as LazyObservableOptionsWithInitialValue, r as LazyObservableArray, s as lazyObservable, t as InferLazyObservable } from "./lazy-observable-Bx58qmfb.mjs";
2
2
  import React from "react";
3
3
 
4
4
  //#region src/lazy-observable/components/lazy-observer.d.ts
@@ -1 +1 @@
1
- {"version":3,"file":"lazy-observable.d.mts","names":[],"sources":["../src/lazy-observable/components/lazy-observer.tsx"],"mappings":";;;;KAQK,EAAA,GAAK,cAAA,GAAiB,mBAAA;AAAA,KAEtB,YAAA,WAAuB,EAAA,oBACd,CAAA,GAAI,mBAAA,CAAoB,CAAA,CAAE,CAAA;AAAA,UAGvB,qBAAA;EACf,WAAA,GAAc,KAAA,CAAM,SAAA;AAAA;AAAA,UAGL,sBAAA,WAAiC,EAAA,YAAc,qBAAA;EAC9D,OAAA,MAAa,CAAA;EACb,QAAA,MAAc,KAAA,EAAO,YAAA,CAAa,CAAA,MAAO,KAAA,CAAM,SAAA;AAAA;AAAA,UAGhC,uBAAA,WAAkC,EAAA,UAAY,qBAAA;EAC7D,OAAA,EAAS,CAAA;EACT,QAAA,GAAW,KAAA,EAAO,mBAAA,CAAoB,CAAA,MAAO,KAAA,CAAM,SAAA;AAAA;AAAA,iBAGrC,YAAA,WAAuB,EAAA,GAAA,CAAM,KAAA,EAAO,sBAAA,CAAuB,CAAA,IAAK,KAAA,CAAM,SAAA;AAAA,iBACtE,YAAA,WAAuB,cAAA,CAAA,CACrC,KAAA,EAAO,uBAAA,CAAwB,CAAA,IAC9B,KAAA,CAAM,SAAA"}
1
+ {"version":3,"file":"lazy-observable.d.mts","names":[],"sources":["../src/lazy-observable/components/lazy-observer.tsx"],"mappings":";;;;KAQK,EAAA,GAAK,cAAA,GAAiB,mBAAmB;AAAA,KAEzC,YAAA,WAAuB,EAAA,oBACd,CAAA,GAAI,mBAAA,CAAoB,CAAA,CAAE,CAAA;AAAA,UAGvB,qBAAA;EACf,WAAA,GAAc,KAAA,CAAM,SAAS;AAAA;AAAA,UAGd,sBAAA,WAAiC,EAAA,YAAc,qBAAA;EAC9D,OAAA,MAAa,CAAA;EACb,QAAA,MAAc,KAAA,EAAO,YAAA,CAAa,CAAA,MAAO,KAAA,CAAM,SAAA;AAAA;AAAA,UAGhC,uBAAA,WAAkC,EAAA,UAAY,qBAAA;EAC7D,OAAA,EAAS,CAAA;EACT,QAAA,GAAW,KAAA,EAAO,mBAAA,CAAoB,CAAA,MAAO,KAAA,CAAM,SAAA;AAAA;AAAA,iBAGrC,YAAA,WAAuB,EAAA,IAAM,KAAA,EAAO,sBAAA,CAAuB,CAAA,IAAK,KAAA,CAAM,SAAA;AAAA,iBACtE,YAAA,WAAuB,cAAA,EACrC,KAAA,EAAO,uBAAA,CAAwB,CAAA,IAC9B,KAAA,CAAM,SAAA"}
@@ -1,4 +1,4 @@
1
- import { n as lazyObservableArray, t as lazyObservable } from "./lazy-observable-CdHXpUkk.mjs";
1
+ import { n as lazyObservableArray, t as lazyObservable } from "./lazy-observable-Ce5e1Izm.mjs";
2
2
  import { Observer } from "mobx-react-lite";
3
3
  import { jsx } from "react/jsx-runtime";
4
4
 
@@ -1 +1 @@
1
- {"version":3,"file":"lazy-observable.mjs","names":[],"sources":["../src/lazy-observable/components/lazy-observer.tsx"],"sourcesContent":["import type { InferLazyObservable, LazyObservable, LazyObservableArray } from \"../lazy-observable\";\nimport { Observer } from \"mobx-react-lite\";\nimport type React from \"react\";\n\nfunction ThrowError({ error }: { error: unknown }): never {\n throw error;\n}\n\ntype LO = LazyObservable | LazyObservableArray;\n\ntype ObserveTuple<O extends LO[]> = {\n [K in keyof O]: InferLazyObservable<O[K]>;\n};\n\nexport interface LazyObserverBaseProps {\n placeholder?: React.ReactNode;\n}\n\nexport interface LazyObserverTupleProps<O extends LO[]> extends LazyObserverBaseProps {\n observe: [...O];\n children: (...value: ObserveTuple<O>) => React.ReactNode;\n}\n\nexport interface LazyObserverSingleProps<O extends LO> extends LazyObserverBaseProps {\n observe: O;\n children: (value: InferLazyObservable<O>) => React.ReactNode;\n}\n\nexport function LazyObserver<O extends LO[]>(props: LazyObserverTupleProps<O>): React.ReactNode;\nexport function LazyObserver<O extends LazyObservable>(\n props: LazyObserverSingleProps<O>,\n): React.ReactNode;\nexport function LazyObserver(\n props: LazyObserverTupleProps<any> | LazyObserverSingleProps<any>,\n): React.ReactNode {\n const { observe, placeholder, children } = props;\n const observeAsArray = [observe].flat() as LO[];\n return (\n <Observer>\n {() => {\n const failed = observeAsArray.find((o) => o.status === \"error\");\n if (failed) return <ThrowError error={failed.error} />;\n if (!observeAsArray.every((o) => o.loaded)) return placeholder;\n return (children as any)(...observeAsArray.map((o) => o.value));\n }}\n </Observer>\n );\n}\n"],"mappings":";;;;;AAIA,SAAS,WAAW,EAAE,SAAoC;AACxD,OAAM;;AA2BR,SAAgB,aACd,OACiB;CACjB,MAAM,EAAE,SAAS,aAAa,aAAa;CAC3C,MAAM,iBAAiB,CAAC,QAAQ,CAAC,MAAM;AACvC,QACE,oBAAC,UAAD,kBACS;EACL,MAAM,SAAS,eAAe,MAAM,MAAM,EAAE,WAAW,QAAQ;AAC/D,MAAI,OAAQ,QAAO,oBAAC,YAAD,EAAY,OAAO,OAAO,OAAS;AACtD,MAAI,CAAC,eAAe,OAAO,MAAM,EAAE,OAAO,CAAE,QAAO;AACnD,SAAQ,SAAiB,GAAG,eAAe,KAAK,MAAM,EAAE,MAAM,CAAC;IAExD"}
1
+ {"version":3,"file":"lazy-observable.mjs","names":[],"sources":["../src/lazy-observable/components/lazy-observer.tsx"],"sourcesContent":["import type { InferLazyObservable, LazyObservable, LazyObservableArray } from \"../lazy-observable\";\nimport { Observer } from \"mobx-react-lite\";\nimport type React from \"react\";\n\nfunction ThrowError({ error }: { error: unknown }): never {\n throw error;\n}\n\ntype LO = LazyObservable | LazyObservableArray;\n\ntype ObserveTuple<O extends LO[]> = {\n [K in keyof O]: InferLazyObservable<O[K]>;\n};\n\nexport interface LazyObserverBaseProps {\n placeholder?: React.ReactNode;\n}\n\nexport interface LazyObserverTupleProps<O extends LO[]> extends LazyObserverBaseProps {\n observe: [...O];\n children: (...value: ObserveTuple<O>) => React.ReactNode;\n}\n\nexport interface LazyObserverSingleProps<O extends LO> extends LazyObserverBaseProps {\n observe: O;\n children: (value: InferLazyObservable<O>) => React.ReactNode;\n}\n\nexport function LazyObserver<O extends LO[]>(props: LazyObserverTupleProps<O>): React.ReactNode;\nexport function LazyObserver<O extends LazyObservable>(\n props: LazyObserverSingleProps<O>,\n): React.ReactNode;\nexport function LazyObserver(\n props: LazyObserverTupleProps<any> | LazyObserverSingleProps<any>,\n): React.ReactNode {\n const { observe, placeholder, children } = props;\n const observeAsArray = [observe].flat() as LO[];\n return (\n <Observer>\n {() => {\n const failed = observeAsArray.find((o) => o.status === \"error\");\n if (failed) return <ThrowError error={failed.error} />;\n if (!observeAsArray.every((o) => o.loaded)) return placeholder;\n return (children as any)(...observeAsArray.map((o) => o.value));\n }}\n </Observer>\n );\n}\n"],"mappings":";;;;;AAIA,SAAS,WAAW,EAAE,SAAoC;CACxD,MAAM;AACR;AA0BA,SAAgB,aACd,OACiB;CACjB,MAAM,EAAE,SAAS,aAAa,aAAa;CAC3C,MAAM,iBAAiB,CAAC,OAAO,CAAC,CAAC,KAAK;CACtC,OACE,oBAAC,UAAD,kBACS;EACL,MAAM,SAAS,eAAe,MAAM,MAAM,EAAE,WAAW,OAAO;EAC9D,IAAI,QAAQ,OAAO,oBAAC,YAAD,EAAY,OAAO,OAAO,MAAQ;EACrD,IAAI,CAAC,eAAe,OAAO,MAAM,EAAE,MAAM,GAAG,OAAO;EACnD,OAAQ,SAAiB,GAAG,eAAe,KAAK,MAAM,EAAE,KAAK,CAAC;CAChE,EACQ;AAEd"}
package/dist/model.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { r as LazyObservableArray } from "./lazy-observable-DA4DIMbc.mjs";
1
+ import { r as LazyObservableArray } from "./lazy-observable-Bx58qmfb.mjs";
2
2
  import { AnnotationsMap } from "mobx";
3
3
  import * as T from "typebox";
4
4
 
@@ -7,17 +7,23 @@ import * as T from "typebox";
7
7
  interface ModelStore<M> {
8
8
  remove?(model: M): void;
9
9
  }
10
- type Resource<S extends T.TObject> = T.Static<S>;
11
- type KeyShape<S extends T.TObject, K extends readonly (keyof Resource<S>)[]> = K extends readonly [] ? undefined : Pick<Resource<S>, K[number]>;
12
- type KeyedFn<S extends T.TObject, K extends readonly (keyof Resource<S>)[], R> = K extends readonly [] ? (...args: any[]) => Promise<R> : (params: KeyShape<S, K>, ...rest: any[]) => Promise<R>;
13
- type KeyedBodyFn<S extends T.TObject, K extends readonly (keyof Resource<S>)[], R> = K extends readonly [] ? (body: any, ...rest: any[]) => Promise<R> : (params: KeyShape<S, K>, body: any, ...rest: any[]) => Promise<R>;
10
+ /**
11
+ * Root schema for a model: a single object (`makeModel`) or a discriminated
12
+ * union of objects (`makeUnionModel`). Shared by both factories and by
13
+ * `makeStore`, which accepts either.
14
+ */
15
+ type ModelSchema = T.TObject | T.TUnion<T.TObject[]>;
16
+ type Resource<S extends ModelSchema> = T.Static<S>;
17
+ type KeyShape<S extends ModelSchema, K extends readonly (keyof Resource<S>)[]> = K extends readonly [] ? undefined : Pick<Resource<S>, K[number]>;
18
+ type KeyedFn<S extends ModelSchema, K extends readonly (keyof Resource<S>)[], R> = K extends readonly [] ? (...args: any[]) => Promise<R> : (params: KeyShape<S, K>, ...rest: any[]) => Promise<R>;
19
+ type KeyedBodyFn<S extends ModelSchema, K extends readonly (keyof Resource<S>)[], R> = K extends readonly [] ? (body: any, ...rest: any[]) => Promise<R> : (params: KeyShape<S, K>, body: any, ...rest: any[]) => Promise<R>;
14
20
  type StripParams<K extends readonly any[], F> = K extends readonly [] ? F : F extends ((params: any, ...rest: infer R) => infer Ret) ? (...args: R) => Ret : never;
15
21
  type ReplaceReturn$1<F, R> = F extends ((...args: infer A) => Promise<any>) ? (...args: A) => Promise<R> : never;
16
22
  type ReservedActionKey = "reload" | "update" | "delete" | "setData" | "toJSON" | "store";
17
- type ActionsConfig<S extends T.TObject, K extends readonly (keyof Resource<S>)[]> = {
23
+ type ActionsConfig<S extends ModelSchema, K extends readonly (keyof Resource<S>)[]> = {
18
24
  [name: string]: KeyedFn<S, K, Resource<S>>;
19
25
  } & { [Key in ReservedActionKey]?: never };
20
- interface ModelConfig<S extends T.TObject, K extends readonly (keyof Resource<S>)[]> {
26
+ interface ModelConfig<S extends ModelSchema, K extends readonly (keyof Resource<S>)[]> {
21
27
  keys: K;
22
28
  reload?: KeyedFn<S, K, Resource<S>>;
23
29
  update?: KeyedBodyFn<S, K, Resource<S>>;
@@ -39,19 +45,41 @@ type ModelMethods<K extends readonly any[], Cfg> = (Cfg extends {
39
45
  } : {}) & (Cfg extends {
40
46
  actions: infer A;
41
47
  } ? { [N in keyof A]: A[N] extends ((...args: any[]) => any) ? ReplaceReturn$1<StripParams<K, A[N]>, any> : never } : {});
42
- type ModelInstance<S extends T.TObject, K extends readonly any[], Cfg> = Resource<S> & {
48
+ type ModelInstance<S extends ModelSchema, K extends readonly any[], Cfg> = Resource<S> & {
43
49
  readonly store?: ModelStore<any>;
44
- setData(data: Partial<Resource<S>>): void;
50
+ setData(data: Resource<S>): void;
45
51
  toJSON(): Resource<S>;
46
52
  buildParams(): KeyShape<S, K extends readonly (keyof Resource<S>)[] ? K : readonly []>;
47
53
  getMobxAnnotations?(): AnnotationsMap<any, never>;
48
54
  } & ModelMethods<K, Cfg>;
49
- type ModelConstructor<S extends T.TObject, K extends readonly any[], Cfg> = {
55
+ type ModelConstructor<S extends ModelSchema, K extends readonly any[], Cfg> = {
50
56
  new (data: Resource<S>, store?: ModelStore<any>): ModelInstance<S, K, Cfg>;
51
57
  readonly schema: S;
52
58
  };
53
59
  declare function makeModel<S extends T.TObject>(schema: S): ModelConstructor<S, readonly [], {}>;
54
60
  declare function makeModel<S extends T.TObject, K extends readonly (keyof Resource<S>)[], Cfg extends ModelConfig<S, K>>(schema: S, config: Cfg): ModelConstructor<S, K, Cfg>;
61
+ type UnionSchema = T.TUnion<T.TObject[]>;
62
+ type SharedFields<S extends UnionSchema> = { [K in keyof Resource<S>]: Resource<S>[K] };
63
+ type VariantFields<S extends UnionSchema, D extends keyof Resource<S>, V> = Extract<Resource<S>, Record<D, V>>;
64
+ interface UnionModelMembers<S extends UnionSchema, D extends keyof Resource<S>, K extends readonly any[]> {
65
+ readonly store?: ModelStore<any>;
66
+ setData(data: Resource<S>): void;
67
+ toJSON(): Resource<S>;
68
+ buildParams(): KeyShape<S, K extends readonly (keyof Resource<S>)[] ? K : readonly []>;
69
+ getMobxAnnotations?(): AnnotationsMap<any, never>;
70
+ /** Type guard: true when the discriminator equals `value`, revealing that variant's fields on this same instance. */
71
+ is<V extends Resource<S>[D]>(value: V): this is this & VariantFields<S, D, V>;
72
+ /** This instance narrowed to the `value` variant (fields exposed directly), or `undefined` if it doesn't match. */
73
+ as<V extends Resource<S>[D]>(value: V): (this & VariantFields<S, D, V>) | undefined;
74
+ }
75
+ type UnionModelInstance<S extends UnionSchema, D extends keyof Resource<S>, K extends readonly any[], Cfg> = SharedFields<S> & UnionModelMembers<S, D, K> & ModelMethods<K, Cfg>;
76
+ type UnionModelConstructor<S extends UnionSchema, D extends keyof Resource<S>, K extends readonly any[], Cfg> = {
77
+ new (data: Resource<S>, store?: ModelStore<any>): UnionModelInstance<S, D, K, Cfg>;
78
+ readonly schema: S;
79
+ readonly discriminator: D;
80
+ };
81
+ declare function makeUnionModel<S extends UnionSchema, D extends keyof Resource<S> & string>(schema: S, discriminator: D): UnionModelConstructor<S, D, readonly [], {}>;
82
+ declare function makeUnionModel<S extends UnionSchema, D extends keyof Resource<S> & string, K extends readonly (keyof Resource<S>)[], Cfg extends ModelConfig<S, K>>(schema: S, discriminator: D, config: Cfg): UnionModelConstructor<S, D, K, Cfg>;
55
83
  //#endregion
56
84
  //#region src/model/make-store.d.ts
57
85
  type ReplaceReturn<F, R> = F extends ((...args: infer A) => Promise<any>) ? (...args: A) => Promise<R> : never;
@@ -88,8 +116,8 @@ type StoreInstance<M, Cfg> = {
88
116
  type StoreConstructor<M, Cfg> = {
89
117
  new (): StoreInstance<M, Cfg>;
90
118
  };
91
- declare function makeStore<S extends T.TObject>(schema: S): StoreConstructor<T.Static<S>, {}>;
92
- declare function makeStore<S extends T.TObject, Cfg extends StoreConfig<T.Static<S>>>(schema: S, config: Cfg & ThisType<StoreThis<InferModel<T.Static<S>, Cfg>>>): StoreConstructor<InferModel<T.Static<S>, Cfg>, Cfg>;
119
+ declare function makeStore<S extends ModelSchema>(schema: S): StoreConstructor<T.Static<S>, {}>;
120
+ declare function makeStore<S extends ModelSchema, Cfg extends StoreConfig<T.Static<S>>>(schema: S, config: Cfg & ThisType<StoreThis<InferModel<T.Static<S>, Cfg>>>): StoreConstructor<InferModel<T.Static<S>, Cfg>, Cfg>;
93
121
  //#endregion
94
- export { type AnnotationsMap, type LazyObservableArray, ModelConfig, ModelConstructor, ModelStore, StoreConfig, StoreConstructor, makeModel, makeStore };
122
+ export { type AnnotationsMap, type LazyObservableArray, ModelConfig, ModelConstructor, ModelSchema, ModelStore, StoreConfig, StoreConstructor, UnionModelConstructor, makeModel, makeStore, makeUnionModel };
95
123
  //# sourceMappingURL=model.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"model.d.mts","names":[],"sources":["../src/model/make-model.ts","../src/model/make-store.ts"],"mappings":"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"}
1
+ {"version":3,"file":"model.d.mts","names":[],"sources":["../src/model/make-model.ts","../src/model/make-store.ts"],"mappings":"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"}
package/dist/model.mjs CHANGED
@@ -1,17 +1,32 @@
1
- import { n as lazyObservableArray } from "./lazy-observable-CdHXpUkk.mjs";
1
+ import { n as lazyObservableArray } from "./lazy-observable-Ce5e1Izm.mjs";
2
2
  import { action, makeObservable, observable, runInAction, toJS } from "mobx";
3
- import "typebox";
3
+ import * as Value from "typebox/value";
4
+ import * as T from "typebox";
4
5
 
5
6
  //#region src/model/make-model.ts
6
- function makeModel(schema, config) {
7
+ /**
8
+ * Every property name across the schema. For a union this is the merged set of
9
+ * all variants' keys, so all of them are made observable up front — that keeps
10
+ * `setData` reactive even when it switches the active variant. `toJSON` runs
11
+ * `Value.Clean` to emit only the keys of the variant the data currently matches.
12
+ */
13
+ function getPropertyNames(schema) {
14
+ if (!T.IsUnion(schema)) return Object.keys(schema.properties);
15
+ const names = /* @__PURE__ */ new Set();
16
+ for (const variant of schema.anyOf) for (const key of Object.keys(variant.properties)) names.add(key);
17
+ return [...names];
18
+ }
19
+ function createModelClass(schema, config) {
7
20
  const keys = config?.keys ?? [];
21
+ const isUnion = T.IsUnion(schema);
22
+ const propertyNames = getPropertyNames(schema);
8
23
  class BaseModel {
9
24
  static schema = schema;
10
25
  store;
11
26
  constructor(data, store) {
12
27
  this.store = store;
13
28
  const annotations = {};
14
- for (const key of Object.keys(schema.properties)) {
29
+ for (const key of propertyNames) {
15
30
  Object.defineProperty(this, key, {
16
31
  value: data[key],
17
32
  enumerable: true,
@@ -26,8 +41,14 @@ function makeModel(schema, config) {
26
41
  ...this.getMobxAnnotations?.()
27
42
  });
28
43
  }
44
+ /**
45
+ * Replace the model's data with a complete resource. Every property is
46
+ * reassigned (fields absent from `data` — e.g. another variant's — become
47
+ * `undefined`), so the model always holds a coherent, whole variant rather
48
+ * than a partial merge that could mix fields across the union.
49
+ */
29
50
  setData(data) {
30
- Object.assign(this, data);
51
+ for (const key of propertyNames) this[key] = data[key];
31
52
  }
32
53
  /**
33
54
  * Build the params object passed as the first arg to keyed API methods.
@@ -42,10 +63,11 @@ function makeModel(schema, config) {
42
63
  }
43
64
  toJSON() {
44
65
  const data = this;
45
- return Object.keys(schema.properties).reduce((obj, key) => {
66
+ const snapshot = propertyNames.reduce((obj, key) => {
46
67
  if (data[key] !== void 0) obj[key] = toJS(data[key]);
47
68
  return obj;
48
69
  }, {});
70
+ return isUnion ? Value.Clean(schema, snapshot) : snapshot;
49
71
  }
50
72
  }
51
73
  const proto = BaseModel.prototype;
@@ -89,6 +111,21 @@ function makeModel(schema, config) {
89
111
  }
90
112
  return BaseModel;
91
113
  }
114
+ function makeModel(schema, config) {
115
+ return createModelClass(schema, config);
116
+ }
117
+ function makeUnionModel(schema, discriminator, config) {
118
+ const ModelClass = createModelClass(schema, config);
119
+ ModelClass.discriminator = discriminator;
120
+ const proto = ModelClass.prototype;
121
+ proto.is = function(value) {
122
+ return this[discriminator] === value;
123
+ };
124
+ proto.as = function(value) {
125
+ return this[discriminator] === value ? this : void 0;
126
+ };
127
+ return ModelClass;
128
+ }
92
129
 
93
130
  //#endregion
94
131
  //#region src/model/make-store.ts
@@ -136,5 +173,5 @@ function makeStore(schema, config) {
136
173
  }
137
174
 
138
175
  //#endregion
139
- export { makeModel, makeStore };
176
+ export { makeModel, makeStore, makeUnionModel };
140
177
  //# sourceMappingURL=model.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"model.mjs","names":[],"sources":["../src/model/make-model.ts","../src/model/make-store.ts"],"sourcesContent":["import { action, makeObservable, observable, runInAction, toJS, type AnnotationsMap } from \"mobx\";\nimport * as T from \"typebox\";\n\n// -----------------------------------------------------------------------------\n// Public structural contract\n// -----------------------------------------------------------------------------\n\n/** Minimal interface a model's host store must satisfy. */\nexport interface ModelStore<M> {\n remove?(model: M): void;\n}\n\n// -----------------------------------------------------------------------------\n// Type plumbing\n// -----------------------------------------------------------------------------\n\ntype Resource<S extends T.TObject> = T.Static<S>;\n\ntype KeyShape<S extends T.TObject, K extends readonly (keyof Resource<S>)[]> = K extends readonly []\n ? undefined\n : Pick<Resource<S>, K[number]>;\n\ntype KeyedFn<\n S extends T.TObject,\n K extends readonly (keyof Resource<S>)[],\n R,\n> = K extends readonly []\n ? (...args: any[]) => Promise<R>\n : (params: KeyShape<S, K>, ...rest: any[]) => Promise<R>;\n\ntype KeyedBodyFn<\n S extends T.TObject,\n K extends readonly (keyof Resource<S>)[],\n R,\n> = K extends readonly []\n ? (body: any, ...rest: any[]) => Promise<R>\n : (params: KeyShape<S, K>, body: any, ...rest: any[]) => Promise<R>;\n\n// Strip the first arg when keys is non-empty — model methods don't take the params.\ntype StripParams<K extends readonly any[], F> = K extends readonly []\n ? F\n : F extends (params: any, ...rest: infer R) => infer Ret\n ? (...args: R) => Ret\n : never;\n\n// Replace a function's Promise return with Promise<R>.\ntype ReplaceReturn<F, R> = F extends (...args: infer A) => Promise<any>\n ? (...args: A) => Promise<R>\n : never;\n\ntype ReservedActionKey = \"reload\" | \"update\" | \"delete\" | \"setData\" | \"toJSON\" | \"store\";\n\ntype ActionsConfig<S extends T.TObject, K extends readonly (keyof Resource<S>)[]> = {\n [name: string]: KeyedFn<S, K, Resource<S>>;\n} & { [Key in ReservedActionKey]?: never };\n\nexport interface ModelConfig<S extends T.TObject, K extends readonly (keyof Resource<S>)[]> {\n keys: K;\n reload?: KeyedFn<S, K, Resource<S>>;\n update?: KeyedBodyFn<S, K, Resource<S>>;\n delete?: KeyedFn<S, K, any>;\n actions?: ActionsConfig<S, K>;\n}\n\n// Instance method shape from config. Self-mutating methods return Promise<any>;\n// the instance is mutated in place via setData, so callers typically read fields\n// off the same reference instead of chaining the return.\ntype ModelMethods<K extends readonly any[], Cfg> = (Cfg extends { reload: infer F }\n ? { reload: ReplaceReturn<StripParams<K, F>, any> }\n : {}) &\n (Cfg extends { update: infer F } ? { update: ReplaceReturn<StripParams<K, F>, any> } : {}) &\n (Cfg extends { delete: infer F } ? { delete: StripParams<K, F> } : {}) &\n (Cfg extends { actions: infer A }\n ? {\n [N in keyof A]: A[N] extends (...args: any[]) => any\n ? ReplaceReturn<StripParams<K, A[N]>, any>\n : never;\n }\n : {});\n\n// -----------------------------------------------------------------------------\n// Constructor type\n// -----------------------------------------------------------------------------\n\ntype ModelInstance<S extends T.TObject, K extends readonly any[], Cfg> = Resource<S> & {\n readonly store?: ModelStore<any>;\n setData(data: Partial<Resource<S>>): void;\n toJSON(): Resource<S>;\n buildParams(): KeyShape<S, K extends readonly (keyof Resource<S>)[] ? K : readonly []>;\n getMobxAnnotations?(): AnnotationsMap<any, never>;\n} & ModelMethods<K, Cfg>;\n\nexport type ModelConstructor<S extends T.TObject, K extends readonly any[], Cfg> = {\n new (data: Resource<S>, store?: ModelStore<any>): ModelInstance<S, K, Cfg>;\n readonly schema: S;\n};\n\n// -----------------------------------------------------------------------------\n// makeModel\n// -----------------------------------------------------------------------------\n\nexport function makeModel<S extends T.TObject>(schema: S): ModelConstructor<S, readonly [], {}>;\nexport function makeModel<\n S extends T.TObject,\n K extends readonly (keyof Resource<S>)[],\n Cfg extends ModelConfig<S, K>,\n>(schema: S, config: Cfg): ModelConstructor<S, K, Cfg>;\nexport function makeModel<S extends T.TObject>(\n schema: S,\n config?: ModelConfig<S, readonly (keyof Resource<S>)[]>,\n): any {\n const keys = (config?.keys ?? []) as readonly PropertyKey[];\n\n abstract class BaseModel {\n static readonly schema = schema;\n\n readonly store?: ModelStore<any>;\n\n constructor(data: Resource<S>, store?: ModelStore<any>) {\n this.store = store;\n\n const annotations: Record<string, any> = {};\n for (const key of Object.keys(schema.properties)) {\n Object.defineProperty(this, key, {\n value: (data as any)[key],\n enumerable: true,\n configurable: true,\n writable: true,\n });\n annotations[key] = observable.ref;\n }\n\n makeObservable(this, {\n ...annotations,\n setData: action,\n ...(this as any).getMobxAnnotations?.(),\n });\n }\n\n setData(data: Partial<Resource<S>>): void {\n Object.assign(this, data);\n }\n\n /**\n * Build the params object passed as the first arg to keyed API methods.\n * Default extracts each property in `keys` from the model. Override on a\n * subclass when the model field name differs from the API param name, or\n * to construct composite params from derived values.\n */\n buildParams(): any {\n if (keys.length === 0) return undefined;\n const data = this as any;\n return Object.fromEntries(keys.map((k) => [k, data[k]]));\n }\n\n toJSON(): Resource<S> {\n const data = this as any;\n return Object.keys(schema.properties).reduce(\n (obj, key) => {\n if (data[key] !== undefined) obj[key] = toJS(data[key]);\n return obj;\n },\n {} as Record<string, any>,\n ) as Resource<S>;\n }\n }\n\n const proto = BaseModel.prototype as any;\n\n if (config?.reload) {\n const reload = config.reload as (...args: any[]) => Promise<any>;\n proto.reload = async function (...rest: any[]) {\n const params = this.buildParams();\n const data = params === undefined ? await reload(...rest) : await reload(params, ...rest);\n runInAction(() => this.setData(data));\n return this;\n };\n }\n\n if (config?.update) {\n const update = config.update as (...args: any[]) => Promise<any>;\n proto.update = async function (body: any, ...rest: any[]) {\n const params = this.buildParams();\n const data =\n params === undefined ? await update(body, ...rest) : await update(params, body, ...rest);\n runInAction(() => this.setData(data));\n return this;\n };\n }\n\n if (config?.delete) {\n const del = config.delete as (...args: any[]) => Promise<any>;\n proto.delete = async function (...rest: any[]) {\n const params = this.buildParams();\n const result = params === undefined ? await del(...rest) : await del(params, ...rest);\n this.store?.remove?.(this);\n return result;\n };\n }\n\n if (config?.actions) {\n for (const [name, fn] of Object.entries(config.actions)) {\n const call = fn as (...args: any[]) => Promise<any>;\n proto[name] = async function (body?: any, ...rest: any[]) {\n const params = this.buildParams();\n let data: any;\n if (params === undefined) {\n data = body === undefined ? await call() : await call(body, ...rest);\n } else {\n data = body === undefined ? await call(params) : await call(params, body, ...rest);\n }\n runInAction(() => this.setData(data));\n return this;\n };\n }\n }\n\n return BaseModel;\n}\n\nexport type { AnnotationsMap };\n","import * as T from \"typebox\";\nimport { lazyObservableArray, type LazyObservableArray } from \"../lazy-observable/lazy-observable\";\nimport { action, makeObservable, runInAction } from \"mobx\";\n\n// -----------------------------------------------------------------------------\n// Type plumbing\n// -----------------------------------------------------------------------------\n\n// Replace a function's Promise return with Promise<R> — used so get/create\n// return models rather than the raw API response.\ntype ReplaceReturn<F, R> = F extends (...args: infer A) => Promise<any>\n ? (...args: A) => Promise<R>\n : never;\n\n// The structural shape passed as `this` inside `transform` — the only member\n// transform ever needs is `remove`, since it's about to construct a model and\n// hand the store reference along to its constructor.\ntype StoreThis<M> = {\n remove(model: M): void;\n};\n\n// Infer M from config: when transform is present use its return type, else use R.\ntype InferModel<R, Cfg> = Cfg extends { transform: (...args: any[]) => infer M } ? M : R;\n\nexport interface StoreConfig<R> {\n transform?: (data: R, store: { remove(model: any): void }) => any;\n get?: (...args: any[]) => Promise<R>;\n getAll?: (...args: any[]) => Promise<R[]>;\n create?: (...args: any[]) => Promise<R>;\n}\n\n// Final store-instance shape, derived from config slots.\ntype StoreInstance<M, Cfg> = {\n remove(model: M): void;\n} & (Cfg extends { get: infer G } ? { get: ReplaceReturn<G, M> } : {}) &\n (Cfg extends { getAll: any } ? { getAll: () => Promise<M[]>; all: LazyObservableArray<M> } : {}) &\n (Cfg extends { create: infer C } ? { create: ReplaceReturn<C, M> } : {});\n\nexport type StoreConstructor<M, Cfg> = {\n new (): StoreInstance<M, Cfg>;\n};\n\n// -----------------------------------------------------------------------------\n// makeStore\n// -----------------------------------------------------------------------------\n\nexport function makeStore<S extends T.TObject>(schema: S): StoreConstructor<T.Static<S>, {}>;\nexport function makeStore<S extends T.TObject, Cfg extends StoreConfig<T.Static<S>>>(\n schema: S,\n config: Cfg & ThisType<StoreThis<InferModel<T.Static<S>, Cfg>>>,\n): StoreConstructor<InferModel<T.Static<S>, Cfg>, Cfg>;\nexport function makeStore<S extends T.TObject>(\n schema: S,\n config?: StoreConfig<T.Static<S>>,\n): StoreConstructor<any, any> {\n type R = T.Static<S>;\n\n class Store {\n private readonly _transform: (data: R) => any;\n\n all?: LazyObservableArray<any>;\n\n constructor() {\n const rawTransform = config?.transform;\n this._transform = rawTransform\n ? (data: R) => rawTransform.call(this, data, this)\n : (data: R) => data as any;\n\n makeObservable<this, \"_transform\">(this, {\n _transform: false,\n remove: action,\n });\n\n if (config?.getAll) {\n this.all = lazyObservableArray(async () => {\n const items = await (config.getAll as (...args: any[]) => Promise<R[]>)();\n return items.map((item) => this._transform(item));\n });\n }\n }\n\n remove(model: any): void {\n this.all?.value?.remove?.(model);\n }\n }\n\n const proto = Store.prototype as any;\n\n if (config?.get) {\n const get = config.get;\n proto.get = function (...args: any[]) {\n return get(...args).then((data: R) => this._transform(data));\n };\n }\n\n if (config?.getAll) {\n proto.getAll = function () {\n return this.all.getOrLoad();\n };\n }\n\n if (config?.create) {\n const create = config.create;\n proto.create = async function (...args: any[]) {\n const data = await create(...args);\n return runInAction(() => {\n const model = this._transform(data);\n if (this.all) this.all.value.unshift(model);\n return model;\n });\n };\n }\n\n return Store as unknown as StoreConstructor<any, any>;\n}\n\nexport type { LazyObservableArray };\n"],"mappings":";;;;;AA2GA,SAAgB,UACd,QACA,QACK;CACL,MAAM,OAAQ,QAAQ,QAAQ,EAAE;CAEhC,MAAe,UAAU;EACvB,OAAgB,SAAS;EAEzB,AAAS;EAET,YAAY,MAAmB,OAAyB;AACtD,QAAK,QAAQ;GAEb,MAAM,cAAmC,EAAE;AAC3C,QAAK,MAAM,OAAO,OAAO,KAAK,OAAO,WAAW,EAAE;AAChD,WAAO,eAAe,MAAM,KAAK;KAC/B,OAAQ,KAAa;KACrB,YAAY;KACZ,cAAc;KACd,UAAU;KACX,CAAC;AACF,gBAAY,OAAO,WAAW;;AAGhC,kBAAe,MAAM;IACnB,GAAG;IACH,SAAS;IACT,GAAI,KAAa,sBAAsB;IACxC,CAAC;;EAGJ,QAAQ,MAAkC;AACxC,UAAO,OAAO,MAAM,KAAK;;;;;;;;EAS3B,cAAmB;AACjB,OAAI,KAAK,WAAW,EAAG,QAAO;GAC9B,MAAM,OAAO;AACb,UAAO,OAAO,YAAY,KAAK,KAAK,MAAM,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC;;EAG1D,SAAsB;GACpB,MAAM,OAAO;AACb,UAAO,OAAO,KAAK,OAAO,WAAW,CAAC,QACnC,KAAK,QAAQ;AACZ,QAAI,KAAK,SAAS,OAAW,KAAI,OAAO,KAAK,KAAK,KAAK;AACvD,WAAO;MAET,EAAE,CACH;;;CAIL,MAAM,QAAQ,UAAU;AAExB,KAAI,QAAQ,QAAQ;EAClB,MAAM,SAAS,OAAO;AACtB,QAAM,SAAS,eAAgB,GAAG,MAAa;GAC7C,MAAM,SAAS,KAAK,aAAa;GACjC,MAAM,OAAO,WAAW,SAAY,MAAM,OAAO,GAAG,KAAK,GAAG,MAAM,OAAO,QAAQ,GAAG,KAAK;AACzF,qBAAkB,KAAK,QAAQ,KAAK,CAAC;AACrC,UAAO;;;AAIX,KAAI,QAAQ,QAAQ;EAClB,MAAM,SAAS,OAAO;AACtB,QAAM,SAAS,eAAgB,MAAW,GAAG,MAAa;GACxD,MAAM,SAAS,KAAK,aAAa;GACjC,MAAM,OACJ,WAAW,SAAY,MAAM,OAAO,MAAM,GAAG,KAAK,GAAG,MAAM,OAAO,QAAQ,MAAM,GAAG,KAAK;AAC1F,qBAAkB,KAAK,QAAQ,KAAK,CAAC;AACrC,UAAO;;;AAIX,KAAI,QAAQ,QAAQ;EAClB,MAAM,MAAM,OAAO;AACnB,QAAM,SAAS,eAAgB,GAAG,MAAa;GAC7C,MAAM,SAAS,KAAK,aAAa;GACjC,MAAM,SAAS,WAAW,SAAY,MAAM,IAAI,GAAG,KAAK,GAAG,MAAM,IAAI,QAAQ,GAAG,KAAK;AACrF,QAAK,OAAO,SAAS,KAAK;AAC1B,UAAO;;;AAIX,KAAI,QAAQ,QACV,MAAK,MAAM,CAAC,MAAM,OAAO,OAAO,QAAQ,OAAO,QAAQ,EAAE;EACvD,MAAM,OAAO;AACb,QAAM,QAAQ,eAAgB,MAAY,GAAG,MAAa;GACxD,MAAM,SAAS,KAAK,aAAa;GACjC,IAAI;AACJ,OAAI,WAAW,OACb,QAAO,SAAS,SAAY,MAAM,MAAM,GAAG,MAAM,KAAK,MAAM,GAAG,KAAK;OAEpE,QAAO,SAAS,SAAY,MAAM,KAAK,OAAO,GAAG,MAAM,KAAK,QAAQ,MAAM,GAAG,KAAK;AAEpF,qBAAkB,KAAK,QAAQ,KAAK,CAAC;AACrC,UAAO;;;AAKb,QAAO;;;;;ACtKT,SAAgB,UACd,QACA,QAC4B;CAG5B,MAAM,MAAM;EACV,AAAiB;EAEjB;EAEA,cAAc;GACZ,MAAM,eAAe,QAAQ;AAC7B,QAAK,aAAa,gBACb,SAAY,aAAa,KAAK,MAAM,MAAM,KAAK,IAC/C,SAAY;AAEjB,kBAAmC,MAAM;IACvC,YAAY;IACZ,QAAQ;IACT,CAAC;AAEF,OAAI,QAAQ,OACV,MAAK,MAAM,oBAAoB,YAAY;AAEzC,YADc,MAAO,OAAO,QAA6C,EAC5D,KAAK,SAAS,KAAK,WAAW,KAAK,CAAC;KACjD;;EAIN,OAAO,OAAkB;AACvB,QAAK,KAAK,OAAO,SAAS,MAAM;;;CAIpC,MAAM,QAAQ,MAAM;AAEpB,KAAI,QAAQ,KAAK;EACf,MAAM,MAAM,OAAO;AACnB,QAAM,MAAM,SAAU,GAAG,MAAa;AACpC,UAAO,IAAI,GAAG,KAAK,CAAC,MAAM,SAAY,KAAK,WAAW,KAAK,CAAC;;;AAIhE,KAAI,QAAQ,OACV,OAAM,SAAS,WAAY;AACzB,SAAO,KAAK,IAAI,WAAW;;AAI/B,KAAI,QAAQ,QAAQ;EAClB,MAAM,SAAS,OAAO;AACtB,QAAM,SAAS,eAAgB,GAAG,MAAa;GAC7C,MAAM,OAAO,MAAM,OAAO,GAAG,KAAK;AAClC,UAAO,kBAAkB;IACvB,MAAM,QAAQ,KAAK,WAAW,KAAK;AACnC,QAAI,KAAK,IAAK,MAAK,IAAI,MAAM,QAAQ,MAAM;AAC3C,WAAO;KACP;;;AAIN,QAAO"}
1
+ {"version":3,"file":"model.mjs","names":[],"sources":["../src/model/make-model.ts","../src/model/make-store.ts"],"sourcesContent":["import { action, makeObservable, observable, runInAction, toJS, type AnnotationsMap } from \"mobx\";\nimport * as T from \"typebox\";\nimport * as Value from \"typebox/value\";\n\n// -----------------------------------------------------------------------------\n// Public structural contract\n// -----------------------------------------------------------------------------\n\n/** Minimal interface a model's host store must satisfy. */\nexport interface ModelStore<M> {\n remove?(model: M): void;\n}\n\n/**\n * Root schema for a model: a single object (`makeModel`) or a discriminated\n * union of objects (`makeUnionModel`). Shared by both factories and by\n * `makeStore`, which accepts either.\n */\nexport type ModelSchema = T.TObject | T.TUnion<T.TObject[]>;\n\n/**\n * Every property name across the schema. For a union this is the merged set of\n * all variants' keys, so all of them are made observable up front — that keeps\n * `setData` reactive even when it switches the active variant. `toJSON` runs\n * `Value.Clean` to emit only the keys of the variant the data currently matches.\n */\nfunction getPropertyNames(schema: ModelSchema): string[] {\n if (!T.IsUnion(schema)) return Object.keys(schema.properties);\n const names = new Set<string>();\n for (const variant of schema.anyOf) {\n for (const key of Object.keys((variant as T.TObject).properties)) names.add(key);\n }\n return [...names];\n}\n\n// -----------------------------------------------------------------------------\n// Type plumbing\n// -----------------------------------------------------------------------------\n\ntype Resource<S extends ModelSchema> = T.Static<S>;\n\ntype KeyShape<\n S extends ModelSchema,\n K extends readonly (keyof Resource<S>)[],\n> = K extends readonly [] ? undefined : Pick<Resource<S>, K[number]>;\n\ntype KeyedFn<\n S extends ModelSchema,\n K extends readonly (keyof Resource<S>)[],\n R,\n> = K extends readonly []\n ? (...args: any[]) => Promise<R>\n : (params: KeyShape<S, K>, ...rest: any[]) => Promise<R>;\n\ntype KeyedBodyFn<\n S extends ModelSchema,\n K extends readonly (keyof Resource<S>)[],\n R,\n> = K extends readonly []\n ? (body: any, ...rest: any[]) => Promise<R>\n : (params: KeyShape<S, K>, body: any, ...rest: any[]) => Promise<R>;\n\n// Strip the first arg when keys is non-empty — model methods don't take the params.\ntype StripParams<K extends readonly any[], F> = K extends readonly []\n ? F\n : F extends (params: any, ...rest: infer R) => infer Ret\n ? (...args: R) => Ret\n : never;\n\n// Replace a function's Promise return with Promise<R>.\ntype ReplaceReturn<F, R> = F extends (...args: infer A) => Promise<any>\n ? (...args: A) => Promise<R>\n : never;\n\ntype ReservedActionKey = \"reload\" | \"update\" | \"delete\" | \"setData\" | \"toJSON\" | \"store\";\n\ntype ActionsConfig<S extends ModelSchema, K extends readonly (keyof Resource<S>)[]> = {\n [name: string]: KeyedFn<S, K, Resource<S>>;\n} & { [Key in ReservedActionKey]?: never };\n\nexport interface ModelConfig<S extends ModelSchema, K extends readonly (keyof Resource<S>)[]> {\n keys: K;\n reload?: KeyedFn<S, K, Resource<S>>;\n update?: KeyedBodyFn<S, K, Resource<S>>;\n delete?: KeyedFn<S, K, any>;\n actions?: ActionsConfig<S, K>;\n}\n\n// Instance method shape from config. Self-mutating methods return Promise<any>;\n// the instance is mutated in place via setData, so callers typically read fields\n// off the same reference instead of chaining the return.\ntype ModelMethods<K extends readonly any[], Cfg> = (Cfg extends { reload: infer F }\n ? { reload: ReplaceReturn<StripParams<K, F>, any> }\n : {}) &\n (Cfg extends { update: infer F } ? { update: ReplaceReturn<StripParams<K, F>, any> } : {}) &\n (Cfg extends { delete: infer F } ? { delete: StripParams<K, F> } : {}) &\n (Cfg extends { actions: infer A }\n ? {\n [N in keyof A]: A[N] extends (...args: any[]) => any\n ? ReplaceReturn<StripParams<K, A[N]>, any>\n : never;\n }\n : {});\n\n// -----------------------------------------------------------------------------\n// Constructor type\n// -----------------------------------------------------------------------------\n\ntype ModelInstance<S extends ModelSchema, K extends readonly any[], Cfg> = Resource<S> & {\n readonly store?: ModelStore<any>;\n setData(data: Resource<S>): void;\n toJSON(): Resource<S>;\n buildParams(): KeyShape<S, K extends readonly (keyof Resource<S>)[] ? K : readonly []>;\n getMobxAnnotations?(): AnnotationsMap<any, never>;\n} & ModelMethods<K, Cfg>;\n\nexport type ModelConstructor<S extends ModelSchema, K extends readonly any[], Cfg> = {\n new (data: Resource<S>, store?: ModelStore<any>): ModelInstance<S, K, Cfg>;\n readonly schema: S;\n};\n\n// -----------------------------------------------------------------------------\n// Shared class builder\n// -----------------------------------------------------------------------------\n\n// Builds the observable model class used by both makeModel and makeUnionModel.\n// Handles object and union schemas at runtime; the public factories layer the\n// appropriate types (and, for unions, the `is`/`as` guards) on top.\nfunction createModelClass(schema: ModelSchema, config?: ModelConfig<any, any>): any {\n const keys = (config?.keys ?? []) as readonly PropertyKey[];\n const isUnion = T.IsUnion(schema);\n const propertyNames = getPropertyNames(schema);\n\n abstract class BaseModel {\n static readonly schema = schema;\n\n readonly store?: ModelStore<any>;\n\n constructor(data: any, store?: ModelStore<any>) {\n this.store = store;\n\n // Make every property of every variant observable up front, so `setData`\n // stays reactive even when it switches the active variant. Foreign-variant\n // fields sit as `undefined`; TypeScript hides them, and `toJSON` cleans them out.\n const annotations: Record<string, any> = {};\n for (const key of propertyNames) {\n Object.defineProperty(this, key, {\n value: (data as any)[key],\n enumerable: true,\n configurable: true,\n writable: true,\n });\n annotations[key] = observable.ref;\n }\n\n makeObservable(this, {\n ...annotations,\n setData: action,\n ...(this as any).getMobxAnnotations?.(),\n });\n }\n\n /**\n * Replace the model's data with a complete resource. Every property is\n * reassigned (fields absent from `data` — e.g. another variant's — become\n * `undefined`), so the model always holds a coherent, whole variant rather\n * than a partial merge that could mix fields across the union.\n */\n setData(data: any): void {\n for (const key of propertyNames) {\n (this as any)[key] = (data as any)[key];\n }\n }\n\n /**\n * Build the params object passed as the first arg to keyed API methods.\n * Default extracts each property in `keys` from the model. Override on a\n * subclass when the model field name differs from the API param name, or\n * to construct composite params from derived values.\n */\n buildParams(): any {\n if (keys.length === 0) return undefined;\n const data = this as any;\n return Object.fromEntries(keys.map((k) => [k, data[k]]));\n }\n\n toJSON(): any {\n const data = this as any;\n const snapshot = propertyNames.reduce(\n (obj, key) => {\n if (data[key] !== undefined) obj[key] = toJS(data[key]);\n return obj;\n },\n {} as Record<string, any>,\n );\n // For a union, strip any fields not belonging to the variant the current\n // data matches (e.g. a stale field left over from a previous variant).\n return isUnion ? Value.Clean(schema, snapshot) : snapshot;\n }\n }\n\n const proto = BaseModel.prototype as any;\n\n if (config?.reload) {\n const reload = config.reload as (...args: any[]) => Promise<any>;\n proto.reload = async function (...rest: any[]) {\n const params = this.buildParams();\n const data = params === undefined ? await reload(...rest) : await reload(params, ...rest);\n runInAction(() => this.setData(data));\n return this;\n };\n }\n\n if (config?.update) {\n const update = config.update as (...args: any[]) => Promise<any>;\n proto.update = async function (body: any, ...rest: any[]) {\n const params = this.buildParams();\n const data =\n params === undefined ? await update(body, ...rest) : await update(params, body, ...rest);\n runInAction(() => this.setData(data));\n return this;\n };\n }\n\n if (config?.delete) {\n const del = config.delete as (...args: any[]) => Promise<any>;\n proto.delete = async function (...rest: any[]) {\n const params = this.buildParams();\n const result = params === undefined ? await del(...rest) : await del(params, ...rest);\n this.store?.remove?.(this);\n return result;\n };\n }\n\n if (config?.actions) {\n for (const [name, fn] of Object.entries(config.actions)) {\n const call = fn as (...args: any[]) => Promise<any>;\n proto[name] = async function (body?: any, ...rest: any[]) {\n const params = this.buildParams();\n let data: any;\n if (params === undefined) {\n data = body === undefined ? await call() : await call(body, ...rest);\n } else {\n data = body === undefined ? await call(params) : await call(params, body, ...rest);\n }\n runInAction(() => this.setData(data));\n return this;\n };\n }\n }\n\n return BaseModel;\n}\n\n// -----------------------------------------------------------------------------\n// makeModel (single object schemas)\n// -----------------------------------------------------------------------------\n\nexport function makeModel<S extends T.TObject>(schema: S): ModelConstructor<S, readonly [], {}>;\nexport function makeModel<\n S extends T.TObject,\n K extends readonly (keyof Resource<S>)[],\n Cfg extends ModelConfig<S, K>,\n>(schema: S, config: Cfg): ModelConstructor<S, K, Cfg>;\nexport function makeModel<S extends T.TObject>(\n schema: S,\n config?: ModelConfig<S, readonly (keyof Resource<S>)[]>,\n): any {\n return createModelClass(schema, config);\n}\n\n// -----------------------------------------------------------------------------\n// makeUnionModel (discriminated union schemas)\n// -----------------------------------------------------------------------------\n\ntype UnionSchema = T.TUnion<T.TObject[]>;\n\n// Properties common to every variant (`keyof` a union resolves to shared keys).\ntype SharedFields<S extends UnionSchema> = { [K in keyof Resource<S>]: Resource<S>[K] };\n\n// The full static shape of the variant whose discriminator `D` equals `V`.\ntype VariantFields<S extends UnionSchema, D extends keyof Resource<S>, V> = Extract<\n Resource<S>,\n Record<D, V>\n>;\n\n// The members makeUnionModel adds. An interface (not a type-alias literal) so the\n// polymorphic `this` in `is`/`as` is allowed; at a call site `this` resolves to\n// the full instance, so the guard reveals the variant's fields on it.\ninterface UnionModelMembers<\n S extends UnionSchema,\n D extends keyof Resource<S>,\n K extends readonly any[],\n> {\n readonly store?: ModelStore<any>;\n setData(data: Resource<S>): void;\n toJSON(): Resource<S>;\n buildParams(): KeyShape<S, K extends readonly (keyof Resource<S>)[] ? K : readonly []>;\n getMobxAnnotations?(): AnnotationsMap<any, never>;\n /** Type guard: true when the discriminator equals `value`, revealing that variant's fields on this same instance. */\n is<V extends Resource<S>[D]>(value: V): this is this & VariantFields<S, D, V>;\n /** This instance narrowed to the `value` variant (fields exposed directly), or `undefined` if it doesn't match. */\n as<V extends Resource<S>[D]>(value: V): (this & VariantFields<S, D, V>) | undefined;\n}\n\n// Base instance exposes only the shared fields (a single object type, so it can\n// be subclassed). Variant-specific fields exist at runtime but are revealed on\n// the type only through `is`/`as`.\ntype UnionModelInstance<\n S extends UnionSchema,\n D extends keyof Resource<S>,\n K extends readonly any[],\n Cfg,\n> = SharedFields<S> & UnionModelMembers<S, D, K> & ModelMethods<K, Cfg>;\n\nexport type UnionModelConstructor<\n S extends UnionSchema,\n D extends keyof Resource<S>,\n K extends readonly any[],\n Cfg,\n> = {\n new (data: Resource<S>, store?: ModelStore<any>): UnionModelInstance<S, D, K, Cfg>;\n readonly schema: S;\n readonly discriminator: D;\n};\n\nexport function makeUnionModel<S extends UnionSchema, D extends keyof Resource<S> & string>(\n schema: S,\n discriminator: D,\n): UnionModelConstructor<S, D, readonly [], {}>;\nexport function makeUnionModel<\n S extends UnionSchema,\n D extends keyof Resource<S> & string,\n K extends readonly (keyof Resource<S>)[],\n Cfg extends ModelConfig<S, K>,\n>(schema: S, discriminator: D, config: Cfg): UnionModelConstructor<S, D, K, Cfg>;\nexport function makeUnionModel(\n schema: UnionSchema,\n discriminator: string,\n config?: ModelConfig<any, any>,\n): any {\n const ModelClass = createModelClass(schema, config);\n ModelClass.discriminator = discriminator;\n\n const proto = ModelClass.prototype as any;\n proto.is = function (value: unknown): boolean {\n return (this as any)[discriminator] === value;\n };\n proto.as = function (value: unknown): unknown {\n return (this as any)[discriminator] === value ? this : undefined;\n };\n\n return ModelClass;\n}\n\nexport type { AnnotationsMap };\n","import * as T from \"typebox\";\nimport { lazyObservableArray, type LazyObservableArray } from \"../lazy-observable/lazy-observable\";\nimport { action, makeObservable, runInAction } from \"mobx\";\nimport type { ModelSchema } from \"./make-model\";\n\n// -----------------------------------------------------------------------------\n// Type plumbing\n// -----------------------------------------------------------------------------\n\n// Replace a function's Promise return with Promise<R> — used so get/create\n// return models rather than the raw API response.\ntype ReplaceReturn<F, R> = F extends (...args: infer A) => Promise<any>\n ? (...args: A) => Promise<R>\n : never;\n\n// The structural shape passed as `this` inside `transform` — the only member\n// transform ever needs is `remove`, since it's about to construct a model and\n// hand the store reference along to its constructor.\ntype StoreThis<M> = {\n remove(model: M): void;\n};\n\n// Infer M from config: when transform is present use its return type, else use R.\ntype InferModel<R, Cfg> = Cfg extends { transform: (...args: any[]) => infer M } ? M : R;\n\nexport interface StoreConfig<R> {\n transform?: (data: R, store: { remove(model: any): void }) => any;\n get?: (...args: any[]) => Promise<R>;\n getAll?: (...args: any[]) => Promise<R[]>;\n create?: (...args: any[]) => Promise<R>;\n}\n\n// Final store-instance shape, derived from config slots.\ntype StoreInstance<M, Cfg> = {\n remove(model: M): void;\n} & (Cfg extends { get: infer G } ? { get: ReplaceReturn<G, M> } : {}) &\n (Cfg extends { getAll: any } ? { getAll: () => Promise<M[]>; all: LazyObservableArray<M> } : {}) &\n (Cfg extends { create: infer C } ? { create: ReplaceReturn<C, M> } : {});\n\nexport type StoreConstructor<M, Cfg> = {\n new (): StoreInstance<M, Cfg>;\n};\n\n// -----------------------------------------------------------------------------\n// makeStore\n// -----------------------------------------------------------------------------\n\nexport function makeStore<S extends ModelSchema>(schema: S): StoreConstructor<T.Static<S>, {}>;\nexport function makeStore<S extends ModelSchema, Cfg extends StoreConfig<T.Static<S>>>(\n schema: S,\n config: Cfg & ThisType<StoreThis<InferModel<T.Static<S>, Cfg>>>,\n): StoreConstructor<InferModel<T.Static<S>, Cfg>, Cfg>;\nexport function makeStore<S extends ModelSchema>(\n schema: S,\n config?: StoreConfig<T.Static<S>>,\n): StoreConstructor<any, any> {\n type R = T.Static<S>;\n\n class Store {\n private readonly _transform: (data: R) => any;\n\n all?: LazyObservableArray<any>;\n\n constructor() {\n const rawTransform = config?.transform;\n this._transform = rawTransform\n ? (data: R) => rawTransform.call(this, data, this)\n : (data: R) => data as any;\n\n makeObservable<this, \"_transform\">(this, {\n _transform: false,\n remove: action,\n });\n\n if (config?.getAll) {\n this.all = lazyObservableArray(async () => {\n const items = await (config.getAll as (...args: any[]) => Promise<R[]>)();\n return items.map((item) => this._transform(item));\n });\n }\n }\n\n remove(model: any): void {\n this.all?.value?.remove?.(model);\n }\n }\n\n const proto = Store.prototype as any;\n\n if (config?.get) {\n const get = config.get;\n proto.get = function (...args: any[]) {\n return get(...args).then((data: R) => this._transform(data));\n };\n }\n\n if (config?.getAll) {\n proto.getAll = function () {\n return this.all.getOrLoad();\n };\n }\n\n if (config?.create) {\n const create = config.create;\n proto.create = async function (...args: any[]) {\n const data = await create(...args);\n return runInAction(() => {\n const model = this._transform(data);\n if (this.all) this.all.value.unshift(model);\n return model;\n });\n };\n }\n\n return Store as unknown as StoreConstructor<any, any>;\n}\n\nexport type { LazyObservableArray };\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"react-util.d.mts","names":[],"sources":["../src/react-util/useAsyncFn.ts","../src/react-util/useAsync.ts","../src/react-util/useDebouncedCallback.tsx","../src/react-util/useDebouncedEffect.tsx","../src/react-util/useMountEffect.tsx","../src/react-util/useMountedState.ts","../src/react-util/useResizeObserver.tsx"],"mappings":";;;UAEiB,iBAAA,WAA4B,UAAA;EAC3C,YAAA,GAAe,UAAA,CAAW,CAAA;EAC1B,UAAA;EACA,YAAA;AAAA;AAAA,KAGU,UAAA,IAAc,MAAA,EAAQ,WAAA,KAAgB,IAAA,YAAgB,OAAA;AAAA,KACtD,aAAA,gBAA6B,IAAA,yBACjC,IAAA,EAAM,IAAA,KAAS,OAAA,CAAQ,KAAA,UACrB,OAAA,CAAQ,KAAA;AAAA,UAED,mBAAA;EACf,GAAA,EAAK,aAAA,CAAc,KAAA,EAAO,IAAA;AAAA;AAAA,UAGX,sBAAA,sBAA4C,mBAAA,CAAoB,KAAA,EAAO,IAAA;EACtF,OAAA;EACA,KAAA,GAAQ,KAAA;EACR,KAAA,GAAQ,KAAA;AAAA;AAAA,UAGO,oBAAA,sBAA0C,mBAAA,CAAoB,KAAA,EAAO,IAAA;EACpF,OAAA;EACA,KAAA,EAAO,KAAA;EACP,KAAA;AAAA;AAAA,UAGe,uBAAA,sBAA6C,mBAAA,CAAoB,KAAA,EAAO,IAAA;EACvF,OAAA;EACA,KAAA;EACA,KAAA,EAAO,KAAA;AAAA;AAAA,KAGJ,UAAA,WAAqB,UAAA,IAAc,OAAA,CAAQ,UAAA,CAAW,CAAA;AAAA,KACtD,SAAA,WAAoB,UAAA,IAAc,UAAA,CAAW,CAAA,iCAAkC,IAAA;AAAA,KAExE,eAAA,gBACR,sBAAA,CAAuB,KAAA,EAAO,IAAA,IAC9B,oBAAA,CAAqB,KAAA,EAAO,IAAA,IAC5B,uBAAA,CAAwB,KAAA,EAAO,IAAA;AAAA,cAEtB,UAAA,aAAwB,UAAA,UAAoB,UAAA,CAAW,CAAA,UAAW,SAAA,CAAU,CAAA,GAAE,EAAA,EACrF,CAAA,EAAC,IAAA,GACC,cAAA,EAAc,OAAA,GACV,iBAAA,CAAkB,CAAA,MAC3B,eAAA,CAAgB,KAAA,EAAO,IAAA;;;cC5Cb,QAAA,aAAsB,UAAA,EAAU,EAAA,EACvC,CAAA,EAAC,IAAA,GACC,cAAA,EAAc,OAAA,GACV,iBAAA,CAAkB,CAAA;EAAO,cAAA;AAAA,MAA0B,eAAA,CAAA,OAAA,CAAA,UAAA,CAAA,CAAA,IAAA,UAAA,CAAA,CAAA,iCAAA,IAAA;;;UCJ9C,2BAAA;EACf,OAAA;EACA,OAAA;AAAA;AAAA,iBAGc,oBAAA,eAAmC,IAAA,cAAA,CACjD,QAAA,EAAU,CAAA,EACV,IAAA,EAAM,cAAA,EACN,OAAA,GAAU,2BAAA,GA0CE,CAAA;;;iBCjDE,kBAAA,CACd,QAAA,EAAU,cAAA,EACV,IAAA,EAAM,cAAA,EACN,OAAA,GAAU,2BAAA;;;cCJC,cAAA,GAAc,QAAA,EAAc,KAAA,CAAM,cAAA;;;cCAlC,eAAA;;;cCAA,iBAAA,GAAiB,GAAA,EACvB,KAAA,CAAM,gBAAA,CAAiB,WAAA,UAAmB,QAAA,GACpC,KAAA,UAAe,MAAA"}
1
+ {"version":3,"file":"react-util.d.mts","names":[],"sources":["../src/react-util/useAsyncFn.ts","../src/react-util/useAsync.ts","../src/react-util/useDebouncedCallback.tsx","../src/react-util/useDebouncedEffect.tsx","../src/react-util/useMountEffect.tsx","../src/react-util/useMountedState.ts","../src/react-util/useResizeObserver.tsx"],"mappings":";;;UAEiB,iBAAA,WAA4B,UAAA;EAC3C,YAAA,GAAe,UAAA,CAAW,CAAA;EAC1B,UAAA;EACA,YAAA;AAAA;AAAA,KAGU,UAAA,IAAc,MAAA,EAAQ,WAAA,KAAgB,IAAA,YAAgB,OAAO;AAAA,KAC7D,aAAA,gBAA6B,IAAA,yBACjC,IAAA,EAAM,IAAA,KAAS,OAAA,CAAQ,KAAA,UACrB,OAAA,CAAQ,KAAA;AAAA,UAED,mBAAA;EACf,GAAA,EAAK,aAAA,CAAc,KAAA,EAAO,IAAA;AAAA;AAAA,UAGX,sBAAA,sBAA4C,mBAAA,CAAoB,KAAA,EAAO,IAAA;EACtF,OAAA;EACA,KAAA,GAAQ,KAAA;EACR,KAAA,GAAQ,KAAA;AAAA;AAAA,UAGO,oBAAA,sBAA0C,mBAAA,CAAoB,KAAA,EAAO,IAAA;EACpF,OAAA;EACA,KAAA,EAAO,KAAA;EACP,KAAA;AAAA;AAAA,UAGe,uBAAA,sBAA6C,mBAAA,CAAoB,KAAA,EAAO,IAAA;EACvF,OAAA;EACA,KAAA;EACA,KAAA,EAAO,KAAA;AAAA;AAAA,KAGJ,UAAA,WAAqB,UAAA,IAAc,OAAA,CAAQ,UAAA,CAAW,CAAA;AAAA,KACtD,SAAA,WAAoB,UAAA,IAAc,UAAA,CAAW,CAAA,iCAAkC,IAAA;AAAA,KAExE,eAAA,gBACR,sBAAA,CAAuB,KAAA,EAAO,IAAA,IAC9B,oBAAA,CAAqB,KAAA,EAAO,IAAA,IAC5B,uBAAA,CAAwB,KAAA,EAAO,IAAA;AAAA,cAEtB,UAAA,aAAwB,UAAA,UAAoB,UAAA,CAAW,CAAA,UAAW,SAAA,CAAU,CAAA,GAAE,EAAA,EACrF,CAAA,EAAC,IAAA,GACC,cAAA,EAAc,OAAA,GACV,iBAAA,CAAkB,CAAA,MAC3B,eAAA,CAAgB,KAAA,EAAO,IAAA;;;cC5Cb,QAAA,aAAsB,UAAA,EAAU,EAAA,EACvC,CAAA,EAAC,IAAA,GACC,cAAA,EAAc,OAAA,GACV,iBAAA,CAAkB,CAAA;EAAO,cAAA;AAAA,MAA0B,eAAA,CAAA,OAAA,CAAA,UAAA,CAAA,CAAA,IAAA,UAAA,CAAA,CAAA,iCAAA,IAAA;;;UCJ9C,2BAAA;EACf,OAAA;EACA,OAAO;AAAA;AAAA,iBAGO,oBAAA,eAAmC,IAAA,eACjD,QAAA,EAAU,CAAA,EACV,IAAA,EAAM,cAAA,EACN,OAAA,GAAU,2BAAA,GA0CE,CAAA;;;iBCjDE,kBAAA,CACd,QAAA,EAAU,cAAA,EACV,IAAA,EAAM,cAAA,EACN,OAAA,GAAU,2BAAA;;;cCJC,cAAA,GAAc,QAAA,EAAc,KAAA,CAAM,cAAc;;;cCAhD,eAAA;;;cCAA,iBAAA,GAAiB,GAAA,EACvB,KAAA,CAAM,gBAAgB,CAAC,WAAA,UAAmB,QAAA,GACpC,KAAA,UAAe,MAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"react-util.mjs","names":[],"sources":["../src/react-util/useAsyncFn.ts","../src/react-util/useAsync.ts","../src/react-util/useDebouncedCallback.tsx","../src/react-util/useDebouncedEffect.tsx","../src/react-util/useMountEffect.tsx","../src/react-util/useMountedState.ts","../src/react-util/useResizeObserver.tsx"],"sourcesContent":["import { type DependencyList, useCallback, useEffect, useRef, useState } from \"react\";\n\nexport interface UseAsyncFnOptions<F extends UseAsyncFn> {\n initialValue?: InferValue<F>;\n debounceMs?: number;\n debounceType?: \"leading\" | \"trailing\";\n}\n\nexport type UseAsyncFn = (signal: AbortSignal, ...args: any[]) => Promise<any>;\nexport type UseAsyncFnRun<Value, Args> = Args extends unknown[]\n ? (...args: Args) => Promise<Value>\n : () => Promise<Value>;\n\nexport interface UseAsyncFnStateBase<Value, Args> {\n run: UseAsyncFnRun<Value, Args>;\n}\n\nexport interface UseAsyncFnStateLoading<Value, Args> extends UseAsyncFnStateBase<Value, Args> {\n loading: true;\n error?: Error | undefined;\n value?: Value;\n}\n\nexport interface UseAsyncFnStateError<Value, Args> extends UseAsyncFnStateBase<Value, Args> {\n loading: false;\n error: Error;\n value?: undefined;\n}\n\nexport interface UseAsyncFnStateResolved<Value, Args> extends UseAsyncFnStateBase<Value, Args> {\n loading: false;\n error?: undefined;\n value: Value;\n}\n\ntype InferValue<F extends UseAsyncFn> = Awaited<ReturnType<F>>;\ntype InferArgs<F extends UseAsyncFn> = Parameters<F> extends [any, ...infer Rest] ? Rest : [];\n\nexport type UseAsyncFnState<Value, Args> =\n | UseAsyncFnStateLoading<Value, Args>\n | UseAsyncFnStateError<Value, Args>\n | UseAsyncFnStateResolved<Value, Args>;\n\nexport const useAsyncFn = <F extends UseAsyncFn, Value = InferValue<F>, Args = InferArgs<F>>(\n fn: F,\n deps: DependencyList = [],\n options?: UseAsyncFnOptions<F>,\n): UseAsyncFnState<Value, Args> => {\n const { debounceType = \"leading\", debounceMs = 650 } = options ?? {};\n\n const timeoutRef = useRef<number | undefined>(undefined);\n const abortControllerRef = useRef<AbortController | undefined>(undefined);\n\n const [state, setState] = useState<Omit<UseAsyncFnState<Value, Args>, \"run\">>(\n options?.initialValue ? { loading: false, value: options?.initialValue } : { loading: true },\n );\n\n const run = useCallback((...args: Parameters<F>) => {\n window.clearTimeout(timeoutRef.current);\n\n abortControllerRef.current?.abort();\n const abortController = new AbortController();\n abortControllerRef.current = abortController;\n\n if (!state?.loading) {\n setState((prevState) => ({ ...prevState, loading: true }));\n }\n\n return new Promise((resolve, reject) => {\n const timeoutMs = debounceType === \"leading\" && !timeoutRef.current ? 0 : debounceMs;\n\n timeoutRef.current = window.setTimeout(() => {\n fn(abortController.signal, ...args)\n .then(\n (value) => {\n if (!abortController.signal.aborted) {\n setState({ value, loading: false });\n }\n resolve(value);\n },\n (error) => {\n if (!abortController.signal.aborted) {\n setState({ error, loading: false });\n }\n reject(error);\n },\n )\n .finally(() => {\n timeoutRef.current = undefined;\n });\n }, timeoutMs);\n });\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: deps are controlled by caller\n }, deps);\n\n useEffect(() => {\n return () => abortControllerRef.current?.abort();\n }, []);\n\n return { ...state, run } as UseAsyncFnState<Value, Args>;\n};\n","import { type DependencyList, useEffect, useRef } from \"react\";\nimport { type UseAsyncFn, type UseAsyncFnOptions, useAsyncFn } from \"./useAsyncFn\";\n\nexport const useAsync = <F extends UseAsyncFn>(\n fn: F,\n deps: DependencyList = [],\n options?: UseAsyncFnOptions<F> & { runImmediately?: boolean },\n) => {\n const firstRun = useRef(true);\n\n const { runImmediately = true, ...useAsyncFnOptions } = options ?? {};\n\n const asyncFn = useAsyncFn(fn, deps, useAsyncFnOptions);\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: option changes should not trigger effect\n useEffect(() => {\n const isFirstRun = firstRun.current;\n firstRun.current = false;\n\n if (!runImmediately && isFirstRun) return;\n\n // TODO: how should errors be handled? this isn't great...\n void asyncFn.run();\n }, [asyncFn.run]);\n\n return asyncFn;\n};\n","import { type DependencyList, useCallback, useEffect, useRef } from \"react\";\n\nexport interface UseDebouncedCallbackOptions {\n leading?: boolean;\n delayMs?: number;\n}\n\nexport function useDebouncedCallback<T extends (...args: any) => any>(\n callback: T,\n deps: DependencyList,\n options?: UseDebouncedCallbackOptions,\n) {\n const ref = useRef<\n UseDebouncedCallbackOptions & {\n timeout: number | null;\n mounted: boolean;\n leadingTriggered: boolean;\n }\n >({\n ...options,\n timeout: null,\n mounted: false,\n leadingTriggered: options?.leading ?? false,\n });\n\n useEffect(() => {\n const currentRef = ref.current;\n currentRef.mounted = true;\n currentRef.leadingTriggered = false;\n return () => {\n currentRef.mounted = false;\n window.clearTimeout(currentRef.timeout!);\n };\n }, []);\n\n return useCallback((...params: Parameters<T>) => {\n const currentRef = ref.current;\n window.clearTimeout(currentRef.timeout!);\n if (!currentRef.leadingTriggered && currentRef.leading) {\n currentRef.leadingTriggered = true;\n callback(...params);\n currentRef.timeout = window.setTimeout(() => {\n currentRef.leadingTriggered = true;\n }, currentRef.delayMs ?? 1600);\n } else {\n currentRef.timeout = window.setTimeout(() => {\n if (!currentRef.mounted) return;\n callback(...params);\n currentRef.leadingTriggered = false;\n }, currentRef.delayMs ?? 1600);\n }\n // biome-ignore lint/correctness/useExhaustiveDependencies: <explanation>\n }, deps) as T;\n}\n","import { type DependencyList, type EffectCallback, useEffect } from \"react\";\nimport { type UseDebouncedCallbackOptions, useDebouncedCallback } from \"./useDebouncedCallback\";\n\nexport function useDebouncedEffect(\n callback: EffectCallback,\n deps: DependencyList,\n options?: UseDebouncedCallbackOptions,\n) {\n const debouncedCallback = useDebouncedCallback(callback, deps, { leading: true, ...options });\n // biome-ignore lint/correctness/useExhaustiveDependencies: <explanation>\n return useEffect(debouncedCallback, deps);\n}\n","import { useEffect } from \"react\";\n\nexport const useMountEffect = (effectFn: React.EffectCallback): void => useEffect(effectFn, []);\n","import { useCallback, useEffect, useRef } from \"react\";\n\nexport const useMountedState = (): (() => boolean) => {\n const mountedRef = useRef<boolean>(false);\n const get = useCallback(() => mountedRef.current, []);\n\n useEffect(() => {\n mountedRef.current = true;\n\n return () => {\n mountedRef.current = false;\n };\n }, []);\n\n return get;\n};\n","import { useCallback, useLayoutEffect, useRef } from \"react\";\n\nexport const useResizeObserver = (\n ref: React.MutableRefObject<HTMLElement | null>,\n onResize: (width: number, height: number) => void,\n): void => {\n const onResizeRef = useRef(onResize);\n const handleResize = useCallback(() => {\n if (ref.current) {\n onResizeRef.current(ref.current.clientWidth, ref.current.clientHeight);\n }\n }, [ref]);\n\n useLayoutEffect(() => {\n const el = ref.current;\n if (!el) {\n return;\n }\n\n handleResize();\n\n if (typeof ResizeObserver === \"function\") {\n const resizeObserver = new ResizeObserver(() => handleResize());\n\n resizeObserver.observe(el);\n\n return () => resizeObserver.disconnect();\n } else {\n window.addEventListener(\"resize\", handleResize);\n\n return () => window.window.removeEventListener(\"resize\", handleResize);\n }\n }, [ref, handleResize]);\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"react-util.mjs","names":[],"sources":["../src/react-util/useAsyncFn.ts","../src/react-util/useAsync.ts","../src/react-util/useDebouncedCallback.tsx","../src/react-util/useDebouncedEffect.tsx","../src/react-util/useMountEffect.tsx","../src/react-util/useMountedState.ts","../src/react-util/useResizeObserver.tsx"],"sourcesContent":["import { type DependencyList, useCallback, useEffect, useRef, useState } from \"react\";\n\nexport interface UseAsyncFnOptions<F extends UseAsyncFn> {\n initialValue?: InferValue<F>;\n debounceMs?: number;\n debounceType?: \"leading\" | \"trailing\";\n}\n\nexport type UseAsyncFn = (signal: AbortSignal, ...args: any[]) => Promise<any>;\nexport type UseAsyncFnRun<Value, Args> = Args extends unknown[]\n ? (...args: Args) => Promise<Value>\n : () => Promise<Value>;\n\nexport interface UseAsyncFnStateBase<Value, Args> {\n run: UseAsyncFnRun<Value, Args>;\n}\n\nexport interface UseAsyncFnStateLoading<Value, Args> extends UseAsyncFnStateBase<Value, Args> {\n loading: true;\n error?: Error | undefined;\n value?: Value;\n}\n\nexport interface UseAsyncFnStateError<Value, Args> extends UseAsyncFnStateBase<Value, Args> {\n loading: false;\n error: Error;\n value?: undefined;\n}\n\nexport interface UseAsyncFnStateResolved<Value, Args> extends UseAsyncFnStateBase<Value, Args> {\n loading: false;\n error?: undefined;\n value: Value;\n}\n\ntype InferValue<F extends UseAsyncFn> = Awaited<ReturnType<F>>;\ntype InferArgs<F extends UseAsyncFn> = Parameters<F> extends [any, ...infer Rest] ? Rest : [];\n\nexport type UseAsyncFnState<Value, Args> =\n | UseAsyncFnStateLoading<Value, Args>\n | UseAsyncFnStateError<Value, Args>\n | UseAsyncFnStateResolved<Value, Args>;\n\nexport const useAsyncFn = <F extends UseAsyncFn, Value = InferValue<F>, Args = InferArgs<F>>(\n fn: F,\n deps: DependencyList = [],\n options?: UseAsyncFnOptions<F>,\n): UseAsyncFnState<Value, Args> => {\n const { debounceType = \"leading\", debounceMs = 650 } = options ?? {};\n\n const timeoutRef = useRef<number | undefined>(undefined);\n const abortControllerRef = useRef<AbortController | undefined>(undefined);\n\n const [state, setState] = useState<Omit<UseAsyncFnState<Value, Args>, \"run\">>(\n options?.initialValue ? { loading: false, value: options?.initialValue } : { loading: true },\n );\n\n const run = useCallback((...args: Parameters<F>) => {\n window.clearTimeout(timeoutRef.current);\n\n abortControllerRef.current?.abort();\n const abortController = new AbortController();\n abortControllerRef.current = abortController;\n\n if (!state?.loading) {\n setState((prevState) => ({ ...prevState, loading: true }));\n }\n\n return new Promise((resolve, reject) => {\n const timeoutMs = debounceType === \"leading\" && !timeoutRef.current ? 0 : debounceMs;\n\n timeoutRef.current = window.setTimeout(() => {\n fn(abortController.signal, ...args)\n .then(\n (value) => {\n if (!abortController.signal.aborted) {\n setState({ value, loading: false });\n }\n resolve(value);\n },\n (error) => {\n if (!abortController.signal.aborted) {\n setState({ error, loading: false });\n }\n reject(error);\n },\n )\n .finally(() => {\n timeoutRef.current = undefined;\n });\n }, timeoutMs);\n });\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: deps are controlled by caller\n }, deps);\n\n useEffect(() => {\n return () => abortControllerRef.current?.abort();\n }, []);\n\n return { ...state, run } as UseAsyncFnState<Value, Args>;\n};\n","import { type DependencyList, useEffect, useRef } from \"react\";\nimport { type UseAsyncFn, type UseAsyncFnOptions, useAsyncFn } from \"./useAsyncFn\";\n\nexport const useAsync = <F extends UseAsyncFn>(\n fn: F,\n deps: DependencyList = [],\n options?: UseAsyncFnOptions<F> & { runImmediately?: boolean },\n) => {\n const firstRun = useRef(true);\n\n const { runImmediately = true, ...useAsyncFnOptions } = options ?? {};\n\n const asyncFn = useAsyncFn(fn, deps, useAsyncFnOptions);\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: option changes should not trigger effect\n useEffect(() => {\n const isFirstRun = firstRun.current;\n firstRun.current = false;\n\n if (!runImmediately && isFirstRun) return;\n\n // TODO: how should errors be handled? this isn't great...\n void asyncFn.run();\n }, [asyncFn.run]);\n\n return asyncFn;\n};\n","import { type DependencyList, useCallback, useEffect, useRef } from \"react\";\n\nexport interface UseDebouncedCallbackOptions {\n leading?: boolean;\n delayMs?: number;\n}\n\nexport function useDebouncedCallback<T extends (...args: any) => any>(\n callback: T,\n deps: DependencyList,\n options?: UseDebouncedCallbackOptions,\n) {\n const ref = useRef<\n UseDebouncedCallbackOptions & {\n timeout: number | null;\n mounted: boolean;\n leadingTriggered: boolean;\n }\n >({\n ...options,\n timeout: null,\n mounted: false,\n leadingTriggered: options?.leading ?? false,\n });\n\n useEffect(() => {\n const currentRef = ref.current;\n currentRef.mounted = true;\n currentRef.leadingTriggered = false;\n return () => {\n currentRef.mounted = false;\n window.clearTimeout(currentRef.timeout!);\n };\n }, []);\n\n return useCallback((...params: Parameters<T>) => {\n const currentRef = ref.current;\n window.clearTimeout(currentRef.timeout!);\n if (!currentRef.leadingTriggered && currentRef.leading) {\n currentRef.leadingTriggered = true;\n callback(...params);\n currentRef.timeout = window.setTimeout(() => {\n currentRef.leadingTriggered = true;\n }, currentRef.delayMs ?? 1600);\n } else {\n currentRef.timeout = window.setTimeout(() => {\n if (!currentRef.mounted) return;\n callback(...params);\n currentRef.leadingTriggered = false;\n }, currentRef.delayMs ?? 1600);\n }\n // biome-ignore lint/correctness/useExhaustiveDependencies: <explanation>\n }, deps) as T;\n}\n","import { type DependencyList, type EffectCallback, useEffect } from \"react\";\nimport { type UseDebouncedCallbackOptions, useDebouncedCallback } from \"./useDebouncedCallback\";\n\nexport function useDebouncedEffect(\n callback: EffectCallback,\n deps: DependencyList,\n options?: UseDebouncedCallbackOptions,\n) {\n const debouncedCallback = useDebouncedCallback(callback, deps, { leading: true, ...options });\n // biome-ignore lint/correctness/useExhaustiveDependencies: <explanation>\n return useEffect(debouncedCallback, deps);\n}\n","import { useEffect } from \"react\";\n\nexport const useMountEffect = (effectFn: React.EffectCallback): void => useEffect(effectFn, []);\n","import { useCallback, useEffect, useRef } from \"react\";\n\nexport const useMountedState = (): (() => boolean) => {\n const mountedRef = useRef<boolean>(false);\n const get = useCallback(() => mountedRef.current, []);\n\n useEffect(() => {\n mountedRef.current = true;\n\n return () => {\n mountedRef.current = false;\n };\n }, []);\n\n return get;\n};\n","import { useCallback, useLayoutEffect, useRef } from \"react\";\n\nexport const useResizeObserver = (\n ref: React.MutableRefObject<HTMLElement | null>,\n onResize: (width: number, height: number) => void,\n): void => {\n const onResizeRef = useRef(onResize);\n const handleResize = useCallback(() => {\n if (ref.current) {\n onResizeRef.current(ref.current.clientWidth, ref.current.clientHeight);\n }\n }, [ref]);\n\n useLayoutEffect(() => {\n const el = ref.current;\n if (!el) {\n return;\n }\n\n handleResize();\n\n if (typeof ResizeObserver === \"function\") {\n const resizeObserver = new ResizeObserver(() => handleResize());\n\n resizeObserver.observe(el);\n\n return () => resizeObserver.disconnect();\n } else {\n window.addEventListener(\"resize\", handleResize);\n\n return () => window.window.removeEventListener(\"resize\", handleResize);\n }\n }, [ref, handleResize]);\n};\n"],"mappings":"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"}
package/dist/router.d.mts CHANGED
@@ -1,6 +1,4 @@
1
- import * as _$react from "react";
2
1
  import React$1 from "react";
3
- import * as _$react_jsx_runtime0 from "react/jsx-runtime";
4
2
  import { History, Location } from "history";
5
3
 
6
4
  //#region src/router/outlet.d.ts
@@ -144,6 +142,7 @@ type ExtractPaths<R> = { [S in keyof R]: S extends string ? S extends "index" ?
144
142
  type LinkComponentProps<C extends React$1.ElementType> = Omit<React$1.ComponentProps<C>, " ref" | "exact" | "to" | "params" | "onClick">;
145
143
  type LinkPropsBase<C extends React$1.ElementType, I extends React$1.ElementType = C> = LinkComponentProps<C> & {
146
144
  exact?: boolean;
145
+ preserveSearch?: boolean;
147
146
  ref?: React$1.Ref<React$1.ComponentRef<I>>;
148
147
  };
149
148
  interface LinkComponent<C extends React$1.ElementType, I extends React$1.ElementType = C> {
@@ -194,14 +193,14 @@ declare const RouterOutlet: React.FC<{
194
193
  route: Route;
195
194
  components: (Component | undefined)[];
196
195
  }>;
197
- declare const routerContext: _$react.Context<RouterStore>;
196
+ declare const routerContext: import("react").Context<RouterStore>;
198
197
  declare const useRouter: () => RouterStore;
199
198
  interface RouterProps {
200
199
  store: RouterStore;
201
200
  }
202
201
  declare const Router: (({
203
202
  store
204
- }: RouterProps) => _$react_jsx_runtime0.JSX.Element | null) & {
203
+ }: RouterProps) => import("react/jsx-runtime").JSX.Element | null) & {
205
204
  displayName: string;
206
205
  };
207
206
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"router.d.mts","names":[],"sources":["../src/router/outlet.tsx","../src/router/route.tsx","../src/router/symbols.ts","../src/router/types.ts","../src/router/components/link.tsx","../src/router/components/navigate.tsx","../src/router/router.store.ts","../src/router/components/router.tsx","../src/router/make-routes.tsx","../src/router/redirect.ts","../src/router/util.ts"],"mappings":"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"}
1
+ {"version":3,"file":"router.d.mts","names":[],"sources":["../src/router/outlet.tsx","../src/router/route.tsx","../src/router/symbols.ts","../src/router/types.ts","../src/router/components/link.tsx","../src/router/components/navigate.tsx","../src/router/router.store.ts","../src/router/components/router.tsx","../src/router/make-routes.tsx","../src/router/redirect.ts","../src/router/util.ts"],"mappings":"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"}
package/dist/router.mjs CHANGED
@@ -76,7 +76,7 @@ const Router = observer(({ store }) => {
76
76
  //#endregion
77
77
  //#region src/router/components/link.tsx
78
78
  const makeLinkComponent = (C, baseProps) => {
79
- return observer(({ to, params, exact, children, ...props }) => {
79
+ return observer(({ to, params, exact, preserveSearch, children, ...props }) => {
80
80
  const router = useRouter();
81
81
  const mergedProps = {
82
82
  ...baseProps,
@@ -89,6 +89,7 @@ const makeLinkComponent = (C, baseProps) => {
89
89
  if (props.disabled) return;
90
90
  router.navigate({
91
91
  to,
92
+ preserveSearch,
92
93
  ...params
93
94
  });
94
95
  }, [
@@ -116,6 +117,7 @@ const Navigate = (props) => {
116
117
  const DefaultOutlet = ({ children }) => children;
117
118
  const LoadingPlaceholder = () => /* @__PURE__ */ jsx("p", { children: "Loading..." });
118
119
  var Outlet = class {
120
+ config;
119
121
  state = "preloading";
120
122
  promise;
121
123
  data;
@@ -183,6 +185,7 @@ var Outlet = class {
183
185
  //#endregion
184
186
  //#region src/router/redirect.ts
185
187
  var Redirect = class {
188
+ options;
186
189
  constructor(options) {
187
190
  this.options = options;
188
191
  }
@@ -1 +1 @@
1
- {"version":3,"file":"router.mjs","names":[],"sources":["../src/router/symbols.ts","../src/router/util.ts","../src/router/components/router.tsx","../src/router/components/link.tsx","../src/router/components/navigate.tsx","../src/router/outlet.tsx","../src/router/redirect.ts","../src/router/route.tsx","../src/router/make-routes.tsx","../src/router/router.store.ts"],"sourcesContent":["export const CONTEXT: unique symbol = Symbol.for(\"MOBX_ROUTER_CONTEXT\");\nexport const LAYOUT: unique symbol = Symbol.for(\"MOBX_ROUTER_LAYOUT\");\nexport const WRAPPER: unique symbol = Symbol.for(\"MOBX_ROUTER_WRAPPER\");\nexport const LOAD: unique symbol = Symbol.for(\"MOBX_ROUTER_LOAD\");\nexport const GUARD: unique symbol = Symbol.for(\"MOBX_ROUTER_GUARD\");\nexport const PAGE: unique symbol = Symbol.for(\"MOBX_ROUTER_PAGE\");\nexport const REDIRECT: unique symbol = Symbol.for(\"MOBX_ROUTER_REDIRECT\");\n","import { PAGE, REDIRECT } from \"./symbols\";\nimport type { Component, LazyComponent, Leaf, Obj, Page, Redirector } from \"./types\";\n\nexport const resolvePath = (to: string, params?: Obj): string => {\n return to.replaceAll(/:[^/]*/g, (segment) => {\n const value = params?.[segment.slice(1)];\n if (!value)\n throw new Error(`Unable to resolve route '${to}. Paramater '${segment}' not specified.`);\n return value;\n });\n};\n\nexport const isComponent = (data: any): data is Component => {\n if (!data) return false;\n return (\n typeof data === \"function\" ||\n (typeof data === \"object\" && data[\"$$typeof\"] === Symbol.for(\"react.memo\"))\n );\n};\n\nexport const isPage = (data: any): data is Page => {\n if (typeof data !== \"object\") return false;\n const symbols = Object.getOwnPropertySymbols(data);\n return symbols.includes(PAGE);\n};\n\nexport const isRedirect = (data: any): data is Redirector => {\n if (typeof data !== \"object\") return false;\n const symbols = Object.getOwnPropertySymbols(data);\n return symbols.includes(REDIRECT);\n};\n\nexport const isLeaf = (data: any): data is Leaf => {\n return isComponent(data) || isPage(data) || isRedirect(data);\n};\n\nexport const isLazyComponent = (data: any): data is LazyComponent => {\n return typeof data === \"function\" && data.toString().startsWith(\"() => import(\");\n};\n","import { observer } from \"mobx-react-lite\";\nimport { createContext, useContext } from \"react\";\nimport type { Route } from \"../route\";\nimport type { RouterStore } from \"../router.store\";\nimport type { Component } from \"../types\";\n\nexport const PassThrough: Component = ({ children }) => children;\n\n// Plain (non-observer) renderer. State observation lives one level up\n// in `Router`, so the page component renders as a child of a plain\n// FunctionComponent — no memo wrapper in the parent chain to interact\n// with React Refresh's family-update propagation.\nexport const RouterOutlet: React.FC<{ route: Route; components: (Component | undefined)[] }> = ({\n route,\n components,\n}) => {\n const [C, ...remaining] = components;\n\n if (!C) return null;\n\n return (\n <C route={route}>\n {remaining.length > 0 && <RouterOutlet route={route} components={remaining} />}\n </C>\n );\n};\n\nexport const routerContext = createContext<RouterStore>(null as any);\nexport const useRouter = () => useContext(routerContext);\n\nexport interface RouterProps {\n store: RouterStore;\n}\n\nexport const Router = observer(({ store }: RouterProps) => {\n if (!store.activeRoute) {\n return null;\n }\n\n const Layout = store.activeRoute.layout ?? PassThrough;\n const components = store.activeRoute.outlets.map((o) => o.Component);\n\n return (\n <routerContext.Provider value={store}>\n <Layout route={store.activeRoute}>\n <RouterOutlet route={store.activeRoute} components={components} />\n </Layout>\n </routerContext.Provider>\n );\n});\n","import { observer } from \"mobx-react-lite\";\nimport React, { useCallback } from \"react\";\nimport type {\n DynamicRoutePath,\n ExtractParams,\n NavigateOptions,\n RoutePath,\n StaticRoutePath,\n} from \"../types\";\nimport { resolvePath } from \"../util\";\nimport { useRouter } from \"./router\";\n\ntype LinkComponentProps<C extends React.ElementType> = Omit<\n React.ComponentProps<C>,\n \" ref\" | \"exact\" | \"to\" | \"params\" | \"onClick\"\n>;\n\nexport type LinkPropsBase<\n C extends React.ElementType,\n I extends React.ElementType = C,\n> = LinkComponentProps<C> & {\n exact?: boolean;\n ref?: React.Ref<React.ComponentRef<I>>;\n};\n\n// function overloading is much faster than leveraging conditional types\n// but once the typescript go compiler is released and performance is no\n// longer an issue, it might make sense to simplify this a bit so it can\n// be more easily consumed by users\nexport interface LinkComponent<C extends React.ElementType, I extends React.ElementType = C> {\n <P extends StaticRoutePath>(\n props: LinkPropsBase<C, I> & { to: P; params?: undefined },\n ): React.ReactNode;\n <P extends DynamicRoutePath>(\n props: LinkPropsBase<C, I> & { to: P; params: ExtractParams<P> },\n ): React.ReactNode;\n}\n\n// final thing to do is make sure refs still work in React 19\n\n// this smooths over some of the awkwardness when extending this component\nexport const makeLinkComponent = <C extends React.ElementType, I extends React.ElementType = C>(\n C: C,\n baseProps?: Partial<LinkComponentProps<C>> & { as?: I },\n) => {\n return observer(({ to, params, exact, children, ...props }: any) => {\n const router = useRouter();\n const mergedProps = { ...baseProps, ...props };\n\n if (props.role !== \"link\") {\n mergedProps.href = resolvePath(to, params);\n }\n\n if (router.doesPathMatch(to, exact)) {\n mergedProps[\"aria-current\"] = \"page\";\n }\n\n mergedProps.onClick = useCallback(\n (event: React.MouseEvent<HTMLElement>) => {\n event.preventDefault();\n if (props.disabled) return;\n router.navigate({ to, ...(params as any) } as NavigateOptions<RoutePath>);\n },\n [router, params, to, props.disabled],\n );\n\n return React.createElement(C, mergedProps, children);\n }) as LinkComponent<C, I>;\n};\n\n//export const Link = makeLinkComponent('a');\n","import { useLayoutEffect } from \"react\";\nimport type { NavigateOptions, RoutePath } from \"../types\";\nimport { useRouter } from \"./router\";\n\nexport const Navigate = <P extends RoutePath>(props: NavigateOptions<P>) => {\n const router = useRouter();\n\n useLayoutEffect(() => {\n router.navigate(props);\n }, [router, props]);\n\n return null;\n};\n","import { makeAutoObservable, observable } from \"mobx\";\nimport type { Route } from \"./route\";\nimport type { Component, LazyComponent, Loader } from \"./types\";\nimport { isLazyComponent } from \"./util\";\n\nexport interface OutletConfig {\n component?: Component | LazyComponent;\n loader?: Loader;\n}\n\nexport type RouteSegmentState = \"preloading\" | \"loading\" | \"error\" | \"ready\";\n\nexport const DefaultOutlet: Component = ({ children }) => children;\n\nconst LoadingPlaceholder: Component = () => <p>Loading...</p>;\n\nexport class Outlet {\n state: RouteSegmentState = \"preloading\";\n promise: Promise<unknown> | undefined;\n data: unknown;\n\n // Plain (non-observable) reference. The page component must reach\n // React unmediated by MobX — once MobX deep-observes the holder,\n // React Refresh can no longer swap the page identity via family\n // lookup on the original function. This mirrors how Route holds\n // `layout` as a plain field under makeObservable.\n component: Component | undefined;\n\n get Component(): Component | undefined {\n switch (this.state) {\n case \"loading\":\n return LoadingPlaceholder;\n case \"ready\":\n return this.component ?? DefaultOutlet;\n default:\n return undefined;\n }\n }\n\n constructor(readonly config: OutletConfig) {\n if (!isLazyComponent(config.component)) {\n this.component = config.component;\n }\n\n makeAutoObservable<Outlet, \"component\" | \"config\">(this, {\n promise: observable.ref,\n data: observable.ref,\n component: false,\n config: false,\n });\n }\n\n async load(route: Route): Promise<void> {\n const promises: Promise<void>[] = [];\n\n if (isLazyComponent(this.config.component) && !this.component) {\n promises.push(this.loadComponent());\n }\n\n if (this.config.loader) {\n promises.push(this.loadData(route));\n }\n\n if (!promises.length) {\n this.setState(\"ready\");\n return;\n }\n\n // wait to transition to loading to avoid\n // screen flashes when the loader function\n // executes quickly\n const preloadingTimer = setTimeout(() => {\n if (this.state === \"preloading\") {\n this.setState(\"loading\");\n }\n }, 300);\n\n this.promise = Promise.all(promises)\n .then(() => {\n clearTimeout(preloadingTimer);\n if (this.state === \"loading\") {\n // if we had to transition to regular loading because\n // the loader was taking too long, force an additional\n // timeout to prevent a loading flash\n setTimeout(() => {\n this.setState(\"ready\");\n }, 300);\n } else {\n this.setState(\"ready\");\n }\n })\n .catch(() => {\n clearTimeout(preloadingTimer);\n // TODO: check for type of error\n // handle access denied and redirects\n this.setState(\"error\");\n });\n\n await this.promise;\n }\n\n setData(data: unknown) {\n this.data = data;\n }\n\n setState(state: RouteSegmentState) {\n this.state = state;\n }\n\n private async loadData(route: Route): Promise<void> {\n await this.config.loader?.(route).then((data) => this.setData(data));\n }\n\n private async loadComponent(): Promise<void> {\n if (!isLazyComponent(this.config.component)) return;\n const module = await this.config.component();\n for (const exportName in module) {\n if (exportName === \"default\" || exportName.endsWith(\"Page\")) {\n this.component = module[exportName];\n return;\n }\n }\n throw new Error(\n \"Lazy route component module did not export `default` or a `*Page` named export\",\n );\n }\n}\n","import type { NavigateOptions, RoutePath } from \"./types\";\n\nexport class Redirect<P extends RoutePath> {\n constructor(readonly options: NavigateOptions<P>) {}\n}\n\nexport const redirect = <P extends RoutePath>(options: NavigateOptions<P>): Redirect<P> =>\n new Redirect(options);\n","import { computed, makeObservable } from \"mobx\";\nimport type { Outlet } from \"./outlet\";\nimport type { Component, Guard, Obj } from \"./types\";\n\nexport interface RouteConfig {\n path: string;\n outlets: Outlet[];\n guards: Guard[];\n context?: Obj;\n layout?: Component;\n params: Obj;\n}\n\nexport class Route {\n readonly path: string;\n readonly outlets: Outlet[];\n readonly guards: Guard[];\n readonly context: Obj;\n readonly params: Obj;\n readonly layout?: Component;\n\n get data(): Obj {\n return Object.assign({}, ...this.outlets.map((o) => o.data));\n }\n\n constructor(def: RouteConfig) {\n this.path = def.path;\n this.guards = def.guards;\n this.context = def.context ?? {};\n this.outlets = def.outlets;\n this.params = def.params;\n this.layout = def.layout;\n\n makeObservable(this, {\n data: computed,\n });\n }\n\n async guard(): Promise<void> {\n for (const guard of this.guards) {\n await guard(this);\n }\n }\n\n async load(): Promise<void> {\n await Promise.all(this.outlets.map((outlet) => outlet.load(this)));\n }\n}\n","import { Outlet } from \"./outlet\";\nimport { Redirect } from \"./redirect\";\nimport { Route } from \"./route\";\nimport { CONTEXT, GUARD, LAYOUT, LOAD, PAGE, REDIRECT, WRAPPER } from \"./symbols\";\nimport type { Component, Guard, Obj, Routes } from \"./types\";\nimport { isComponent, isLazyComponent, isLeaf, isPage, isRedirect } from \"./util\";\n\nconst pathToSegments = (path: string): string[] => {\n return path.replace(/^\\/+|\\/+$/g, \"\").split(\"/\");\n};\n\nexport interface MatchState {\n segments: string[];\n context: Obj;\n params: Obj;\n outlets: (Outlet | undefined)[];\n guards: (Guard | undefined)[];\n layout?: Component;\n}\n\nexport const makeRoute = (matchState: MatchState): Route => {\n const outlets = matchState.outlets.filter((o) => o !== undefined);\n const guards = matchState.guards.filter((g) => g !== undefined);\n\n return new Route({ ...matchState, outlets, guards, path: matchState.segments.join(\"/\") });\n};\n\nexport const matchRoute = (path: string, routeDef: Routes, matchState?: MatchState): Route => {\n const state: MatchState = {\n segments: [],\n params: {},\n ...matchState,\n layout: routeDef[LAYOUT] ?? matchState?.layout,\n context: { ...matchState?.context, ...routeDef[CONTEXT] },\n guards: [...(matchState?.guards ?? []), routeDef[GUARD]],\n outlets: [\n ...(matchState?.outlets ?? []),\n routeDef[WRAPPER] ? new Outlet({ component: routeDef[WRAPPER] }) : undefined,\n routeDef[LOAD] ? new Outlet({ loader: routeDef[LOAD] }) : undefined,\n ],\n };\n\n const [segment, ...remainingSegments] = pathToSegments(path);\n const remainingPath = remainingSegments.join(\"/\");\n\n let defAtSegment = routeDef[segment || \"index\"];\n\n if (!defAtSegment) {\n const matchedSegment = Object.keys(routeDef).find((segment) => segment.startsWith(\"$\"));\n if (matchedSegment) {\n defAtSegment = routeDef[matchedSegment];\n state.params[matchedSegment.slice(1)] = segment;\n }\n }\n\n if (!defAtSegment) {\n throw new Error(\"Not Found.\");\n }\n\n state.segments.push(segment ?? \"index\");\n\n if (isLeaf(defAtSegment)) {\n if (remainingPath) {\n throw new Error(\"Not Found.\");\n }\n\n if (isRedirect(defAtSegment)) {\n const redirect =\n typeof defAtSegment[REDIRECT] === \"string\"\n ? { to: defAtSegment[REDIRECT] }\n : defAtSegment[REDIRECT];\n throw new Redirect(redirect as any);\n }\n\n if (isComponent(defAtSegment) || isLazyComponent(defAtSegment)) {\n state.outlets.push(new Outlet({ component: defAtSegment }));\n return makeRoute(state);\n }\n }\n\n // at this point we have a nested route or a [Page] definition\n\n if (isPage(defAtSegment)) {\n state.layout = defAtSegment[LAYOUT] ?? state.layout;\n Object.assign(state.context, defAtSegment[CONTEXT]);\n state.guards.push(defAtSegment[GUARD]);\n state.outlets.push(\n new Outlet({\n component: defAtSegment[PAGE],\n loader: defAtSegment[LOAD],\n }),\n );\n\n return makeRoute(state);\n }\n\n // now we know we have a nested route\n return matchRoute(remainingPath, defAtSegment, state);\n};\n\n// TODO: ideally this could resolve to something less than R,\n// but specific enough to infer all paths as a literal union.\n// As it stands, there are certain things we can't access reliably\n// without the compiler complaining about circular references\n// try \"as const satisfies\" approach which would allow us to\n// exchange a less specific version of MobxRoutesRoot for this\nexport const makeRoutes =\n () =>\n <R extends Routes>(routes: R): R => {\n // todo: perform some validation here\n // - no forward slashes in keys\n // - at most one variable segment per level\n // - only lowercase letters (except variables)\n // - paths/variables cannot contain $ that aren't at the beginning\n // - path variables must be unique across a path\n\n return routes;\n };\n","import { createBrowserHistory, type History, type Location } from \"history\";\nimport { action, computed, makeObservable, observable, runInAction } from \"mobx\";\nimport { matchRoute } from \"./make-routes\";\nimport { Redirect } from \"./redirect\";\nimport type { Route } from \"./route\";\nimport type { Component, MobxRouterConfig, NavigateOptions, Obj, RoutePath, Routes } from \"./types\";\nimport { resolvePath } from \"./util\";\n\nexport interface MobxRenderSegment {\n segment: string;\n component: Component;\n props?: Obj;\n}\n\nexport class RouterStore {\n readonly history: History;\n\n routesDef?: Routes;\n\n location!: Location;\n activeRoute: Route | undefined;\n\n get search(): URLSearchParams {\n return new URLSearchParams(this.location?.search);\n }\n\n get query(): Record<string, string> {\n return Object.fromEntries(this.search);\n }\n\n get pathParams(): Record<string, string> {\n const params = {} as Record<string, string>;\n\n const paramSegments = this.activeSegments.filter((segment) => segment.startsWith(\"$\"));\n const pathValues = this.location.pathname.split(\"/\").slice(1);\n\n paramSegments.forEach((segment, index) => {\n const value = pathValues[index + 1];\n if (value) {\n params[segment] = value;\n }\n });\n\n return params as Record<string, string>;\n }\n\n get activeSegments(): string[] {\n return this.activeRoute?.path.split(\"/\") ?? [];\n }\n\n constructor(config?: MobxRouterConfig) {\n makeObservable(this, {\n location: observable.ref,\n activeRoute: observable.ref,\n\n search: computed,\n pathParams: computed,\n activeSegments: computed,\n\n setLocation: action,\n });\n\n this.history = config?.history ?? createBrowserHistory();\n }\n\n initialize(routesDef: Routes): void {\n this.routesDef = routesDef;\n this.history.listen((data) => {\n void this.setLocation(data.location);\n });\n\n void this.setLocation(this.history.location);\n }\n\n doesPathMatch<P extends RoutePath>(path: P, exact?: boolean): boolean {\n const segments = path.slice(1).split(\"/\");\n const segmentsMatch = segments.every(\n (segment, i) => segment === this.activeSegments[i] || segment.startsWith(\"$\"),\n );\n\n return (\n segmentsMatch &&\n this.activeSegments.length >= segments.length &&\n (!exact || segments.length === this.activeSegments.length)\n );\n }\n\n navigate<P extends RoutePath>(options: NavigateOptions<P>): void {\n if (!document.startViewTransition) {\n this._navigate(options);\n } else {\n const transition = document.startViewTransition(() => this._navigate(options));\n transition.ready.catch((e) => console.log(e, typeof e));\n }\n }\n\n _navigate<P extends RoutePath>(options: NavigateOptions<P>): void {\n const { to, replace, state, search = {}, preserveSearch, params } = options;\n\n const searchParams = search instanceof URLSearchParams ? search : new URLSearchParams(search);\n\n if (preserveSearch) {\n for (const [name, value] of this.search) {\n if (!searchParams.has(name)) {\n searchParams.set(name, value);\n }\n }\n }\n\n const location = {\n pathname: resolvePath(to, params),\n search: searchParams.size ? `?${searchParams.toString()}` : undefined,\n };\n\n if (replace) {\n this.history.replace(location, state);\n } else {\n this.history.push(location, state);\n }\n }\n\n setQueryParam(param: string, value: string): void {\n const params = new URLSearchParams(this.location.search);\n params.set(param, value);\n this.history.replace({ search: params.toString() });\n }\n\n removeQueryParam(param: string): string | undefined {\n const params = new URLSearchParams(this.location.search);\n const value = params.get(param) ?? undefined;\n if (value !== undefined) {\n params.delete(param);\n this.history.replace({ search: params.toString() });\n }\n return value;\n }\n\n async setLocation(location: Location): Promise<void> {\n if (!this.routesDef) return;\n\n // TODO: this should not be the responsibility of mobx-router\n // and should really be handled server-side\n if (location.pathname !== \"/\" && location.pathname.endsWith(\"/\")) {\n this.history.replace({ ...location, pathname: location.pathname.slice(0, -1) });\n return;\n }\n\n this.location = location;\n\n try {\n const matchedRoute = matchRoute(location.pathname, this.routesDef);\n\n await matchedRoute.guard();\n\n // navigating within a guard function\n // is essentially a redirect\n if (this.location !== location) {\n return;\n }\n\n runInAction(() => {\n this.activeRoute = matchedRoute;\n });\n\n await this.activeRoute?.load();\n } catch (e) {\n if (e instanceof Redirect) {\n this.navigate(e.options);\n return;\n }\n throw e;\n }\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"router.mjs","names":[],"sources":["../src/router/symbols.ts","../src/router/util.ts","../src/router/components/router.tsx","../src/router/components/link.tsx","../src/router/components/navigate.tsx","../src/router/outlet.tsx","../src/router/redirect.ts","../src/router/route.tsx","../src/router/make-routes.tsx","../src/router/router.store.ts"],"sourcesContent":["export const CONTEXT: unique symbol = Symbol.for(\"MOBX_ROUTER_CONTEXT\");\nexport const LAYOUT: unique symbol = Symbol.for(\"MOBX_ROUTER_LAYOUT\");\nexport const WRAPPER: unique symbol = Symbol.for(\"MOBX_ROUTER_WRAPPER\");\nexport const LOAD: unique symbol = Symbol.for(\"MOBX_ROUTER_LOAD\");\nexport const GUARD: unique symbol = Symbol.for(\"MOBX_ROUTER_GUARD\");\nexport const PAGE: unique symbol = Symbol.for(\"MOBX_ROUTER_PAGE\");\nexport const REDIRECT: unique symbol = Symbol.for(\"MOBX_ROUTER_REDIRECT\");\n","import { PAGE, REDIRECT } from \"./symbols\";\nimport type { Component, LazyComponent, Leaf, Obj, Page, Redirector } from \"./types\";\n\nexport const resolvePath = (to: string, params?: Obj): string => {\n return to.replaceAll(/:[^/]*/g, (segment) => {\n const value = params?.[segment.slice(1)];\n if (!value)\n throw new Error(`Unable to resolve route '${to}. Paramater '${segment}' not specified.`);\n return value;\n });\n};\n\nexport const isComponent = (data: any): data is Component => {\n if (!data) return false;\n return (\n typeof data === \"function\" ||\n (typeof data === \"object\" && data[\"$$typeof\"] === Symbol.for(\"react.memo\"))\n );\n};\n\nexport const isPage = (data: any): data is Page => {\n if (typeof data !== \"object\") return false;\n const symbols = Object.getOwnPropertySymbols(data);\n return symbols.includes(PAGE);\n};\n\nexport const isRedirect = (data: any): data is Redirector => {\n if (typeof data !== \"object\") return false;\n const symbols = Object.getOwnPropertySymbols(data);\n return symbols.includes(REDIRECT);\n};\n\nexport const isLeaf = (data: any): data is Leaf => {\n return isComponent(data) || isPage(data) || isRedirect(data);\n};\n\nexport const isLazyComponent = (data: any): data is LazyComponent => {\n return typeof data === \"function\" && data.toString().startsWith(\"() => import(\");\n};\n","import { observer } from \"mobx-react-lite\";\nimport { createContext, useContext } from \"react\";\nimport type { Route } from \"../route\";\nimport type { RouterStore } from \"../router.store\";\nimport type { Component } from \"../types\";\n\nexport const PassThrough: Component = ({ children }) => children;\n\n// Plain (non-observer) renderer. State observation lives one level up\n// in `Router`, so the page component renders as a child of a plain\n// FunctionComponent — no memo wrapper in the parent chain to interact\n// with React Refresh's family-update propagation.\nexport const RouterOutlet: React.FC<{ route: Route; components: (Component | undefined)[] }> = ({\n route,\n components,\n}) => {\n const [C, ...remaining] = components;\n\n if (!C) return null;\n\n return (\n <C route={route}>\n {remaining.length > 0 && <RouterOutlet route={route} components={remaining} />}\n </C>\n );\n};\n\nexport const routerContext = createContext<RouterStore>(null as any);\nexport const useRouter = () => useContext(routerContext);\n\nexport interface RouterProps {\n store: RouterStore;\n}\n\nexport const Router = observer(({ store }: RouterProps) => {\n if (!store.activeRoute) {\n return null;\n }\n\n const Layout = store.activeRoute.layout ?? PassThrough;\n const components = store.activeRoute.outlets.map((o) => o.Component);\n\n return (\n <routerContext.Provider value={store}>\n <Layout route={store.activeRoute}>\n <RouterOutlet route={store.activeRoute} components={components} />\n </Layout>\n </routerContext.Provider>\n );\n});\n","import { observer } from \"mobx-react-lite\";\nimport React, { useCallback } from \"react\";\nimport type {\n DynamicRoutePath,\n ExtractParams,\n NavigateOptions,\n RoutePath,\n StaticRoutePath,\n} from \"../types\";\nimport { resolvePath } from \"../util\";\nimport { useRouter } from \"./router\";\n\ntype LinkComponentProps<C extends React.ElementType> = Omit<\n React.ComponentProps<C>,\n \" ref\" | \"exact\" | \"to\" | \"params\" | \"onClick\"\n>;\n\nexport type LinkPropsBase<\n C extends React.ElementType,\n I extends React.ElementType = C,\n> = LinkComponentProps<C> & {\n exact?: boolean;\n preserveSearch?: boolean;\n ref?: React.Ref<React.ComponentRef<I>>;\n};\n\n// function overloading is much faster than leveraging conditional types\n// but once the typescript go compiler is released and performance is no\n// longer an issue, it might make sense to simplify this a bit so it can\n// be more easily consumed by users\nexport interface LinkComponent<C extends React.ElementType, I extends React.ElementType = C> {\n <P extends StaticRoutePath>(\n props: LinkPropsBase<C, I> & { to: P; params?: undefined },\n ): React.ReactNode;\n <P extends DynamicRoutePath>(\n props: LinkPropsBase<C, I> & { to: P; params: ExtractParams<P> },\n ): React.ReactNode;\n}\n\n// final thing to do is make sure refs still work in React 19\n\n// this smooths over some of the awkwardness when extending this component\nexport const makeLinkComponent = <C extends React.ElementType, I extends React.ElementType = C>(\n C: C,\n baseProps?: Partial<LinkComponentProps<C>> & { as?: I },\n) => {\n return observer(({ to, params, exact, preserveSearch, children, ...props }: any) => {\n const router = useRouter();\n const mergedProps = { ...baseProps, ...props };\n\n if (props.role !== \"link\") {\n mergedProps.href = resolvePath(to, params);\n }\n\n if (router.doesPathMatch(to, exact)) {\n mergedProps[\"aria-current\"] = \"page\";\n }\n\n mergedProps.onClick = useCallback(\n (event: React.MouseEvent<HTMLElement>) => {\n event.preventDefault();\n if (props.disabled) return;\n router.navigate({ to, preserveSearch, ...(params as any) } as NavigateOptions<RoutePath>);\n },\n [router, params, to, props.disabled],\n );\n\n return React.createElement(C, mergedProps, children);\n }) as LinkComponent<C, I>;\n};\n\n//export const Link = makeLinkComponent('a');\n","import { useLayoutEffect } from \"react\";\nimport type { NavigateOptions, RoutePath } from \"../types\";\nimport { useRouter } from \"./router\";\n\nexport const Navigate = <P extends RoutePath>(props: NavigateOptions<P>) => {\n const router = useRouter();\n\n useLayoutEffect(() => {\n router.navigate(props);\n }, [router, props]);\n\n return null;\n};\n","import { makeAutoObservable, observable } from \"mobx\";\nimport type { Route } from \"./route\";\nimport type { Component, LazyComponent, Loader } from \"./types\";\nimport { isLazyComponent } from \"./util\";\n\nexport interface OutletConfig {\n component?: Component | LazyComponent;\n loader?: Loader;\n}\n\nexport type RouteSegmentState = \"preloading\" | \"loading\" | \"error\" | \"ready\";\n\nexport const DefaultOutlet: Component = ({ children }) => children;\n\nconst LoadingPlaceholder: Component = () => <p>Loading...</p>;\n\nexport class Outlet {\n state: RouteSegmentState = \"preloading\";\n promise: Promise<unknown> | undefined;\n data: unknown;\n\n // Plain (non-observable) reference. The page component must reach\n // React unmediated by MobX — once MobX deep-observes the holder,\n // React Refresh can no longer swap the page identity via family\n // lookup on the original function. This mirrors how Route holds\n // `layout` as a plain field under makeObservable.\n component: Component | undefined;\n\n get Component(): Component | undefined {\n switch (this.state) {\n case \"loading\":\n return LoadingPlaceholder;\n case \"ready\":\n return this.component ?? DefaultOutlet;\n default:\n return undefined;\n }\n }\n\n constructor(readonly config: OutletConfig) {\n if (!isLazyComponent(config.component)) {\n this.component = config.component;\n }\n\n makeAutoObservable<Outlet, \"component\" | \"config\">(this, {\n promise: observable.ref,\n data: observable.ref,\n component: false,\n config: false,\n });\n }\n\n async load(route: Route): Promise<void> {\n const promises: Promise<void>[] = [];\n\n if (isLazyComponent(this.config.component) && !this.component) {\n promises.push(this.loadComponent());\n }\n\n if (this.config.loader) {\n promises.push(this.loadData(route));\n }\n\n if (!promises.length) {\n this.setState(\"ready\");\n return;\n }\n\n // wait to transition to loading to avoid\n // screen flashes when the loader function\n // executes quickly\n const preloadingTimer = setTimeout(() => {\n if (this.state === \"preloading\") {\n this.setState(\"loading\");\n }\n }, 300);\n\n this.promise = Promise.all(promises)\n .then(() => {\n clearTimeout(preloadingTimer);\n if (this.state === \"loading\") {\n // if we had to transition to regular loading because\n // the loader was taking too long, force an additional\n // timeout to prevent a loading flash\n setTimeout(() => {\n this.setState(\"ready\");\n }, 300);\n } else {\n this.setState(\"ready\");\n }\n })\n .catch(() => {\n clearTimeout(preloadingTimer);\n // TODO: check for type of error\n // handle access denied and redirects\n this.setState(\"error\");\n });\n\n await this.promise;\n }\n\n setData(data: unknown) {\n this.data = data;\n }\n\n setState(state: RouteSegmentState) {\n this.state = state;\n }\n\n private async loadData(route: Route): Promise<void> {\n await this.config.loader?.(route).then((data) => this.setData(data));\n }\n\n private async loadComponent(): Promise<void> {\n if (!isLazyComponent(this.config.component)) return;\n const module = await this.config.component();\n for (const exportName in module) {\n if (exportName === \"default\" || exportName.endsWith(\"Page\")) {\n this.component = module[exportName];\n return;\n }\n }\n throw new Error(\n \"Lazy route component module did not export `default` or a `*Page` named export\",\n );\n }\n}\n","import type { NavigateOptions, RoutePath } from \"./types\";\n\nexport class Redirect<P extends RoutePath> {\n constructor(readonly options: NavigateOptions<P>) {}\n}\n\nexport const redirect = <P extends RoutePath>(options: NavigateOptions<P>): Redirect<P> =>\n new Redirect(options);\n","import { computed, makeObservable } from \"mobx\";\nimport type { Outlet } from \"./outlet\";\nimport type { Component, Guard, Obj } from \"./types\";\n\nexport interface RouteConfig {\n path: string;\n outlets: Outlet[];\n guards: Guard[];\n context?: Obj;\n layout?: Component;\n params: Obj;\n}\n\nexport class Route {\n readonly path: string;\n readonly outlets: Outlet[];\n readonly guards: Guard[];\n readonly context: Obj;\n readonly params: Obj;\n readonly layout?: Component;\n\n get data(): Obj {\n return Object.assign({}, ...this.outlets.map((o) => o.data));\n }\n\n constructor(def: RouteConfig) {\n this.path = def.path;\n this.guards = def.guards;\n this.context = def.context ?? {};\n this.outlets = def.outlets;\n this.params = def.params;\n this.layout = def.layout;\n\n makeObservable(this, {\n data: computed,\n });\n }\n\n async guard(): Promise<void> {\n for (const guard of this.guards) {\n await guard(this);\n }\n }\n\n async load(): Promise<void> {\n await Promise.all(this.outlets.map((outlet) => outlet.load(this)));\n }\n}\n","import { Outlet } from \"./outlet\";\nimport { Redirect } from \"./redirect\";\nimport { Route } from \"./route\";\nimport { CONTEXT, GUARD, LAYOUT, LOAD, PAGE, REDIRECT, WRAPPER } from \"./symbols\";\nimport type { Component, Guard, Obj, Routes } from \"./types\";\nimport { isComponent, isLazyComponent, isLeaf, isPage, isRedirect } from \"./util\";\n\nconst pathToSegments = (path: string): string[] => {\n return path.replace(/^\\/+|\\/+$/g, \"\").split(\"/\");\n};\n\nexport interface MatchState {\n segments: string[];\n context: Obj;\n params: Obj;\n outlets: (Outlet | undefined)[];\n guards: (Guard | undefined)[];\n layout?: Component;\n}\n\nexport const makeRoute = (matchState: MatchState): Route => {\n const outlets = matchState.outlets.filter((o) => o !== undefined);\n const guards = matchState.guards.filter((g) => g !== undefined);\n\n return new Route({ ...matchState, outlets, guards, path: matchState.segments.join(\"/\") });\n};\n\nexport const matchRoute = (path: string, routeDef: Routes, matchState?: MatchState): Route => {\n const state: MatchState = {\n segments: [],\n params: {},\n ...matchState,\n layout: routeDef[LAYOUT] ?? matchState?.layout,\n context: { ...matchState?.context, ...routeDef[CONTEXT] },\n guards: [...(matchState?.guards ?? []), routeDef[GUARD]],\n outlets: [\n ...(matchState?.outlets ?? []),\n routeDef[WRAPPER] ? new Outlet({ component: routeDef[WRAPPER] }) : undefined,\n routeDef[LOAD] ? new Outlet({ loader: routeDef[LOAD] }) : undefined,\n ],\n };\n\n const [segment, ...remainingSegments] = pathToSegments(path);\n const remainingPath = remainingSegments.join(\"/\");\n\n let defAtSegment = routeDef[segment || \"index\"];\n\n if (!defAtSegment) {\n const matchedSegment = Object.keys(routeDef).find((segment) => segment.startsWith(\"$\"));\n if (matchedSegment) {\n defAtSegment = routeDef[matchedSegment];\n state.params[matchedSegment.slice(1)] = segment;\n }\n }\n\n if (!defAtSegment) {\n throw new Error(\"Not Found.\");\n }\n\n state.segments.push(segment ?? \"index\");\n\n if (isLeaf(defAtSegment)) {\n if (remainingPath) {\n throw new Error(\"Not Found.\");\n }\n\n if (isRedirect(defAtSegment)) {\n const redirect =\n typeof defAtSegment[REDIRECT] === \"string\"\n ? { to: defAtSegment[REDIRECT] }\n : defAtSegment[REDIRECT];\n throw new Redirect(redirect as any);\n }\n\n if (isComponent(defAtSegment) || isLazyComponent(defAtSegment)) {\n state.outlets.push(new Outlet({ component: defAtSegment }));\n return makeRoute(state);\n }\n }\n\n // at this point we have a nested route or a [Page] definition\n\n if (isPage(defAtSegment)) {\n state.layout = defAtSegment[LAYOUT] ?? state.layout;\n Object.assign(state.context, defAtSegment[CONTEXT]);\n state.guards.push(defAtSegment[GUARD]);\n state.outlets.push(\n new Outlet({\n component: defAtSegment[PAGE],\n loader: defAtSegment[LOAD],\n }),\n );\n\n return makeRoute(state);\n }\n\n // now we know we have a nested route\n return matchRoute(remainingPath, defAtSegment, state);\n};\n\n// TODO: ideally this could resolve to something less than R,\n// but specific enough to infer all paths as a literal union.\n// As it stands, there are certain things we can't access reliably\n// without the compiler complaining about circular references\n// try \"as const satisfies\" approach which would allow us to\n// exchange a less specific version of MobxRoutesRoot for this\nexport const makeRoutes =\n () =>\n <R extends Routes>(routes: R): R => {\n // todo: perform some validation here\n // - no forward slashes in keys\n // - at most one variable segment per level\n // - only lowercase letters (except variables)\n // - paths/variables cannot contain $ that aren't at the beginning\n // - path variables must be unique across a path\n\n return routes;\n };\n","import { createBrowserHistory, type History, type Location } from \"history\";\nimport { action, computed, makeObservable, observable, runInAction } from \"mobx\";\nimport { matchRoute } from \"./make-routes\";\nimport { Redirect } from \"./redirect\";\nimport type { Route } from \"./route\";\nimport type { Component, MobxRouterConfig, NavigateOptions, Obj, RoutePath, Routes } from \"./types\";\nimport { resolvePath } from \"./util\";\n\nexport interface MobxRenderSegment {\n segment: string;\n component: Component;\n props?: Obj;\n}\n\nexport class RouterStore {\n readonly history: History;\n\n routesDef?: Routes;\n\n location!: Location;\n activeRoute: Route | undefined;\n\n get search(): URLSearchParams {\n return new URLSearchParams(this.location?.search);\n }\n\n get query(): Record<string, string> {\n return Object.fromEntries(this.search);\n }\n\n get pathParams(): Record<string, string> {\n const params = {} as Record<string, string>;\n\n const paramSegments = this.activeSegments.filter((segment) => segment.startsWith(\"$\"));\n const pathValues = this.location.pathname.split(\"/\").slice(1);\n\n paramSegments.forEach((segment, index) => {\n const value = pathValues[index + 1];\n if (value) {\n params[segment] = value;\n }\n });\n\n return params as Record<string, string>;\n }\n\n get activeSegments(): string[] {\n return this.activeRoute?.path.split(\"/\") ?? [];\n }\n\n constructor(config?: MobxRouterConfig) {\n makeObservable(this, {\n location: observable.ref,\n activeRoute: observable.ref,\n\n search: computed,\n pathParams: computed,\n activeSegments: computed,\n\n setLocation: action,\n });\n\n this.history = config?.history ?? createBrowserHistory();\n }\n\n initialize(routesDef: Routes): void {\n this.routesDef = routesDef;\n this.history.listen((data) => {\n void this.setLocation(data.location);\n });\n\n void this.setLocation(this.history.location);\n }\n\n doesPathMatch<P extends RoutePath>(path: P, exact?: boolean): boolean {\n const segments = path.slice(1).split(\"/\");\n const segmentsMatch = segments.every(\n (segment, i) => segment === this.activeSegments[i] || segment.startsWith(\"$\"),\n );\n\n return (\n segmentsMatch &&\n this.activeSegments.length >= segments.length &&\n (!exact || segments.length === this.activeSegments.length)\n );\n }\n\n navigate<P extends RoutePath>(options: NavigateOptions<P>): void {\n if (!document.startViewTransition) {\n this._navigate(options);\n } else {\n const transition = document.startViewTransition(() => this._navigate(options));\n transition.ready.catch((e) => console.log(e, typeof e));\n }\n }\n\n _navigate<P extends RoutePath>(options: NavigateOptions<P>): void {\n const { to, replace, state, search = {}, preserveSearch, params } = options;\n\n const searchParams = search instanceof URLSearchParams ? search : new URLSearchParams(search);\n\n if (preserveSearch) {\n for (const [name, value] of this.search) {\n if (!searchParams.has(name)) {\n searchParams.set(name, value);\n }\n }\n }\n\n const location = {\n pathname: resolvePath(to, params),\n search: searchParams.size ? `?${searchParams.toString()}` : undefined,\n };\n\n if (replace) {\n this.history.replace(location, state);\n } else {\n this.history.push(location, state);\n }\n }\n\n setQueryParam(param: string, value: string): void {\n const params = new URLSearchParams(this.location.search);\n params.set(param, value);\n this.history.replace({ search: params.toString() });\n }\n\n removeQueryParam(param: string): string | undefined {\n const params = new URLSearchParams(this.location.search);\n const value = params.get(param) ?? undefined;\n if (value !== undefined) {\n params.delete(param);\n this.history.replace({ search: params.toString() });\n }\n return value;\n }\n\n async setLocation(location: Location): Promise<void> {\n if (!this.routesDef) return;\n\n // TODO: this should not be the responsibility of mobx-router\n // and should really be handled server-side\n if (location.pathname !== \"/\" && location.pathname.endsWith(\"/\")) {\n this.history.replace({ ...location, pathname: location.pathname.slice(0, -1) });\n return;\n }\n\n this.location = location;\n\n try {\n const matchedRoute = matchRoute(location.pathname, this.routesDef);\n\n await matchedRoute.guard();\n\n // navigating within a guard function\n // is essentially a redirect\n if (this.location !== location) {\n return;\n }\n\n runInAction(() => {\n this.activeRoute = matchedRoute;\n });\n\n await this.activeRoute?.load();\n } catch (e) {\n if (e instanceof Redirect) {\n this.navigate(e.options);\n return;\n }\n throw e;\n }\n }\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"util.d.mts","names":[],"sources":["../src/util/mutable.ts","../src/util/use-autorun.ts"],"mappings":";;;;cAGa,OAAA,EAAS,sBAAA;;;iBCAN,UAAA,CAAW,IAAA,GAAO,CAAA,EAAG,eAAA,cAA6B,OAAA,GAAU,eAAA"}
1
+ {"version":3,"file":"util.d.mts","names":[],"sources":["../src/util/mutable.ts","../src/util/use-autorun.ts"],"mappings":";;;;cAGa,OAAA,EAAS,sBAwBrB;;;iBCxBe,UAAA,CAAW,IAAA,GAAO,CAAA,EAAG,eAAA,cAA6B,OAAA,GAAU,eAAe"}
package/dist/util.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"util.mjs","names":[],"sources":["../src/util/mutable.ts","../src/util/use-autorun.ts"],"sourcesContent":["import { observable, runInAction } from \"mobx\";\nimport type { ClassAccessorDecorator } from \"mobx/dist/types/decorator_fills\";\n\nexport const mutable: ClassAccessorDecorator = (accessor) => {\n const boxedValues = new WeakMap();\n\n return {\n get() {\n let boxedValue = boxedValues.get(this);\n if (!boxedValue) {\n const value = accessor.get.call(this);\n boxedValue = observable.box(value);\n boxedValues.set(this, boxedValue);\n }\n\n return boxedValue.get();\n },\n set(value) {\n let boxedValue = boxedValues.get(this);\n if (!boxedValue) {\n boxedValue = observable.box(value);\n boxedValues.set(this, boxedValue);\n }\n\n runInAction(() => boxedValue.set(value));\n },\n };\n};\n","import { autorun, type IAutorunOptions, type IReactionPublic } from \"mobx\";\nimport { useEffect } from \"react\";\n\nexport function useAutorun(func: (r: IReactionPublic) => unknown, options?: IAutorunOptions): void {\n // biome-ignore lint/correctness/useExhaustiveDependencies: by design\n useEffect(() => autorun(func, options), []);\n}\n"],"mappings":";;;;AAGA,MAAa,WAAmC,aAAa;CAC3D,MAAM,8BAAc,IAAI,SAAS;AAEjC,QAAO;EACL,MAAM;GACJ,IAAI,aAAa,YAAY,IAAI,KAAK;AACtC,OAAI,CAAC,YAAY;IACf,MAAM,QAAQ,SAAS,IAAI,KAAK,KAAK;AACrC,iBAAa,WAAW,IAAI,MAAM;AAClC,gBAAY,IAAI,MAAM,WAAW;;AAGnC,UAAO,WAAW,KAAK;;EAEzB,IAAI,OAAO;GACT,IAAI,aAAa,YAAY,IAAI,KAAK;AACtC,OAAI,CAAC,YAAY;AACf,iBAAa,WAAW,IAAI,MAAM;AAClC,gBAAY,IAAI,MAAM,WAAW;;AAGnC,qBAAkB,WAAW,IAAI,MAAM,CAAC;;EAE3C;;;;;ACvBH,SAAgB,WAAW,MAAuC,SAAiC;AAEjG,iBAAgB,QAAQ,MAAM,QAAQ,EAAE,EAAE,CAAC"}
1
+ {"version":3,"file":"util.mjs","names":[],"sources":["../src/util/mutable.ts","../src/util/use-autorun.ts"],"sourcesContent":["import { observable, runInAction } from \"mobx\";\nimport type { ClassAccessorDecorator } from \"mobx/dist/types/decorator_fills\";\n\nexport const mutable: ClassAccessorDecorator = (accessor) => {\n const boxedValues = new WeakMap();\n\n return {\n get() {\n let boxedValue = boxedValues.get(this);\n if (!boxedValue) {\n const value = accessor.get.call(this);\n boxedValue = observable.box(value);\n boxedValues.set(this, boxedValue);\n }\n\n return boxedValue.get();\n },\n set(value) {\n let boxedValue = boxedValues.get(this);\n if (!boxedValue) {\n boxedValue = observable.box(value);\n boxedValues.set(this, boxedValue);\n }\n\n runInAction(() => boxedValue.set(value));\n },\n };\n};\n","import { autorun, type IAutorunOptions, type IReactionPublic } from \"mobx\";\nimport { useEffect } from \"react\";\n\nexport function useAutorun(func: (r: IReactionPublic) => unknown, options?: IAutorunOptions): void {\n // biome-ignore lint/correctness/useExhaustiveDependencies: by design\n useEffect(() => autorun(func, options), []);\n}\n"],"mappings":";;;;AAGA,MAAa,WAAmC,aAAa;CAC3D,MAAM,8BAAc,IAAI,QAAQ;CAEhC,OAAO;EACL,MAAM;GACJ,IAAI,aAAa,YAAY,IAAI,IAAI;GACrC,IAAI,CAAC,YAAY;IACf,MAAM,QAAQ,SAAS,IAAI,KAAK,IAAI;IACpC,aAAa,WAAW,IAAI,KAAK;IACjC,YAAY,IAAI,MAAM,UAAU;GAClC;GAEA,OAAO,WAAW,IAAI;EACxB;EACA,IAAI,OAAO;GACT,IAAI,aAAa,YAAY,IAAI,IAAI;GACrC,IAAI,CAAC,YAAY;IACf,aAAa,WAAW,IAAI,KAAK;IACjC,YAAY,IAAI,MAAM,UAAU;GAClC;GAEA,kBAAkB,WAAW,IAAI,KAAK,CAAC;EACzC;CACF;AACF;;;;ACxBA,SAAgB,WAAW,MAAuC,SAAiC;CAEjG,gBAAgB,QAAQ,MAAM,OAAO,GAAG,CAAC,CAAC;AAC5C"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jayalfredprufrock/mobx-toolbox",
3
- "version": "0.6.0",
3
+ "version": "0.6.2",
4
4
  "description": "Misc mobx/react modules/utilities.",
5
5
  "homepage": "https://github.com/jayalfredprufrock/mobx-toolbox#readme",
6
6
  "bugs": {
@@ -40,7 +40,7 @@
40
40
  "semantic-release": "^25.0.3",
41
41
  "typebox": "^1.1.17",
42
42
  "typescript": "^6.0.2",
43
- "vite-plus": "^0.1.14"
43
+ "vite-plus": "0.2.1"
44
44
  },
45
45
  "peerDependencies": {
46
46
  "history": "^5.3.0",
@@ -1 +0,0 @@
1
- {"version":3,"file":"lazy-observable-DA4DIMbc.d.mts","names":[],"sources":["../src/lazy-observable/lazy-observable.ts"],"mappings":";;;UAUiB,cAAA,0BAAwC,CAAA;EACvD,KAAA,EAAO,aAAA;EACP,KAAA,IAAS,aAAA;EACT,SAAA,IAAa,OAAA,CAAQ,CAAA;EACrB,GAAA,CAAI,KAAA,EAAO,CAAA;EACX,MAAA,IAAU,OAAA,CAAQ,CAAA;EAClB,MAAA;EACA,KAAA;EACA,OAAA;EACA,MAAA;AAAA;AAAA,UAGe,qBAAA;EACf,OAAA;EACA,iBAAA;EACA,SAAA;AAAA;AAAA,UAGe,qCAAA,wBAEP,qBAAA;EACR,YAAA,GAAe,aAAA;AAAA;AAAA,iBAGD,cAAA,GAAA,CAAkB,KAAA,QAAa,OAAA,CAAQ,CAAA,IAAK,cAAA,CAAe,CAAA;AAAA,iBAC3D,cAAA,GAAA,CACd,KAAA,QAAa,OAAA,CAAQ,CAAA,GACrB,OAAA,EAAS,qBAAA,GACR,cAAA,CAAe,CAAA;AAAA,iBACF,cAAA,kBAAA,CACd,KAAA,QAAa,OAAA,CAAQ,CAAA,GACrB,OAAA,EAAS,qCAAA,CAAsC,aAAA,IAC9C,cAAA,CAAe,CAAA,EAAG,aAAA;AAAA,UAkLJ,mBAAA,kBAAqC,IAAA,CACpD,cAAA,CAAe,gBAAA,CAAiB,CAAA;EAGhC,GAAA,CAAI,KAAA,EAAO,CAAA;AAAA;AAAA,UAGI,0BAAA,YAAsC,qBAAA;EACrD,YAAA,GAAe,CAAA;AAAA;AAAA,iBAGD,mBAAA,GAAA,CACd,KAAA,QAAa,OAAA,CAAQ,CAAA,KACrB,OAAA,GAAU,0BAAA,CAA2B,CAAA,IACpC,mBAAA,CAAoB,CAAA;AAAA,KAIX,mBAAA,MACV,CAAA,SAAU,mBAAA,YAA+B,CAAA,KAAM,CAAA,SAAU,cAAA,YAA0B,CAAA"}