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.cjs ADDED
@@ -0,0 +1,285 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ Behavior: () => Behavior,
24
+ View: () => View,
25
+ ViewModel: () => View,
26
+ configure: () => configure,
27
+ createBehavior: () => createBehavior,
28
+ createView: () => createView
29
+ });
30
+ module.exports = __toCommonJS(index_exports);
31
+
32
+ // src/mantle.tsx
33
+ var import_react = require("react");
34
+ var import_mobx2 = require("mobx");
35
+ var import_mobx_react_lite = require("mobx-react-lite");
36
+
37
+ // src/behavior.ts
38
+ var import_mobx = require("mobx");
39
+ var BEHAVIOR_MARKER = /* @__PURE__ */ Symbol("behavior");
40
+ var BEHAVIOR_EXCLUDES = /* @__PURE__ */ new Set([
41
+ "onCreate",
42
+ "onLayoutMount",
43
+ "onMount",
44
+ "onUnmount",
45
+ "constructor"
46
+ ]);
47
+ var Behavior = class {
48
+ };
49
+ function makeBehaviorObservable(instance) {
50
+ const annotations = {};
51
+ const ownKeys = /* @__PURE__ */ new Set([
52
+ ...Object.keys(instance),
53
+ ...Object.keys(Object.getPrototypeOf(instance))
54
+ ]);
55
+ for (const key of ownKeys) {
56
+ if (BEHAVIOR_EXCLUDES.has(key)) continue;
57
+ if (key in annotations) continue;
58
+ const value = instance[key];
59
+ if (typeof value === "function") continue;
60
+ annotations[key] = import_mobx.observable;
61
+ }
62
+ let proto = Object.getPrototypeOf(instance);
63
+ while (proto && proto !== Behavior.prototype) {
64
+ const descriptors = Object.getOwnPropertyDescriptors(proto);
65
+ for (const [key, descriptor] of Object.entries(descriptors)) {
66
+ if (BEHAVIOR_EXCLUDES.has(key)) continue;
67
+ if (key in annotations) continue;
68
+ if (descriptor.get) {
69
+ annotations[key] = import_mobx.computed;
70
+ } else if (typeof descriptor.value === "function") {
71
+ annotations[key] = import_mobx.action.bound;
72
+ }
73
+ }
74
+ proto = Object.getPrototypeOf(proto);
75
+ }
76
+ (0, import_mobx.makeObservable)(instance, annotations);
77
+ }
78
+ function createBehavior(Def) {
79
+ var _a, _b, _c;
80
+ const BehaviorClass = (_c = class extends (_b = Def, _a = BEHAVIOR_MARKER, _b) {
81
+ constructor(...args) {
82
+ super(...args);
83
+ if (typeof this.onCreate === "function") {
84
+ this.onCreate(...args);
85
+ }
86
+ makeBehaviorObservable(this);
87
+ }
88
+ }, _c[_a] = true, _c);
89
+ Object.defineProperty(BehaviorClass, "name", { value: Def.name });
90
+ return BehaviorClass;
91
+ }
92
+ function isBehavior(value) {
93
+ if (value === null || typeof value !== "object") return false;
94
+ return value.constructor?.[BEHAVIOR_MARKER] === true;
95
+ }
96
+ function layoutMountBehavior(behavior) {
97
+ const inst = behavior.instance;
98
+ if ("onLayoutMount" in inst && typeof inst.onLayoutMount === "function") {
99
+ behavior.layoutCleanup = inst.onLayoutMount() ?? void 0;
100
+ }
101
+ }
102
+ function mountBehavior(behavior) {
103
+ const inst = behavior.instance;
104
+ if ("onMount" in inst && typeof inst.onMount === "function") {
105
+ behavior.cleanup = inst.onMount() ?? void 0;
106
+ }
107
+ }
108
+ function unmountBehavior(behavior) {
109
+ behavior.layoutCleanup?.();
110
+ behavior.cleanup?.();
111
+ const inst = behavior.instance;
112
+ if ("onUnmount" in inst && typeof inst.onUnmount === "function") {
113
+ inst.onUnmount();
114
+ }
115
+ }
116
+
117
+ // src/mantle.tsx
118
+ var globalConfig = {
119
+ autoObservable: true
120
+ };
121
+ function configure(config) {
122
+ Object.assign(globalConfig, config);
123
+ }
124
+ var View = class {
125
+ constructor() {
126
+ /** @internal */
127
+ this._behaviors = [];
128
+ }
129
+ get props() {
130
+ return this._propsBox.get();
131
+ }
132
+ set props(value) {
133
+ (0, import_mobx2.runInAction)(() => this._propsBox.set(value));
134
+ }
135
+ ref() {
136
+ return { current: null };
137
+ }
138
+ /** @internal - Scan own properties for behavior instances and register them */
139
+ _collectBehaviors() {
140
+ for (const key of Object.keys(this)) {
141
+ if (key.startsWith("_")) continue;
142
+ const value = this[key];
143
+ if (isBehavior(value)) {
144
+ this._behaviors.push({ instance: value });
145
+ }
146
+ }
147
+ }
148
+ /** @internal */
149
+ _layoutMountBehaviors() {
150
+ for (const behavior of this._behaviors) {
151
+ layoutMountBehavior(behavior);
152
+ }
153
+ }
154
+ /** @internal */
155
+ _mountBehaviors() {
156
+ for (const behavior of this._behaviors) {
157
+ mountBehavior(behavior);
158
+ }
159
+ }
160
+ /** @internal */
161
+ _unmountBehaviors() {
162
+ for (const behavior of this._behaviors) {
163
+ unmountBehavior(behavior);
164
+ }
165
+ }
166
+ };
167
+ var BASE_EXCLUDES = /* @__PURE__ */ new Set([
168
+ "props",
169
+ "_propsBox",
170
+ "forwardRef",
171
+ "onCreate",
172
+ "onLayoutMount",
173
+ "onMount",
174
+ "onUnmount",
175
+ "render",
176
+ "ref",
177
+ "constructor",
178
+ "_behaviors",
179
+ "_collectBehaviors",
180
+ "_layoutMountBehaviors",
181
+ "_mountBehaviors",
182
+ "_unmountBehaviors"
183
+ ]);
184
+ function isRefLike(value) {
185
+ return value !== null && typeof value === "object" && "current" in value && Object.keys(value).length === 1;
186
+ }
187
+ function makeViewObservable(instance, autoBind) {
188
+ const annotations = {};
189
+ const ownKeys = /* @__PURE__ */ new Set([
190
+ ...Object.keys(instance),
191
+ ...Object.keys(Object.getPrototypeOf(instance))
192
+ ]);
193
+ for (const key of ownKeys) {
194
+ if (BASE_EXCLUDES.has(key)) continue;
195
+ if (key in annotations) continue;
196
+ const value = instance[key];
197
+ if (typeof value === "function") continue;
198
+ if (isBehavior(value)) {
199
+ annotations[key] = import_mobx2.observable.ref;
200
+ continue;
201
+ }
202
+ if (isRefLike(value)) {
203
+ annotations[key] = import_mobx2.observable.ref;
204
+ } else {
205
+ annotations[key] = import_mobx2.observable;
206
+ }
207
+ }
208
+ let proto = Object.getPrototypeOf(instance);
209
+ while (proto && proto !== View.prototype) {
210
+ const descriptors = Object.getOwnPropertyDescriptors(proto);
211
+ for (const [key, descriptor] of Object.entries(descriptors)) {
212
+ if (BASE_EXCLUDES.has(key)) continue;
213
+ if (key in annotations) continue;
214
+ if (descriptor.get) {
215
+ annotations[key] = import_mobx2.computed;
216
+ } else if (typeof descriptor.value === "function") {
217
+ annotations[key] = autoBind ? import_mobx2.action.bound : import_mobx2.action;
218
+ }
219
+ }
220
+ proto = Object.getPrototypeOf(proto);
221
+ }
222
+ (0, import_mobx2.makeObservable)(instance, annotations);
223
+ }
224
+ function createView(ViewClass, templateOrOptions) {
225
+ const template = typeof templateOrOptions === "function" ? templateOrOptions : void 0;
226
+ const options = typeof templateOrOptions === "object" ? templateOrOptions : {};
227
+ const { autoObservable = globalConfig.autoObservable } = options;
228
+ const Component = (0, import_react.forwardRef)((props, ref) => {
229
+ const vmRef = (0, import_react.useRef)(null);
230
+ const classRef = (0, import_react.useRef)(ViewClass);
231
+ if (vmRef.current && classRef.current !== ViewClass) {
232
+ classRef.current = ViewClass;
233
+ vmRef.current = null;
234
+ }
235
+ if (!vmRef.current) {
236
+ const instance = new ViewClass();
237
+ instance._propsBox = import_mobx2.observable.box(props, { deep: false });
238
+ instance.forwardRef = ref;
239
+ instance._collectBehaviors();
240
+ if (autoObservable) {
241
+ makeViewObservable(instance, true);
242
+ } else {
243
+ (0, import_mobx2.makeObservable)(instance);
244
+ }
245
+ instance.onCreate?.();
246
+ vmRef.current = instance;
247
+ }
248
+ const vm = vmRef.current;
249
+ vm.props = props;
250
+ vm.forwardRef = ref;
251
+ (0, import_react.useLayoutEffect)(() => {
252
+ vm._layoutMountBehaviors();
253
+ const cleanup = vm.onLayoutMount?.();
254
+ return () => {
255
+ cleanup?.();
256
+ };
257
+ }, [vm]);
258
+ (0, import_react.useEffect)(() => {
259
+ vm._mountBehaviors();
260
+ const cleanup = vm.onMount?.();
261
+ return () => {
262
+ cleanup?.();
263
+ vm.onUnmount?.();
264
+ vm._unmountBehaviors();
265
+ };
266
+ }, [vm]);
267
+ if (!template && !vm.render) {
268
+ throw new Error(
269
+ `${ViewClass.name}: Missing render() method. Either define render() in your View class or pass a template function to createView().`
270
+ );
271
+ }
272
+ return template ? template(vm) : vm.render();
273
+ });
274
+ return (0, import_mobx_react_lite.observer)(Component);
275
+ }
276
+ // Annotate the CommonJS export names for ESM import in node:
277
+ 0 && (module.exports = {
278
+ Behavior,
279
+ View,
280
+ ViewModel,
281
+ configure,
282
+ createBehavior,
283
+ createView
284
+ });
285
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/mantle.tsx","../src/behavior.ts"],"sourcesContent":["export { View, ViewModel, Behavior, createBehavior, createView, configure } from './mantle';\r\nexport type { MantleConfig } from './mantle';\r\n","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":["import_mobx","reactForwardRef"]}
@@ -0,0 +1,143 @@
1
+ import * as react from 'react';
2
+ import { Ref, JSX } from 'react';
3
+ import { IObservableValue } from 'mobx';
4
+
5
+ /**
6
+ * Base class for behaviors. Provides lifecycle method signatures and IDE autocomplete.
7
+ * Extend this class and wrap with createBehavior().
8
+ *
9
+ * You can pass arguments either via constructor or onCreate:
10
+ *
11
+ * @example Constructor args
12
+ * ```tsx
13
+ * class FetchBehavior extends Behavior {
14
+ * constructor(public url: string, public interval = 5000) {
15
+ * super();
16
+ * }
17
+ * }
18
+ * ```
19
+ *
20
+ * @example onCreate args (no constructor boilerplate)
21
+ * ```tsx
22
+ * class FetchBehavior extends Behavior {
23
+ * url!: string;
24
+ * interval = 5000;
25
+ *
26
+ * onCreate(url: string, interval = 5000) {
27
+ * this.url = url;
28
+ * this.interval = interval;
29
+ * }
30
+ * }
31
+ * ```
32
+ */
33
+ declare class Behavior {
34
+ onCreate?(...args: any[]): void;
35
+ onLayoutMount?(): void | (() => void);
36
+ onMount?(): void | (() => void);
37
+ onUnmount?(): void;
38
+ }
39
+ /** @internal */
40
+ interface BehaviorEntry {
41
+ instance: any;
42
+ cleanup?: () => void;
43
+ layoutCleanup?: () => void;
44
+ }
45
+ /**
46
+ * Extracts parameter types from onCreate method
47
+ */
48
+ type OnCreateParams<T> = T extends {
49
+ onCreate(...args: infer A): any;
50
+ } ? A : [];
51
+ /**
52
+ * Extracts constructor parameter types
53
+ */
54
+ type ConstructorParams<T> = T extends new (...args: infer A) => any ? A : [];
55
+ /**
56
+ * Determines the args for createBehavior:
57
+ * - If constructor has args, use those
58
+ * - Otherwise, if onCreate has args, use those
59
+ */
60
+ type BehaviorArgs<T extends new (...args: any[]) => any> = ConstructorParams<T> extends [] ? OnCreateParams<InstanceType<T>> : ConstructorParams<T>;
61
+ /**
62
+ * Creates a behavior class with automatic observable wrapping and lifecycle management.
63
+ *
64
+ * Arguments can be passed via constructor OR onCreate - your choice:
65
+ *
66
+ * @example Constructor args
67
+ * ```tsx
68
+ * class FetchBehavior extends Behavior {
69
+ * constructor(public url: string, public interval = 5000) {
70
+ * super();
71
+ * }
72
+ * onMount() { ... }
73
+ * }
74
+ * export default createBehavior(FetchBehavior);
75
+ * ```
76
+ *
77
+ * @example onCreate args (no constructor needed)
78
+ * ```tsx
79
+ * class FetchBehavior extends Behavior {
80
+ * url!: string;
81
+ * onCreate(url: string, interval = 5000) {
82
+ * this.url = url;
83
+ * }
84
+ * onMount() { ... }
85
+ * }
86
+ * export default createBehavior(FetchBehavior);
87
+ * ```
88
+ *
89
+ * Usage in a View - just instantiate:
90
+ * ```tsx
91
+ * class MyView extends View<Props> {
92
+ * fetcher = new FetchBehavior('/api/items', 3000);
93
+ * }
94
+ * ```
95
+ */
96
+ declare function createBehavior<T extends new (...args: any[]) => any>(Def: T): new (...args: BehaviorArgs<T>) => InstanceType<T>;
97
+
98
+ /**
99
+ * Global configuration options for mobx-mantle
100
+ */
101
+ interface MantleConfig {
102
+ /** Whether to automatically make View instances observable (default: true) */
103
+ autoObservable?: boolean;
104
+ }
105
+ /**
106
+ * Configure global defaults for mobx-mantle.
107
+ * Settings can still be overridden per-view in createView options.
108
+ */
109
+ declare function configure(config: MantleConfig): void;
110
+ declare class View<P = {}> {
111
+ /** @internal */
112
+ _propsBox: IObservableValue<P>;
113
+ get props(): P;
114
+ set props(value: P);
115
+ forwardRef?: Ref<any>;
116
+ /** @internal */
117
+ _behaviors: BehaviorEntry[];
118
+ onCreate?(): void;
119
+ onLayoutMount?(): void | (() => void);
120
+ onMount?(): void | (() => void);
121
+ onUnmount?(): void;
122
+ ref<T extends HTMLElement = HTMLElement>(): {
123
+ current: T | null;
124
+ };
125
+ /** @internal - Scan own properties for behavior instances and register them */
126
+ _collectBehaviors(): void;
127
+ /** @internal */
128
+ _layoutMountBehaviors(): void;
129
+ /** @internal */
130
+ _mountBehaviors(): void;
131
+ /** @internal */
132
+ _unmountBehaviors(): void;
133
+ render?(): JSX.Element;
134
+ }
135
+
136
+ type PropsOf<V> = V extends View<infer P> ? P : object;
137
+ declare function createView<V extends View<any>>(ViewClass: new () => V, templateOrOptions?: ((vm: V) => JSX.Element) | {
138
+ autoObservable?: boolean;
139
+ }): react.ForwardRefExoticComponent<react.PropsWithoutRef<PropsOf<V>> & react.RefAttributes<unknown>> & {
140
+ displayName: string;
141
+ };
142
+
143
+ export { Behavior, type MantleConfig, View, View as ViewModel, configure, createBehavior, createView };
@@ -0,0 +1,143 @@
1
+ import * as react from 'react';
2
+ import { Ref, JSX } from 'react';
3
+ import { IObservableValue } from 'mobx';
4
+
5
+ /**
6
+ * Base class for behaviors. Provides lifecycle method signatures and IDE autocomplete.
7
+ * Extend this class and wrap with createBehavior().
8
+ *
9
+ * You can pass arguments either via constructor or onCreate:
10
+ *
11
+ * @example Constructor args
12
+ * ```tsx
13
+ * class FetchBehavior extends Behavior {
14
+ * constructor(public url: string, public interval = 5000) {
15
+ * super();
16
+ * }
17
+ * }
18
+ * ```
19
+ *
20
+ * @example onCreate args (no constructor boilerplate)
21
+ * ```tsx
22
+ * class FetchBehavior extends Behavior {
23
+ * url!: string;
24
+ * interval = 5000;
25
+ *
26
+ * onCreate(url: string, interval = 5000) {
27
+ * this.url = url;
28
+ * this.interval = interval;
29
+ * }
30
+ * }
31
+ * ```
32
+ */
33
+ declare class Behavior {
34
+ onCreate?(...args: any[]): void;
35
+ onLayoutMount?(): void | (() => void);
36
+ onMount?(): void | (() => void);
37
+ onUnmount?(): void;
38
+ }
39
+ /** @internal */
40
+ interface BehaviorEntry {
41
+ instance: any;
42
+ cleanup?: () => void;
43
+ layoutCleanup?: () => void;
44
+ }
45
+ /**
46
+ * Extracts parameter types from onCreate method
47
+ */
48
+ type OnCreateParams<T> = T extends {
49
+ onCreate(...args: infer A): any;
50
+ } ? A : [];
51
+ /**
52
+ * Extracts constructor parameter types
53
+ */
54
+ type ConstructorParams<T> = T extends new (...args: infer A) => any ? A : [];
55
+ /**
56
+ * Determines the args for createBehavior:
57
+ * - If constructor has args, use those
58
+ * - Otherwise, if onCreate has args, use those
59
+ */
60
+ type BehaviorArgs<T extends new (...args: any[]) => any> = ConstructorParams<T> extends [] ? OnCreateParams<InstanceType<T>> : ConstructorParams<T>;
61
+ /**
62
+ * Creates a behavior class with automatic observable wrapping and lifecycle management.
63
+ *
64
+ * Arguments can be passed via constructor OR onCreate - your choice:
65
+ *
66
+ * @example Constructor args
67
+ * ```tsx
68
+ * class FetchBehavior extends Behavior {
69
+ * constructor(public url: string, public interval = 5000) {
70
+ * super();
71
+ * }
72
+ * onMount() { ... }
73
+ * }
74
+ * export default createBehavior(FetchBehavior);
75
+ * ```
76
+ *
77
+ * @example onCreate args (no constructor needed)
78
+ * ```tsx
79
+ * class FetchBehavior extends Behavior {
80
+ * url!: string;
81
+ * onCreate(url: string, interval = 5000) {
82
+ * this.url = url;
83
+ * }
84
+ * onMount() { ... }
85
+ * }
86
+ * export default createBehavior(FetchBehavior);
87
+ * ```
88
+ *
89
+ * Usage in a View - just instantiate:
90
+ * ```tsx
91
+ * class MyView extends View<Props> {
92
+ * fetcher = new FetchBehavior('/api/items', 3000);
93
+ * }
94
+ * ```
95
+ */
96
+ declare function createBehavior<T extends new (...args: any[]) => any>(Def: T): new (...args: BehaviorArgs<T>) => InstanceType<T>;
97
+
98
+ /**
99
+ * Global configuration options for mobx-mantle
100
+ */
101
+ interface MantleConfig {
102
+ /** Whether to automatically make View instances observable (default: true) */
103
+ autoObservable?: boolean;
104
+ }
105
+ /**
106
+ * Configure global defaults for mobx-mantle.
107
+ * Settings can still be overridden per-view in createView options.
108
+ */
109
+ declare function configure(config: MantleConfig): void;
110
+ declare class View<P = {}> {
111
+ /** @internal */
112
+ _propsBox: IObservableValue<P>;
113
+ get props(): P;
114
+ set props(value: P);
115
+ forwardRef?: Ref<any>;
116
+ /** @internal */
117
+ _behaviors: BehaviorEntry[];
118
+ onCreate?(): void;
119
+ onLayoutMount?(): void | (() => void);
120
+ onMount?(): void | (() => void);
121
+ onUnmount?(): void;
122
+ ref<T extends HTMLElement = HTMLElement>(): {
123
+ current: T | null;
124
+ };
125
+ /** @internal - Scan own properties for behavior instances and register them */
126
+ _collectBehaviors(): void;
127
+ /** @internal */
128
+ _layoutMountBehaviors(): void;
129
+ /** @internal */
130
+ _mountBehaviors(): void;
131
+ /** @internal */
132
+ _unmountBehaviors(): void;
133
+ render?(): JSX.Element;
134
+ }
135
+
136
+ type PropsOf<V> = V extends View<infer P> ? P : object;
137
+ declare function createView<V extends View<any>>(ViewClass: new () => V, templateOrOptions?: ((vm: V) => JSX.Element) | {
138
+ autoObservable?: boolean;
139
+ }): react.ForwardRefExoticComponent<react.PropsWithoutRef<PropsOf<V>> & react.RefAttributes<unknown>> & {
140
+ displayName: string;
141
+ };
142
+
143
+ export { Behavior, type MantleConfig, View, View as ViewModel, configure, createBehavior, createView };