mobx-mantle 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,253 @@
1
+ // src/mantle.tsx
2
+ import { useRef, useEffect, useLayoutEffect, forwardRef as reactForwardRef } from "react";
3
+ import { makeObservable as makeObservable2, observable as observable2, computed as computed2, action as action2, runInAction } from "mobx";
4
+ import { observer } from "mobx-react-lite";
5
+
6
+ // src/behavior.ts
7
+ import { makeObservable, observable, computed, action } from "mobx";
8
+ var BEHAVIOR_MARKER = /* @__PURE__ */ Symbol("behavior");
9
+ var BEHAVIOR_EXCLUDES = /* @__PURE__ */ new Set([
10
+ "onCreate",
11
+ "onLayoutMount",
12
+ "onMount",
13
+ "onUnmount",
14
+ "constructor"
15
+ ]);
16
+ var Behavior = class {
17
+ };
18
+ function makeBehaviorObservable(instance) {
19
+ const annotations = {};
20
+ const ownKeys = /* @__PURE__ */ new Set([
21
+ ...Object.keys(instance),
22
+ ...Object.keys(Object.getPrototypeOf(instance))
23
+ ]);
24
+ for (const key of ownKeys) {
25
+ if (BEHAVIOR_EXCLUDES.has(key)) continue;
26
+ if (key in annotations) continue;
27
+ const value = instance[key];
28
+ if (typeof value === "function") continue;
29
+ annotations[key] = observable;
30
+ }
31
+ let proto = Object.getPrototypeOf(instance);
32
+ while (proto && proto !== Behavior.prototype) {
33
+ const descriptors = Object.getOwnPropertyDescriptors(proto);
34
+ for (const [key, descriptor] of Object.entries(descriptors)) {
35
+ if (BEHAVIOR_EXCLUDES.has(key)) continue;
36
+ if (key in annotations) continue;
37
+ if (descriptor.get) {
38
+ annotations[key] = computed;
39
+ } else if (typeof descriptor.value === "function") {
40
+ annotations[key] = action.bound;
41
+ }
42
+ }
43
+ proto = Object.getPrototypeOf(proto);
44
+ }
45
+ makeObservable(instance, annotations);
46
+ }
47
+ function createBehavior(Def) {
48
+ var _a, _b, _c;
49
+ const BehaviorClass = (_c = class extends (_b = Def, _a = BEHAVIOR_MARKER, _b) {
50
+ constructor(...args) {
51
+ super(...args);
52
+ if (typeof this.onCreate === "function") {
53
+ this.onCreate(...args);
54
+ }
55
+ makeBehaviorObservable(this);
56
+ }
57
+ }, _c[_a] = true, _c);
58
+ Object.defineProperty(BehaviorClass, "name", { value: Def.name });
59
+ return BehaviorClass;
60
+ }
61
+ function isBehavior(value) {
62
+ if (value === null || typeof value !== "object") return false;
63
+ return value.constructor?.[BEHAVIOR_MARKER] === true;
64
+ }
65
+ function layoutMountBehavior(behavior) {
66
+ const inst = behavior.instance;
67
+ if ("onLayoutMount" in inst && typeof inst.onLayoutMount === "function") {
68
+ behavior.layoutCleanup = inst.onLayoutMount() ?? void 0;
69
+ }
70
+ }
71
+ function mountBehavior(behavior) {
72
+ const inst = behavior.instance;
73
+ if ("onMount" in inst && typeof inst.onMount === "function") {
74
+ behavior.cleanup = inst.onMount() ?? void 0;
75
+ }
76
+ }
77
+ function unmountBehavior(behavior) {
78
+ behavior.layoutCleanup?.();
79
+ behavior.cleanup?.();
80
+ const inst = behavior.instance;
81
+ if ("onUnmount" in inst && typeof inst.onUnmount === "function") {
82
+ inst.onUnmount();
83
+ }
84
+ }
85
+
86
+ // src/mantle.tsx
87
+ var globalConfig = {
88
+ autoObservable: true
89
+ };
90
+ function configure(config) {
91
+ Object.assign(globalConfig, config);
92
+ }
93
+ var View = class {
94
+ constructor() {
95
+ /** @internal */
96
+ this._behaviors = [];
97
+ }
98
+ get props() {
99
+ return this._propsBox.get();
100
+ }
101
+ set props(value) {
102
+ runInAction(() => this._propsBox.set(value));
103
+ }
104
+ ref() {
105
+ return { current: null };
106
+ }
107
+ /** @internal - Scan own properties for behavior instances and register them */
108
+ _collectBehaviors() {
109
+ for (const key of Object.keys(this)) {
110
+ if (key.startsWith("_")) continue;
111
+ const value = this[key];
112
+ if (isBehavior(value)) {
113
+ this._behaviors.push({ instance: value });
114
+ }
115
+ }
116
+ }
117
+ /** @internal */
118
+ _layoutMountBehaviors() {
119
+ for (const behavior of this._behaviors) {
120
+ layoutMountBehavior(behavior);
121
+ }
122
+ }
123
+ /** @internal */
124
+ _mountBehaviors() {
125
+ for (const behavior of this._behaviors) {
126
+ mountBehavior(behavior);
127
+ }
128
+ }
129
+ /** @internal */
130
+ _unmountBehaviors() {
131
+ for (const behavior of this._behaviors) {
132
+ unmountBehavior(behavior);
133
+ }
134
+ }
135
+ };
136
+ var BASE_EXCLUDES = /* @__PURE__ */ new Set([
137
+ "props",
138
+ "_propsBox",
139
+ "forwardRef",
140
+ "onCreate",
141
+ "onLayoutMount",
142
+ "onMount",
143
+ "onUnmount",
144
+ "render",
145
+ "ref",
146
+ "constructor",
147
+ "_behaviors",
148
+ "_collectBehaviors",
149
+ "_layoutMountBehaviors",
150
+ "_mountBehaviors",
151
+ "_unmountBehaviors"
152
+ ]);
153
+ function isRefLike(value) {
154
+ return value !== null && typeof value === "object" && "current" in value && Object.keys(value).length === 1;
155
+ }
156
+ function makeViewObservable(instance, autoBind) {
157
+ const annotations = {};
158
+ const ownKeys = /* @__PURE__ */ new Set([
159
+ ...Object.keys(instance),
160
+ ...Object.keys(Object.getPrototypeOf(instance))
161
+ ]);
162
+ for (const key of ownKeys) {
163
+ if (BASE_EXCLUDES.has(key)) continue;
164
+ if (key in annotations) continue;
165
+ const value = instance[key];
166
+ if (typeof value === "function") continue;
167
+ if (isBehavior(value)) {
168
+ annotations[key] = observable2.ref;
169
+ continue;
170
+ }
171
+ if (isRefLike(value)) {
172
+ annotations[key] = observable2.ref;
173
+ } else {
174
+ annotations[key] = observable2;
175
+ }
176
+ }
177
+ let proto = Object.getPrototypeOf(instance);
178
+ while (proto && proto !== View.prototype) {
179
+ const descriptors = Object.getOwnPropertyDescriptors(proto);
180
+ for (const [key, descriptor] of Object.entries(descriptors)) {
181
+ if (BASE_EXCLUDES.has(key)) continue;
182
+ if (key in annotations) continue;
183
+ if (descriptor.get) {
184
+ annotations[key] = computed2;
185
+ } else if (typeof descriptor.value === "function") {
186
+ annotations[key] = autoBind ? action2.bound : action2;
187
+ }
188
+ }
189
+ proto = Object.getPrototypeOf(proto);
190
+ }
191
+ makeObservable2(instance, annotations);
192
+ }
193
+ function createView(ViewClass, templateOrOptions) {
194
+ const template = typeof templateOrOptions === "function" ? templateOrOptions : void 0;
195
+ const options = typeof templateOrOptions === "object" ? templateOrOptions : {};
196
+ const { autoObservable = globalConfig.autoObservable } = options;
197
+ const Component = reactForwardRef((props, ref) => {
198
+ const vmRef = useRef(null);
199
+ const classRef = useRef(ViewClass);
200
+ if (vmRef.current && classRef.current !== ViewClass) {
201
+ classRef.current = ViewClass;
202
+ vmRef.current = null;
203
+ }
204
+ if (!vmRef.current) {
205
+ const instance = new ViewClass();
206
+ instance._propsBox = observable2.box(props, { deep: false });
207
+ instance.forwardRef = ref;
208
+ instance._collectBehaviors();
209
+ if (autoObservable) {
210
+ makeViewObservable(instance, true);
211
+ } else {
212
+ makeObservable2(instance);
213
+ }
214
+ instance.onCreate?.();
215
+ vmRef.current = instance;
216
+ }
217
+ const vm = vmRef.current;
218
+ vm.props = props;
219
+ vm.forwardRef = ref;
220
+ useLayoutEffect(() => {
221
+ vm._layoutMountBehaviors();
222
+ const cleanup = vm.onLayoutMount?.();
223
+ return () => {
224
+ cleanup?.();
225
+ };
226
+ }, [vm]);
227
+ useEffect(() => {
228
+ vm._mountBehaviors();
229
+ const cleanup = vm.onMount?.();
230
+ return () => {
231
+ cleanup?.();
232
+ vm.onUnmount?.();
233
+ vm._unmountBehaviors();
234
+ };
235
+ }, [vm]);
236
+ if (!template && !vm.render) {
237
+ throw new Error(
238
+ `${ViewClass.name}: Missing render() method. Either define render() in your View class or pass a template function to createView().`
239
+ );
240
+ }
241
+ return template ? template(vm) : vm.render();
242
+ });
243
+ return observer(Component);
244
+ }
245
+ export {
246
+ Behavior,
247
+ View,
248
+ View as ViewModel,
249
+ configure,
250
+ createBehavior,
251
+ createView
252
+ };
253
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/mantle.tsx","../src/behavior.ts"],"sourcesContent":["import { useRef, useEffect, useLayoutEffect, forwardRef as reactForwardRef, type Ref, type JSX } from 'react';\nimport { makeObservable, observable, computed, action, runInAction, AnnotationsMap, type IObservableValue } from 'mobx';\nimport { observer } from 'mobx-react-lite';\nimport {\n type BehaviorEntry,\n isBehavior,\n layoutMountBehavior,\n mountBehavior,\n unmountBehavior,\n} from './behavior';\n\n/**\n * Global configuration options for mobx-mantle\n */\nexport interface MantleConfig {\n /** Whether to automatically make View instances observable (default: true) */\n autoObservable?: boolean;\n}\n\nconst globalConfig: MantleConfig = {\n autoObservable: true,\n};\n\n/**\n * Configure global defaults for mobx-mantle.\n * Settings can still be overridden per-view in createView options.\n */\nexport function configure(config: MantleConfig): void {\n Object.assign(globalConfig, config);\n}\n\nexport class View<P = {}> {\n /** @internal */\n _propsBox!: IObservableValue<P>;\n \n get props(): P {\n return this._propsBox.get();\n }\n \n set props(value: P) {\n runInAction(() => this._propsBox.set(value));\n }\n\n forwardRef?: Ref<any>;\n\n /** @internal */\n _behaviors: BehaviorEntry[] = [];\n\n onCreate?(): void;\n onLayoutMount?(): void | (() => void);\n onMount?(): void | (() => void);\n onUnmount?(): void;\n\n ref<T extends HTMLElement = HTMLElement>(): { current: T | null } {\n return { current: null };\n }\n\n /** @internal - Scan own properties for behavior instances and register them */\n _collectBehaviors(): void {\n for (const key of Object.keys(this)) {\n if (key.startsWith('_')) continue;\n const value = (this as any)[key];\n if (isBehavior(value)) {\n this._behaviors.push({ instance: value });\n }\n }\n }\n\n /** @internal */\n _layoutMountBehaviors(): void {\n for (const behavior of this._behaviors) {\n layoutMountBehavior(behavior);\n }\n }\n\n /** @internal */\n _mountBehaviors(): void {\n for (const behavior of this._behaviors) {\n mountBehavior(behavior);\n }\n }\n\n /** @internal */\n _unmountBehaviors(): void {\n for (const behavior of this._behaviors) {\n unmountBehavior(behavior);\n }\n }\n\n render?(): JSX.Element;\n}\n\n/** Alias for View - use when separating ViewModel from template */\nexport { View as ViewModel };\n\n// Re-export from behavior module\nexport { createBehavior, Behavior } from './behavior';\n\n// Base class members that should not be made observable\nconst BASE_EXCLUDES = new Set([\n 'props',\n '_propsBox',\n 'forwardRef', \n 'onCreate',\n 'onLayoutMount',\n 'onMount', \n 'onUnmount',\n 'render', \n 'ref', \n 'constructor',\n '_behaviors',\n '_collectBehaviors',\n '_layoutMountBehaviors',\n '_mountBehaviors',\n '_unmountBehaviors',\n]);\n\n/**\n * Detects if a value is a ref-like object ({ current: ... })\n * These should use observable.ref to preserve object identity for React\n */\nfunction isRefLike(value: unknown): boolean {\n return (\n value !== null &&\n typeof value === 'object' &&\n 'current' in value &&\n Object.keys(value).length === 1\n );\n}\n\n/**\n * Creates observable annotations for a View subclass instance.\n * This is needed because makeAutoObservable doesn't work with inheritance.\n */\nfunction makeViewObservable<T extends View>(instance: T, autoBind: boolean) {\n const annotations: AnnotationsMap<T, never> = {} as AnnotationsMap<T, never>;\n\n // Collect own properties (instance state) → observable\n // Also check prototype for class field declarations (handles uninitialized fields)\n const ownKeys = new Set([\n ...Object.keys(instance),\n ...Object.keys(Object.getPrototypeOf(instance)),\n ]);\n\n for (const key of ownKeys) {\n if (BASE_EXCLUDES.has(key)) continue;\n if (key in annotations) continue;\n\n const value = (instance as any)[key];\n\n // Skip functions (these are handled in the prototype walk)\n if (typeof value === 'function') continue;\n\n // Skip behavior instances (they're already observable)\n if (isBehavior(value)) {\n (annotations as any)[key] = observable.ref;\n continue;\n }\n\n // Use observable.ref for ref-like objects to preserve identity\n if (isRefLike(value)) {\n (annotations as any)[key] = observable.ref;\n } else {\n (annotations as any)[key] = observable;\n }\n }\n\n // Walk prototype chain up to (but not including) View\n let proto = Object.getPrototypeOf(instance);\n while (proto && proto !== View.prototype) {\n const descriptors = Object.getOwnPropertyDescriptors(proto);\n\n for (const [key, descriptor] of Object.entries(descriptors)) {\n if (BASE_EXCLUDES.has(key)) continue;\n if (key in annotations) continue;\n\n if (descriptor.get) {\n // Getter → computed\n (annotations as any)[key] = computed;\n } else if (typeof descriptor.value === 'function') {\n // Method → action (optionally bound)\n (annotations as any)[key] = autoBind ? action.bound : action;\n }\n }\n\n proto = Object.getPrototypeOf(proto);\n }\n\n makeObservable(instance, annotations);\n}\n\ntype PropsOf<V> = V extends View<infer P> ? P : object;\n\nexport function createView<V extends View<any>>(\n ViewClass: new () => V,\n templateOrOptions?: ((vm: V) => JSX.Element) | { autoObservable?: boolean }\n) {\n type P = PropsOf<V>;\n\n const template = typeof templateOrOptions === 'function' ? templateOrOptions : undefined;\n const options = typeof templateOrOptions === 'object' ? templateOrOptions : {};\n const { autoObservable = globalConfig.autoObservable } = options;\n\n const Component = reactForwardRef<unknown, P>((props, ref) => {\n const vmRef = useRef<V | null>(null);\n const classRef = useRef(ViewClass);\n\n // HMR: class identity changes when the module re-executes, but useRef\n // values survive (React Fast Refresh preserves hooks). On detection,\n // we simply discard the old instance and create fresh — clean slate.\n // In production this check is always false (class identity is stable).\n if (vmRef.current && classRef.current !== ViewClass) {\n classRef.current = ViewClass;\n vmRef.current = null;\n }\n\n if (!vmRef.current) {\n const instance = new ViewClass();\n\n // Props is always reactive via observable.box (works with all decorator modes)\n instance._propsBox = observable.box(props, { deep: false });\n instance.forwardRef = ref;\n\n // Collect behavior instances from properties (must happen before makeObservable)\n instance._collectBehaviors();\n\n if (autoObservable) {\n makeViewObservable(instance, true);\n } else {\n // For decorator users: applies legacy decorator metadata\n // For TC39 decorators: no-op (they're self-registering)\n makeObservable(instance);\n }\n\n instance.onCreate?.();\n vmRef.current = instance;\n }\n\n const vm = vmRef.current;\n\n // Props setter handles reactivity via observable.box\n vm.props = props;\n vm.forwardRef = ref;\n\n // [vm] dep ensures effects re-run when instance changes (HMR).\n // On normal renders vm is stable, so effects run once — same as [].\n useLayoutEffect(() => {\n vm._layoutMountBehaviors();\n const cleanup = vm.onLayoutMount?.();\n return () => {\n cleanup?.();\n };\n }, [vm]);\n\n useEffect(() => {\n vm._mountBehaviors();\n const cleanup = vm.onMount?.();\n return () => {\n cleanup?.();\n vm.onUnmount?.();\n vm._unmountBehaviors();\n };\n }, [vm]);\n\n if (!template && !vm.render) {\n throw new Error(\n `${ViewClass.name}: Missing render() method. Either define render() in your View class or pass a template function to createView().`\n );\n }\n\n return template ? template(vm) : vm.render!();\n });\n\n return observer(Component);\n}\n","import { makeObservable, observable, computed, action, type AnnotationsMap } from 'mobx';\r\n\r\n/** Symbol marker to identify behavior instances */\r\nexport const BEHAVIOR_MARKER = Symbol('behavior');\r\n\r\n// Behavior base class members that should not be made observable\r\nconst BEHAVIOR_EXCLUDES = new Set([\r\n 'onCreate',\r\n 'onLayoutMount',\r\n 'onMount',\r\n 'onUnmount',\r\n 'constructor',\r\n]);\r\n\r\n/**\r\n * Base class for behaviors. Provides lifecycle method signatures and IDE autocomplete.\r\n * Extend this class and wrap with createBehavior().\r\n * \r\n * You can pass arguments either via constructor or onCreate:\r\n * \r\n * @example Constructor args\r\n * ```tsx\r\n * class FetchBehavior extends Behavior {\r\n * constructor(public url: string, public interval = 5000) {\r\n * super();\r\n * }\r\n * }\r\n * ```\r\n * \r\n * @example onCreate args (no constructor boilerplate)\r\n * ```tsx\r\n * class FetchBehavior extends Behavior {\r\n * url!: string;\r\n * interval = 5000;\r\n * \r\n * onCreate(url: string, interval = 5000) {\r\n * this.url = url;\r\n * this.interval = interval;\r\n * }\r\n * }\r\n * ```\r\n */\r\nexport class Behavior {\r\n onCreate?(...args: any[]): void;\r\n onLayoutMount?(): void | (() => void);\r\n onMount?(): void | (() => void);\r\n onUnmount?(): void;\r\n}\r\n\r\n/**\r\n * Makes a behavior instance observable, handling inheritance properly.\r\n * Similar to makeViewObservable but for behaviors.\r\n */\r\nfunction makeBehaviorObservable<T extends Behavior>(instance: T): void {\r\n const annotations: AnnotationsMap<T, never> = {} as AnnotationsMap<T, never>;\r\n\r\n // Collect own properties → observable\r\n const ownKeys = new Set([\r\n ...Object.keys(instance),\r\n ...Object.keys(Object.getPrototypeOf(instance)),\r\n ]);\r\n\r\n for (const key of ownKeys) {\r\n if (BEHAVIOR_EXCLUDES.has(key)) continue;\r\n if (key in annotations) continue;\r\n\r\n const value = (instance as any)[key];\r\n if (typeof value === 'function') continue;\r\n\r\n (annotations as any)[key] = observable;\r\n }\r\n\r\n // Walk prototype chain up to (but not including) Behavior\r\n let proto = Object.getPrototypeOf(instance);\r\n while (proto && proto !== Behavior.prototype) {\r\n const descriptors = Object.getOwnPropertyDescriptors(proto);\r\n\r\n for (const [key, descriptor] of Object.entries(descriptors)) {\r\n if (BEHAVIOR_EXCLUDES.has(key)) continue;\r\n if (key in annotations) continue;\r\n\r\n if (descriptor.get) {\r\n (annotations as any)[key] = computed;\r\n } else if (typeof descriptor.value === 'function') {\r\n (annotations as any)[key] = action.bound;\r\n }\r\n }\r\n\r\n proto = Object.getPrototypeOf(proto);\r\n }\r\n\r\n makeObservable(instance, annotations);\r\n}\r\n\r\n/** @internal */\r\nexport interface BehaviorEntry {\r\n instance: any;\r\n cleanup?: () => void;\r\n layoutCleanup?: () => void;\r\n}\r\n\r\n/**\r\n * Extracts parameter types from onCreate method\r\n */\r\ntype OnCreateParams<T> = T extends { onCreate(...args: infer A): any } ? A : [];\r\n\r\n/**\r\n * Extracts constructor parameter types\r\n */\r\ntype ConstructorParams<T> = T extends new (...args: infer A) => any ? A : [];\r\n\r\n/**\r\n * Determines the args for createBehavior:\r\n * - If constructor has args, use those\r\n * - Otherwise, if onCreate has args, use those\r\n */\r\ntype BehaviorArgs<T extends new (...args: any[]) => any> = \r\n ConstructorParams<T> extends [] \r\n ? OnCreateParams<InstanceType<T>> \r\n : ConstructorParams<T>;\r\n\r\n/**\r\n * Creates a behavior class with automatic observable wrapping and lifecycle management.\r\n * \r\n * Arguments can be passed via constructor OR onCreate - your choice:\r\n * \r\n * @example Constructor args\r\n * ```tsx\r\n * class FetchBehavior extends Behavior {\r\n * constructor(public url: string, public interval = 5000) {\r\n * super();\r\n * }\r\n * onMount() { ... }\r\n * }\r\n * export default createBehavior(FetchBehavior);\r\n * ```\r\n * \r\n * @example onCreate args (no constructor needed)\r\n * ```tsx\r\n * class FetchBehavior extends Behavior {\r\n * url!: string;\r\n * onCreate(url: string, interval = 5000) {\r\n * this.url = url;\r\n * }\r\n * onMount() { ... }\r\n * }\r\n * export default createBehavior(FetchBehavior);\r\n * ```\r\n * \r\n * Usage in a View - just instantiate:\r\n * ```tsx\r\n * class MyView extends View<Props> {\r\n * fetcher = new FetchBehavior('/api/items', 3000);\r\n * }\r\n * ```\r\n */\r\nexport function createBehavior<T extends new (...args: any[]) => any>(\r\n Def: T\r\n): new (...args: BehaviorArgs<T>) => InstanceType<T> {\r\n const BehaviorClass = class extends (Def as any) {\r\n static [BEHAVIOR_MARKER] = true;\r\n\r\n constructor(...args: any[]) {\r\n super(...args);\r\n \r\n // Call onCreate with args (if it exists)\r\n if (typeof this.onCreate === 'function') {\r\n this.onCreate(...args);\r\n }\r\n \r\n // Make the instance observable (after onCreate so all properties exist)\r\n makeBehaviorObservable(this);\r\n }\r\n };\r\n\r\n // Preserve the original class name for debugging\r\n Object.defineProperty(BehaviorClass, 'name', { value: Def.name });\r\n\r\n return BehaviorClass as any;\r\n}\r\n\r\n/**\r\n * Checks if a value is a behavior instance created by createBehavior()\r\n */\r\nexport function isBehavior(value: unknown): boolean {\r\n if (value === null || typeof value !== 'object') return false;\r\n return (value.constructor as any)?.[BEHAVIOR_MARKER] === true;\r\n}\r\n\r\n/** @internal */\r\nexport function layoutMountBehavior(behavior: BehaviorEntry): void {\r\n const inst = behavior.instance;\r\n\r\n if ('onLayoutMount' in inst && typeof inst.onLayoutMount === 'function') {\r\n behavior.layoutCleanup = inst.onLayoutMount() ?? undefined;\r\n }\r\n}\r\n\r\n/** @internal */\r\nexport function mountBehavior(behavior: BehaviorEntry): void {\r\n const inst = behavior.instance;\r\n\r\n if ('onMount' in inst && typeof inst.onMount === 'function') {\r\n behavior.cleanup = inst.onMount() ?? undefined;\r\n }\r\n}\r\n\r\n/** @internal */\r\nexport function unmountBehavior(behavior: BehaviorEntry): void {\r\n // Call layout cleanup if exists\r\n behavior.layoutCleanup?.();\r\n\r\n // Call cleanup if exists\r\n behavior.cleanup?.();\r\n\r\n // Call onUnmount if exists\r\n const inst = behavior.instance;\r\n if ('onUnmount' in inst && typeof inst.onUnmount === 'function') {\r\n inst.onUnmount();\r\n }\r\n}\r\n"],"mappings":"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","names":["makeObservable","observable","computed","action","observable","computed","action","makeObservable"]}
package/package.json ADDED
@@ -0,0 +1,64 @@
1
+ {
2
+ "name": "mobx-mantle",
3
+ "version": "0.1.5",
4
+ "description": "A minimal library that brings MobX reactivity to React components with a familiar class-based API",
5
+ "author": "Craig Albert <me@craigalbert.com>",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/craigthings/mobx-mantle"
9
+ },
10
+ "homepage": "https://github.com/craigthings/mobx-mantle#readme",
11
+ "bugs": {
12
+ "url": "https://github.com/craigthings/mobx-mantle/issues"
13
+ },
14
+ "license": "MIT",
15
+ "keywords": [
16
+ "react",
17
+ "mobx",
18
+ "viewmodel",
19
+ "mvvm",
20
+ "class-components"
21
+ ],
22
+ "type": "module",
23
+ "main": "./dist/index.cjs",
24
+ "module": "./dist/index.js",
25
+ "types": "./dist/index.d.ts",
26
+ "exports": {
27
+ ".": {
28
+ "import": {
29
+ "types": "./dist/index.d.ts",
30
+ "default": "./dist/index.js"
31
+ },
32
+ "require": {
33
+ "types": "./dist/index.d.cts",
34
+ "default": "./dist/index.cjs"
35
+ }
36
+ }
37
+ },
38
+ "files": [
39
+ "dist"
40
+ ],
41
+ "sideEffects": false,
42
+ "scripts": {
43
+ "dev": "vite",
44
+ "build": "tsup",
45
+ "prepublishOnly": "npm run build"
46
+ },
47
+ "peerDependencies": {
48
+ "mobx": ">=6.0.0",
49
+ "mobx-react-lite": ">=3.0.0",
50
+ "react": ">=17.0.0"
51
+ },
52
+ "devDependencies": {
53
+ "@types/react": "^18.2.0",
54
+ "@types/react-dom": "^18.2.0",
55
+ "@vitejs/plugin-react": "^4.2.0",
56
+ "mobx": "^6.12.0",
57
+ "mobx-react-lite": "^4.0.0",
58
+ "react": "^18.2.0",
59
+ "react-dom": "^18.2.0",
60
+ "tsup": "^8.0.0",
61
+ "typescript": "^5.3.0",
62
+ "vite": "^5.0.0"
63
+ }
64
+ }