@jayalfredprufrock/mobx-toolbox 0.4.0 → 0.4.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.
@@ -1 +1 @@
1
- {"version":3,"file":"lazy-observable.d.mts","names":[],"sources":["../src/lazy-observable/lazy-observable.ts","../src/lazy-observable/components/lazy-observer.tsx"],"mappings":";;;;UAUiB,cAAA,0BAAwC,CAAA;EACvD,KAAA,EAAO,aAAA;EACP,KAAA,IAAS,aAAA;EACT,SAAA,IAAa,OAAA,CAAQ,CAAA;EACrB,GAAA,CAAI,KAAA,EAAO,CAAA;EACX,MAAA,IAAU,OAAA,CAAQ,CAAA;EAClB,MAAA;EACA,KAAA;EACA,OAAA;EACA,MAAA;AAAA;AAAA,UAGe,qBAAA;EACf,OAAA;EACA,iBAAA;EACA,SAAA;AAAA;AAAA,UAGe,qCAAA,wBAEP,qBAAA;EACR,YAAA,GAAe,aAAA;AAAA;AAAA,iBAGD,cAAA,GAAA,CAAkB,KAAA,QAAa,OAAA,CAAQ,CAAA,IAAK,cAAA,CAAe,CAAA;AAAA,iBAC3D,cAAA,GAAA,CACd,KAAA,QAAa,OAAA,CAAQ,CAAA,GACrB,OAAA,EAAS,qBAAA,GACR,cAAA,CAAe,CAAA;AAAA,iBACF,cAAA,kBAAA,CACd,KAAA,QAAa,OAAA,CAAQ,CAAA,GACrB,OAAA,EAAS,qCAAA,CAAsC,aAAA,IAC9C,cAAA,CAAe,CAAA,EAAG,aAAA;AAAA,UAyJJ,mBAAA,kBAAqC,IAAA,CACpD,cAAA,CAAe,gBAAA,CAAiB,CAAA;EAGhC,GAAA,CAAI,KAAA,EAAO,CAAA;AAAA;AAAA,UAGI,0BAAA,YAAsC,qBAAA;EACrD,YAAA,GAAe,CAAA;AAAA;AAAA,iBAGD,mBAAA,GAAA,CACd,KAAA,QAAa,OAAA,CAAQ,CAAA,KACrB,OAAA,GAAU,0BAAA,CAA2B,CAAA,IACpC,mBAAA,CAAoB,CAAA;AAAA,KAIX,mBAAA,MACV,CAAA,SAAU,mBAAA,YAA+B,CAAA,KAAM,CAAA,SAAU,cAAA,YAA0B,CAAA;;;KClNhF,EAAA,GAAK,cAAA,GAAiB,mBAAA;AAAA,KAEtB,YAAA,WAAuB,EAAA,oBACd,CAAA,GAAI,mBAAA,CAAoB,CAAA,CAAE,CAAA;AAAA,UAGvB,qBAAA;EACf,WAAA,GAAc,KAAA,CAAM,SAAA;AAAA;AAAA,UAGL,sBAAA,WAAiC,EAAA,YAAc,qBAAA;EAC9D,OAAA,MAAa,CAAA;EACb,QAAA,MAAc,KAAA,EAAO,YAAA,CAAa,CAAA,MAAO,KAAA,CAAM,SAAA;AAAA;AAAA,UAGhC,uBAAA,WAAkC,EAAA,UAAY,qBAAA;EAC7D,OAAA,EAAS,CAAA;EACT,QAAA,GAAW,KAAA,EAAO,mBAAA,CAAoB,CAAA,MAAO,KAAA,CAAM,SAAA;AAAA;AAAA,iBAGrC,YAAA,WAAuB,EAAA,GAAA,CAAM,KAAA,EAAO,sBAAA,CAAuB,CAAA,IAAK,KAAA,CAAM,SAAA;AAAA,iBACtE,YAAA,WAAuB,cAAA,CAAA,CACrC,KAAA,EAAO,uBAAA,CAAwB,CAAA,IAC9B,KAAA,CAAM,SAAA"}
1
+ {"version":3,"file":"lazy-observable.d.mts","names":[],"sources":["../src/lazy-observable/lazy-observable.ts","../src/lazy-observable/components/lazy-observer.tsx"],"mappings":";;;;UAUiB,cAAA,0BAAwC,CAAA;EACvD,KAAA,EAAO,aAAA;EACP,KAAA,IAAS,aAAA;EACT,SAAA,IAAa,OAAA,CAAQ,CAAA;EACrB,GAAA,CAAI,KAAA,EAAO,CAAA;EACX,MAAA,IAAU,OAAA,CAAQ,CAAA;EAClB,MAAA;EACA,KAAA;EACA,OAAA;EACA,MAAA;AAAA;AAAA,UAGe,qBAAA;EACf,OAAA;EACA,iBAAA;EACA,SAAA;AAAA;AAAA,UAGe,qCAAA,wBAEP,qBAAA;EACR,YAAA,GAAe,aAAA;AAAA;AAAA,iBAGD,cAAA,GAAA,CAAkB,KAAA,QAAa,OAAA,CAAQ,CAAA,IAAK,cAAA,CAAe,CAAA;AAAA,iBAC3D,cAAA,GAAA,CACd,KAAA,QAAa,OAAA,CAAQ,CAAA,GACrB,OAAA,EAAS,qBAAA,GACR,cAAA,CAAe,CAAA;AAAA,iBACF,cAAA,kBAAA,CACd,KAAA,QAAa,OAAA,CAAQ,CAAA,GACrB,OAAA,EAAS,qCAAA,CAAsC,aAAA,IAC9C,cAAA,CAAe,CAAA,EAAG,aAAA;AAAA,UAqKJ,mBAAA,kBAAqC,IAAA,CACpD,cAAA,CAAe,gBAAA,CAAiB,CAAA;EAGhC,GAAA,CAAI,KAAA,EAAO,CAAA;AAAA;AAAA,UAGI,0BAAA,YAAsC,qBAAA;EACrD,YAAA,GAAe,CAAA;AAAA;AAAA,iBAGD,mBAAA,GAAA,CACd,KAAA,QAAa,OAAA,CAAQ,CAAA,KACrB,OAAA,GAAU,0BAAA,CAA2B,CAAA,IACpC,mBAAA,CAAoB,CAAA;AAAA,KAIX,mBAAA,MACV,CAAA,SAAU,mBAAA,YAA+B,CAAA,KAAM,CAAA,SAAU,cAAA,YAA0B,CAAA;;;KC1NhF,EAAA,GAAK,cAAA,GAAiB,mBAAA;AAAA,KAEtB,YAAA,WAAuB,EAAA,oBACd,CAAA,GAAI,mBAAA,CAAoB,CAAA,CAAE,CAAA;AAAA,UAGvB,qBAAA;EACf,WAAA,GAAc,KAAA,CAAM,SAAA;AAAA;AAAA,UAGL,sBAAA,WAAiC,EAAA,YAAc,qBAAA;EAC9D,OAAA,MAAa,CAAA;EACb,QAAA,MAAc,KAAA,EAAO,YAAA,CAAa,CAAA,MAAO,KAAA,CAAM,SAAA;AAAA;AAAA,UAGhC,uBAAA,WAAkC,EAAA,UAAY,qBAAA;EAC7D,OAAA,EAAS,CAAA;EACT,QAAA,GAAW,KAAA,EAAO,mBAAA,CAAoB,CAAA,MAAO,KAAA,CAAM,SAAA;AAAA;AAAA,iBAGrC,YAAA,WAAuB,EAAA,GAAA,CAAM,KAAA,EAAO,sBAAA,CAAuB,CAAA,IAAK,KAAA,CAAM,SAAA;AAAA,iBACtE,YAAA,WAAuB,cAAA,CAAA,CACrC,KAAA,EAAO,uBAAA,CAAwB,CAAA,IAC9B,KAAA,CAAM,SAAA"}
@@ -37,6 +37,7 @@ function lazyObservable(fetch, options) {
37
37
  autorunDisposer = autorun(() => {
38
38
  _allowStateChanges(true, () => {
39
39
  status.set("loading");
40
+ error.set(void 0);
40
41
  });
41
42
  fetch().then((newValue) => {
42
43
  _allowStateChanges(true, () => {
@@ -71,6 +72,13 @@ function lazyObservable(fetch, options) {
71
72
  observedCount = Math.max(0, observedCount - 1);
72
73
  if (observedCount) return;
73
74
  if (options?.debugName) console.log(`lazyObservable ${options.debugName}`, "unobserved");
75
+ if (status.get() === "error") {
76
+ _allowStateChanges(true, () => {
77
+ status.set("init");
78
+ error.set(void 0);
79
+ });
80
+ return;
81
+ }
74
82
  if (options?.resetOnUnobserved === "never") return;
75
83
  else if (typeof options?.resetOnUnobserved === "number") resetTimer = setTimeout(() => {
76
84
  reset();
@@ -121,12 +129,15 @@ function lazyObservableArray(fetch, options) {
121
129
 
122
130
  //#endregion
123
131
  //#region src/lazy-observable/components/lazy-observer.tsx
132
+ function ThrowError({ error }) {
133
+ throw error;
134
+ }
124
135
  function LazyObserver(props) {
125
136
  const { observe, placeholder, children } = props;
126
137
  const observeAsArray = [observe].flat();
127
138
  return /* @__PURE__ */ jsx(Observer, { children: () => {
128
139
  const failed = observeAsArray.find((o) => o.status === "error");
129
- if (failed) throw failed.error;
140
+ if (failed) return /* @__PURE__ */ jsx(ThrowError, { error: failed.error });
130
141
  if (!observeAsArray.every((o) => o.loaded)) return placeholder;
131
142
  return children(...observeAsArray.map((o) => o.value));
132
143
  } });
@@ -1 +1 @@
1
- {"version":3,"file":"lazy-observable.mjs","names":[],"sources":["../src/lazy-observable/lazy-observable.ts","../src/lazy-observable/components/lazy-observer.tsx"],"sourcesContent":["import {\n _allowStateChanges,\n autorun,\n type IObservableArray,\n type IReactionDisposer,\n observable,\n onBecomeObserved,\n onBecomeUnobserved,\n} from \"mobx\";\n\nexport interface LazyObservable<T = any, TInitialValue = T | undefined> {\n value: TInitialValue;\n reset(): TInitialValue;\n getOrLoad(): Promise<T>;\n set(value: T): void;\n reload(): Promise<T>;\n status: \"init\" | \"loading\" | \"loaded\" | \"error\";\n error: unknown;\n loading: boolean;\n loaded: boolean;\n}\n\nexport interface LazyObservableOptions {\n shallow?: boolean;\n resetOnUnobserved?: \"never\" | \"always\" | number;\n debugName?: string;\n}\n\nexport interface LazyObservableOptionsWithInitialValue<\n TInitialValue,\n> extends LazyObservableOptions {\n initialValue?: TInitialValue;\n}\n\nexport function lazyObservable<T>(fetch: () => Promise<T>): LazyObservable<T>;\nexport function lazyObservable<T>(\n fetch: () => Promise<T>,\n options: LazyObservableOptions,\n): LazyObservable<T>;\nexport function lazyObservable<T, TInitialValue>(\n fetch: () => Promise<T>,\n options: LazyObservableOptionsWithInitialValue<TInitialValue>,\n): LazyObservable<T, TInitialValue>;\n\nexport function lazyObservable<T>(\n fetch: () => Promise<T>,\n options?: LazyObservableOptionsWithInitialValue<T>,\n): LazyObservable<T> {\n const value = observable.box<T>(options?.initialValue, { deep: !options?.shallow });\n const status = observable.box<LazyObservable<T>[\"status\"]>(\"init\");\n const error = observable.box<unknown>(undefined);\n\n let resetTimer: NodeJS.Timeout;\n let autorunDisposer: IReactionDisposer;\n\n let promise: Promise<T> | undefined;\n let promiseResolve: ((value: T) => void) | undefined;\n let promiseReject: ((value: unknown) => void) | undefined;\n\n const getOrCreatePromise = () => {\n if (promise && status.get() !== \"loaded\" && status.get() !== \"error\") {\n return promise;\n }\n promise = new Promise<T>((resolve, reject) => {\n promiseResolve = resolve;\n promiseReject = reject;\n });\n return promise;\n };\n\n const reset = () => {\n clearTimeout(resetTimer);\n autorunDisposer?.();\n _allowStateChanges(true, () => {\n value.set(options?.initialValue);\n status.set(\"init\");\n error.set(undefined);\n });\n return options?.initialValue;\n };\n\n const load = (): void => {\n if (status.get() === \"loading\") return;\n clearTimeout(resetTimer);\n\n // TODO: this disposer is unreliable while we are using\n // babel to convert all async function to generators\n autorunDisposer?.();\n autorunDisposer = autorun(() => {\n _allowStateChanges(true, () => {\n status.set(\"loading\");\n });\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 error.set(e);\n status.set(\"error\");\n promiseReject?.(e);\n });\n });\n });\n };\n\n // TODO: should this resolve any promises?\n const set = (val: T): void => {\n _allowStateChanges(true, () => {\n value.set(val);\n status.set(\"loaded\");\n });\n };\n\n let observedCount = 0;\n\n const onObserved = () => {\n observedCount = Math.min(2, observedCount + 1);\n\n // only consider observed the first time this handler gets called\n if (observedCount !== 1) return;\n\n if (options?.debugName) {\n console.log(`lazyObservable ${options.debugName}`, \"observed\");\n }\n clearTimeout(resetTimer);\n if (status.get() === \"error\" || status.get() === \"init\") {\n load();\n }\n };\n\n const onUnobserved = () => {\n observedCount = Math.max(0, observedCount - 1);\n\n // only consider unobserved when count reaches zero\n if (observedCount) return;\n\n if (options?.debugName) {\n console.log(`lazyObservable ${options.debugName}`, \"unobserved\");\n }\n if (options?.resetOnUnobserved === \"never\") {\n return;\n } else if (typeof options?.resetOnUnobserved === \"number\") {\n resetTimer = setTimeout(() => {\n reset();\n }, options?.resetOnUnobserved);\n } else {\n reset();\n }\n };\n\n onBecomeObserved(value, onObserved);\n onBecomeObserved(status, onObserved);\n onBecomeObserved(error, onObserved);\n\n onBecomeUnobserved(value, onUnobserved);\n onBecomeUnobserved(status, onUnobserved);\n onBecomeUnobserved(error, onUnobserved);\n\n return {\n get value() {\n return value.get();\n },\n get status() {\n return status.get();\n },\n get error() {\n return error.get();\n },\n get loading() {\n return status.get() === \"loading\";\n },\n get loaded() {\n return status.get() === \"loaded\";\n },\n reload() {\n const promise = getOrCreatePromise();\n load();\n return promise;\n },\n getOrLoad() {\n // TODO: this assertion shouldn't be necessary\n // consider fixing box/value type\n if (this.loaded) return Promise.resolve(value.get() as Promise<T>);\n return this.reload();\n },\n set,\n reset,\n };\n}\n\nexport interface LazyObservableArray<T = any> extends Omit<\n LazyObservable<IObservableArray<T>>,\n \"set\"\n> {\n set(value: T[]): void;\n}\n\nexport interface LazyObservableArrayOptions<T> extends LazyObservableOptions {\n initialValue?: T[];\n}\n\nexport function lazyObservableArray<T>(\n fetch: () => Promise<T[]>,\n options?: LazyObservableArrayOptions<T>,\n): LazyObservableArray<T> {\n return lazyObservable(fetch, { initialValue: [], ...options }) as LazyObservableArray<T>;\n}\n\nexport type InferLazyObservable<O> =\n O extends LazyObservableArray<infer T> ? T[] : O extends LazyObservable<infer T> ? T : never;\n","import type { InferLazyObservable, LazyObservable, LazyObservableArray } from \"../lazy-observable\";\nimport { Observer } from \"mobx-react-lite\";\nimport type React from \"react\";\n\ntype LO = LazyObservable | LazyObservableArray;\n\ntype ObserveTuple<O extends LO[]> = {\n [K in keyof O]: InferLazyObservable<O[K]>;\n};\n\nexport interface LazyObserverBaseProps {\n placeholder?: React.ReactNode;\n}\n\nexport interface LazyObserverTupleProps<O extends LO[]> extends LazyObserverBaseProps {\n observe: [...O];\n children: (...value: ObserveTuple<O>) => React.ReactNode;\n}\n\nexport interface LazyObserverSingleProps<O extends LO> extends LazyObserverBaseProps {\n observe: O;\n children: (value: InferLazyObservable<O>) => React.ReactNode;\n}\n\nexport function LazyObserver<O extends LO[]>(props: LazyObserverTupleProps<O>): React.ReactNode;\nexport function LazyObserver<O extends LazyObservable>(\n props: LazyObserverSingleProps<O>,\n): React.ReactNode;\nexport function LazyObserver(\n props: LazyObserverTupleProps<any> | LazyObserverSingleProps<any>,\n): React.ReactNode {\n const { observe, placeholder, children } = props;\n const observeAsArray = [observe].flat() as LO[];\n return (\n <Observer>\n {() => {\n const failed = observeAsArray.find((o) => o.status === \"error\");\n if (failed) throw failed.error;\n if (!observeAsArray.every((o) => o.loaded)) return placeholder;\n return (children as any)(...observeAsArray.map((o) => o.value));\n }}\n </Observer>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"lazy-observable.mjs","names":[],"sources":["../src/lazy-observable/lazy-observable.ts","../src/lazy-observable/components/lazy-observer.tsx"],"sourcesContent":["import {\n _allowStateChanges,\n autorun,\n type IObservableArray,\n type IReactionDisposer,\n observable,\n onBecomeObserved,\n onBecomeUnobserved,\n} from \"mobx\";\n\nexport interface LazyObservable<T = any, TInitialValue = T | undefined> {\n value: TInitialValue;\n reset(): TInitialValue;\n getOrLoad(): Promise<T>;\n set(value: T): void;\n reload(): Promise<T>;\n status: \"init\" | \"loading\" | \"loaded\" | \"error\";\n error: unknown;\n loading: boolean;\n loaded: boolean;\n}\n\nexport interface LazyObservableOptions {\n shallow?: boolean;\n resetOnUnobserved?: \"never\" | \"always\" | number;\n debugName?: string;\n}\n\nexport interface LazyObservableOptionsWithInitialValue<\n TInitialValue,\n> extends LazyObservableOptions {\n initialValue?: TInitialValue;\n}\n\nexport function lazyObservable<T>(fetch: () => Promise<T>): LazyObservable<T>;\nexport function lazyObservable<T>(\n fetch: () => Promise<T>,\n options: LazyObservableOptions,\n): LazyObservable<T>;\nexport function lazyObservable<T, TInitialValue>(\n fetch: () => Promise<T>,\n options: LazyObservableOptionsWithInitialValue<TInitialValue>,\n): LazyObservable<T, TInitialValue>;\n\nexport function lazyObservable<T>(\n fetch: () => Promise<T>,\n options?: LazyObservableOptionsWithInitialValue<T>,\n): LazyObservable<T> {\n const value = observable.box<T>(options?.initialValue, { deep: !options?.shallow });\n const status = observable.box<LazyObservable<T>[\"status\"]>(\"init\");\n const error = observable.box<unknown>(undefined);\n\n let resetTimer: NodeJS.Timeout;\n let autorunDisposer: IReactionDisposer;\n\n let promise: Promise<T> | undefined;\n let promiseResolve: ((value: T) => void) | undefined;\n let promiseReject: ((value: unknown) => void) | undefined;\n\n const getOrCreatePromise = () => {\n if (promise && status.get() !== \"loaded\" && status.get() !== \"error\") {\n return promise;\n }\n promise = new Promise<T>((resolve, reject) => {\n promiseResolve = resolve;\n promiseReject = reject;\n });\n return promise;\n };\n\n const reset = () => {\n clearTimeout(resetTimer);\n autorunDisposer?.();\n _allowStateChanges(true, () => {\n value.set(options?.initialValue);\n status.set(\"init\");\n error.set(undefined);\n });\n return options?.initialValue;\n };\n\n const load = (): void => {\n if (status.get() === \"loading\") return;\n clearTimeout(resetTimer);\n\n // TODO: this disposer is unreliable while we are using\n // babel to convert all async function to generators\n autorunDisposer?.();\n autorunDisposer = autorun(() => {\n _allowStateChanges(true, () => {\n status.set(\"loading\");\n error.set(undefined);\n });\n 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 error.set(e);\n status.set(\"error\");\n promiseReject?.(e);\n });\n });\n });\n };\n\n // TODO: should this resolve any promises?\n const set = (val: T): void => {\n _allowStateChanges(true, () => {\n value.set(val);\n status.set(\"loaded\");\n });\n };\n\n let observedCount = 0;\n\n const onObserved = () => {\n observedCount = Math.min(2, observedCount + 1);\n\n // only consider observed the first time this handler gets called\n if (observedCount !== 1) return;\n\n if (options?.debugName) {\n console.log(`lazyObservable ${options.debugName}`, \"observed\");\n }\n clearTimeout(resetTimer);\n if (status.get() === \"error\" || status.get() === \"init\") {\n load();\n }\n };\n\n const onUnobserved = () => {\n observedCount = Math.max(0, observedCount - 1);\n\n // only consider unobserved when count reaches zero\n if (observedCount) return;\n\n if (options?.debugName) {\n console.log(`lazyObservable ${options.debugName}`, \"unobserved\");\n }\n\n // Errors are never cached regardless of resetOnUnobserved — failure state\n // shouldn't persist across mounts, only successfully loaded values should.\n if (status.get() === \"error\") {\n _allowStateChanges(true, () => {\n status.set(\"init\");\n error.set(undefined);\n });\n return;\n }\n\n if (options?.resetOnUnobserved === \"never\") {\n return;\n } else if (typeof options?.resetOnUnobserved === \"number\") {\n resetTimer = setTimeout(() => {\n reset();\n }, options?.resetOnUnobserved);\n } else {\n reset();\n }\n };\n\n onBecomeObserved(value, onObserved);\n onBecomeObserved(status, onObserved);\n onBecomeObserved(error, onObserved);\n\n onBecomeUnobserved(value, onUnobserved);\n onBecomeUnobserved(status, onUnobserved);\n onBecomeUnobserved(error, onUnobserved);\n\n return {\n get value() {\n return value.get();\n },\n get status() {\n return status.get();\n },\n get error() {\n return error.get();\n },\n get loading() {\n return status.get() === \"loading\";\n },\n get loaded() {\n return status.get() === \"loaded\";\n },\n reload() {\n const promise = getOrCreatePromise();\n load();\n return promise;\n },\n getOrLoad() {\n // TODO: this assertion shouldn't be necessary\n // consider fixing box/value type\n if (this.loaded) return Promise.resolve(value.get() as Promise<T>);\n return this.reload();\n },\n set,\n reset,\n };\n}\n\nexport interface LazyObservableArray<T = any> extends Omit<\n LazyObservable<IObservableArray<T>>,\n \"set\"\n> {\n set(value: T[]): void;\n}\n\nexport interface LazyObservableArrayOptions<T> extends LazyObservableOptions {\n initialValue?: T[];\n}\n\nexport function lazyObservableArray<T>(\n fetch: () => Promise<T[]>,\n options?: LazyObservableArrayOptions<T>,\n): LazyObservableArray<T> {\n return lazyObservable(fetch, { initialValue: [], ...options }) as LazyObservableArray<T>;\n}\n\nexport type InferLazyObservable<O> =\n O extends LazyObservableArray<infer T> ? T[] : O extends LazyObservable<infer T> ? T : never;\n","import type { InferLazyObservable, LazyObservable, LazyObservableArray } from \"../lazy-observable\";\nimport { Observer } from \"mobx-react-lite\";\nimport type React from \"react\";\n\nfunction ThrowError({ error }: { error: unknown }): never {\n throw error;\n}\n\ntype LO = LazyObservable | LazyObservableArray;\n\ntype ObserveTuple<O extends LO[]> = {\n [K in keyof O]: InferLazyObservable<O[K]>;\n};\n\nexport interface LazyObserverBaseProps {\n placeholder?: React.ReactNode;\n}\n\nexport interface LazyObserverTupleProps<O extends LO[]> extends LazyObserverBaseProps {\n observe: [...O];\n children: (...value: ObserveTuple<O>) => React.ReactNode;\n}\n\nexport interface LazyObserverSingleProps<O extends LO> extends LazyObserverBaseProps {\n observe: O;\n children: (value: InferLazyObservable<O>) => React.ReactNode;\n}\n\nexport function LazyObserver<O extends LO[]>(props: LazyObserverTupleProps<O>): React.ReactNode;\nexport function LazyObserver<O extends LazyObservable>(\n props: LazyObserverSingleProps<O>,\n): React.ReactNode;\nexport function LazyObserver(\n props: LazyObserverTupleProps<any> | LazyObserverSingleProps<any>,\n): React.ReactNode {\n const { observe, placeholder, children } = props;\n const observeAsArray = [observe].flat() as LO[];\n return (\n <Observer>\n {() => {\n const failed = observeAsArray.find((o) => o.status === \"error\");\n if (failed) return <ThrowError error={failed.error} />;\n if (!observeAsArray.every((o) => o.loaded)) return placeholder;\n return (children as any)(...observeAsArray.map((o) => o.value));\n }}\n </Observer>\n );\n}\n"],"mappings":";;;;;AA4CA,SAAgB,eACd,OACA,SACmB;CACnB,MAAM,QAAQ,WAAW,IAAO,SAAS,cAAc,EAAE,MAAM,CAAC,SAAS,SAAS,CAAC;CACnF,MAAM,SAAS,WAAW,IAAiC,OAAO;CAClE,MAAM,QAAQ,WAAW,IAAa,OAAU;CAEhD,IAAI;CACJ,IAAI;CAEJ,IAAI;CACJ,IAAI;CACJ,IAAI;CAEJ,MAAM,2BAA2B;AAC/B,MAAI,WAAW,OAAO,KAAK,KAAK,YAAY,OAAO,KAAK,KAAK,QAC3D,QAAO;AAET,YAAU,IAAI,SAAY,SAAS,WAAW;AAC5C,oBAAiB;AACjB,mBAAgB;IAChB;AACF,SAAO;;CAGT,MAAM,cAAc;AAClB,eAAa,WAAW;AACxB,qBAAmB;AACnB,qBAAmB,YAAY;AAC7B,SAAM,IAAI,SAAS,aAAa;AAChC,UAAO,IAAI,OAAO;AAClB,SAAM,IAAI,OAAU;IACpB;AACF,SAAO,SAAS;;CAGlB,MAAM,aAAmB;AACvB,MAAI,OAAO,KAAK,KAAK,UAAW;AAChC,eAAa,WAAW;AAIxB,qBAAmB;AACnB,oBAAkB,cAAc;AAC9B,sBAAmB,YAAY;AAC7B,WAAO,IAAI,UAAU;AACrB,UAAM,IAAI,OAAU;KACpB;AACF,UAAO,CACJ,MAAM,aAAa;AAClB,uBAAmB,YAAY;AAC7B,WAAM,IAAI,SAAS;AACnB,YAAO,IAAI,SAAS;AACpB,sBAAiB,SAAS;MAC1B;KACF,CACD,OAAO,MAAM;AACZ,uBAAmB,YAAY;AAC7B,WAAM,IAAI,EAAE;AACZ,YAAO,IAAI,QAAQ;AACnB,qBAAgB,EAAE;MAClB;KACF;IACJ;;CAIJ,MAAM,OAAO,QAAiB;AAC5B,qBAAmB,YAAY;AAC7B,SAAM,IAAI,IAAI;AACd,UAAO,IAAI,SAAS;IACpB;;CAGJ,IAAI,gBAAgB;CAEpB,MAAM,mBAAmB;AACvB,kBAAgB,KAAK,IAAI,GAAG,gBAAgB,EAAE;AAG9C,MAAI,kBAAkB,EAAG;AAEzB,MAAI,SAAS,UACX,SAAQ,IAAI,kBAAkB,QAAQ,aAAa,WAAW;AAEhE,eAAa,WAAW;AACxB,MAAI,OAAO,KAAK,KAAK,WAAW,OAAO,KAAK,KAAK,OAC/C,OAAM;;CAIV,MAAM,qBAAqB;AACzB,kBAAgB,KAAK,IAAI,GAAG,gBAAgB,EAAE;AAG9C,MAAI,cAAe;AAEnB,MAAI,SAAS,UACX,SAAQ,IAAI,kBAAkB,QAAQ,aAAa,aAAa;AAKlE,MAAI,OAAO,KAAK,KAAK,SAAS;AAC5B,sBAAmB,YAAY;AAC7B,WAAO,IAAI,OAAO;AAClB,UAAM,IAAI,OAAU;KACpB;AACF;;AAGF,MAAI,SAAS,sBAAsB,QACjC;WACS,OAAO,SAAS,sBAAsB,SAC/C,cAAa,iBAAiB;AAC5B,UAAO;KACN,SAAS,kBAAkB;MAE9B,QAAO;;AAIX,kBAAiB,OAAO,WAAW;AACnC,kBAAiB,QAAQ,WAAW;AACpC,kBAAiB,OAAO,WAAW;AAEnC,oBAAmB,OAAO,aAAa;AACvC,oBAAmB,QAAQ,aAAa;AACxC,oBAAmB,OAAO,aAAa;AAEvC,QAAO;EACL,IAAI,QAAQ;AACV,UAAO,MAAM,KAAK;;EAEpB,IAAI,SAAS;AACX,UAAO,OAAO,KAAK;;EAErB,IAAI,QAAQ;AACV,UAAO,MAAM,KAAK;;EAEpB,IAAI,UAAU;AACZ,UAAO,OAAO,KAAK,KAAK;;EAE1B,IAAI,SAAS;AACX,UAAO,OAAO,KAAK,KAAK;;EAE1B,SAAS;GACP,MAAM,UAAU,oBAAoB;AACpC,SAAM;AACN,UAAO;;EAET,YAAY;AAGV,OAAI,KAAK,OAAQ,QAAO,QAAQ,QAAQ,MAAM,KAAK,CAAe;AAClE,UAAO,KAAK,QAAQ;;EAEtB;EACA;EACD;;AAcH,SAAgB,oBACd,OACA,SACwB;AACxB,QAAO,eAAe,OAAO;EAAE,cAAc,EAAE;EAAE,GAAG;EAAS,CAAC;;;;;AC1NhE,SAAS,WAAW,EAAE,SAAoC;AACxD,OAAM;;AA2BR,SAAgB,aACd,OACiB;CACjB,MAAM,EAAE,SAAS,aAAa,aAAa;CAC3C,MAAM,iBAAiB,CAAC,QAAQ,CAAC,MAAM;AACvC,QACE,oBAAC,UAAD,kBACS;EACL,MAAM,SAAS,eAAe,MAAM,MAAM,EAAE,WAAW,QAAQ;AAC/D,MAAI,OAAQ,QAAO,oBAAC,YAAD,EAAY,OAAO,OAAO,OAAS;AACtD,MAAI,CAAC,eAAe,OAAO,MAAM,EAAE,OAAO,CAAE,QAAO;AACnD,SAAQ,SAAiB,GAAG,eAAe,KAAK,MAAM,EAAE,MAAM,CAAC;IAExD"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jayalfredprufrock/mobx-toolbox",
3
- "version": "0.4.0",
3
+ "version": "0.4.1",
4
4
  "description": "Misc mobx/react modules/utilities.",
5
5
  "homepage": "https://github.com/jayalfredprufrock/mobx-toolbox#readme",
6
6
  "bugs": {