@jayalfredprufrock/mobx-toolbox 0.1.1 → 0.2.1

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.
@@ -2,7 +2,7 @@ import * as _$react from "react";
2
2
  import { FC } from "react";
3
3
  import * as _$react_jsx_runtime0 from "react/jsx-runtime";
4
4
 
5
- //#region src/mobx-dialog/dialog.types.d.ts
5
+ //#region src/dialog/dialog.types.d.ts
6
6
  type DialogState = "opening" | "opened" | "closing" | "closed";
7
7
  type RequiredKeys<T> = { [K in keyof T]-?: {} extends Pick<T, K> ? never : K }[keyof T];
8
8
  type AnyComponent = FC<any>;
@@ -15,7 +15,7 @@ interface DialogModelConfig {
15
15
  initialState?: DialogState;
16
16
  }
17
17
  //#endregion
18
- //#region src/mobx-dialog/dialog.store.d.ts
18
+ //#region src/dialog/dialog.store.d.ts
19
19
  declare class DialogStore {
20
20
  dialogs: Map<string, DialogModel>;
21
21
  get openDialogs(): DialogModel[];
@@ -26,7 +26,7 @@ declare class DialogStore {
26
26
  close(closeImmediately?: boolean): void;
27
27
  }
28
28
  //#endregion
29
- //#region src/mobx-dialog/dialog.model.d.ts
29
+ //#region src/dialog/dialog.model.d.ts
30
30
  declare class DialogModel {
31
31
  readonly store: DialogStore;
32
32
  readonly config: DialogModelConfig;
@@ -42,7 +42,7 @@ declare class DialogModel {
42
42
  setState(state: DialogState): void;
43
43
  }
44
44
  //#endregion
45
- //#region src/mobx-dialog/components/dialogs.d.ts
45
+ //#region src/dialog/components/dialogs.d.ts
46
46
  interface MobxDialogsProps {
47
47
  store?: DialogStore;
48
48
  }
@@ -60,7 +60,7 @@ declare const MobxDialog: (({
60
60
  displayName: string;
61
61
  };
62
62
  //#endregion
63
- //#region src/mobx-dialog/dialog.context.d.ts
63
+ //#region src/dialog/dialog.context.d.ts
64
64
  declare const dialogStoreContext: _$react.Context<DialogStore | undefined>;
65
65
  declare const useDialogStore: () => DialogStore;
66
66
  declare const DialogStoreProvider: _$react.Provider<DialogStore | undefined>;
@@ -69,8 +69,8 @@ declare const useDialogContext: () => DialogModel;
69
69
  declare const useDialogContextIfAvailable: () => DialogModel | undefined;
70
70
  declare const DialogProvider: _$react.Provider<DialogModel | undefined>;
71
71
  //#endregion
72
- //#region src/mobx-dialog/use-dialogs.d.ts
72
+ //#region src/dialog/use-dialogs.d.ts
73
73
  declare const useDialogs: (store?: DialogStore) => DialogStore;
74
74
  //#endregion
75
75
  export { AnyComponent, DialogComponentAndProps, DialogModel, DialogModelConfig, DialogProvider, DialogState, DialogStore, DialogStoreProvider, MobxDialog, MobxDialogProps, MobxDialogs, MobxDialogsProps, dialogContext, dialogStoreContext, useDialogContext, useDialogContextIfAvailable, useDialogStore, useDialogs };
76
- //# sourceMappingURL=mobx-dialog.d.mts.map
76
+ //# sourceMappingURL=dialog.d.mts.map
@@ -0,0 +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,2 +1,2 @@
1
1
  import{observer as e}from"mobx-react-lite";import{createContext as t,useContext as n,useRef as r}from"react";import{makeAutoObservable as i}from"mobx";import{jsx as a}from"react/jsx-runtime";const o=t(void 0),s=()=>{let e=n(o);if(!e)throw Error(`Dialog store context not available. Are you using the <Dialogs /> component?`);return e},c=o.Provider,l=t(void 0),u=()=>{let e=n(l);if(!e)throw Error(`Dialog context not available. Are you using <DialogProvider /> ?`);return e},d=()=>n(l),f=l.Provider;var p=class{id;component;props;openedAt=0;previouslyFocusedElement=null;state;constructor(e,t){this.store=e,this.config=t,this.id=t.id??btoa(Math.random().toString()).substring(3,12),this.component=t.component,this.props=t.props,this.setState(t.initialState??`closed`),i(this,{id:!1,component:!1,props:!1,openedAt:!1,previouslyFocusedElement:!1})}close(e){this.setState(e?`closed`:`closing`)}open(e){this.setState(e?`opened`:`opening`)}setState(e){this.state!==e&&(this.state=e,e===`opened`||e===`opening`?(this.openedAt=Date.now(),e===`opening`&&(this.previouslyFocusedElement=document.activeElement instanceof HTMLElement?document.activeElement:null)):e===`closed`&&(this.previouslyFocusedElement?.focus(),this.config.removeOnClosed&&this.store.dialogs.delete(this.id),this.previouslyFocusedElement=null))}},m=class{dialogs=new Map;get openDialogs(){return[...this.dialogs.values()].filter(e=>e.state!==`closed`).sort((e,t)=>e.openedAt-t.openedAt)}get activeDialog(){return this.openDialogs.at(-1)}constructor(){i(this)}add(e){let t=new p(this,e);return this.dialogs.set(t.id,t),t}open(...e){let[t,n]=e;return this.add({component:t,props:n,removeOnClosed:!0,initialState:`opening`})}close(e){this.activeDialog?.close(e)}};const h=e=>{let t=r(e);return t.current||=new m,t.current},g=e(({store:e})=>{let t=h(e);return a(c,{value:t,children:t.openDialogs.map(e=>a(_,{dialog:e},e.id))})}),_=e(({dialog:e})=>{let{component:t,props:n}=e;return a(f,{value:e,children:a(t,{...n})})});export{p as DialogModel,f as DialogProvider,m as DialogStore,c as DialogStoreProvider,_ as MobxDialog,g as MobxDialogs,l as dialogContext,o as dialogStoreContext,u as useDialogContext,d as useDialogContextIfAvailable,s as useDialogStore,h as useDialogs};
2
- //# sourceMappingURL=mobx-dialog.mjs.map
2
+ //# sourceMappingURL=dialog.mjs.map
@@ -0,0 +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":"+LAIA,MAAa,EAAqB,EAAuC,IAAA,GAAU,CACtE,MAAuB,CAClC,IAAM,EAAU,EAAW,EAAmB,CAC9C,GAAI,CAAC,EACH,MAAU,MAAM,+EAA+E,CAEjG,OAAO,GAGI,EAAsB,EAAmB,SAEzC,EAAgB,EAAuC,IAAA,GAAU,CACjE,MAAyB,CACpC,IAAM,EAAU,EAAW,EAAc,CACzC,GAAI,CAAC,EACH,MAAU,MAAM,mEAAmE,CAErF,OAAO,GAGI,MAAoC,EAAW,EAAc,CAE7D,EAAiB,EAAc,SCtB5C,IAAa,EAAb,KAAyB,CACvB,GACA,UACA,MAEA,SAAW,EACX,yBAA+C,KAE/C,MAEA,YACE,EACA,EACA,CAFS,KAAA,MAAA,EACA,KAAA,OAAA,EAET,KAAK,GAAK,EAAO,IAAM,KAAK,KAAK,QAAQ,CAAC,UAAU,CAAC,CAAC,UAAU,EAAG,GAAG,CACtE,KAAK,UAAY,EAAO,UACxB,KAAK,MAAQ,EAAO,MAEpB,KAAK,SAAS,EAAO,cAAgB,SAAS,CAE9C,EAAmB,KAAM,CACvB,GAAI,GACJ,UAAW,GACX,MAAO,GACP,SAAU,GACV,yBAA0B,GAC3B,CAAC,CAGJ,MAAM,EAAkC,CACtC,KAAK,SAAS,EAAmB,SAAW,UAAU,CAGxD,KAAK,EAAiC,CACpC,KAAK,SAAS,EAAkB,SAAW,UAAU,CAGvD,SAAS,EAA0B,CAC7B,KAAK,QAAU,IAEnB,KAAK,MAAQ,EACT,IAAU,UAAY,IAAU,WAClC,KAAK,SAAW,KAAK,KAAK,CACtB,IAAU,YACZ,KAAK,yBACH,SAAS,yBAAyB,YAAc,SAAS,cAAgB,OAEpE,IAAU,WACnB,KAAK,0BAA0B,OAAO,CAClC,KAAK,OAAO,gBACd,KAAK,MAAM,QAAQ,OAAO,KAAK,GAAG,CAEpC,KAAK,yBAA2B,SCpDzB,EAAb,KAAyB,CACvB,QAAU,IAAI,IAEd,IAAI,aAA6B,CAC/B,MAAO,CAAC,GAAG,KAAK,QAAQ,QAAQ,CAAC,CAC9B,OAAQ,GAAM,EAAE,QAAU,SAAS,CACnC,MAAM,EAAI,IAAO,EAAG,SAAW,EAAG,SAAS,CAGhD,IAAI,cAAwC,CAC1C,OAAO,KAAK,YAAY,GAAG,GAAG,CAGhC,aAAc,CACZ,EAAmB,KAAK,CAG1B,IAAI,EAAwC,CAC1C,IAAM,EAAc,IAAI,EAAY,KAAM,EAAO,CAEjD,OADA,KAAK,QAAQ,IAAI,EAAY,GAAI,EAAY,CACtC,EAGT,KAA6B,GAAG,EAA+C,CAC7E,GAAM,CAAC,EAAW,GAAS,EAC3B,OAAO,KAAK,IAAI,CACd,YACA,QACA,eAAgB,GAChB,aAAc,UACf,CAAC,CAGJ,MAAM,EAAkC,CACtC,KAAK,cAAc,MAAM,EAAiB,GCnC9C,MAAa,EAAc,GAAqC,CAC9D,IAAM,EAAW,EAAgC,EAAM,CAIvD,MAHA,CACE,EAAS,UAAU,IAAI,EAElB,EAAS,SCEL,EAAc,GAAU,CAAE,WAA8B,CACnE,IAAM,EAAc,EAAW,EAAM,CAErC,OACE,EAAC,EAAD,CAAqB,MAAO,WACzB,EAAY,YAAY,IAAK,GACrB,EAAC,EAAD,CAAoC,SAAU,CAA7B,EAAO,GAAsB,CACrD,CACkB,CAAA,EAExB,CAMW,EAAa,GAAU,CAAE,YAA8B,CAClE,GAAM,CAAE,UAAW,EAAiB,MAAO,GAAgB,EAC3D,OACE,EAAC,EAAD,CAAgB,MAAO,WACrB,EAAC,EAAD,CAAiB,GAAI,EAAe,CAAA,CACrB,CAAA,EAEnB"}
@@ -3,7 +3,7 @@ import * as _$typebox from "typebox";
3
3
  import { Static, TObject, TSchema } from "typebox";
4
4
  import { Validator } from "typebox/schema";
5
5
 
6
- //#region src/mobx-form/form-field.model.d.ts
6
+ //#region src/form/form-field.model.d.ts
7
7
  declare class FormFieldModel<T extends TSchema = TSchema> {
8
8
  readonly name: string;
9
9
  readonly schema: T;
@@ -21,7 +21,7 @@ declare class FormFieldModel<T extends TSchema = TSchema> {
21
21
  toJSON(): Static<T> | undefined;
22
22
  }
23
23
  //#endregion
24
- //#region src/mobx-form/form.types.d.ts
24
+ //#region src/form/form.types.d.ts
25
25
  interface FormConfig<T extends TObject = TObject> {
26
26
  handleSubmit: (data: Static<T>) => Promise<unknown>;
27
27
  initialValues?: Partial<Static<T>>;
@@ -33,7 +33,7 @@ interface FormFieldConfig<T extends TSchema = TSchema> {
33
33
  }
34
34
  type FormFields<T extends TObject = TObject> = { [K in keyof T["properties"]]: FormFieldModel<T["properties"][K]> };
35
35
  //#endregion
36
- //#region src/mobx-form/form.model.d.ts
36
+ //#region src/form/form.model.d.ts
37
37
  declare class FormModel<T extends TObject = TObject> {
38
38
  readonly fields: FormFields<T>;
39
39
  readonly config: FormConfig<T>;
@@ -52,20 +52,20 @@ declare class FormModel<T extends TObject = TObject> {
52
52
  toJSON(): Partial<Static<T>>;
53
53
  }
54
54
  //#endregion
55
- //#region src/mobx-form/components/form.d.ts
55
+ //#region src/form/components/form.d.ts
56
56
  interface MobxFormProps extends Omit<React.HTMLProps<HTMLFormElement>, "form" | "action" | "method"> {
57
57
  form: FormModel<any>;
58
58
  }
59
59
  declare const MobxForm: _$react.ForwardRefExoticComponent<Omit<MobxFormProps, "ref"> & _$react.RefAttributes<unknown>>;
60
60
  //#endregion
61
- //#region src/mobx-form/form.context.d.ts
61
+ //#region src/form/form.context.d.ts
62
62
  declare const formContext: _$react.Context<FormModel<_$typebox.TObject<_$typebox.TProperties>> | undefined>;
63
63
  declare const useFormContext: () => FormModel<_$typebox.TObject<_$typebox.TProperties>>;
64
64
  declare const FormProvider: _$react.Provider<FormModel<_$typebox.TObject<_$typebox.TProperties>> | undefined>;
65
65
  declare const useFormContextIfAvailable: () => FormModel<_$typebox.TObject<_$typebox.TProperties>> | undefined;
66
66
  //#endregion
67
- //#region src/mobx-form/use-form.d.ts
67
+ //#region src/form/use-form.d.ts
68
68
  declare const useForm: <T extends TObject = TObject>(schema: T, config: FormConfig<T>) => FormModel<T>;
69
69
  //#endregion
70
70
  export { FormConfig, FormFieldConfig, FormFieldModel, FormFields, FormModel, FormProvider, MobxForm, MobxFormProps, formContext, useForm, useFormContext, useFormContextIfAvailable };
71
- //# sourceMappingURL=mobx-form.d.mts.map
71
+ //# sourceMappingURL=form.d.mts.map
@@ -0,0 +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/form.context.ts","../src/form/use-form.ts"],"mappings":";;;;;;cAUa,cAAA,WAAyB,OAAA,GAAU,OAAA;EAAA,SACrC,IAAA;EAAA,SACA,MAAA,EAAQ,CAAA;EAAA,SACR,MAAA,EAAQ,eAAA,CAAgB,CAAA;EAAA,SACxB,SAAA,EAAW,SAAA,CAAU,CAAA;EAE9B,KAAA,EAAO,MAAA,CAAO,CAAA;EACd,OAAA;EAAA,IAEI,KAAA,CAAA;EAAA,IAKA,YAAA,CAAA;EAOJ,WAAA,CAAY,MAAA,EAAQ,eAAA,CAAgB,CAAA;EAepC,QAAA,CAAS,KAAA,GAAQ,MAAA,CAAO,CAAA;EAMxB,UAAA,CAAW,OAAA;EAIX,KAAA,CAAA;EAQA,KAAA,CAAA;EAWA,MAAA,CAAA,GAAU,MAAA,CAAO,CAAA;AAAA;;;UCxEF,UAAA,WAAqB,OAAA,GAAU,OAAA;EAC9C,YAAA,GAAe,IAAA,EAAM,MAAA,CAAO,CAAA,MAAO,OAAA;EACnC,aAAA,GAAgB,OAAA,CAAQ,MAAA,CAAO,CAAA;AAAA;AAAA,UAGhB,eAAA,WAA0B,OAAA,GAAU,OAAA;EACnD,IAAA;EACA,MAAA,EAAQ,CAAA;EACR,YAAA,GAAe,MAAA,CAAO,CAAA;AAAA;AAAA,KAGZ,UAAA,WAAqB,OAAA,GAAU,OAAA,kBAC7B,CAAA,iBAAkB,cAAA,CAAe,CAAA,eAAgB,CAAA;;;cCyBlD,SAAA,WAAoB,OAAA,GAAU,OAAA;EAAA,SAChC,MAAA,EAAQ,UAAA,CAAW,CAAA;EAAA,SACnB,MAAA,EAAQ,UAAA,CAAW,CAAA;EAAA,SACnB,MAAA,EAAQ,CAAA;EAGjB,UAAA;EACA,SAAA;EAGA,WAAA;EAEA,WAAA,CAAY,MAAA,EAAQ,CAAA,EAAG,MAAA,EAAQ,UAAA,CAAW,CAAA;EAAA,IAmBtC,KAAA,CAAA;EAIJ,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;;;UC7HV,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;;;cCRR,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,OAAA,GAAU,OAAA,EAAO,MAAA,EACzC,CAAA,EAAC,MAAA,EACD,UAAA,CAAW,CAAA,MAClB,SAAA,CAAU,CAAA"}
@@ -1,2 +1,2 @@
1
1
  import{createContext as e,forwardRef as t,useContext as n,useRef as r}from"react";import{makeAutoObservable as i,toJS as a}from"mobx";import{jsx as o}from"react/jsx-runtime";import s from"typebox/format";import{Type as c}from"typebox";import l from"typebox/schema";import u from"typebox/value";const d=e(void 0),f=()=>{let e=n(d);if(!e)throw Error(`Form context not available. Make sure you are within the <Form> component or providing the form context manually.`);return e},p=d.Provider,m=()=>n(d),h=t(function({form:e,children:t,...n},r){return o(p,{value:e,children:o(`form`,{noValidate:!0,...n,ref:r,...e.props(),children:t})})});var g=class{name;schema;config;validator;value;touched=!1;get valid(){return this.value===void 0&&c.IsOptional(this.schema)?!0:this.validator.Check(this.value)}get errorMessage(){if(this.valid||!this.touched)return``;let[e,t]=this.validator.Errors(this.value);return t.at(0)?.message??``}constructor(e){i(this,{name:!1,schema:!1,config:!1,validator:!1}),this.config=e,this.name=e.name,this.schema=e.schema,this.validator=l.Compile(this.schema),this.setValue(e.initialValue)}setValue(e){this.value=u.Convert(this.schema,e)}setTouched(e){this.touched=e}reset(){this.setTouched(!1),this.setValue(this.config.initialValue)}props(){return{name:this.name,onChange:e=>this.setValue(e),value:this.value,onBlur:()=>{this.setTouched(!0)}}}toJSON(){return a(this.value)}};s.Set(`password`,()=>!0),s.Set(`phone`,()=>!0);var _=class{fields;config;schema;submitting=!1;submitted=!1;submitError;constructor(e,t){this.schema=e,this.config=t,i(this,{fields:!1,schema:!1,config:!1}),this.fields=Object.entries(e.properties).reduce((e,[n,r])=>(e[n]=new g({name:n,schema:r,initialValue:t?.initialValues?.[n]}),e),{})}get valid(){return Object.values(this.fields).every(e=>e.valid)}props(){return{onSubmit:e=>{e.preventDefault(),this.setSubmitError(void 0),this.validate()&&(this.setSubmitting(!0),this.config.handleSubmit(this.toJSON()).then(e=>(this.setSubmitted(!0),e)).catch(e=>{this.setSubmitError(e)}).finally(()=>{this.setSubmitting(!1)}))}}}setSubmitError(e){this.submitError=e}setSubmitting(e){this.submitting=e}setSubmitted(e){this.submitted=e}reset(){this.setSubmitError(void 0);for(let e of Object.values(this.fields))e.reset()}validate(){for(let e of Object.values(this.fields))e.setTouched(!0);return this.valid}toJSON(){return Object.values(this.fields).reduce((e,t)=>(e[t.name]=t.value,e),{})}};const v=(e,t)=>{let n=r(void 0);return n.current?Object.assign(n.current.config,t):n.current=new _(e,t),n.current};export{g as FormFieldModel,_ as FormModel,p as FormProvider,h as MobxForm,d as formContext,v as useForm,f as useFormContext,m as useFormContextIfAvailable};
2
- //# sourceMappingURL=mobx-form.mjs.map
2
+ //# sourceMappingURL=form.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"form.mjs","names":[],"sources":["../src/form/form.context.ts","../src/form/components/form.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 Schema, { Validator } from \"typebox/schema\";\nimport Value from \"typebox/value\";\nimport { type Static, type TSchema, Type } 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 TSchema = TSchema> {\n readonly name: string;\n readonly schema: T;\n readonly config: FormFieldConfig<T>;\n readonly validator: Validator<T>;\n\n value: Static<T> | undefined;\n touched = false;\n\n get valid(): boolean {\n if (this.value === undefined && Type.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 return errors.at(0)?.message ?? \"\";\n }\n\n constructor(config: FormFieldConfig<T>) {\n makeAutoObservable(this, {\n name: false,\n schema: false,\n config: false,\n validator: false,\n });\n\n this.config = config;\n this.name = config.name;\n this.schema = config.schema;\n this.validator = Schema.Compile(this.schema);\n this.setValue(config.initialValue);\n }\n\n setValue(value?: 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 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?: Static<T>) => this.setValue(v),\n value: this.value,\n onBlur: () => {\n this.setTouched(true);\n },\n };\n }\n\n toJSON(): Static<T> | undefined {\n return toJS(this.value);\n }\n}\n","import Format from \"typebox/format\";\nimport { type Static, type TObject, type TSchema } from \"typebox\";\nimport { makeAutoObservable } from \"mobx\";\nimport type { FormConfig, FormFields } 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/*\nSetErrorFunction((param) => {\n const { schema, value } = param;\n\n const message =\n typeof schema.errorMessage === \"function\" ? schema.errorMessage(param) : schema.errorMessage;\n\n if (message !== undefined) return message;\n\n if ((value === undefined || value === \"\") && !TypeGuard.IsOptional(schema)) {\n return \"This field is required.\";\n }\n\n if (Type.IsString(schema)) {\n if (Schema.IsFormat(schema) && schema.format === \"email\")\n return \"Please enter a valid email address.\";\n }\n\n return DefaultErrorFunction(param);\n});\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 TObject = TObject> {\n readonly fields: FormFields<T>;\n readonly config: FormConfig<T>;\n readonly schema: 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\n makeAutoObservable(this, { fields: false, schema: false, config: false });\n\n this.fields = Object.entries(schema.properties).reduce(\n (fields, [fieldName, fieldSchema]) => {\n fields[fieldName] = new FormFieldModel({\n name: fieldName,\n schema: fieldSchema,\n initialValue: config?.initialValues?.[fieldName],\n });\n return fields;\n },\n {} as Record<string, FormFieldModel<TSchema>>,\n ) as FormFields<T>;\n }\n\n get valid(): boolean {\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 return Object.values(this.fields).reduce(\n (fields, field) => {\n fields[field.name] = field.value;\n return fields;\n },\n {} as Partial<Static<T>>,\n );\n }\n}\n","import type { TObject } from \"typebox\";\nimport { useRef } from \"react\";\nimport { FormModel } from \"./form.model\";\nimport type { FormConfig } from \"./form.types\";\n\nexport const useForm = <T extends TObject = 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,9 +1,9 @@
1
1
  import * as _$react from "react";
2
- import React$1, { HTMLProps } from "react";
2
+ import React$1 from "react";
3
3
  import * as _$react_jsx_runtime0 from "react/jsx-runtime";
4
4
  import { History, Location } from "history";
5
5
 
6
- //#region src/mobx-router/outlet.d.ts
6
+ //#region src/router/outlet.d.ts
7
7
  interface OutletConfig {
8
8
  component?: Component | LazyComponent;
9
9
  loader?: Loader;
@@ -24,7 +24,7 @@ declare class Outlet {
24
24
  private loadComponent;
25
25
  }
26
26
  //#endregion
27
- //#region src/mobx-router/route.d.ts
27
+ //#region src/router/route.d.ts
28
28
  interface RouteConfig$1 {
29
29
  path: string;
30
30
  outlets: Outlet[];
@@ -45,7 +45,7 @@ declare class Route {
45
45
  load(): Promise<void>;
46
46
  }
47
47
  //#endregion
48
- //#region src/mobx-router/symbols.d.ts
48
+ //#region src/router/symbols.d.ts
49
49
  declare const CONTEXT: unique symbol;
50
50
  declare const LAYOUT: unique symbol;
51
51
  declare const WRAPPER: unique symbol;
@@ -54,7 +54,7 @@ declare const GUARD: unique symbol;
54
54
  declare const PAGE: unique symbol;
55
55
  declare const REDIRECT: unique symbol;
56
56
  //#endregion
57
- //#region src/mobx-router/types.d.ts
57
+ //#region src/router/types.d.ts
58
58
  type Component = React.FC<any>;
59
59
  type LazyComponent = () => Promise<any>;
60
60
  type Obj<T = any> = Record<string, T>;
@@ -113,34 +113,30 @@ type ExtractParam<P, NextPart> = P extends `:${infer Param}` ? Record<Param, str
113
113
  type ExtractParams<P> = P extends `${infer S1}/${infer Rest}` ? ExtractParam<S1, ExtractParams<Rest>> : ExtractParam<P, {}>;
114
114
  type ExtractPaths<R> = { [S in keyof R]: S extends string ? S extends "index" ? "/" : R[S] extends Leaf ? `/${S}` : JoinSegments<S, ExtractPaths<R[S]>> : never }[keyof R];
115
115
  //#endregion
116
- //#region src/mobx-router/components/link.d.ts
117
- interface LinkComponent<T> {
118
- <P extends StaticRoutePath>(props: T & {
116
+ //#region src/router/components/link.d.ts
117
+ type LinkComponentProps<C extends React$1.ElementType> = Omit<React$1.ComponentProps<C>, " ref" | "exact" | "to" | "params" | "onClick">;
118
+ type LinkPropsBase<C extends React$1.ElementType, I extends React$1.ElementType = C> = LinkComponentProps<C> & {
119
+ exact?: boolean;
120
+ ref?: React$1.Ref<React$1.ComponentRef<I>>;
121
+ };
122
+ interface LinkComponent<C extends React$1.ElementType, I extends React$1.ElementType = C> {
123
+ <P extends StaticRoutePath>(props: LinkPropsBase<C, I> & {
119
124
  to: P;
120
125
  params?: undefined;
121
126
  }): React$1.ReactNode;
122
- <P extends DynamicRoutePath>(props: T & {
127
+ <P extends DynamicRoutePath>(props: LinkPropsBase<C, I> & {
123
128
  to: P;
124
129
  params: ExtractParams<P>;
125
130
  }): React$1.ReactNode;
126
131
  }
127
- interface LinkPropsBase extends Omit<HTMLProps<HTMLAnchorElement>, "onClick" | "href"> {
128
- exact?: boolean;
129
- ref?: React$1.RefObject<HTMLAnchorElement>;
130
- }
131
- type Link = LinkComponent<LinkPropsBase>;
132
- type LinkProps = React$1.ComponentProps<Link>;
133
- declare const Link: Link & {
134
- displayName: string;
135
- };
136
- declare const makeLinkComponent: <C extends React$1.JSXElementConstructor<{
137
- children?: React$1.ReactNode;
138
- }>>(C: C) => LinkComponent<React$1.ComponentProps<C>>;
132
+ declare const makeLinkComponent: <C extends React$1.ElementType, I extends React$1.ElementType = C>(C: C, baseProps?: Partial<LinkComponentProps<C>> & {
133
+ as?: I;
134
+ }) => LinkComponent<C, I>;
139
135
  //#endregion
140
- //#region src/mobx-router/components/navigate.d.ts
136
+ //#region src/router/components/navigate.d.ts
141
137
  declare const Navigate: <P extends RoutePath>(props: NavigateOptions<P>) => null;
142
138
  //#endregion
143
- //#region src/mobx-router/router.store.d.ts
139
+ //#region src/router/router.store.d.ts
144
140
  interface MobxRenderSegment {
145
141
  segment: string;
146
142
  component: Component;
@@ -165,7 +161,7 @@ declare class RouterStore {
165
161
  setLocation(location: Location): Promise<void>;
166
162
  }
167
163
  //#endregion
168
- //#region src/mobx-router/components/router.d.ts
164
+ //#region src/router/components/router.d.ts
169
165
  declare const PassThrough: Component;
170
166
  declare const RouterOutlet: React.FC<{
171
167
  route: Route;
@@ -182,7 +178,7 @@ declare const Router: (({
182
178
  displayName: string;
183
179
  };
184
180
  //#endregion
185
- //#region src/mobx-router/make-routes.d.ts
181
+ //#region src/router/make-routes.d.ts
186
182
  interface MatchState {
187
183
  segments: string[];
188
184
  context: Obj;
@@ -195,14 +191,14 @@ declare const makeRoute: (matchState: MatchState) => Route;
195
191
  declare const matchRoute: (path: string, routeDef: Routes, matchState?: MatchState) => Route;
196
192
  declare const makeRoutes: () => <R extends Routes>(routes: R) => R;
197
193
  //#endregion
198
- //#region src/mobx-router/redirect.d.ts
194
+ //#region src/router/redirect.d.ts
199
195
  declare class Redirect<P extends RoutePath> {
200
196
  readonly options: NavigateOptions<P>;
201
197
  constructor(options: NavigateOptions<P>);
202
198
  }
203
199
  declare const redirect: <P extends RoutePath>(options: NavigateOptions<P>) => Redirect<P>;
204
200
  //#endregion
205
- //#region src/mobx-router/util.d.ts
201
+ //#region src/router/util.d.ts
206
202
  declare const resolvePath: (to: string, params?: Obj) => string;
207
203
  declare const isComponent: (data: any) => data is Component;
208
204
  declare const isPage: (data: any) => data is Page;
@@ -210,5 +206,5 @@ declare const isRedirect: (data: any) => data is Redirector;
210
206
  declare const isLeaf: (data: any) => data is Leaf;
211
207
  declare const isLazyComponent: (data: any) => data is LazyComponent;
212
208
  //#endregion
213
- export { CONTEXT, Component, DynamicRoutePath, ExtractParam, ExtractParams, ExtractPaths, GUARD, Guard, HasParam, JoinSegments, LAYOUT, LOAD, LazyComponent, Leaf, Link, LinkComponent, LinkProps, LinkPropsBase, Loader, MatchState, MobxRenderSegment, MobxRouter, MobxRouterConfig, MobxRouterRoutes, Navigate, NavigateOptions, Obj, PAGE, Page, PassThrough, REDIRECT, Redirect, Redirector, RouteConfig, RoutePath, Router, RouterOutlet, RouterProps, RouterStore, Routes, StaticRoutePath, WRAPPER, WithToAndParams, isComponent, isLazyComponent, isLeaf, isPage, isRedirect, makeLinkComponent, makeRoute, makeRoutes, matchRoute, redirect, resolvePath, routerContext, useRouter };
214
- //# sourceMappingURL=mobx-router.d.mts.map
209
+ export { CONTEXT, Component, DynamicRoutePath, ExtractParam, ExtractParams, ExtractPaths, GUARD, Guard, HasParam, JoinSegments, LAYOUT, LOAD, LazyComponent, Leaf, LinkComponent, LinkPropsBase, Loader, MatchState, MobxRenderSegment, MobxRouter, MobxRouterConfig, MobxRouterRoutes, Navigate, NavigateOptions, Obj, PAGE, Page, PassThrough, REDIRECT, Redirect, Redirector, RouteConfig, RoutePath, Router, RouterOutlet, RouterProps, RouterStore, Routes, StaticRoutePath, WRAPPER, WithToAndParams, isComponent, isLazyComponent, isLeaf, isPage, isRedirect, makeLinkComponent, makeRoute, makeRoutes, matchRoute, redirect, resolvePath, routerContext, useRouter };
210
+ //# sourceMappingURL=router.d.mts.map
@@ -0,0 +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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"}
@@ -0,0 +1,2 @@
1
+ import{observer as e}from"mobx-react-lite";import t,{createContext as n,useCallback as r,useContext as i,useLayoutEffect as a}from"react";import{action as o,computed as s,makeAutoObservable as c,observable as l}from"mobx";import{jsx as u}from"react/jsx-runtime";import{createBrowserHistory as d}from"history";const f=Symbol.for(`MOBX_ROUTER_CONTEXT`),p=Symbol.for(`MOBX_ROUTER_LAYOUT`),m=Symbol.for(`MOBX_ROUTER_WRAPPER`),h=Symbol.for(`MOBX_ROUTER_LOAD`),g=Symbol.for(`MOBX_ROUTER_GUARD`),_=Symbol.for(`MOBX_ROUTER_PAGE`),v=Symbol.for(`MOBX_ROUTER_REDIRECT`),y=(e,t)=>e.replaceAll(/:[^/]*/g,n=>{let r=t?.[n.slice(0)];if(!r)throw Error(`Unable to resolve route '${e}. Paramater '${n}' not specified.`);return r}),b=e=>e?typeof e==`function`||typeof e==`object`&&e.$$typeof===Symbol.for(`react.memo`):!1,x=e=>typeof e==`object`?Object.getOwnPropertySymbols(e).includes(_):!1,S=e=>typeof e==`object`?Object.getOwnPropertySymbols(e).includes(v):!1,C=e=>b(e)||x(e)||S(e),w=e=>typeof e==`function`&&e.toString().startsWith(`() => import(`),T=({children:e})=>e,E=e(({route:e,outlets:t})=>{let[n,...r]=t;if(!n)return null;let i=n.Component;return i?u(i,{route:e,children:r.length>0&&u(E,{route:e,outlets:r})}):null}),D=n(null),O=()=>i(D),k=e(({store:e})=>e.activeRoute?u(D.Provider,{value:e,children:u(E,{route:e.activeRoute,outlets:e.activeRoute.outlets})}):null),A=(n,i)=>e(({to:e,params:a,exact:o,children:s,...c})=>{let l=O(),u={...i,...c};return c.role!==`link`&&(u.href=y(e,a)),l.doesPathMatch(e,o)&&(u[`aria-current`]=`page`),u.onClick=r(t=>{t.preventDefault(),!c.disabled&&l.navigate({to:e,...a})},[l,a,e,c.disabled]),t.createElement(n,u,s)}),j=e=>{let t=O();return a(()=>{t.navigate(e)},[t,e]),null},M=({children:e})=>e;var N=class{@l accessor state=`preloading`;@l.ref accessor promise;@l.ref accessor data;@l.ref accessor component;@s get Component(){switch(this.state){case`loading`:return function(){return u(`p`,{children:`Loading...`})};case`ready`:return this.component??M;default:return}}constructor(e){this.config=e}@o async load(e){let t=[];if(w(this.config.component)?t.push(this.loadComponent()):this.component=this.config.component,this.config.loader&&t.push(this.loadData(e)),!t.length){this.setState(`ready`);return}let n=setTimeout(()=>{this.state===`preloading`&&this.setState(`loading`)},300);this.promise=Promise.all(t).then(()=>{clearTimeout(n),this.state===`loading`?setTimeout(()=>{this.setState(`ready`)},300):this.setState(`ready`)}).catch(()=>{clearTimeout(n),this.setState(`error`)}),await this.promise}@o setData(e){this.data=e}@o setState(e){this.state=e}async loadData(e){await this.config.loader?.(e).then(e=>this.setData(e))}async loadComponent(){if(!(this.component||!this.config.component))if(w(this.config.component)){let e=await this.config.component();for(let t in e)(t===`default`||t.endsWith(`Page`))&&(this.component=e[t])}else this.component=this.config.component}},P=class{constructor(e){this.options=e}};const F=e=>new P(e);var I=class{path;outlets;guards;context;params;@s get data(){return Object.assign({},...this.outlets.map(e=>e.data))}constructor(e){this.path=e.path,this.guards=e.guards,this.context=e.context??{},this.outlets=e.outlets,this.params=e.params}async guard(){for(let e of this.guards)await e(this)}async load(){await Promise.all(this.outlets.map(e=>e.load(this)))}};const L=e=>e.replace(/^\/+|\/+$/g,``).split(`/`),R=e=>{let t=e.outlets.filter(e=>e!==void 0),n=e.guards.filter(e=>e!==void 0);return e.layout&&t.unshift(new N({component:e.layout})),new I({...e,outlets:t,guards:n,path:e.segments.join(`/`)})},z=(e,t,n)=>{let r={segments:[],params:{},...n,layout:t[p]??n?.layout,context:{...n?.context,...t[f]},guards:[...n?.guards??[],t[g]],outlets:[...n?.outlets??[],t[m]?new N({component:t[m]}):void 0,t[h]?new N({loader:t[h]}):void 0]},[i,...a]=L(e),o=a.join(`/`),s=t[i||`index`];if(!s){let e=Object.keys(t).find(e=>e.startsWith(`$`));e&&(s=t[e],r.params[e.slice(1)]=i)}if(!s)throw Error(`Not Found.`);if(r.segments.push(i??`index`),C(s)){if(o)throw Error(`Not Found.`);if(S(s))throw new P(typeof s[v]==`string`?{to:s[v]}:s[v]);if(b(s)||w(s))return r.outlets.push(new N({component:s})),R(r)}return x(s)?(r.layout=s[p]??r.layout,Object.assign(r.context,s[f]),r.guards.push(s[g]),r.outlets.push(new N({component:s[_],loader:s[h]})),R(r)):z(o,s,r)},B=()=>e=>e;var V=class{history;routesDef;location;activeRoute;get search(){return new URLSearchParams(this.location?.search)}get query(){return Object.fromEntries(this.search)}get pathParams(){let e={},t=this.activeSegments.filter(e=>e.startsWith(`$`)),n=this.location.pathname.split(`/`).slice(1);return t.forEach((t,r)=>{let i=n[r+1];i&&(e[t]=i)}),e}get activeSegments(){return this.activeRoute?.path.split(`/`)??[]}constructor(e){c({history:!1,routesDef:!1}),this.history=e?.history??d()}initialize(e){this.routesDef=e,this.history.listen(e=>{this.setLocation(e.location)}),this.setLocation(this.history.location)}doesPathMatch(e,t){let n=e.slice(1).split(`/`);return n.every((e,t)=>e===this.activeSegments[t]||e.startsWith(`$`))&&this.activeSegments.length>=n.length&&(!t||n.length===this.activeSegments.length)}navigate(e){document.startViewTransition?document.startViewTransition(()=>this._navigate(e)).ready.catch(e=>console.log(e,typeof e)):this._navigate(e)}_navigate(e){let{to:t,replace:n,state:r,search:i={},preserveSearch:a,params:o}=e,s=i instanceof URLSearchParams?i:new URLSearchParams(i);if(a)for(let[e,t]of this.search)s.has(e)||s.set(e,t);let c={pathname:y(t,o),search:s.size?`?${s.toString()}`:void 0};n?this.history.replace(c,r):this.history.push(c,r)}setQueryParam(e,t){this.search.set(e,t),this.history.replace({search:this.search.toString()})}removeQueryParam(e){let t=new URLSearchParams(this.location.search),n=t.get(e)??void 0;return n!==void 0&&(t.delete(e),this.history.replace({search:t.toString()})),n}async setLocation(e){if(this.routesDef){if(e.pathname!==`/`&&e.pathname.endsWith(`/`)){this.history.replace({...e,pathname:e.pathname.slice(0,-1)});return}this.location=e;try{let t=z(e.pathname,this.routesDef);if(await t.guard(),this.location!==e)return;this.activeRoute=t,await this.activeRoute?.load()}catch(e){if(e instanceof P){this.navigate(e.options);return}throw e}}}};export{f as CONTEXT,g as GUARD,p as LAYOUT,h as LOAD,j as Navigate,_ as PAGE,T as PassThrough,v as REDIRECT,P as Redirect,k as Router,E as RouterOutlet,V as RouterStore,m as WRAPPER,b as isComponent,w as isLazyComponent,C as isLeaf,x as isPage,S as isRedirect,A as makeLinkComponent,R as makeRoute,B as makeRoutes,z as matchRoute,F as redirect,y as resolvePath,D as routerContext,O as useRouter};
2
+ //# sourceMappingURL=router.mjs.map
@@ -0,0 +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(0)];\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 { Outlet } from \"../outlet\";\nimport type { Route } from \"../route\";\nimport type { RouterStore } from \"../router.store\";\nimport type { Component } from \"../types\";\n\nexport const PassThrough: Component = ({ children }) => children;\n\nexport const RouterOutlet: React.FC<{ route: Route; outlets: Outlet[] }> = observer(\n ({ route, outlets }) => {\n const [outlet, ...remainingOutlets] = outlets;\n\n if (!outlet) return null;\n\n const C = outlet.Component;\n\n if (!C) return null;\n\n return (\n <C route={route}>\n {remainingOutlets.length > 0 && <RouterOutlet route={route} outlets={remainingOutlets} />}\n </C>\n );\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 return (\n <routerContext.Provider value={store}>\n <RouterOutlet route={store.activeRoute} outlets={store.activeRoute.outlets} />\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 { action, computed, 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\nexport class Outlet {\n @observable accessor state: RouteSegmentState = \"preloading\";\n @observable.ref accessor promise: Promise<unknown> | undefined;\n @observable.ref accessor data: unknown;\n @observable.ref accessor component: Component | undefined;\n\n @computed get Component(): Component | undefined {\n switch (this.state) {\n case \"loading\":\n return function Loading() {\n return <p>Loading...</p>;\n };\n\n case \"ready\":\n return this.component ?? DefaultOutlet;\n\n default:\n return undefined;\n }\n }\n\n constructor(readonly config: OutletConfig) {}\n\n @action\n async load(route: Route): Promise<void> {\n const promises: Promise<void>[] = [];\n\n if (isLazyComponent(this.config.component)) {\n promises.push(this.loadComponent());\n } else {\n this.component = this.config.component;\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 @action\n setData(data: unknown) {\n this.data = data;\n }\n\n @action\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 (this.component || !this.config.component) {\n return;\n }\n\n if (isLazyComponent(this.config.component)) {\n const importResult = await this.config.component();\n for (const exportName in importResult) {\n if (exportName === \"default\" || exportName.endsWith(\"Page\")) {\n this.component = importResult[exportName];\n }\n }\n } else {\n this.component = this.config.component;\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 } 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\n @computed 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 }\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 if (matchState.layout) {\n outlets.unshift(new Outlet({ component: matchState.layout }));\n }\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 { makeAutoObservable } 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 makeAutoObservable({\n history: false,\n routesDef: false,\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 this.search.set(param, value);\n this.history.replace({ search: this.search.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 this.activeRoute = matchedRoute;\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,7 +1,7 @@
1
1
  import { IAutorunOptions, IObservableArray, IReactionPublic } from "mobx";
2
2
  import { ClassAccessorDecorator } from "mobx/dist/types/decorator_fills";
3
3
 
4
- //#region src/mobx-util/lazy-observable.d.ts
4
+ //#region src/util/lazy-observable.d.ts
5
5
  interface LazyObservable<T = any, TInitialValue = T | undefined> {
6
6
  value: TInitialValue;
7
7
  reset(): TInitialValue;
@@ -32,11 +32,11 @@ interface LazyObservableArrayOptions<T> extends LazyObservableOptions {
32
32
  declare function lazyObservableArray<T>(fetch: () => Promise<T[]>, options?: LazyObservableArrayOptions<T>): LazyObservableArray<T>;
33
33
  type InferLazyObservable<O> = O extends LazyObservableArray<infer T> ? T[] : O extends LazyObservable<infer T> ? T : never;
34
34
  //#endregion
35
- //#region src/mobx-util/mutable.d.ts
35
+ //#region src/util/mutable.d.ts
36
36
  declare const mutable: ClassAccessorDecorator;
37
37
  //#endregion
38
- //#region src/mobx-util/use-autorun.d.ts
38
+ //#region src/util/use-autorun.d.ts
39
39
  declare function useAutorun(func: (r: IReactionPublic) => unknown, options?: IAutorunOptions): void;
40
40
  //#endregion
41
41
  export { InferLazyObservable, LazyObservable, LazyObservableArray, LazyObservableArrayOptions, LazyObservableOptions, LazyObservableOptionsWithInitialValue, lazyObservable, lazyObservableArray, mutable, useAutorun };
42
- //# sourceMappingURL=mobx-util.d.mts.map
42
+ //# sourceMappingURL=util.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"util.d.mts","names":[],"sources":["../src/util/lazy-observable.ts","../src/util/mutable.ts","../src/util/use-autorun.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,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,UAiJJ,mBAAA,YAA+B,IAAA,CAAK,cAAA,CAAe,gBAAA,CAAiB,CAAA;EACnF,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;;;cCvMxE,OAAA,EAAS,sBAAA;;;iBCAN,UAAA,CAAW,IAAA,GAAO,CAAA,EAAG,eAAA,cAA6B,OAAA,GAAU,eAAA"}
@@ -1,2 +1,2 @@
1
1
  import{useEffect as e}from"react";import{_allowStateChanges as t,autorun as n,observable as r,onBecomeObserved as i,onBecomeUnobserved as a,runInAction as o}from"mobx";function s(e,o){let s=r.box(o?.initialValue,{deep:!o?.shallow}),c=r.box(`init`),l,u,d,f,p,m=()=>(d&&c.get()!==`loaded`&&c.get()!==`error`||(d=new Promise((e,t)=>{f=e,p=t})),d),h=()=>(clearTimeout(l),u?.(),t(!0,()=>{s.set(o?.initialValue),c.set(`init`)}),o?.initialValue),g=()=>{c.get()!==`loading`&&(clearTimeout(l),u?.(),u=n(()=>{t(!0,()=>{c.set(`loading`)}),e().then(e=>{t(!0,()=>{s.set(e),c.set(`loaded`),f?.(e)})}).catch(e=>{t(!0,()=>{c.set(`error`),p?.(e)})})}))},_=e=>{t(!0,()=>{s.set(e),c.set(`loaded`)})},v=0,y=()=>{v=Math.min(2,v+1),v===1&&(o?.debugName&&console.log(`lazyObservable ${o.debugName}`,`observed`),clearTimeout(l),(c.get()===`error`||c.get()===`init`)&&g())},b=()=>{v=Math.max(0,v-1),!v&&(o?.debugName&&console.log(`lazyObservable ${o.debugName}`,`unobserved`),o?.resetOnUnobserved!==`never`&&(typeof o?.resetOnUnobserved==`number`?l=setTimeout(()=>{h()},o?.resetOnUnobserved):h()))};return i(s,y),i(c,y),a(s,b),a(c,b),{get value(){return s.get()},get status(){return c.get()},get loading(){return c.get()===`loading`},get loaded(){return c.get()===`loaded`},reload(){let e=m();return g(),e},getOrLoad(){return this.loaded?Promise.resolve(s.get()):this.reload()},set:_,reset:h}}function c(e,t){return s(e,{initialValue:[],...t})}const l=e=>{let t=new WeakMap;return{get(){let n=t.get(this);if(!n){let i=e.get.call(this);n=r.box(i),t.set(this,n)}return n.get()},set(e){let n=t.get(this);n||(n=r.box(e),t.set(this,n)),o(()=>n.set(e))}}};function u(t,r){e(()=>n(t,r),[])}export{s as lazyObservable,c as lazyObservableArray,l as mutable,u as useAutorun};
2
- //# sourceMappingURL=mobx-util.mjs.map
2
+ //# sourceMappingURL=util.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"util.mjs","names":[],"sources":["../src/util/lazy-observable.ts","../src/util/mutable.ts","../src/util/use-autorun.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 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\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 });\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 });\n fetch()\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 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 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\n onBecomeUnobserved(value, onUnobserved);\n onBecomeUnobserved(status, onUnobserved);\n\n return {\n get value() {\n return value.get();\n },\n get status() {\n return status.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> extends Omit<LazyObservable<IObservableArray<T>>, \"set\"> {\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","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":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jayalfredprufrock/mobx-toolbox",
3
- "version": "0.1.1",
3
+ "version": "0.2.1",
4
4
  "description": "Misc mobx/react modules/utilities.",
5
5
  "homepage": "https://github.com/jayalfredprufrock/mobx-toolbox#readme",
6
6
  "bugs": {
@@ -16,24 +16,13 @@
16
16
  "dist"
17
17
  ],
18
18
  "exports": {
19
- "./mobx-dialog": "./src/mobx-dialog/index.ts",
20
- "./mobx-form": "./src/mobx-form/index.ts",
21
- "./mobx-router": "./src/mobx-router/index.ts",
22
- "./mobx-util": "./src/mobx-util/index.ts",
23
- "./react-util": "./src/react-util/index.ts",
19
+ "./dialog": "./dist/dialog.mjs",
20
+ "./form": "./dist/form.mjs",
21
+ "./react-util": "./dist/react-util.mjs",
22
+ "./router": "./dist/router.mjs",
23
+ "./util": "./dist/util.mjs",
24
24
  "./package.json": "./package.json"
25
25
  },
26
- "publishConfig": {
27
- "access": "public",
28
- "exports": {
29
- "./mobx-dialog": "./dist/mobx-dialog.mjs",
30
- "./mobx-form": "./dist/mobx-form.mjs",
31
- "./mobx-router": "./dist/mobx-router.mjs",
32
- "./mobx-util": "./dist/mobx-util.mjs",
33
- "./react-util": "./dist/react-util.mjs",
34
- "./package.json": "./package.json"
35
- }
36
- },
37
26
  "scripts": {
38
27
  "dev": "vp run -r dev",
39
28
  "prepare": "vp config"
@@ -1 +0,0 @@
1
- {"version":3,"file":"mobx-dialog.d.mts","names":[],"sources":["../src/mobx-dialog/dialog.types.ts","../src/mobx-dialog/dialog.store.ts","../src/mobx-dialog/dialog.model.ts","../src/mobx-dialog/components/dialogs.tsx","../src/mobx-dialog/dialog.context.ts","../src/mobx-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 +0,0 @@
1
- {"version":3,"file":"mobx-dialog.mjs","names":[],"sources":["../src/mobx-dialog/dialog.context.ts","../src/mobx-dialog/dialog.model.ts","../src/mobx-dialog/dialog.store.ts","../src/mobx-dialog/use-dialogs.ts","../src/mobx-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":"+LAIA,MAAa,EAAqB,EAAuC,IAAA,GAAU,CACtE,MAAuB,CAClC,IAAM,EAAU,EAAW,EAAmB,CAC9C,GAAI,CAAC,EACH,MAAU,MAAM,+EAA+E,CAEjG,OAAO,GAGI,EAAsB,EAAmB,SAEzC,EAAgB,EAAuC,IAAA,GAAU,CACjE,MAAyB,CACpC,IAAM,EAAU,EAAW,EAAc,CACzC,GAAI,CAAC,EACH,MAAU,MAAM,mEAAmE,CAErF,OAAO,GAGI,MAAoC,EAAW,EAAc,CAE7D,EAAiB,EAAc,SCtB5C,IAAa,EAAb,KAAyB,CACvB,GACA,UACA,MAEA,SAAW,EACX,yBAA+C,KAE/C,MAEA,YACE,EACA,EACA,CAFS,KAAA,MAAA,EACA,KAAA,OAAA,EAET,KAAK,GAAK,EAAO,IAAM,KAAK,KAAK,QAAQ,CAAC,UAAU,CAAC,CAAC,UAAU,EAAG,GAAG,CACtE,KAAK,UAAY,EAAO,UACxB,KAAK,MAAQ,EAAO,MAEpB,KAAK,SAAS,EAAO,cAAgB,SAAS,CAE9C,EAAmB,KAAM,CACvB,GAAI,GACJ,UAAW,GACX,MAAO,GACP,SAAU,GACV,yBAA0B,GAC3B,CAAC,CAGJ,MAAM,EAAkC,CACtC,KAAK,SAAS,EAAmB,SAAW,UAAU,CAGxD,KAAK,EAAiC,CACpC,KAAK,SAAS,EAAkB,SAAW,UAAU,CAGvD,SAAS,EAA0B,CAC7B,KAAK,QAAU,IAEnB,KAAK,MAAQ,EACT,IAAU,UAAY,IAAU,WAClC,KAAK,SAAW,KAAK,KAAK,CACtB,IAAU,YACZ,KAAK,yBACH,SAAS,yBAAyB,YAAc,SAAS,cAAgB,OAEpE,IAAU,WACnB,KAAK,0BAA0B,OAAO,CAClC,KAAK,OAAO,gBACd,KAAK,MAAM,QAAQ,OAAO,KAAK,GAAG,CAEpC,KAAK,yBAA2B,SCpDzB,EAAb,KAAyB,CACvB,QAAU,IAAI,IAEd,IAAI,aAA6B,CAC/B,MAAO,CAAC,GAAG,KAAK,QAAQ,QAAQ,CAAC,CAC9B,OAAQ,GAAM,EAAE,QAAU,SAAS,CACnC,MAAM,EAAI,IAAO,EAAG,SAAW,EAAG,SAAS,CAGhD,IAAI,cAAwC,CAC1C,OAAO,KAAK,YAAY,GAAG,GAAG,CAGhC,aAAc,CACZ,EAAmB,KAAK,CAG1B,IAAI,EAAwC,CAC1C,IAAM,EAAc,IAAI,EAAY,KAAM,EAAO,CAEjD,OADA,KAAK,QAAQ,IAAI,EAAY,GAAI,EAAY,CACtC,EAGT,KAA6B,GAAG,EAA+C,CAC7E,GAAM,CAAC,EAAW,GAAS,EAC3B,OAAO,KAAK,IAAI,CACd,YACA,QACA,eAAgB,GAChB,aAAc,UACf,CAAC,CAGJ,MAAM,EAAkC,CACtC,KAAK,cAAc,MAAM,EAAiB,GCnC9C,MAAa,EAAc,GAAqC,CAC9D,IAAM,EAAW,EAAgC,EAAM,CAIvD,MAHA,CACE,EAAS,UAAU,IAAI,EAElB,EAAS,SCEL,EAAc,GAAU,CAAE,WAA8B,CACnE,IAAM,EAAc,EAAW,EAAM,CAErC,OACE,EAAC,EAAD,CAAqB,MAAO,WACzB,EAAY,YAAY,IAAK,GACrB,EAAC,EAAD,CAAoC,SAAU,CAA7B,EAAO,GAAsB,CACrD,CACkB,CAAA,EAExB,CAMW,EAAa,GAAU,CAAE,YAA8B,CAClE,GAAM,CAAE,UAAW,EAAiB,MAAO,GAAgB,EAC3D,OACE,EAAC,EAAD,CAAgB,MAAO,WACrB,EAAC,EAAD,CAAiB,GAAI,EAAe,CAAA,CACrB,CAAA,EAEnB"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"mobx-form.d.mts","names":[],"sources":["../src/mobx-form/form-field.model.ts","../src/mobx-form/form.types.ts","../src/mobx-form/form.model.ts","../src/mobx-form/components/form.tsx","../src/mobx-form/form.context.ts","../src/mobx-form/use-form.ts"],"mappings":";;;;;;cAUa,cAAA,WAAyB,OAAA,GAAU,OAAA;EAAA,SACrC,IAAA;EAAA,SACA,MAAA,EAAQ,CAAA;EAAA,SACR,MAAA,EAAQ,eAAA,CAAgB,CAAA;EAAA,SACxB,SAAA,EAAW,SAAA,CAAU,CAAA;EAE9B,KAAA,EAAO,MAAA,CAAO,CAAA;EACd,OAAA;EAAA,IAEI,KAAA,CAAA;EAAA,IAKA,YAAA,CAAA;EAOJ,WAAA,CAAY,MAAA,EAAQ,eAAA,CAAgB,CAAA;EAepC,QAAA,CAAS,KAAA,GAAQ,MAAA,CAAO,CAAA;EAMxB,UAAA,CAAW,OAAA;EAIX,KAAA,CAAA;EAQA,KAAA,CAAA;EAWA,MAAA,CAAA,GAAU,MAAA,CAAO,CAAA;AAAA;;;UCxEF,UAAA,WAAqB,OAAA,GAAU,OAAA;EAC9C,YAAA,GAAe,IAAA,EAAM,MAAA,CAAO,CAAA,MAAO,OAAA;EACnC,aAAA,GAAgB,OAAA,CAAQ,MAAA,CAAO,CAAA;AAAA;AAAA,UAGhB,eAAA,WAA0B,OAAA,GAAU,OAAA;EACnD,IAAA;EACA,MAAA,EAAQ,CAAA;EACR,YAAA,GAAe,MAAA,CAAO,CAAA;AAAA;AAAA,KAGZ,UAAA,WAAqB,OAAA,GAAU,OAAA,kBAC7B,CAAA,iBAAkB,cAAA,CAAe,CAAA,eAAgB,CAAA;;;cCyBlD,SAAA,WAAoB,OAAA,GAAU,OAAA;EAAA,SAChC,MAAA,EAAQ,UAAA,CAAW,CAAA;EAAA,SACnB,MAAA,EAAQ,UAAA,CAAW,CAAA;EAAA,SACnB,MAAA,EAAQ,CAAA;EAGjB,UAAA;EACA,SAAA;EAGA,WAAA;EAEA,WAAA,CAAY,MAAA,EAAQ,CAAA,EAAG,MAAA,EAAQ,UAAA,CAAW,CAAA;EAAA,IAmBtC,KAAA,CAAA;EAIJ,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;;;UC7HV,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;;;cCRR,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,OAAA,GAAU,OAAA,EAAO,MAAA,EACzC,CAAA,EAAC,MAAA,EACD,UAAA,CAAW,CAAA,MAClB,SAAA,CAAU,CAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"mobx-form.mjs","names":[],"sources":["../src/mobx-form/form.context.ts","../src/mobx-form/components/form.tsx","../src/mobx-form/form-field.model.ts","../src/mobx-form/form.model.ts","../src/mobx-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 Schema, { Validator } from \"typebox/schema\";\nimport Value from \"typebox/value\";\nimport { type Static, type TSchema, Type } 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 TSchema = TSchema> {\n readonly name: string;\n readonly schema: T;\n readonly config: FormFieldConfig<T>;\n readonly validator: Validator<T>;\n\n value: Static<T> | undefined;\n touched = false;\n\n get valid(): boolean {\n if (this.value === undefined && Type.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 return errors.at(0)?.message ?? \"\";\n }\n\n constructor(config: FormFieldConfig<T>) {\n makeAutoObservable(this, {\n name: false,\n schema: false,\n config: false,\n validator: false,\n });\n\n this.config = config;\n this.name = config.name;\n this.schema = config.schema;\n this.validator = Schema.Compile(this.schema);\n this.setValue(config.initialValue);\n }\n\n setValue(value?: 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 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?: Static<T>) => this.setValue(v),\n value: this.value,\n onBlur: () => {\n this.setTouched(true);\n },\n };\n }\n\n toJSON(): Static<T> | undefined {\n return toJS(this.value);\n }\n}\n","import Format from \"typebox/format\";\nimport { type Static, type TObject, type TSchema } from \"typebox\";\nimport { makeAutoObservable } from \"mobx\";\nimport type { FormConfig, FormFields } 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/*\nSetErrorFunction((param) => {\n const { schema, value } = param;\n\n const message =\n typeof schema.errorMessage === \"function\" ? schema.errorMessage(param) : schema.errorMessage;\n\n if (message !== undefined) return message;\n\n if ((value === undefined || value === \"\") && !TypeGuard.IsOptional(schema)) {\n return \"This field is required.\";\n }\n\n if (Type.IsString(schema)) {\n if (Schema.IsFormat(schema) && schema.format === \"email\")\n return \"Please enter a valid email address.\";\n }\n\n return DefaultErrorFunction(param);\n});\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 TObject = TObject> {\n readonly fields: FormFields<T>;\n readonly config: FormConfig<T>;\n readonly schema: 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\n makeAutoObservable(this, { fields: false, schema: false, config: false });\n\n this.fields = Object.entries(schema.properties).reduce(\n (fields, [fieldName, fieldSchema]) => {\n fields[fieldName] = new FormFieldModel({\n name: fieldName,\n schema: fieldSchema,\n initialValue: config?.initialValues?.[fieldName],\n });\n return fields;\n },\n {} as Record<string, FormFieldModel<TSchema>>,\n ) as FormFields<T>;\n }\n\n get valid(): boolean {\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 return Object.values(this.fields).reduce(\n (fields, field) => {\n fields[field.name] = field.value;\n return fields;\n },\n {} as Partial<Static<T>>,\n );\n }\n}\n","import type { TObject } from \"typebox\";\nimport { useRef } from \"react\";\nimport { FormModel } from \"./form.model\";\nimport type { FormConfig } from \"./form.types\";\n\nexport const useForm = <T extends TObject = 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 +0,0 @@
1
- {"version":3,"file":"mobx-router.d.mts","names":[],"sources":["../src/mobx-router/outlet.tsx","../src/mobx-router/route.tsx","../src/mobx-router/symbols.ts","../src/mobx-router/types.ts","../src/mobx-router/components/link.tsx","../src/mobx-router/components/navigate.tsx","../src/mobx-router/router.store.ts","../src/mobx-router/components/router.tsx","../src/mobx-router/make-routes.tsx","../src/mobx-router/redirect.ts","../src/mobx-router/util.ts"],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- import{observer as e}from"mobx-react-lite";import{createContext as t,useCallback as n,useContext as r,useLayoutEffect as i}from"react";import{action as a,computed as o,makeAutoObservable as s,observable as c}from"mobx";import{jsx as l}from"react/jsx-runtime";import{createBrowserHistory as u}from"history";const d=Symbol.for(`MOBX_ROUTER_CONTEXT`),f=Symbol.for(`MOBX_ROUTER_LAYOUT`),p=Symbol.for(`MOBX_ROUTER_WRAPPER`),m=Symbol.for(`MOBX_ROUTER_LOAD`),h=Symbol.for(`MOBX_ROUTER_GUARD`),g=Symbol.for(`MOBX_ROUTER_PAGE`),_=Symbol.for(`MOBX_ROUTER_REDIRECT`),v=(e,t)=>e.replaceAll(/:[^/]*/g,n=>{let r=t?.[n.slice(0)];if(!r)throw Error(`Unable to resolve route '${e}. Paramater '${n}' not specified.`);return r}),y=e=>e?typeof e==`function`||typeof e==`object`&&e.$$typeof===Symbol.for(`react.memo`):!1,b=e=>typeof e==`object`?Object.getOwnPropertySymbols(e).includes(g):!1,x=e=>typeof e==`object`?Object.getOwnPropertySymbols(e).includes(_):!1,S=e=>y(e)||b(e)||x(e),C=e=>typeof e==`function`&&e.toString().startsWith(`() => import(`),w=({children:e})=>e,T=e(({route:e,outlets:t})=>{let[n,...r]=t;if(!n)return null;let i=n.Component;return i?l(i,{route:e,children:r.length>0&&l(T,{route:e,outlets:r})}):null}),E=t(null),D=()=>r(E),O=e(({store:e})=>e.activeRoute?l(E.Provider,{value:e,children:l(T,{route:e.activeRoute,outlets:e.activeRoute.outlets})}):null),k=e((({to:e,params:t,exact:r,children:i,...a})=>{let o=D(),s=v(e,t),c=o.doesPathMatch(e,r)?{"aria-current":`page`}:void 0,u=n(n=>{n.preventDefault(),o.navigate({to:e,...t})},[o,t,e]);return l(`a`,{href:s,...a,...c,onClick:u,children:i})})),A=e=>(({children:t,to:n,params:r,...i})=>l(e,{...i,children:l(k,{to:n,params:r,children:t})})),j=e=>{let t=D();return i(()=>{t.navigate(e)},[t,e]),null},M=({children:e})=>e;var N=class{@c accessor state=`preloading`;@c.ref accessor promise;@c.ref accessor data;@c.ref accessor component;@o get Component(){switch(this.state){case`loading`:return function(){return l(`p`,{children:`Loading...`})};case`ready`:return this.component??M;default:return}}constructor(e){this.config=e}@a async load(e){let t=[];if(C(this.config.component)?t.push(this.loadComponent()):this.component=this.config.component,this.config.loader&&t.push(this.loadData(e)),!t.length){this.setState(`ready`);return}let n=setTimeout(()=>{this.state===`preloading`&&this.setState(`loading`)},300);this.promise=Promise.all(t).then(()=>{clearTimeout(n),this.state===`loading`?setTimeout(()=>{this.setState(`ready`)},300):this.setState(`ready`)}).catch(()=>{clearTimeout(n),this.setState(`error`)}),await this.promise}@a setData(e){this.data=e}@a setState(e){this.state=e}async loadData(e){await this.config.loader?.(e).then(e=>this.setData(e))}async loadComponent(){if(!(this.component||!this.config.component))if(C(this.config.component)){let e=await this.config.component();for(let t in e)(t===`default`||t.endsWith(`Page`))&&(this.component=e[t])}else this.component=this.config.component}},P=class{constructor(e){this.options=e}};const F=e=>new P(e);var I=class{path;outlets;guards;context;params;@o get data(){return Object.assign({},...this.outlets.map(e=>e.data))}constructor(e){this.path=e.path,this.guards=e.guards,this.context=e.context??{},this.outlets=e.outlets,this.params=e.params}async guard(){for(let e of this.guards)await e(this)}async load(){await Promise.all(this.outlets.map(e=>e.load(this)))}};const L=e=>e.replace(/^\/+|\/+$/g,``).split(`/`),R=e=>{let t=e.outlets.filter(e=>e!==void 0),n=e.guards.filter(e=>e!==void 0);return e.layout&&t.unshift(new N({component:e.layout})),new I({...e,outlets:t,guards:n,path:e.segments.join(`/`)})},z=(e,t,n)=>{let r={segments:[],params:{},...n,layout:t[f]??n?.layout,context:{...n?.context,...t[d]},guards:[...n?.guards??[],t[h]],outlets:[...n?.outlets??[],t[p]?new N({component:t[p]}):void 0,t[m]?new N({loader:t[m]}):void 0]},[i,...a]=L(e),o=a.join(`/`),s=t[i||`index`];if(!s){let e=Object.keys(t).find(e=>e.startsWith(`$`));e&&(s=t[e],r.params[e.slice(1)]=i)}if(!s)throw Error(`Not Found.`);if(r.segments.push(i??`index`),S(s)){if(o)throw Error(`Not Found.`);if(x(s))throw new P(typeof s[_]==`string`?{to:s[_]}:s[_]);if(y(s)||C(s))return r.outlets.push(new N({component:s})),R(r)}return b(s)?(r.layout=s[f]??r.layout,Object.assign(r.context,s[d]),r.guards.push(s[h]),r.outlets.push(new N({component:s[g],loader:s[m]})),R(r)):z(o,s,r)},B=()=>e=>e;var V=class{history;routesDef;location;activeRoute;get search(){return new URLSearchParams(this.location?.search)}get query(){return Object.fromEntries(this.search)}get pathParams(){let e={},t=this.activeSegments.filter(e=>e.startsWith(`$`)),n=this.location.pathname.split(`/`).slice(1);return t.forEach((t,r)=>{let i=n[r+1];i&&(e[t]=i)}),e}get activeSegments(){return this.activeRoute?.path.split(`/`)??[]}constructor(e){s({history:!1,routesDef:!1}),this.history=e?.history??u()}initialize(e){this.routesDef=e,this.history.listen(e=>{this.setLocation(e.location)}),this.setLocation(this.history.location)}doesPathMatch(e,t){let n=e.slice(1).split(`/`);return n.every((e,t)=>e===this.activeSegments[t]||e.startsWith(`$`))&&this.activeSegments.length>=n.length&&(!t||n.length===this.activeSegments.length)}navigate(e){document.startViewTransition?document.startViewTransition(()=>this._navigate(e)).ready.catch(e=>console.log(e,typeof e)):this._navigate(e)}_navigate(e){let{to:t,replace:n,state:r,search:i={},preserveSearch:a,params:o}=e,s=i instanceof URLSearchParams?i:new URLSearchParams(i);if(a)for(let[e,t]of this.search)s.has(e)||s.set(e,t);let c={pathname:v(t,o),search:s.size?`?${s.toString()}`:void 0};n?this.history.replace(c,r):this.history.push(c,r)}setQueryParam(e,t){this.search.set(e,t),this.history.replace({search:this.search.toString()})}removeQueryParam(e){let t=new URLSearchParams(this.location.search),n=t.get(e)??void 0;return n!==void 0&&(t.delete(e),this.history.replace({search:t.toString()})),n}async setLocation(e){if(this.routesDef){if(e.pathname!==`/`&&e.pathname.endsWith(`/`)){this.history.replace({...e,pathname:e.pathname.slice(0,-1)});return}this.location=e;try{let t=z(e.pathname,this.routesDef);if(await t.guard(),this.location!==e)return;this.activeRoute=t,await this.activeRoute?.load()}catch(e){if(e instanceof P){this.navigate(e.options);return}throw e}}}};export{d as CONTEXT,h as GUARD,f as LAYOUT,m as LOAD,k as Link,j as Navigate,g as PAGE,w as PassThrough,_ as REDIRECT,P as Redirect,O as Router,T as RouterOutlet,V as RouterStore,p as WRAPPER,y as isComponent,C as isLazyComponent,S as isLeaf,b as isPage,x as isRedirect,A as makeLinkComponent,R as makeRoute,B as makeRoutes,z as matchRoute,F as redirect,v as resolvePath,E as routerContext,D as useRouter};
2
- //# sourceMappingURL=mobx-router.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"mobx-router.mjs","names":[],"sources":["../src/mobx-router/symbols.ts","../src/mobx-router/util.ts","../src/mobx-router/components/router.tsx","../src/mobx-router/components/link.tsx","../src/mobx-router/components/navigate.tsx","../src/mobx-router/outlet.tsx","../src/mobx-router/redirect.ts","../src/mobx-router/route.tsx","../src/mobx-router/make-routes.tsx","../src/mobx-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(0)];\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 { Outlet } from \"../outlet\";\nimport type { Route } from \"../route\";\nimport type { RouterStore } from \"../router.store\";\nimport type { Component } from \"../types\";\n\nexport const PassThrough: Component = ({ children }) => children;\n\nexport const RouterOutlet: React.FC<{ route: Route; outlets: Outlet[] }> = observer(\n ({ route, outlets }) => {\n const [outlet, ...remainingOutlets] = outlets;\n\n if (!outlet) return null;\n\n const C = outlet.Component;\n\n if (!C) return null;\n\n return (\n <C route={route}>\n {remainingOutlets.length > 0 && <RouterOutlet route={route} outlets={remainingOutlets} />}\n </C>\n );\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 return (\n <routerContext.Provider value={store}>\n <RouterOutlet route={store.activeRoute} outlets={store.activeRoute.outlets} />\n </routerContext.Provider>\n );\n});\n","import { observer } from \"mobx-react-lite\";\nimport React, { type HTMLProps, 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\n// function overloading is much faster than leveraging conditional types\n// but is a bit awkward to use without the makeLinkComponent helper below.\n// consider the commented out solution once the typescript go compiler\n// is released if performance is no longer an issue\nexport interface LinkComponent<T> {\n <P extends StaticRoutePath>(props: T & { to: P; params?: undefined }): React.ReactNode;\n <P extends DynamicRoutePath>(props: T & { to: P; params: ExtractParams<P> }): React.ReactNode;\n}\n\nexport interface LinkPropsBase extends Omit<HTMLProps<HTMLAnchorElement>, \"onClick\" | \"href\"> {\n exact?: boolean;\n ref?: React.RefObject<HTMLAnchorElement>;\n}\n\nexport type Link = LinkComponent<LinkPropsBase>;\nexport type LinkProps = React.ComponentProps<Link>;\n\nexport const Link = observer((({ to, params, exact, children, ...props }: LinkProps) => {\n const router = useRouter();\n\n const resolvedPath = resolvePath(to, params);\n\n const matchingProps = router.doesPathMatch(to, exact)\n ? ({ \"aria-current\": \"page\" } as const)\n : undefined;\n\n const onClick = useCallback(\n (event: React.MouseEvent<HTMLAnchorElement, MouseEvent>) => {\n event.preventDefault();\n router.navigate({ to, ...(params as any) } as NavigateOptions<RoutePath>);\n },\n [router, params, to],\n );\n\n return (\n <a href={resolvedPath} {...props} {...matchingProps} onClick={onClick}>\n {children}\n </a>\n );\n}) as Link);\n\n// this smooths over some of the awkwardness when extending this component\nexport const makeLinkComponent = <\n C extends React.JSXElementConstructor<{ children?: React.ReactNode }>,\n>(\n C: C,\n) => {\n return (({ children, to, params, ...props }: any) => (\n <C {...props}>\n <Link to={to as any} params={params as any}>\n {children}\n </Link>\n </C>\n )) as LinkComponent<React.ComponentProps<C>>;\n};\n\n/*\nexport interface LinkPropsBase extends Omit<HTMLProps<HTMLAnchorElement>, 'onClick' | 'href'> {\n\tref?: React.RefObject<HTMLAnchorElement>;\n}\n\nexport type LinkProps<P extends RoutePath> = WithToAndParams<P, LinkPropsBase>;\n\nexport const Link = <P extends RoutePath>({ to, params, children, ...props }: LinkProps<P>) => {\n\tconst router = useRouter();\n\n\tconst resolvedPath = resolvePath(to, params);\n\n\tconst onClick = useCallback(\n\t\t(event: React.MouseEvent<HTMLAnchorElement, MouseEvent>) => {\n\t\t\tevent.preventDefault();\n\t\t\trouter.navigate({ to, ...params } as NavigateOptions<RoutePath>);\n\t\t},\n\t\t[router, params, to],\n\t);\n\n\treturn (\n\t\t<a href={resolvedPath} {...props} onClick={onClick} ref={ref}>\n\t\t\t{children}\n\t\t</a>\n\t);\n};\n*/\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 { action, computed, 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\nexport class Outlet {\n @observable accessor state: RouteSegmentState = \"preloading\";\n @observable.ref accessor promise: Promise<unknown> | undefined;\n @observable.ref accessor data: unknown;\n @observable.ref accessor component: Component | undefined;\n\n @computed get Component(): Component | undefined {\n switch (this.state) {\n case \"loading\":\n return function Loading() {\n return <p>Loading...</p>;\n };\n\n case \"ready\":\n return this.component ?? DefaultOutlet;\n\n default:\n return undefined;\n }\n }\n\n constructor(readonly config: OutletConfig) {}\n\n @action\n async load(route: Route): Promise<void> {\n const promises: Promise<void>[] = [];\n\n if (isLazyComponent(this.config.component)) {\n promises.push(this.loadComponent());\n } else {\n this.component = this.config.component;\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 @action\n setData(data: unknown) {\n this.data = data;\n }\n\n @action\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 (this.component || !this.config.component) {\n return;\n }\n\n if (isLazyComponent(this.config.component)) {\n const importResult = await this.config.component();\n for (const exportName in importResult) {\n if (exportName === \"default\" || exportName.endsWith(\"Page\")) {\n this.component = importResult[exportName];\n }\n }\n } else {\n this.component = this.config.component;\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 } 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\n @computed 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 }\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 if (matchState.layout) {\n outlets.unshift(new Outlet({ component: matchState.layout }));\n }\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 { makeAutoObservable } 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 makeAutoObservable({\n history: false,\n routesDef: false,\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 this.search.set(param, value);\n this.history.replace({ search: this.search.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 this.activeRoute = matchedRoute;\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":"kTAAA,MAAa,EAAyB,OAAO,IAAI,sBAAsB,CAC1D,EAAwB,OAAO,IAAI,qBAAqB,CACxD,EAAyB,OAAO,IAAI,sBAAsB,CAC1D,EAAsB,OAAO,IAAI,mBAAmB,CACpD,EAAuB,OAAO,IAAI,oBAAoB,CACtD,EAAsB,OAAO,IAAI,mBAAmB,CACpD,EAA0B,OAAO,IAAI,uBAAuB,CCH5D,GAAe,EAAY,IAC/B,EAAG,WAAW,UAAY,GAAY,CAC3C,IAAM,EAAQ,IAAS,EAAQ,MAAM,EAAE,EACvC,GAAI,CAAC,EACH,MAAU,MAAM,4BAA4B,EAAG,eAAe,EAAQ,kBAAkB,CAC1F,OAAO,GACP,CAGS,EAAe,GACrB,EAEH,OAAO,GAAS,YACf,OAAO,GAAS,UAAY,EAAK,WAAgB,OAAO,IAAI,aAAa,CAH1D,GAOP,EAAU,GACjB,OAAO,GAAS,SACJ,OAAO,sBAAsB,EAAK,CACnC,SAAS,EAAK,CAFQ,GAK1B,EAAc,GACrB,OAAO,GAAS,SACJ,OAAO,sBAAsB,EAAK,CACnC,SAAS,EAAS,CAFI,GAK1B,EAAU,GACd,EAAY,EAAK,EAAI,EAAO,EAAK,EAAI,EAAW,EAAK,CAGjD,EAAmB,GACvB,OAAO,GAAS,YAAc,EAAK,UAAU,CAAC,WAAW,gBAAgB,CC9BrE,GAA0B,CAAE,cAAe,EAE3C,EAA8D,GACxE,CAAE,QAAO,aAAc,CACtB,GAAM,CAAC,EAAQ,GAAG,GAAoB,EAEtC,GAAI,CAAC,EAAQ,OAAO,KAEpB,IAAM,EAAI,EAAO,UAIjB,OAFK,EAGH,EAAC,EAAD,CAAU,iBACP,EAAiB,OAAS,GAAK,EAAC,EAAD,CAAqB,QAAO,QAAS,EAAoB,CAAA,CACvF,CAAA,CALS,MAQlB,CAEY,EAAgB,EAA2B,KAAY,CACvD,MAAkB,EAAW,EAAc,CAM3C,EAAS,GAAU,CAAE,WAC3B,EAAM,YAKT,EAAC,EAAc,SAAf,CAAwB,MAAO,WAC7B,EAAC,EAAD,CAAc,MAAO,EAAM,YAAa,QAAS,EAAM,YAAY,QAAW,CAAA,CACvD,CAAA,CANlB,KAQT,CCfW,EAAO,IAAW,CAAE,KAAI,SAAQ,QAAO,WAAU,GAAG,KAAuB,CACtF,IAAM,EAAS,GAAW,CAEpB,EAAe,EAAY,EAAI,EAAO,CAEtC,EAAgB,EAAO,cAAc,EAAI,EAAM,CAChD,CAAE,eAAgB,OAAQ,CAC3B,IAAA,GAEE,EAAU,EACb,GAA2D,CAC1D,EAAM,gBAAgB,CACtB,EAAO,SAAS,CAAE,KAAI,GAAI,EAAgB,CAA+B,EAE3E,CAAC,EAAQ,EAAQ,EAAG,CACrB,CAED,OACE,EAAC,IAAD,CAAG,KAAM,EAAc,GAAI,EAAO,GAAI,EAAwB,UAC3D,WACC,CAAA,GAEG,CAGE,EAGX,KAES,CAAE,WAAU,KAAI,SAAQ,GAAG,KAClC,EAAC,EAAD,CAAG,GAAI,WACL,EAAC,EAAD,CAAU,KAAmB,SAC1B,WACI,CAAA,CACL,CAAA,EC5DK,EAAiC,GAA8B,CAC1E,IAAM,EAAS,GAAW,CAM1B,OAJA,MAAsB,CACpB,EAAO,SAAS,EAAM,EACrB,CAAC,EAAQ,EAAM,CAAC,CAEZ,MCCI,GAA4B,CAAE,cAAe,EAE1D,IAAa,EAAb,KAAoB,CAClB,CAAC,WAAoB,MAA2B,aAChD,CAAC,EAAW,aAAa,QACzB,CAAC,EAAW,aAAa,KACzB,CAAC,EAAW,aAAa,UAEzB,CAAC,MAAa,WAAmC,CAC/C,OAAQ,KAAK,MAAb,CACE,IAAK,UACH,OAAO,UAAmB,CACxB,OAAO,EAAC,IAAD,CAAA,SAAG,aAAc,CAAA,EAG5B,IAAK,QACH,OAAO,KAAK,WAAa,EAE3B,QACE,QAIN,YAAY,EAA+B,CAAtB,KAAA,OAAA,EAErB,CAAC,QACK,KAAK,EAA6B,CACtC,IAAM,EAA4B,EAAE,CAYpC,GAVI,EAAgB,KAAK,OAAO,UAAU,CACxC,EAAS,KAAK,KAAK,eAAe,CAAC,CAEnC,KAAK,UAAY,KAAK,OAAO,UAG3B,KAAK,OAAO,QACd,EAAS,KAAK,KAAK,SAAS,EAAM,CAAC,CAGjC,CAAC,EAAS,OAAQ,CACpB,KAAK,SAAS,QAAQ,CACtB,OAMF,IAAM,EAAkB,eAAiB,CACnC,KAAK,QAAU,cACjB,KAAK,SAAS,UAAU,EAEzB,IAAI,CAEP,KAAK,QAAU,QAAQ,IAAI,EAAS,CACjC,SAAW,CACV,aAAa,EAAgB,CACzB,KAAK,QAAU,UAIjB,eAAiB,CACf,KAAK,SAAS,QAAQ,EACrB,IAAI,CAEP,KAAK,SAAS,QAAQ,EAExB,CACD,UAAY,CACX,aAAa,EAAgB,CAG7B,KAAK,SAAS,QAAQ,EACtB,CAEJ,MAAM,KAAK,QAGb,CAAC,EACD,QAAQ,EAAe,CACrB,KAAK,KAAO,EAGd,CAAC,EACD,SAAS,EAA0B,CACjC,KAAK,MAAQ,EAGf,MAAc,SAAS,EAA6B,CAClD,MAAM,KAAK,OAAO,SAAS,EAAM,CAAC,KAAM,GAAS,KAAK,QAAQ,EAAK,CAAC,CAGtE,MAAc,eAA+B,CACvC,UAAK,WAAa,CAAC,KAAK,OAAO,WAInC,GAAI,EAAgB,KAAK,OAAO,UAAU,CAAE,CAC1C,IAAM,EAAe,MAAM,KAAK,OAAO,WAAW,CAClD,IAAK,IAAM,KAAc,GACnB,IAAe,WAAa,EAAW,SAAS,OAAO,IACzD,KAAK,UAAY,EAAa,SAIlC,KAAK,UAAY,KAAK,OAAO,YClHtB,EAAb,KAA2C,CACzC,YAAY,EAAsC,CAA7B,KAAA,QAAA,IAGvB,MAAa,EAAiC,GAC5C,IAAI,EAAS,EAAQ,CCMvB,IAAa,EAAb,KAAmB,CACjB,KACA,QACA,OACA,QACA,OAEA,CAAC,MAAa,MAAY,CACxB,OAAO,OAAO,OAAO,EAAE,CAAE,GAAG,KAAK,QAAQ,IAAK,GAAM,EAAE,KAAK,CAAC,CAG9D,YAAY,EAAkB,CAC5B,KAAK,KAAO,EAAI,KAChB,KAAK,OAAS,EAAI,OAClB,KAAK,QAAU,EAAI,SAAW,EAAE,CAChC,KAAK,QAAU,EAAI,QACnB,KAAK,OAAS,EAAI,OAGpB,MAAM,OAAuB,CAC3B,IAAK,IAAM,KAAS,KAAK,OACvB,MAAM,EAAM,KAAK,CAIrB,MAAM,MAAsB,CAC1B,MAAM,QAAQ,IAAI,KAAK,QAAQ,IAAK,GAAW,EAAO,KAAK,KAAK,CAAC,CAAC,GChCtE,MAAM,EAAkB,GACf,EAAK,QAAQ,aAAc,GAAG,CAAC,MAAM,IAAI,CAYrC,EAAa,GAAkC,CAC1D,IAAM,EAAU,EAAW,QAAQ,OAAQ,GAAM,IAAM,IAAA,GAAU,CAC3D,EAAS,EAAW,OAAO,OAAQ,GAAM,IAAM,IAAA,GAAU,CAM/D,OAJI,EAAW,QACb,EAAQ,QAAQ,IAAI,EAAO,CAAE,UAAW,EAAW,OAAQ,CAAC,CAAC,CAGxD,IAAI,EAAM,CAAE,GAAG,EAAY,UAAS,SAAQ,KAAM,EAAW,SAAS,KAAK,IAAI,CAAE,CAAC,EAG9E,GAAc,EAAc,EAAkB,IAAmC,CAC5F,IAAM,EAAoB,CACxB,SAAU,EAAE,CACZ,OAAQ,EAAE,CACV,GAAG,EACH,OAAQ,EAAS,IAAW,GAAY,OACxC,QAAS,CAAE,GAAG,GAAY,QAAS,GAAG,EAAS,GAAU,CACzD,OAAQ,CAAC,GAAI,GAAY,QAAU,EAAE,CAAG,EAAS,GAAO,CACxD,QAAS,CACP,GAAI,GAAY,SAAW,EAAE,CAC7B,EAAS,GAAW,IAAI,EAAO,CAAE,UAAW,EAAS,GAAU,CAAC,CAAG,IAAA,GACnE,EAAS,GAAQ,IAAI,EAAO,CAAE,OAAQ,EAAS,GAAO,CAAC,CAAG,IAAA,GAC3D,CACF,CAEK,CAAC,EAAS,GAAG,GAAqB,EAAe,EAAK,CACtD,EAAgB,EAAkB,KAAK,IAAI,CAE7C,EAAe,EAAS,GAAW,SAEvC,GAAI,CAAC,EAAc,CACjB,IAAM,EAAiB,OAAO,KAAK,EAAS,CAAC,KAAM,GAAY,EAAQ,WAAW,IAAI,CAAC,CACnF,IACF,EAAe,EAAS,GACxB,EAAM,OAAO,EAAe,MAAM,EAAE,EAAI,GAI5C,GAAI,CAAC,EACH,MAAU,MAAM,aAAa,CAK/B,GAFA,EAAM,SAAS,KAAK,GAAW,QAAQ,CAEnC,EAAO,EAAa,CAAE,CACxB,GAAI,EACF,MAAU,MAAM,aAAa,CAG/B,GAAI,EAAW,EAAa,CAK1B,MAAM,IAAI,EAHR,OAAO,EAAa,IAAc,SAC9B,CAAE,GAAI,EAAa,GAAW,CAC9B,EAAa,GACgB,CAGrC,GAAI,EAAY,EAAa,EAAI,EAAgB,EAAa,CAE5D,OADA,EAAM,QAAQ,KAAK,IAAI,EAAO,CAAE,UAAW,EAAc,CAAC,CAAC,CACpD,EAAU,EAAM,CAqB3B,OAfI,EAAO,EAAa,EACtB,EAAM,OAAS,EAAa,IAAW,EAAM,OAC7C,OAAO,OAAO,EAAM,QAAS,EAAa,GAAS,CACnD,EAAM,OAAO,KAAK,EAAa,GAAO,CACtC,EAAM,QAAQ,KACZ,IAAI,EAAO,CACT,UAAW,EAAa,GACxB,OAAQ,EAAa,GACtB,CAAC,CACH,CAEM,EAAU,EAAM,EAIlB,EAAW,EAAe,EAAc,EAAM,EAS1C,MAEQ,GAQV,EC1GX,IAAa,EAAb,KAAyB,CACvB,QAEA,UAEA,SACA,YAEA,IAAI,QAA0B,CAC5B,OAAO,IAAI,gBAAgB,KAAK,UAAU,OAAO,CAGnD,IAAI,OAAgC,CAClC,OAAO,OAAO,YAAY,KAAK,OAAO,CAGxC,IAAI,YAAqC,CACvC,IAAM,EAAS,EAAE,CAEX,EAAgB,KAAK,eAAe,OAAQ,GAAY,EAAQ,WAAW,IAAI,CAAC,CAChF,EAAa,KAAK,SAAS,SAAS,MAAM,IAAI,CAAC,MAAM,EAAE,CAS7D,OAPA,EAAc,SAAS,EAAS,IAAU,CACxC,IAAM,EAAQ,EAAW,EAAQ,GAC7B,IACF,EAAO,GAAW,IAEpB,CAEK,EAGT,IAAI,gBAA2B,CAC7B,OAAO,KAAK,aAAa,KAAK,MAAM,IAAI,EAAI,EAAE,CAGhD,YAAY,EAA2B,CACrC,EAAmB,CACjB,QAAS,GACT,UAAW,GACZ,CAAC,CAEF,KAAK,QAAU,GAAQ,SAAW,GAAsB,CAG1D,WAAW,EAAyB,CAClC,KAAK,UAAY,EACjB,KAAK,QAAQ,OAAQ,GAAS,CACvB,KAAK,YAAY,EAAK,SAAS,EACpC,CAEG,KAAK,YAAY,KAAK,QAAQ,SAAS,CAG9C,cAAmC,EAAS,EAA0B,CACpE,IAAM,EAAW,EAAK,MAAM,EAAE,CAAC,MAAM,IAAI,CAKzC,OAJsB,EAAS,OAC5B,EAAS,IAAM,IAAY,KAAK,eAAe,IAAM,EAAQ,WAAW,IAAI,CAC9E,EAIC,KAAK,eAAe,QAAU,EAAS,SACtC,CAAC,GAAS,EAAS,SAAW,KAAK,eAAe,QAIvD,SAA8B,EAAmC,CAC1D,SAAS,oBAGO,SAAS,wBAA0B,KAAK,UAAU,EAAQ,CAAC,CACnE,MAAM,MAAO,GAAM,QAAQ,IAAI,EAAG,OAAO,EAAE,CAAC,CAHvD,KAAK,UAAU,EAAQ,CAO3B,UAA+B,EAAmC,CAChE,GAAM,CAAE,KAAI,UAAS,QAAO,SAAS,EAAE,CAAE,iBAAgB,UAAW,EAE9D,EAAe,aAAkB,gBAAkB,EAAS,IAAI,gBAAgB,EAAO,CAE7F,GAAI,MACG,GAAM,CAAC,EAAM,KAAU,KAAK,OAC1B,EAAa,IAAI,EAAK,EACzB,EAAa,IAAI,EAAM,EAAM,CAKnC,IAAM,EAAW,CACf,SAAU,EAAY,EAAI,EAAO,CACjC,OAAQ,EAAa,KAAO,IAAI,EAAa,UAAU,GAAK,IAAA,GAC7D,CAEG,EACF,KAAK,QAAQ,QAAQ,EAAU,EAAM,CAErC,KAAK,QAAQ,KAAK,EAAU,EAAM,CAItC,cAAc,EAAe,EAAqB,CAChD,KAAK,OAAO,IAAI,EAAO,EAAM,CAC7B,KAAK,QAAQ,QAAQ,CAAE,OAAQ,KAAK,OAAO,UAAU,CAAE,CAAC,CAG1D,iBAAiB,EAAmC,CAClD,IAAM,EAAS,IAAI,gBAAgB,KAAK,SAAS,OAAO,CAClD,EAAQ,EAAO,IAAI,EAAM,EAAI,IAAA,GAKnC,OAJI,IAAU,IAAA,KACZ,EAAO,OAAO,EAAM,CACpB,KAAK,QAAQ,QAAQ,CAAE,OAAQ,EAAO,UAAU,CAAE,CAAC,EAE9C,EAGT,MAAM,YAAY,EAAmC,CAC9C,QAAK,UAIV,IAAI,EAAS,WAAa,KAAO,EAAS,SAAS,SAAS,IAAI,CAAE,CAChE,KAAK,QAAQ,QAAQ,CAAE,GAAG,EAAU,SAAU,EAAS,SAAS,MAAM,EAAG,GAAG,CAAE,CAAC,CAC/E,OAGF,KAAK,SAAW,EAEhB,GAAI,CACF,IAAM,EAAe,EAAW,EAAS,SAAU,KAAK,UAAU,CAMlE,GAJA,MAAM,EAAa,OAAO,CAItB,KAAK,WAAa,EACpB,OAGF,KAAK,YAAc,EACnB,MAAM,KAAK,aAAa,MAAM,OACvB,EAAG,CACV,GAAI,aAAa,EAAU,CACzB,KAAK,SAAS,EAAE,QAAQ,CACxB,OAEF,MAAM"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"mobx-util.d.mts","names":[],"sources":["../src/mobx-util/lazy-observable.ts","../src/mobx-util/mutable.ts","../src/mobx-util/use-autorun.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,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,UAiJJ,mBAAA,YAA+B,IAAA,CAAK,cAAA,CAAe,gBAAA,CAAiB,CAAA;EACnF,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;;;cCvMxE,OAAA,EAAS,sBAAA;;;iBCAN,UAAA,CAAW,IAAA,GAAO,CAAA,EAAG,eAAA,cAA6B,OAAA,GAAU,eAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"mobx-util.mjs","names":[],"sources":["../src/mobx-util/lazy-observable.ts","../src/mobx-util/mutable.ts","../src/mobx-util/use-autorun.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 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\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 });\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 });\n fetch()\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 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 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\n onBecomeUnobserved(value, onUnobserved);\n onBecomeUnobserved(status, onUnobserved);\n\n return {\n get value() {\n return value.get();\n },\n get status() {\n return status.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> extends Omit<LazyObservable<IObservableArray<T>>, \"set\"> {\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","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":"wKA2CA,SAAgB,EACd,EACA,EACmB,CACnB,IAAM,EAAQ,EAAW,IAAO,GAAS,aAAc,CAAE,KAAM,CAAC,GAAS,QAAS,CAAC,CAC7E,EAAS,EAAW,IAAiC,OAAO,CAE9D,EACA,EAEA,EACA,EACA,EAEE,OACA,GAAW,EAAO,KAAK,GAAK,UAAY,EAAO,KAAK,GAAK,UAG7D,EAAU,IAAI,SAAY,EAAS,IAAW,CAC5C,EAAiB,EACjB,EAAgB,GAChB,EALO,GASL,OACJ,aAAa,EAAW,CACxB,KAAmB,CACnB,EAAmB,OAAY,CAC7B,EAAM,IAAI,GAAS,aAAa,CAChC,EAAO,IAAI,OAAO,EAClB,CACK,GAAS,cAGZ,MAAmB,CACnB,EAAO,KAAK,GAAK,YACrB,aAAa,EAAW,CAIxB,KAAmB,CACnB,EAAkB,MAAc,CAC9B,EAAmB,OAAY,CAC7B,EAAO,IAAI,UAAU,EACrB,CACF,GAAO,CACJ,KAAM,GAAa,CAClB,EAAmB,OAAY,CAC7B,EAAM,IAAI,EAAS,CACnB,EAAO,IAAI,SAAS,CACpB,IAAiB,EAAS,EAC1B,EACF,CACD,MAAO,GAAM,CACZ,EAAmB,OAAY,CAC7B,EAAO,IAAI,QAAQ,CACnB,IAAgB,EAAE,EAClB,EACF,EACJ,GAIE,EAAO,GAAiB,CAC5B,EAAmB,OAAY,CAC7B,EAAM,IAAI,EAAI,CACd,EAAO,IAAI,SAAS,EACpB,EAGA,EAAgB,EAEd,MAAmB,CACvB,EAAgB,KAAK,IAAI,EAAG,EAAgB,EAAE,CAG1C,IAAkB,IAElB,GAAS,WACX,QAAQ,IAAI,kBAAkB,EAAQ,YAAa,WAAW,CAEhE,aAAa,EAAW,EACpB,EAAO,KAAK,GAAK,SAAW,EAAO,KAAK,GAAK,SAC/C,GAAM,GAIJ,MAAqB,CACzB,EAAgB,KAAK,IAAI,EAAG,EAAgB,EAAE,CAG1C,KAEA,GAAS,WACX,QAAQ,IAAI,kBAAkB,EAAQ,YAAa,aAAa,CAE9D,GAAS,oBAAsB,UAExB,OAAO,GAAS,mBAAsB,SAC/C,EAAa,eAAiB,CAC5B,GAAO,EACN,GAAS,kBAAkB,CAE9B,GAAO,IAUX,OANA,EAAiB,EAAO,EAAW,CACnC,EAAiB,EAAQ,EAAW,CAEpC,EAAmB,EAAO,EAAa,CACvC,EAAmB,EAAQ,EAAa,CAEjC,CACL,IAAI,OAAQ,CACV,OAAO,EAAM,KAAK,EAEpB,IAAI,QAAS,CACX,OAAO,EAAO,KAAK,EAErB,IAAI,SAAU,CACZ,OAAO,EAAO,KAAK,GAAK,WAE1B,IAAI,QAAS,CACX,OAAO,EAAO,KAAK,GAAK,UAE1B,QAAS,CACP,IAAM,EAAU,GAAoB,CAEpC,OADA,GAAM,CACC,GAET,WAAY,CAIV,OADI,KAAK,OAAe,QAAQ,QAAQ,EAAM,KAAK,CAAe,CAC3D,KAAK,QAAQ,EAEtB,MACA,QACD,CAWH,SAAgB,EACd,EACA,EACwB,CACxB,OAAO,EAAe,EAAO,CAAE,aAAc,EAAE,CAAE,GAAG,EAAS,CAAC,CCnMhE,MAAa,EAAmC,GAAa,CAC3D,IAAM,EAAc,IAAI,QAExB,MAAO,CACL,KAAM,CACJ,IAAI,EAAa,EAAY,IAAI,KAAK,CACtC,GAAI,CAAC,EAAY,CACf,IAAM,EAAQ,EAAS,IAAI,KAAK,KAAK,CACrC,EAAa,EAAW,IAAI,EAAM,CAClC,EAAY,IAAI,KAAM,EAAW,CAGnC,OAAO,EAAW,KAAK,EAEzB,IAAI,EAAO,CACT,IAAI,EAAa,EAAY,IAAI,KAAK,CACjC,IACH,EAAa,EAAW,IAAI,EAAM,CAClC,EAAY,IAAI,KAAM,EAAW,EAGnC,MAAkB,EAAW,IAAI,EAAM,CAAC,EAE3C,ECvBH,SAAgB,EAAW,EAAuC,EAAiC,CAEjG,MAAgB,EAAQ,EAAM,EAAQ,CAAE,EAAE,CAAC"}