mantle-lit 0.1.0
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/LICENSE +21 -0
- package/README.md +600 -0
- package/dist/index.cjs +544 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +358 -0
- package/dist/index.d.ts +358 -0
- package/dist/index.js +500 -0
- package/dist/index.js.map +1 -0
- package/package.json +60 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,500 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4
|
+
|
|
5
|
+
// src/mantle.ts
|
|
6
|
+
import { LitElement } from "lit";
|
|
7
|
+
import { makeObservable as makeObservable2, observable as observable4, computed as computed4, action as action4, reaction as reaction2, runInAction } from "mobx";
|
|
8
|
+
|
|
9
|
+
// src/behavior.ts
|
|
10
|
+
import { makeObservable, observable, computed, action, reaction } from "mobx";
|
|
11
|
+
|
|
12
|
+
// src/config.ts
|
|
13
|
+
var globalConfig = {
|
|
14
|
+
autoObservable: true
|
|
15
|
+
};
|
|
16
|
+
function reportError(error, context) {
|
|
17
|
+
if (globalConfig.onError) {
|
|
18
|
+
globalConfig.onError(error, context);
|
|
19
|
+
} else {
|
|
20
|
+
console.error(
|
|
21
|
+
`[mantle-lit] Error in ${context.isBehavior ? "behavior" : "view"} ${context.name}.${context.phase}():`,
|
|
22
|
+
error
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
function configure(config) {
|
|
27
|
+
Object.assign(globalConfig, config);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// src/behavior.ts
|
|
31
|
+
var BEHAVIOR_MARKER = /* @__PURE__ */ Symbol("behavior");
|
|
32
|
+
var BEHAVIOR_EXCLUDES = /* @__PURE__ */ new Set([
|
|
33
|
+
"onCreate",
|
|
34
|
+
"onMount",
|
|
35
|
+
"onUnmount",
|
|
36
|
+
"watch",
|
|
37
|
+
"constructor",
|
|
38
|
+
"_watchDisposers",
|
|
39
|
+
"_disposeWatchers"
|
|
40
|
+
]);
|
|
41
|
+
var Behavior = class {
|
|
42
|
+
constructor() {
|
|
43
|
+
/** @internal */
|
|
44
|
+
__publicField(this, "_watchDisposers", []);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Watch a reactive expression and run a callback when it changes.
|
|
48
|
+
* Automatically disposed on unmount.
|
|
49
|
+
*
|
|
50
|
+
* @param expr - Reactive expression (getter) to watch
|
|
51
|
+
* @param callback - Called when the expression result changes
|
|
52
|
+
* @param options - Optional configuration (delay, fireImmediately)
|
|
53
|
+
* @returns Dispose function for early teardown
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* ```ts
|
|
57
|
+
* onCreate(url: string) {
|
|
58
|
+
* this.url = url;
|
|
59
|
+
* this.watch(() => this.url, () => this.fetchData());
|
|
60
|
+
* }
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
watch(expr, callback, options) {
|
|
64
|
+
const dispose = reaction(
|
|
65
|
+
expr,
|
|
66
|
+
(value, prevValue) => {
|
|
67
|
+
try {
|
|
68
|
+
callback(value, prevValue);
|
|
69
|
+
} catch (e) {
|
|
70
|
+
reportError(e, { phase: "watch", name: this.constructor.name, isBehavior: true });
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
delay: options?.delay,
|
|
75
|
+
fireImmediately: options?.fireImmediately
|
|
76
|
+
}
|
|
77
|
+
);
|
|
78
|
+
this._watchDisposers.push(dispose);
|
|
79
|
+
return () => {
|
|
80
|
+
dispose();
|
|
81
|
+
const idx = this._watchDisposers.indexOf(dispose);
|
|
82
|
+
if (idx !== -1) this._watchDisposers.splice(idx, 1);
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
/** @internal */
|
|
86
|
+
_disposeWatchers() {
|
|
87
|
+
for (const dispose of this._watchDisposers) {
|
|
88
|
+
dispose();
|
|
89
|
+
}
|
|
90
|
+
this._watchDisposers.length = 0;
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
function makeBehaviorObservable(instance) {
|
|
94
|
+
const annotations = {};
|
|
95
|
+
const ownKeys = /* @__PURE__ */ new Set([
|
|
96
|
+
...Object.keys(instance),
|
|
97
|
+
...Object.keys(Object.getPrototypeOf(instance))
|
|
98
|
+
]);
|
|
99
|
+
for (const key of ownKeys) {
|
|
100
|
+
if (BEHAVIOR_EXCLUDES.has(key)) continue;
|
|
101
|
+
if (key in annotations) continue;
|
|
102
|
+
const value = instance[key];
|
|
103
|
+
if (typeof value === "function") continue;
|
|
104
|
+
annotations[key] = observable;
|
|
105
|
+
}
|
|
106
|
+
let proto = Object.getPrototypeOf(instance);
|
|
107
|
+
while (proto && proto !== Behavior.prototype && proto !== Object.prototype) {
|
|
108
|
+
const descriptors = Object.getOwnPropertyDescriptors(proto);
|
|
109
|
+
for (const [key, descriptor] of Object.entries(descriptors)) {
|
|
110
|
+
if (BEHAVIOR_EXCLUDES.has(key)) continue;
|
|
111
|
+
if (key in annotations) continue;
|
|
112
|
+
if (descriptor.get) {
|
|
113
|
+
annotations[key] = computed;
|
|
114
|
+
} else if (typeof descriptor.value === "function") {
|
|
115
|
+
annotations[key] = action.bound;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
proto = Object.getPrototypeOf(proto);
|
|
119
|
+
}
|
|
120
|
+
makeObservable(instance, annotations);
|
|
121
|
+
}
|
|
122
|
+
function createBehavior(Def, options) {
|
|
123
|
+
var _a, _b, _c;
|
|
124
|
+
const BehaviorClass = (_c = class extends (_b = Def, _a = BEHAVIOR_MARKER, _b) {
|
|
125
|
+
constructor(...args) {
|
|
126
|
+
super(...args);
|
|
127
|
+
if (typeof this.onCreate === "function") {
|
|
128
|
+
this.onCreate(...args);
|
|
129
|
+
}
|
|
130
|
+
const autoObservable = options?.autoObservable ?? globalConfig.autoObservable;
|
|
131
|
+
if (autoObservable) {
|
|
132
|
+
makeBehaviorObservable(this);
|
|
133
|
+
} else {
|
|
134
|
+
makeObservable(this);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}, __publicField(_c, _a, true), _c);
|
|
138
|
+
Object.defineProperty(BehaviorClass, "name", { value: Def.name });
|
|
139
|
+
return new Proxy(BehaviorClass, {
|
|
140
|
+
apply(_target, _thisArg, args) {
|
|
141
|
+
return new BehaviorClass(...args);
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
function isBehavior(value) {
|
|
146
|
+
if (value === null || typeof value !== "object") return false;
|
|
147
|
+
return value.constructor?.[BEHAVIOR_MARKER] === true;
|
|
148
|
+
}
|
|
149
|
+
function mountBehavior(behavior) {
|
|
150
|
+
const inst = behavior.instance;
|
|
151
|
+
if ("onMount" in inst && typeof inst.onMount === "function") {
|
|
152
|
+
try {
|
|
153
|
+
behavior.cleanup = inst.onMount() ?? void 0;
|
|
154
|
+
} catch (e) {
|
|
155
|
+
reportError(e, { phase: "onMount", name: inst.constructor.name, isBehavior: true });
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
function unmountBehavior(behavior) {
|
|
160
|
+
behavior.cleanup?.();
|
|
161
|
+
const inst = behavior.instance;
|
|
162
|
+
if ("onUnmount" in inst && typeof inst.onUnmount === "function") {
|
|
163
|
+
try {
|
|
164
|
+
inst.onUnmount();
|
|
165
|
+
} catch (e) {
|
|
166
|
+
reportError(e, { phase: "onUnmount", name: inst.constructor.name, isBehavior: true });
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
if (typeof inst._disposeWatchers === "function") {
|
|
170
|
+
inst._disposeWatchers();
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// src/decorators.ts
|
|
175
|
+
import * as mobx from "mobx";
|
|
176
|
+
var ANNOTATIONS = /* @__PURE__ */ Symbol("mantle:annotations");
|
|
177
|
+
function setAnnotation(context, annotation) {
|
|
178
|
+
var _a;
|
|
179
|
+
(_a = context.metadata)[ANNOTATIONS] ?? (_a[ANNOTATIONS] = {});
|
|
180
|
+
context.metadata[ANNOTATIONS][context.name] = annotation;
|
|
181
|
+
}
|
|
182
|
+
function observable3(_value, context) {
|
|
183
|
+
setAnnotation(context, mobx.observable);
|
|
184
|
+
}
|
|
185
|
+
observable3.ref = function(_value, context) {
|
|
186
|
+
setAnnotation(context, mobx.observable.ref);
|
|
187
|
+
};
|
|
188
|
+
observable3.shallow = function(_value, context) {
|
|
189
|
+
setAnnotation(context, mobx.observable.shallow);
|
|
190
|
+
};
|
|
191
|
+
observable3.struct = function(_value, context) {
|
|
192
|
+
setAnnotation(context, mobx.observable.struct);
|
|
193
|
+
};
|
|
194
|
+
observable3.deep = function(_value, context) {
|
|
195
|
+
setAnnotation(context, mobx.observable.deep);
|
|
196
|
+
};
|
|
197
|
+
function action3(_value, context) {
|
|
198
|
+
setAnnotation(context, mobx.action.bound);
|
|
199
|
+
}
|
|
200
|
+
function computed3(_value, context) {
|
|
201
|
+
setAnnotation(context, mobx.computed);
|
|
202
|
+
}
|
|
203
|
+
function getAnnotations(instance) {
|
|
204
|
+
const metadata = instance.constructor[Symbol.metadata];
|
|
205
|
+
return metadata?.[ANNOTATIONS];
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// src/mantle.ts
|
|
209
|
+
var BASE_EXCLUDES = /* @__PURE__ */ new Set([
|
|
210
|
+
"props",
|
|
211
|
+
"_propsBox",
|
|
212
|
+
"onCreate",
|
|
213
|
+
"onMount",
|
|
214
|
+
"onUnmount",
|
|
215
|
+
"render",
|
|
216
|
+
"watch",
|
|
217
|
+
"constructor",
|
|
218
|
+
"_behaviors",
|
|
219
|
+
"_collectBehaviors",
|
|
220
|
+
"_mountBehaviors",
|
|
221
|
+
"_unmountBehaviors",
|
|
222
|
+
"_watchDisposers",
|
|
223
|
+
"_disposeWatchers",
|
|
224
|
+
"_reactionDisposer",
|
|
225
|
+
"_requestRender"
|
|
226
|
+
]);
|
|
227
|
+
var View = class {
|
|
228
|
+
constructor() {
|
|
229
|
+
/** @internal */
|
|
230
|
+
__publicField(this, "_propsBox");
|
|
231
|
+
/** @internal */
|
|
232
|
+
__publicField(this, "_behaviors", []);
|
|
233
|
+
/** @internal */
|
|
234
|
+
__publicField(this, "_watchDisposers", []);
|
|
235
|
+
/** @internal - MobX reaction disposer for auto-render */
|
|
236
|
+
__publicField(this, "_reactionDisposer");
|
|
237
|
+
/** @internal - Callback to request a render from the element */
|
|
238
|
+
__publicField(this, "_requestRender");
|
|
239
|
+
}
|
|
240
|
+
/** Access current props (reactive) */
|
|
241
|
+
get props() {
|
|
242
|
+
return this._propsBox.get();
|
|
243
|
+
}
|
|
244
|
+
/** @internal — called by the element to update props */
|
|
245
|
+
_syncProps(value) {
|
|
246
|
+
runInAction(() => {
|
|
247
|
+
this._propsBox.set(value);
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Watch a reactive expression and run a callback when it changes.
|
|
252
|
+
* Automatically disposed on unmount.
|
|
253
|
+
*
|
|
254
|
+
* @param expr - Reactive expression (getter) to watch
|
|
255
|
+
* @param callback - Called when the expression result changes
|
|
256
|
+
* @param options - Optional configuration (delay, fireImmediately)
|
|
257
|
+
* @returns Dispose function for early teardown
|
|
258
|
+
*
|
|
259
|
+
* @example
|
|
260
|
+
* ```ts
|
|
261
|
+
* onCreate() {
|
|
262
|
+
* this.watch(
|
|
263
|
+
* () => this.query,
|
|
264
|
+
* async (query) => {
|
|
265
|
+
* if (query.length > 2) {
|
|
266
|
+
* this.results = await searchApi(query);
|
|
267
|
+
* }
|
|
268
|
+
* },
|
|
269
|
+
* { delay: 300 }
|
|
270
|
+
* );
|
|
271
|
+
* }
|
|
272
|
+
* ```
|
|
273
|
+
*/
|
|
274
|
+
watch(expr, callback, options) {
|
|
275
|
+
const dispose = reaction2(
|
|
276
|
+
expr,
|
|
277
|
+
(value, prevValue) => {
|
|
278
|
+
try {
|
|
279
|
+
callback(value, prevValue);
|
|
280
|
+
} catch (e) {
|
|
281
|
+
reportError(e, { phase: "watch", name: this.constructor.name, isBehavior: false });
|
|
282
|
+
}
|
|
283
|
+
},
|
|
284
|
+
{
|
|
285
|
+
delay: options?.delay,
|
|
286
|
+
fireImmediately: options?.fireImmediately
|
|
287
|
+
}
|
|
288
|
+
);
|
|
289
|
+
this._watchDisposers.push(dispose);
|
|
290
|
+
return () => {
|
|
291
|
+
dispose();
|
|
292
|
+
const idx = this._watchDisposers.indexOf(dispose);
|
|
293
|
+
if (idx !== -1) this._watchDisposers.splice(idx, 1);
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
/** @internal */
|
|
297
|
+
_disposeWatchers() {
|
|
298
|
+
for (const dispose of this._watchDisposers) {
|
|
299
|
+
dispose();
|
|
300
|
+
}
|
|
301
|
+
this._watchDisposers.length = 0;
|
|
302
|
+
}
|
|
303
|
+
/** @internal - Scan own properties for behavior instances and register them */
|
|
304
|
+
_collectBehaviors() {
|
|
305
|
+
for (const key of Object.keys(this)) {
|
|
306
|
+
if (key.startsWith("_")) continue;
|
|
307
|
+
const value = this[key];
|
|
308
|
+
if (isBehavior(value)) {
|
|
309
|
+
this._behaviors.push({ instance: value });
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
/** @internal */
|
|
314
|
+
_mountBehaviors() {
|
|
315
|
+
for (const behavior of this._behaviors) {
|
|
316
|
+
mountBehavior(behavior);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
/** @internal */
|
|
320
|
+
_unmountBehaviors() {
|
|
321
|
+
for (const behavior of this._behaviors) {
|
|
322
|
+
unmountBehavior(behavior);
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
};
|
|
326
|
+
function makeViewObservable(instance, autoBind) {
|
|
327
|
+
const annotations = {};
|
|
328
|
+
const ownKeys = /* @__PURE__ */ new Set([
|
|
329
|
+
...Object.keys(instance),
|
|
330
|
+
...Object.keys(Object.getPrototypeOf(instance))
|
|
331
|
+
]);
|
|
332
|
+
for (const key of ownKeys) {
|
|
333
|
+
if (BASE_EXCLUDES.has(key)) continue;
|
|
334
|
+
if (key in annotations) continue;
|
|
335
|
+
const value = instance[key];
|
|
336
|
+
if (typeof value === "function") continue;
|
|
337
|
+
if (isBehavior(value)) {
|
|
338
|
+
annotations[key] = observable4.ref;
|
|
339
|
+
continue;
|
|
340
|
+
}
|
|
341
|
+
annotations[key] = observable4;
|
|
342
|
+
}
|
|
343
|
+
let proto = Object.getPrototypeOf(instance);
|
|
344
|
+
while (proto && proto !== View.prototype) {
|
|
345
|
+
const descriptors = Object.getOwnPropertyDescriptors(proto);
|
|
346
|
+
for (const [key, descriptor] of Object.entries(descriptors)) {
|
|
347
|
+
if (BASE_EXCLUDES.has(key)) continue;
|
|
348
|
+
if (key in annotations) continue;
|
|
349
|
+
if (descriptor.get) {
|
|
350
|
+
annotations[key] = computed4;
|
|
351
|
+
} else if (typeof descriptor.value === "function") {
|
|
352
|
+
annotations[key] = autoBind ? action4.bound : action4;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
proto = Object.getPrototypeOf(proto);
|
|
356
|
+
}
|
|
357
|
+
makeObservable2(instance, annotations);
|
|
358
|
+
}
|
|
359
|
+
function createView(ViewClass, options) {
|
|
360
|
+
const { tag, autoObservable = globalConfig.autoObservable, shadow = true } = options;
|
|
361
|
+
class MantleElement extends LitElement {
|
|
362
|
+
constructor() {
|
|
363
|
+
super();
|
|
364
|
+
__publicField(this, "_vm", null);
|
|
365
|
+
__publicField(this, "_mountCleanup");
|
|
366
|
+
__publicField(this, "_props", {});
|
|
367
|
+
}
|
|
368
|
+
// Disable Shadow DOM if shadow: false
|
|
369
|
+
createRenderRoot() {
|
|
370
|
+
return shadow ? super.createRenderRoot() : this;
|
|
371
|
+
}
|
|
372
|
+
_initViewModel() {
|
|
373
|
+
if (this._vm) return;
|
|
374
|
+
for (const key of Object.keys(this)) {
|
|
375
|
+
if (key.startsWith("_")) continue;
|
|
376
|
+
this._props[key] = this[key];
|
|
377
|
+
}
|
|
378
|
+
const instance = new ViewClass();
|
|
379
|
+
instance._propsBox = observable4.box(this._props, { deep: false });
|
|
380
|
+
instance._collectBehaviors();
|
|
381
|
+
const decoratorAnnotations = getAnnotations(instance);
|
|
382
|
+
if (decoratorAnnotations) {
|
|
383
|
+
const annotations = { ...decoratorAnnotations };
|
|
384
|
+
let proto = Object.getPrototypeOf(instance);
|
|
385
|
+
while (proto && proto !== View.prototype) {
|
|
386
|
+
const descriptors = Object.getOwnPropertyDescriptors(proto);
|
|
387
|
+
for (const [key, descriptor] of Object.entries(descriptors)) {
|
|
388
|
+
if (BASE_EXCLUDES.has(key)) continue;
|
|
389
|
+
if (key in annotations) continue;
|
|
390
|
+
if (typeof descriptor.value === "function") {
|
|
391
|
+
annotations[key] = action4.bound;
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
proto = Object.getPrototypeOf(proto);
|
|
395
|
+
}
|
|
396
|
+
makeObservable2(instance, annotations);
|
|
397
|
+
} else if (autoObservable) {
|
|
398
|
+
makeViewObservable(instance, true);
|
|
399
|
+
} else {
|
|
400
|
+
makeObservable2(instance);
|
|
401
|
+
}
|
|
402
|
+
instance._requestRender = () => this.requestUpdate();
|
|
403
|
+
instance._reactionDisposer = reaction2(
|
|
404
|
+
() => instance.render?.(),
|
|
405
|
+
() => this.requestUpdate(),
|
|
406
|
+
{ fireImmediately: false }
|
|
407
|
+
);
|
|
408
|
+
try {
|
|
409
|
+
instance.onCreate?.();
|
|
410
|
+
} catch (e) {
|
|
411
|
+
reportError(e, { phase: "onCreate", name: ViewClass.name, isBehavior: false });
|
|
412
|
+
}
|
|
413
|
+
this._vm = instance;
|
|
414
|
+
}
|
|
415
|
+
connectedCallback() {
|
|
416
|
+
super.connectedCallback();
|
|
417
|
+
this._initViewModel();
|
|
418
|
+
if (this._vm) {
|
|
419
|
+
this._vm._mountBehaviors();
|
|
420
|
+
try {
|
|
421
|
+
const result = this._vm.onMount?.();
|
|
422
|
+
if (process.env.NODE_ENV !== "production" && result instanceof Promise) {
|
|
423
|
+
console.error(
|
|
424
|
+
`[mantle-lit] ${ViewClass.name}.onMount() returned a Promise. Lifecycle methods must be synchronous. Use a sync onMount that calls an async method instead.`
|
|
425
|
+
);
|
|
426
|
+
}
|
|
427
|
+
this._mountCleanup = result;
|
|
428
|
+
} catch (e) {
|
|
429
|
+
reportError(e, { phase: "onMount", name: ViewClass.name, isBehavior: false });
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
disconnectedCallback() {
|
|
434
|
+
super.disconnectedCallback();
|
|
435
|
+
if (this._vm) {
|
|
436
|
+
this._mountCleanup?.();
|
|
437
|
+
try {
|
|
438
|
+
this._vm.onUnmount?.();
|
|
439
|
+
} catch (e) {
|
|
440
|
+
reportError(e, { phase: "onUnmount", name: ViewClass.name, isBehavior: false });
|
|
441
|
+
}
|
|
442
|
+
this._vm._disposeWatchers();
|
|
443
|
+
this._vm._unmountBehaviors();
|
|
444
|
+
this._vm._reactionDisposer?.();
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
// Override to handle property updates
|
|
448
|
+
requestUpdate(name, oldValue) {
|
|
449
|
+
if (name && this._vm) {
|
|
450
|
+
this._props[name] = this[name];
|
|
451
|
+
this._vm._syncProps(this._props);
|
|
452
|
+
}
|
|
453
|
+
return super.requestUpdate(name, oldValue);
|
|
454
|
+
}
|
|
455
|
+
render() {
|
|
456
|
+
if (!this._vm) {
|
|
457
|
+
this._initViewModel();
|
|
458
|
+
}
|
|
459
|
+
if (!this._vm?.render) {
|
|
460
|
+
throw new Error(
|
|
461
|
+
`[mantle-lit] ${ViewClass.name}: Missing render() method.`
|
|
462
|
+
);
|
|
463
|
+
}
|
|
464
|
+
return this._vm.render();
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
// Lit will call this when any property changes
|
|
468
|
+
__publicField(MantleElement, "properties", {});
|
|
469
|
+
// Pass through static styles from the View class
|
|
470
|
+
__publicField(MantleElement, "styles", ViewClass.styles);
|
|
471
|
+
if (!customElements.get(tag)) {
|
|
472
|
+
customElements.define(tag, MantleElement);
|
|
473
|
+
}
|
|
474
|
+
return MantleElement;
|
|
475
|
+
}
|
|
476
|
+
function mount(tag, props, container) {
|
|
477
|
+
const el = document.createElement(tag);
|
|
478
|
+
if (props) {
|
|
479
|
+
Object.assign(el, props);
|
|
480
|
+
}
|
|
481
|
+
const target = typeof container === "string" ? document.querySelector(container) : container ?? document.body;
|
|
482
|
+
if (!target) {
|
|
483
|
+
throw new Error(`[mantle-lit] mount: container "${container}" not found`);
|
|
484
|
+
}
|
|
485
|
+
target.appendChild(el);
|
|
486
|
+
return el;
|
|
487
|
+
}
|
|
488
|
+
export {
|
|
489
|
+
Behavior,
|
|
490
|
+
View,
|
|
491
|
+
View as ViewModel,
|
|
492
|
+
action3 as action,
|
|
493
|
+
computed3 as computed,
|
|
494
|
+
configure,
|
|
495
|
+
createBehavior,
|
|
496
|
+
createView,
|
|
497
|
+
mount,
|
|
498
|
+
observable3 as observable
|
|
499
|
+
};
|
|
500
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/mantle.ts","../src/behavior.ts","../src/config.ts","../src/decorators.ts"],"sourcesContent":["import { LitElement, type TemplateResult } from 'lit';\r\nimport { makeObservable, observable, computed, action, reaction, runInAction, type AnnotationsMap, type IObservableValue } from 'mobx';\r\nimport {\r\n type BehaviorEntry,\r\n isBehavior,\r\n mountBehavior,\r\n unmountBehavior,\r\n} from './behavior';\r\nimport { globalConfig, reportError, type WatchOptions } from './config';\r\nimport { getAnnotations } from './decorators';\r\n\r\n// Re-export config utilities\r\nexport { configure, type MantleConfig, type MantleErrorContext, type WatchOptions } from './config';\r\n\r\n// Re-export decorators for single-import convenience\r\nexport { observable, action, computed } from './decorators';\r\n\r\n// Re-export from behavior module\r\nexport { createBehavior, Behavior } from './behavior';\r\n\r\n// Base class members that should not be made observable\r\nconst BASE_EXCLUDES = new Set([\r\n 'props',\r\n '_propsBox',\r\n 'onCreate',\r\n 'onMount',\r\n 'onUnmount',\r\n 'render',\r\n 'watch',\r\n 'constructor',\r\n '_behaviors',\r\n '_collectBehaviors',\r\n '_mountBehaviors',\r\n '_unmountBehaviors',\r\n '_watchDisposers',\r\n '_disposeWatchers',\r\n '_reactionDisposer',\r\n '_requestRender',\r\n]);\r\n\r\n/**\r\n * Base class for Views. Extend this and use createView() to create a custom element.\r\n * \r\n * @example\r\n * ```ts\r\n * import { View, createView } from 'mantle-lit';\r\n * import { html } from 'lit';\r\n * \r\n * class CounterView extends View<{ initial: number }> {\r\n * count = 0;\r\n * \r\n * onCreate() {\r\n * this.count = this.props.initial;\r\n * }\r\n * \r\n * increment() {\r\n * this.count++;\r\n * }\r\n * \r\n * render() {\r\n * return html`\r\n * <button @click=${this.increment}>\r\n * Count: ${this.count}\r\n * </button>\r\n * `;\r\n * }\r\n * }\r\n * \r\n * export const Counter = createView(CounterView, { tag: 'x-counter' });\r\n * ```\r\n */\r\nexport class View<P extends object = {}> {\r\n /** @internal */\r\n _propsBox!: IObservableValue<P>;\r\n\r\n /** Access current props (reactive) */\r\n get props(): P {\r\n return this._propsBox.get();\r\n }\r\n\r\n /** @internal — called by the element to update props */\r\n _syncProps(value: P) {\r\n runInAction(() => {\r\n this._propsBox.set(value);\r\n });\r\n }\r\n\r\n /** @internal */\r\n _behaviors: BehaviorEntry[] = [];\r\n\r\n /** @internal */\r\n _watchDisposers: (() => void)[] = [];\r\n\r\n /** @internal - MobX reaction disposer for auto-render */\r\n _reactionDisposer?: () => void;\r\n\r\n /** @internal - Callback to request a render from the element */\r\n _requestRender?: () => void;\r\n\r\n onCreate?(): void;\r\n onMount?(): void | (() => void);\r\n onUnmount?(): void;\r\n\r\n /**\r\n * Watch a reactive expression and run a callback when it changes.\r\n * Automatically disposed on unmount.\r\n * \r\n * @param expr - Reactive expression (getter) to watch\r\n * @param callback - Called when the expression result changes\r\n * @param options - Optional configuration (delay, fireImmediately)\r\n * @returns Dispose function for early teardown\r\n * \r\n * @example\r\n * ```ts\r\n * onCreate() {\r\n * this.watch(\r\n * () => this.query,\r\n * async (query) => {\r\n * if (query.length > 2) {\r\n * this.results = await searchApi(query);\r\n * }\r\n * },\r\n * { delay: 300 }\r\n * );\r\n * }\r\n * ```\r\n */\r\n watch<T>(\r\n expr: () => T,\r\n callback: (value: T, prevValue: T | undefined) => void,\r\n options?: WatchOptions\r\n ): () => void {\r\n const dispose = reaction(\r\n expr,\r\n (value, prevValue) => {\r\n try {\r\n callback(value, prevValue);\r\n } catch (e) {\r\n reportError(e, { phase: 'watch', name: this.constructor.name, isBehavior: false });\r\n }\r\n },\r\n {\r\n delay: options?.delay,\r\n fireImmediately: options?.fireImmediately,\r\n }\r\n );\r\n\r\n this._watchDisposers.push(dispose);\r\n\r\n // Return a dispose function that also removes from the array\r\n return () => {\r\n dispose();\r\n const idx = this._watchDisposers.indexOf(dispose);\r\n if (idx !== -1) this._watchDisposers.splice(idx, 1);\r\n };\r\n }\r\n\r\n /** @internal */\r\n _disposeWatchers(): void {\r\n for (const dispose of this._watchDisposers) {\r\n dispose();\r\n }\r\n this._watchDisposers.length = 0;\r\n }\r\n\r\n /** @internal - Scan own properties for behavior instances and register them */\r\n _collectBehaviors(): void {\r\n for (const key of Object.keys(this)) {\r\n if (key.startsWith('_')) continue;\r\n const value = (this as any)[key];\r\n if (isBehavior(value)) {\r\n this._behaviors.push({ instance: value });\r\n }\r\n }\r\n }\r\n\r\n /** @internal */\r\n _mountBehaviors(): void {\r\n for (const behavior of this._behaviors) {\r\n mountBehavior(behavior);\r\n }\r\n }\r\n\r\n /** @internal */\r\n _unmountBehaviors(): void {\r\n for (const behavior of this._behaviors) {\r\n unmountBehavior(behavior);\r\n }\r\n }\r\n\r\n render?(): TemplateResult | null;\r\n}\r\n\r\n/** Alias for View - use when separating ViewModel from template */\r\nexport { View as ViewModel };\r\n\r\n/**\r\n * Creates observable annotations for a View subclass instance.\r\n * This is needed because makeAutoObservable doesn't work with inheritance.\r\n */\r\nfunction makeViewObservable<T extends View>(instance: T, autoBind: boolean) {\r\n const annotations: AnnotationsMap<T, never> = {} as AnnotationsMap<T, never>;\r\n\r\n // Collect own properties (instance state) → 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 (BASE_EXCLUDES.has(key)) continue;\r\n if (key in annotations) continue;\r\n\r\n const value = (instance as any)[key];\r\n\r\n // Skip functions (these are handled in the prototype walk)\r\n if (typeof value === 'function') continue;\r\n\r\n // Skip behavior instances (they're already observable)\r\n if (isBehavior(value)) {\r\n (annotations as any)[key] = observable.ref;\r\n continue;\r\n }\r\n\r\n (annotations as any)[key] = observable;\r\n }\r\n\r\n // Walk prototype chain up to (but not including) View\r\n let proto = Object.getPrototypeOf(instance);\r\n while (proto && proto !== View.prototype) {\r\n const descriptors = Object.getOwnPropertyDescriptors(proto);\r\n\r\n for (const [key, descriptor] of Object.entries(descriptors)) {\r\n if (BASE_EXCLUDES.has(key)) continue;\r\n if (key in annotations) continue;\r\n\r\n if (descriptor.get) {\r\n // Getter → computed\r\n (annotations as any)[key] = computed;\r\n } else if (typeof descriptor.value === 'function') {\r\n // Method → action (optionally bound)\r\n (annotations as any)[key] = autoBind ? action.bound : action;\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\ntype PropsOf<V> = V extends View<infer P> ? P : object;\r\n\r\nexport interface CreateViewOptions {\r\n /** Custom element tag name (required, must contain a hyphen) */\r\n tag: string;\r\n /** Whether to automatically make View instances observable (default: true) */\r\n autoObservable?: boolean;\r\n /** Whether to use Shadow DOM (default: true). Set to false to render in light DOM. */\r\n shadow?: boolean;\r\n}\r\n\r\n/**\r\n * Creates a Lit custom element from a View class.\r\n * \r\n * @param ViewClass - The View class to wrap\r\n * @param options - Configuration options including the tag name\r\n * @returns The custom element class (also registers it)\r\n * \r\n * @example\r\n * ```ts\r\n * class CounterView extends View<{ initial: number }> {\r\n * count = 0;\r\n * \r\n * onCreate() {\r\n * this.count = this.props.initial;\r\n * }\r\n * \r\n * increment() {\r\n * this.count++;\r\n * }\r\n * \r\n * render() {\r\n * return html`<button @click=${this.increment}>Count: ${this.count}</button>`;\r\n * }\r\n * }\r\n * \r\n * export const Counter = createView(CounterView, { tag: 'x-counter' });\r\n * \r\n * // Usage in HTML: <x-counter .initial=${5}></x-counter>\r\n * ```\r\n */\r\nexport function createView<V extends View<any>>(\r\n ViewClass: new () => V,\r\n options: CreateViewOptions\r\n): typeof LitElement {\r\n type P = PropsOf<V>;\r\n\r\n const { tag, autoObservable = globalConfig.autoObservable, shadow = true } = options;\r\n\r\n // Create the custom element class\r\n class MantleElement extends LitElement {\r\n private _vm: V | null = null;\r\n private _mountCleanup?: () => void;\r\n private _props: P = {} as P;\r\n\r\n // Lit will call this when any property changes\r\n static properties: Record<string, any> = {};\r\n\r\n // Pass through static styles from the View class\r\n static styles = (ViewClass as any).styles;\r\n\r\n constructor() {\r\n super();\r\n }\r\n\r\n // Disable Shadow DOM if shadow: false\r\n createRenderRoot() {\r\n return shadow ? super.createRenderRoot() : this;\r\n }\r\n\r\n private _initViewModel() {\r\n if (this._vm) return;\r\n\r\n // Capture any properties set on the element before connection\r\n // This handles imperative property setting: el.foo = value\r\n for (const key of Object.keys(this)) {\r\n if (key.startsWith('_')) continue;\r\n (this._props as any)[key] = (this as any)[key];\r\n }\r\n\r\n const instance = new ViewClass();\r\n\r\n // Props is always reactive via observable.box\r\n instance._propsBox = observable.box(this._props, { deep: false });\r\n\r\n // Collect behavior instances from properties (must happen before makeObservable)\r\n instance._collectBehaviors();\r\n\r\n // Check for Mantle decorator annotations first\r\n const decoratorAnnotations = getAnnotations(instance);\r\n\r\n if (decoratorAnnotations) {\r\n // Mantle decorators: use collected annotations\r\n // Auto-bind all methods for stable `this` references\r\n const annotations = { ...decoratorAnnotations };\r\n\r\n // Walk prototype chain to auto-bind methods not explicitly decorated\r\n let proto = Object.getPrototypeOf(instance);\r\n while (proto && proto !== View.prototype) {\r\n const descriptors = Object.getOwnPropertyDescriptors(proto);\r\n for (const [key, descriptor] of Object.entries(descriptors)) {\r\n if (BASE_EXCLUDES.has(key)) continue;\r\n if (key in annotations) continue;\r\n if (typeof descriptor.value === 'function') {\r\n annotations[key] = action.bound;\r\n }\r\n }\r\n proto = Object.getPrototypeOf(proto);\r\n }\r\n\r\n makeObservable(instance, annotations as AnnotationsMap<V, never>);\r\n } else if (autoObservable) {\r\n makeViewObservable(instance, true);\r\n } else {\r\n // For legacy decorator users: applies decorator metadata\r\n makeObservable(instance);\r\n }\r\n\r\n // Set up the render callback\r\n instance._requestRender = () => this.requestUpdate();\r\n\r\n // Set up MobX reaction to trigger renders when observables change\r\n instance._reactionDisposer = reaction(\r\n () => instance.render?.(),\r\n () => this.requestUpdate(),\r\n { fireImmediately: false }\r\n );\r\n\r\n // Call onCreate\r\n try {\r\n instance.onCreate?.();\r\n } catch (e) {\r\n reportError(e, { phase: 'onCreate', name: ViewClass.name, isBehavior: false });\r\n }\r\n\r\n this._vm = instance;\r\n }\r\n\r\n connectedCallback() {\r\n super.connectedCallback();\r\n \r\n this._initViewModel();\r\n \r\n if (this._vm) {\r\n // Mount behaviors\r\n this._vm._mountBehaviors();\r\n\r\n // Call onMount\r\n try {\r\n const result = this._vm.onMount?.();\r\n if (process.env.NODE_ENV !== 'production' && result instanceof Promise) {\r\n console.error(\r\n `[mantle-lit] ${ViewClass.name}.onMount() returned a Promise. ` +\r\n `Lifecycle methods must be synchronous. Use a sync onMount that ` +\r\n `calls an async method instead.`\r\n );\r\n }\r\n this._mountCleanup = result as (() => void) | undefined;\r\n } catch (e) {\r\n reportError(e, { phase: 'onMount', name: ViewClass.name, isBehavior: false });\r\n }\r\n }\r\n }\r\n\r\n disconnectedCallback() {\r\n super.disconnectedCallback();\r\n\r\n if (this._vm) {\r\n // Call mount cleanup\r\n this._mountCleanup?.();\r\n\r\n // Call onUnmount\r\n try {\r\n this._vm.onUnmount?.();\r\n } catch (e) {\r\n reportError(e, { phase: 'onUnmount', name: ViewClass.name, isBehavior: false });\r\n }\r\n\r\n // Dispose watchers\r\n this._vm._disposeWatchers();\r\n\r\n // Unmount behaviors\r\n this._vm._unmountBehaviors();\r\n\r\n // Dispose the render reaction\r\n this._vm._reactionDisposer?.();\r\n }\r\n }\r\n\r\n // Override to handle property updates\r\n requestUpdate(name?: PropertyKey, oldValue?: unknown) {\r\n if (name && this._vm) {\r\n // Update the props when a property changes\r\n (this._props as any)[name] = (this as any)[name];\r\n this._vm._syncProps(this._props);\r\n }\r\n return super.requestUpdate(name, oldValue);\r\n }\r\n\r\n render() {\r\n if (!this._vm) {\r\n this._initViewModel();\r\n }\r\n\r\n if (!this._vm?.render) {\r\n throw new Error(\r\n `[mantle-lit] ${ViewClass.name}: Missing render() method.`\r\n );\r\n }\r\n\r\n return this._vm.render();\r\n }\r\n }\r\n\r\n // Register the custom element\r\n if (!customElements.get(tag)) {\r\n customElements.define(tag, MantleElement);\r\n }\r\n\r\n return MantleElement;\r\n}\r\n\r\n/**\r\n * Helper type for defining props that will be passed as properties (not attributes).\r\n * Use with .prop=${value} syntax in Lit templates.\r\n */\r\nexport type Props<T> = T;\r\n\r\n/**\r\n * Mount a view to the DOM with props.\r\n * \r\n * @param tag - The custom element tag name\r\n * @param props - Props to pass to the component\r\n * @param container - DOM element or selector to mount into (default: document.body)\r\n * @returns The created element\r\n * \r\n * @example\r\n * ```ts\r\n * import { mount } from 'mantle-lit';\r\n * import './Todo'; // registers x-todo\r\n * \r\n * mount('x-todo', {\r\n * title: 'My Tasks',\r\n * initialTodos: [{ id: 1, text: 'Learn mantle', done: false }],\r\n * onCountChange: (count) => console.log(count)\r\n * });\r\n * ```\r\n */\r\nexport function mount<P extends object>(\r\n tag: string,\r\n props?: P,\r\n container?: Element | string\r\n): HTMLElement & P {\r\n const el = document.createElement(tag) as HTMLElement & P;\r\n \r\n if (props) {\r\n Object.assign(el, props);\r\n }\r\n \r\n const target = typeof container === 'string' \r\n ? document.querySelector(container) \r\n : container ?? document.body;\r\n \r\n if (!target) {\r\n throw new Error(`[mantle-lit] mount: container \"${container}\" not found`);\r\n }\r\n \r\n target.appendChild(el);\r\n return el;\r\n}\r\n","import { makeObservable, observable, computed, action, reaction, type AnnotationsMap } from 'mobx';\nimport { globalConfig, reportError, type WatchOptions } from './config';\n\n/** Symbol marker to identify behavior instances */\nexport const BEHAVIOR_MARKER = Symbol('behavior');\n\n// Behavior base class members that should not be made observable\nconst BEHAVIOR_EXCLUDES = new Set([\n 'onCreate',\n 'onMount',\n 'onUnmount',\n 'watch',\n 'constructor',\n '_watchDisposers',\n '_disposeWatchers',\n]);\n\n/**\n * Base class for behaviors. Provides lifecycle method signatures for IDE autocomplete.\n * Extend this class and wrap with createBehavior() to create a factory.\n * \n * @example\n * ```ts\n * class WindowSizeBehavior extends Behavior {\n * width = window.innerWidth;\n * onCreate(breakpoint = 768) { ... }\n * onMount() { ... }\n * }\n * export const withWindowSize = createBehavior(WindowSizeBehavior);\n * ```\n */\nexport class Behavior {\n /** @internal */\n _watchDisposers: (() => void)[] = [];\n\n onCreate?(...args: any[]): void;\n onMount?(): void | (() => void);\n onUnmount?(): void;\n\n /**\n * Watch a reactive expression and run a callback when it changes.\n * Automatically disposed on unmount.\n * \n * @param expr - Reactive expression (getter) to watch\n * @param callback - Called when the expression result changes\n * @param options - Optional configuration (delay, fireImmediately)\n * @returns Dispose function for early teardown\n * \n * @example\n * ```ts\n * onCreate(url: string) {\n * this.url = url;\n * this.watch(() => this.url, () => this.fetchData());\n * }\n * ```\n */\n watch<T>(\n expr: () => T,\n callback: (value: T, prevValue: T | undefined) => void,\n options?: WatchOptions\n ): () => void {\n const dispose = reaction(\n expr,\n (value, prevValue) => {\n try {\n callback(value, prevValue);\n } catch (e) {\n reportError(e, { phase: 'watch', name: this.constructor.name, isBehavior: true });\n }\n },\n {\n delay: options?.delay,\n fireImmediately: options?.fireImmediately,\n }\n );\n\n this._watchDisposers.push(dispose);\n\n // Return a dispose function that also removes from the array\n return () => {\n dispose();\n const idx = this._watchDisposers.indexOf(dispose);\n if (idx !== -1) this._watchDisposers.splice(idx, 1);\n };\n }\n\n /** @internal */\n _disposeWatchers(): void {\n for (const dispose of this._watchDisposers) {\n dispose();\n }\n this._watchDisposers.length = 0;\n }\n}\n\n/**\n * Makes a behavior instance observable, handling inheritance properly.\n * Works with classes that extend Behavior or plain classes.\n */\nfunction makeBehaviorObservable<T extends object>(instance: T): void {\n const annotations: AnnotationsMap<T, never> = {} as AnnotationsMap<T, never>;\n\n // Collect own properties → observable\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 (BEHAVIOR_EXCLUDES.has(key)) continue;\n if (key in annotations) continue;\n\n const value = (instance as any)[key];\n if (typeof value === 'function') continue;\n\n (annotations as any)[key] = observable;\n }\n\n // Walk prototype chain up to (but not including) Behavior or Object\n let proto = Object.getPrototypeOf(instance);\n while (proto && proto !== Behavior.prototype && proto !== Object.prototype) {\n const descriptors = Object.getOwnPropertyDescriptors(proto);\n\n for (const [key, descriptor] of Object.entries(descriptors)) {\n if (BEHAVIOR_EXCLUDES.has(key)) continue;\n if (key in annotations) continue;\n\n if (descriptor.get) {\n (annotations as any)[key] = computed;\n } else if (typeof descriptor.value === 'function') {\n (annotations as any)[key] = action.bound;\n }\n }\n\n proto = Object.getPrototypeOf(proto);\n }\n\n makeObservable(instance, annotations);\n}\n\n/** @internal */\nexport interface BehaviorEntry {\n instance: any;\n cleanup?: () => void;\n}\n\n/**\n * Extracts parameter types from onCreate method\n */\ntype OnCreateParams<T> = T extends { onCreate(...args: infer A): any } ? A : [];\n\n/**\n * Extracts constructor parameter types\n */\ntype ConstructorParams<T> = T extends new (...args: infer A) => any ? A : [];\n\n/**\n * Determines the args for createBehavior:\n * - If constructor has args, use those\n * - Otherwise, if onCreate has args, use those\n */\ntype BehaviorArgs<T extends new (...args: any[]) => any> = \n ConstructorParams<T> extends [] \n ? OnCreateParams<InstanceType<T>> \n : ConstructorParams<T>;\n\n/**\n * Type that supports both `new` and direct call syntax\n */\ntype BehaviorFactory<Args extends any[], Instance> = {\n new (...args: Args): Instance;\n (...args: Args): Instance;\n};\n\n/**\n * Creates a behavior factory with automatic observable wrapping and lifecycle management.\n * \n * Returns a factory function (not a class) — use without `new`:\n * \n * @example Defining a behavior\n * ```ts\n * class DragBehavior extends Behavior {\n * ref!: HTMLElement | null;\n * \n * onCreate(ref: HTMLElement | null) {\n * this.ref = ref;\n * }\n * \n * onMount() {\n * this.ref?.addEventListener('pointerdown', this.onPointerDown);\n * return () => this.ref?.removeEventListener('pointerdown', this.onPointerDown);\n * }\n * }\n * \n * export const withDrag = createBehavior(DragBehavior);\n * ```\n * \n * @example Using in a View\n * ```ts\n * class Editor extends View<Props> {\n * canvasRef: HTMLCanvasElement | null = null;\n * \n * // No `new` keyword — factory function\n * drag = withDrag(this.canvasRef);\n * }\n * export const EditorElement = createView(Editor, { tag: 'x-editor' });\n * ```\n * \n * The `with` prefix convention signals that the view manages this behavior's lifecycle.\n */\nexport function createBehavior<T extends new (...args: any[]) => any>(\n Def: T,\n options?: { autoObservable?: boolean }\n): BehaviorFactory<BehaviorArgs<T>, InstanceType<T>> {\n // Internal class that wraps the user's behavior definition\n const BehaviorClass = class extends (Def as any) {\n static [BEHAVIOR_MARKER] = true;\n\n constructor(...args: any[]) {\n super(...args);\n \n // Call onCreate with args (if it exists)\n if (typeof this.onCreate === 'function') {\n this.onCreate(...args);\n }\n \n // Make the instance observable (respects global config and per-behavior options)\n const autoObservable = options?.autoObservable ?? globalConfig.autoObservable;\n if (autoObservable) {\n makeBehaviorObservable(this);\n } else {\n // For decorator users: applies decorator metadata\n makeObservable(this);\n }\n }\n };\n\n // Preserve the original class name for debugging\n Object.defineProperty(BehaviorClass, 'name', { value: Def.name });\n\n // Use Proxy to make the class callable without `new`\n // This allows both: withWindowSize(768) and new withWindowSize(768)\n return new Proxy(BehaviorClass, {\n apply(_target, _thisArg, args) {\n return new BehaviorClass(...args);\n },\n }) as unknown as BehaviorFactory<BehaviorArgs<T>, InstanceType<T>>;\n}\n\n/**\n * Checks if a value is a behavior instance created by createBehavior()\n */\nexport function isBehavior(value: unknown): boolean {\n if (value === null || typeof value !== 'object') return false;\n return (value.constructor as any)?.[BEHAVIOR_MARKER] === true;\n}\n\n/** @internal */\nexport function mountBehavior(behavior: BehaviorEntry): void {\n const inst = behavior.instance;\n\n if ('onMount' in inst && typeof inst.onMount === 'function') {\n try {\n behavior.cleanup = inst.onMount() ?? undefined;\n } catch (e) {\n reportError(e, { phase: 'onMount', name: inst.constructor.name, isBehavior: true });\n }\n }\n}\n\n/** @internal */\nexport function unmountBehavior(behavior: BehaviorEntry): void {\n // Call cleanup if exists\n behavior.cleanup?.();\n\n // Call onUnmount if exists\n const inst = behavior.instance;\n if ('onUnmount' in inst && typeof inst.onUnmount === 'function') {\n try {\n inst.onUnmount();\n } catch (e) {\n reportError(e, { phase: 'onUnmount', name: inst.constructor.name, isBehavior: true });\n }\n }\n\n // Dispose all watchers\n if (typeof inst._disposeWatchers === 'function') {\n inst._disposeWatchers();\n }\n}\n","/** Options for the watch method */\r\nexport interface WatchOptions {\r\n /** Debounce the callback by N milliseconds */\r\n delay?: number;\r\n /** Run callback immediately with current value */\r\n fireImmediately?: boolean;\r\n}\r\n\r\n/**\r\n * Error context passed to the onError handler\r\n */\r\nexport interface MantleErrorContext {\r\n /** The lifecycle phase where the error occurred */\r\n phase: 'onCreate' | 'onMount' | 'onUnmount' | 'watch';\r\n /** The View or Behavior class name */\r\n name: string;\r\n /** Whether the error came from a Behavior (true) or a View (false) */\r\n isBehavior: boolean;\r\n}\r\n\r\n/**\r\n * Global configuration options for mantle-lit\r\n */\r\nexport interface MantleConfig {\r\n /** Whether to automatically make View/Behavior instances observable (default: true) */\r\n autoObservable?: boolean;\r\n /** Global error handler for lifecycle errors. Defaults to console.error. */\r\n onError?: (error: unknown, context: MantleErrorContext) => void;\r\n}\r\n\r\nexport const globalConfig: MantleConfig = {\r\n autoObservable: true,\r\n};\r\n\r\n/** @internal Report a lifecycle error through the configured handler or console.error */\r\nexport function reportError(error: unknown, context: MantleErrorContext): void {\r\n if (globalConfig.onError) {\r\n globalConfig.onError(error, context);\r\n } else {\r\n console.error(\r\n `[mantle-lit] Error in ${context.isBehavior ? 'behavior' : 'view'} ${context.name}.${context.phase}():`,\r\n error,\r\n );\r\n }\r\n}\r\n\r\n/**\r\n * Configure global defaults for mantle-lit.\r\n * Settings can still be overridden per-view in createView options.\r\n */\r\nexport function configure(config: MantleConfig): void {\r\n Object.assign(globalConfig, config);\r\n}\r\n","import * as mobx from 'mobx';\r\n\r\n/**\r\n * Symbol key for storing decorator annotations in class metadata.\r\n * These annotations are read by createView() after construction.\r\n */\r\nexport const ANNOTATIONS = Symbol('mantle:annotations');\r\n\r\n/**\r\n * Decorator context type for TC39 decorators\r\n */\r\ninterface DecoratorContext {\r\n kind: 'field' | 'method' | 'getter' | 'setter' | 'accessor' | 'class';\r\n name: string | symbol;\r\n metadata: Record<symbol, unknown>;\r\n}\r\n\r\n/**\r\n * Helper to set annotation metadata\r\n */\r\nfunction setAnnotation(context: DecoratorContext, annotation: any): void {\r\n context.metadata[ANNOTATIONS] ??= {};\r\n (context.metadata[ANNOTATIONS] as Record<string | symbol, any>)[context.name] = annotation;\r\n}\r\n\r\n/**\r\n * Marks a field as observable. No `accessor` keyword needed.\r\n * \r\n * @example\r\n * ```ts\r\n * class Counter extends View {\r\n * @observable count = 0;\r\n * }\r\n * export const CounterElement = createView(Counter, { tag: 'x-counter' });\r\n * ```\r\n */\r\nexport function observable(_value: undefined, context: DecoratorContext): void {\r\n setAnnotation(context, mobx.observable);\r\n}\r\n\r\n/**\r\n * Observable variants for different observation modes\r\n */\r\nobservable.ref = function(_value: undefined, context: DecoratorContext): void {\r\n setAnnotation(context, mobx.observable.ref);\r\n};\r\n\r\nobservable.shallow = function(_value: undefined, context: DecoratorContext): void {\r\n setAnnotation(context, mobx.observable.shallow);\r\n};\r\n\r\nobservable.struct = function(_value: undefined, context: DecoratorContext): void {\r\n setAnnotation(context, mobx.observable.struct);\r\n};\r\n\r\nobservable.deep = function(_value: undefined, context: DecoratorContext): void {\r\n setAnnotation(context, mobx.observable.deep);\r\n};\r\n\r\n/**\r\n * Marks a method as an action. Auto-bound by default.\r\n * \r\n * @example\r\n * ```ts\r\n * class Counter extends View {\r\n * @observable count = 0;\r\n * \r\n * @action increment() {\r\n * this.count++;\r\n * }\r\n * }\r\n * export const CounterElement = createView(Counter, { tag: 'x-counter' });\r\n * ```\r\n */\r\nexport function action(_value: Function, context: DecoratorContext): void {\r\n setAnnotation(context, mobx.action.bound);\r\n}\r\n\r\n/**\r\n * Marks a getter as computed.\r\n * Note: Getters are automatically computed in autoObservable mode,\r\n * but this decorator is useful for explicit annotation.\r\n * \r\n * @example\r\n * ```ts\r\n * class Counter extends View {\r\n * @observable count = 0;\r\n * \r\n * @computed get doubled() {\r\n * return this.count * 2;\r\n * }\r\n * }\r\n * export const CounterElement = createView(Counter, { tag: 'x-counter' });\r\n * ```\r\n */\r\nexport function computed(_value: Function, context: DecoratorContext): void {\r\n setAnnotation(context, mobx.computed);\r\n}\r\n\r\n/**\r\n * Retrieves the annotations stored in class metadata.\r\n * Used by createView() to apply MobX observability.\r\n */\r\nexport function getAnnotations(instance: object): Record<string, any> | undefined {\r\n const metadata = (instance.constructor as any)[Symbol.metadata];\r\n return metadata?.[ANNOTATIONS] as Record<string, any> | undefined;\r\n}\r\n"],"mappings":";;;;;AAAA,SAAS,kBAAuC;AAChD,SAAS,kBAAAA,iBAAgB,cAAAC,aAAY,YAAAC,WAAU,UAAAC,SAAQ,YAAAC,WAAU,mBAA+D;;;ACDhI,SAAS,gBAAgB,YAAY,UAAU,QAAQ,gBAAqC;;;AC8BrF,IAAM,eAA6B;AAAA,EACxC,gBAAgB;AAClB;AAGO,SAAS,YAAY,OAAgB,SAAmC;AAC7E,MAAI,aAAa,SAAS;AACxB,iBAAa,QAAQ,OAAO,OAAO;AAAA,EACrC,OAAO;AACL,YAAQ;AAAA,MACN,yBAAyB,QAAQ,aAAa,aAAa,MAAM,IAAI,QAAQ,IAAI,IAAI,QAAQ,KAAK;AAAA,MAClG;AAAA,IACF;AAAA,EACF;AACF;AAMO,SAAS,UAAU,QAA4B;AACpD,SAAO,OAAO,cAAc,MAAM;AACpC;;;ADhDO,IAAM,kBAAkB,uBAAO,UAAU;AAGhD,IAAM,oBAAoB,oBAAI,IAAI;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAgBM,IAAM,WAAN,MAAe;AAAA,EAAf;AAEL;AAAA,2CAAkC,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAuBnC,MACE,MACA,UACA,SACY;AACZ,UAAM,UAAU;AAAA,MACd;AAAA,MACA,CAAC,OAAO,cAAc;AACpB,YAAI;AACF,mBAAS,OAAO,SAAS;AAAA,QAC3B,SAAS,GAAG;AACV,sBAAY,GAAG,EAAE,OAAO,SAAS,MAAM,KAAK,YAAY,MAAM,YAAY,KAAK,CAAC;AAAA,QAClF;AAAA,MACF;AAAA,MACA;AAAA,QACE,OAAO,SAAS;AAAA,QAChB,iBAAiB,SAAS;AAAA,MAC5B;AAAA,IACF;AAEA,SAAK,gBAAgB,KAAK,OAAO;AAGjC,WAAO,MAAM;AACX,cAAQ;AACR,YAAM,MAAM,KAAK,gBAAgB,QAAQ,OAAO;AAChD,UAAI,QAAQ,GAAI,MAAK,gBAAgB,OAAO,KAAK,CAAC;AAAA,IACpD;AAAA,EACF;AAAA;AAAA,EAGA,mBAAyB;AACvB,eAAW,WAAW,KAAK,iBAAiB;AAC1C,cAAQ;AAAA,IACV;AACA,SAAK,gBAAgB,SAAS;AAAA,EAChC;AACF;AAMA,SAAS,uBAAyC,UAAmB;AACnE,QAAM,cAAwC,CAAC;AAG/C,QAAM,UAAU,oBAAI,IAAI;AAAA,IACtB,GAAG,OAAO,KAAK,QAAQ;AAAA,IACvB,GAAG,OAAO,KAAK,OAAO,eAAe,QAAQ,CAAC;AAAA,EAChD,CAAC;AAED,aAAW,OAAO,SAAS;AACzB,QAAI,kBAAkB,IAAI,GAAG,EAAG;AAChC,QAAI,OAAO,YAAa;AAExB,UAAM,QAAS,SAAiB,GAAG;AACnC,QAAI,OAAO,UAAU,WAAY;AAEjC,IAAC,YAAoB,GAAG,IAAI;AAAA,EAC9B;AAGA,MAAI,QAAQ,OAAO,eAAe,QAAQ;AAC1C,SAAO,SAAS,UAAU,SAAS,aAAa,UAAU,OAAO,WAAW;AAC1E,UAAM,cAAc,OAAO,0BAA0B,KAAK;AAE1D,eAAW,CAAC,KAAK,UAAU,KAAK,OAAO,QAAQ,WAAW,GAAG;AAC3D,UAAI,kBAAkB,IAAI,GAAG,EAAG;AAChC,UAAI,OAAO,YAAa;AAExB,UAAI,WAAW,KAAK;AAClB,QAAC,YAAoB,GAAG,IAAI;AAAA,MAC9B,WAAW,OAAO,WAAW,UAAU,YAAY;AACjD,QAAC,YAAoB,GAAG,IAAI,OAAO;AAAA,MACrC;AAAA,IACF;AAEA,YAAQ,OAAO,eAAe,KAAK;AAAA,EACrC;AAEA,iBAAe,UAAU,WAAW;AACtC;AAwEO,SAAS,eACd,KACA,SACmD;AArNrD;AAuNE,QAAM,iBAAgB,oBAAe,UAC3B,sBAD2B,IAAY;AAAA,IAG/C,eAAe,MAAa;AAC1B,YAAM,GAAG,IAAI;AAGb,UAAI,OAAO,KAAK,aAAa,YAAY;AACvC,aAAK,SAAS,GAAG,IAAI;AAAA,MACvB;AAGA,YAAM,iBAAiB,SAAS,kBAAkB,aAAa;AAC/D,UAAI,gBAAgB;AAClB,+BAAuB,IAAI;AAAA,MAC7B,OAAO;AAEL,uBAAe,IAAI;AAAA,MACrB;AAAA,IACF;AAAA,EACF,GAnBE,cADoB,IACZ,IAAmB,OADP;AAuBtB,SAAO,eAAe,eAAe,QAAQ,EAAE,OAAO,IAAI,KAAK,CAAC;AAIhE,SAAO,IAAI,MAAM,eAAe;AAAA,IAC9B,MAAM,SAAS,UAAU,MAAM;AAC7B,aAAO,IAAI,cAAc,GAAG,IAAI;AAAA,IAClC;AAAA,EACF,CAAC;AACH;AAKO,SAAS,WAAW,OAAyB;AAClD,MAAI,UAAU,QAAQ,OAAO,UAAU,SAAU,QAAO;AACxD,SAAQ,MAAM,cAAsB,eAAe,MAAM;AAC3D;AAGO,SAAS,cAAc,UAA+B;AAC3D,QAAM,OAAO,SAAS;AAEtB,MAAI,aAAa,QAAQ,OAAO,KAAK,YAAY,YAAY;AAC3D,QAAI;AACF,eAAS,UAAU,KAAK,QAAQ,KAAK;AAAA,IACvC,SAAS,GAAG;AACV,kBAAY,GAAG,EAAE,OAAO,WAAW,MAAM,KAAK,YAAY,MAAM,YAAY,KAAK,CAAC;AAAA,IACpF;AAAA,EACF;AACF;AAGO,SAAS,gBAAgB,UAA+B;AAE7D,WAAS,UAAU;AAGnB,QAAM,OAAO,SAAS;AACtB,MAAI,eAAe,QAAQ,OAAO,KAAK,cAAc,YAAY;AAC/D,QAAI;AACF,WAAK,UAAU;AAAA,IACjB,SAAS,GAAG;AACV,kBAAY,GAAG,EAAE,OAAO,aAAa,MAAM,KAAK,YAAY,MAAM,YAAY,KAAK,CAAC;AAAA,IACtF;AAAA,EACF;AAGA,MAAI,OAAO,KAAK,qBAAqB,YAAY;AAC/C,SAAK,iBAAiB;AAAA,EACxB;AACF;;;AEjSA,YAAY,UAAU;AAMf,IAAM,cAAc,uBAAO,oBAAoB;AActD,SAAS,cAAc,SAA2B,YAAuB;AApBzE;AAqBE,gBAAQ,UAAR,mCAAkC,CAAC;AACnC,EAAC,QAAQ,SAAS,WAAW,EAAmC,QAAQ,IAAI,IAAI;AAClF;AAaO,SAASC,YAAW,QAAmB,SAAiC;AAC7E,gBAAc,SAAc,eAAU;AACxC;AAKAA,YAAW,MAAM,SAAS,QAAmB,SAAiC;AAC5E,gBAAc,SAAc,gBAAW,GAAG;AAC5C;AAEAA,YAAW,UAAU,SAAS,QAAmB,SAAiC;AAChF,gBAAc,SAAc,gBAAW,OAAO;AAChD;AAEAA,YAAW,SAAS,SAAS,QAAmB,SAAiC;AAC/E,gBAAc,SAAc,gBAAW,MAAM;AAC/C;AAEAA,YAAW,OAAO,SAAS,QAAmB,SAAiC;AAC7E,gBAAc,SAAc,gBAAW,IAAI;AAC7C;AAiBO,SAASC,QAAO,QAAkB,SAAiC;AACxE,gBAAc,SAAc,YAAO,KAAK;AAC1C;AAmBO,SAASC,UAAS,QAAkB,SAAiC;AAC1E,gBAAc,SAAc,aAAQ;AACtC;AAMO,SAAS,eAAe,UAAmD;AAChF,QAAM,WAAY,SAAS,YAAoB,OAAO,QAAQ;AAC9D,SAAO,WAAW,WAAW;AAC/B;;;AHrFA,IAAM,gBAAgB,oBAAI,IAAI;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAiCM,IAAM,OAAN,MAAkC;AAAA,EAAlC;AAEL;AAAA;AAeA;AAAA,sCAA8B,CAAC;AAG/B;AAAA,2CAAkC,CAAC;AAGnC;AAAA;AAGA;AAAA;AAAA;AAAA;AAAA,EArBA,IAAI,QAAW;AACb,WAAO,KAAK,UAAU,IAAI;AAAA,EAC5B;AAAA;AAAA,EAGA,WAAW,OAAU;AACnB,gBAAY,MAAM;AAChB,WAAK,UAAU,IAAI,KAAK;AAAA,IAC1B,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA0CA,MACE,MACA,UACA,SACY;AACZ,UAAM,UAAUC;AAAA,MACd;AAAA,MACA,CAAC,OAAO,cAAc;AACpB,YAAI;AACF,mBAAS,OAAO,SAAS;AAAA,QAC3B,SAAS,GAAG;AACV,sBAAY,GAAG,EAAE,OAAO,SAAS,MAAM,KAAK,YAAY,MAAM,YAAY,MAAM,CAAC;AAAA,QACnF;AAAA,MACF;AAAA,MACA;AAAA,QACE,OAAO,SAAS;AAAA,QAChB,iBAAiB,SAAS;AAAA,MAC5B;AAAA,IACF;AAEA,SAAK,gBAAgB,KAAK,OAAO;AAGjC,WAAO,MAAM;AACX,cAAQ;AACR,YAAM,MAAM,KAAK,gBAAgB,QAAQ,OAAO;AAChD,UAAI,QAAQ,GAAI,MAAK,gBAAgB,OAAO,KAAK,CAAC;AAAA,IACpD;AAAA,EACF;AAAA;AAAA,EAGA,mBAAyB;AACvB,eAAW,WAAW,KAAK,iBAAiB;AAC1C,cAAQ;AAAA,IACV;AACA,SAAK,gBAAgB,SAAS;AAAA,EAChC;AAAA;AAAA,EAGA,oBAA0B;AACxB,eAAW,OAAO,OAAO,KAAK,IAAI,GAAG;AACnC,UAAI,IAAI,WAAW,GAAG,EAAG;AACzB,YAAM,QAAS,KAAa,GAAG;AAC/B,UAAI,WAAW,KAAK,GAAG;AACrB,aAAK,WAAW,KAAK,EAAE,UAAU,MAAM,CAAC;AAAA,MAC1C;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAGA,kBAAwB;AACtB,eAAW,YAAY,KAAK,YAAY;AACtC,oBAAc,QAAQ;AAAA,IACxB;AAAA,EACF;AAAA;AAAA,EAGA,oBAA0B;AACxB,eAAW,YAAY,KAAK,YAAY;AACtC,sBAAgB,QAAQ;AAAA,IAC1B;AAAA,EACF;AAGF;AASA,SAAS,mBAAmC,UAAa,UAAmB;AAC1E,QAAM,cAAwC,CAAC;AAG/C,QAAM,UAAU,oBAAI,IAAI;AAAA,IACtB,GAAG,OAAO,KAAK,QAAQ;AAAA,IACvB,GAAG,OAAO,KAAK,OAAO,eAAe,QAAQ,CAAC;AAAA,EAChD,CAAC;AAED,aAAW,OAAO,SAAS;AACzB,QAAI,cAAc,IAAI,GAAG,EAAG;AAC5B,QAAI,OAAO,YAAa;AAExB,UAAM,QAAS,SAAiB,GAAG;AAGnC,QAAI,OAAO,UAAU,WAAY;AAGjC,QAAI,WAAW,KAAK,GAAG;AACrB,MAAC,YAAoB,GAAG,IAAIC,YAAW;AACvC;AAAA,IACF;AAEA,IAAC,YAAoB,GAAG,IAAIA;AAAA,EAC9B;AAGA,MAAI,QAAQ,OAAO,eAAe,QAAQ;AAC1C,SAAO,SAAS,UAAU,KAAK,WAAW;AACxC,UAAM,cAAc,OAAO,0BAA0B,KAAK;AAE1D,eAAW,CAAC,KAAK,UAAU,KAAK,OAAO,QAAQ,WAAW,GAAG;AAC3D,UAAI,cAAc,IAAI,GAAG,EAAG;AAC5B,UAAI,OAAO,YAAa;AAExB,UAAI,WAAW,KAAK;AAElB,QAAC,YAAoB,GAAG,IAAIC;AAAA,MAC9B,WAAW,OAAO,WAAW,UAAU,YAAY;AAEjD,QAAC,YAAoB,GAAG,IAAI,WAAWC,QAAO,QAAQA;AAAA,MACxD;AAAA,IACF;AAEA,YAAQ,OAAO,eAAe,KAAK;AAAA,EACrC;AAEA,EAAAC,gBAAe,UAAU,WAAW;AACtC;AA2CO,SAAS,WACd,WACA,SACmB;AAGnB,QAAM,EAAE,KAAK,iBAAiB,aAAa,gBAAgB,SAAS,KAAK,IAAI;AAAA,EAG7E,MAAM,sBAAsB,WAAW;AAAA,IAWrC,cAAc;AACZ,YAAM;AAXR,0BAAQ,OAAgB;AACxB,0BAAQ;AACR,0BAAQ,UAAY,CAAC;AAAA,IAUrB;AAAA;AAAA,IAGA,mBAAmB;AACjB,aAAO,SAAS,MAAM,iBAAiB,IAAI;AAAA,IAC7C;AAAA,IAEQ,iBAAiB;AACvB,UAAI,KAAK,IAAK;AAId,iBAAW,OAAO,OAAO,KAAK,IAAI,GAAG;AACnC,YAAI,IAAI,WAAW,GAAG,EAAG;AACzB,QAAC,KAAK,OAAe,GAAG,IAAK,KAAa,GAAG;AAAA,MAC/C;AAEA,YAAM,WAAW,IAAI,UAAU;AAG/B,eAAS,YAAYH,YAAW,IAAI,KAAK,QAAQ,EAAE,MAAM,MAAM,CAAC;AAGhE,eAAS,kBAAkB;AAG3B,YAAM,uBAAuB,eAAe,QAAQ;AAEpD,UAAI,sBAAsB;AAGxB,cAAM,cAAc,EAAE,GAAG,qBAAqB;AAG9C,YAAI,QAAQ,OAAO,eAAe,QAAQ;AAC1C,eAAO,SAAS,UAAU,KAAK,WAAW;AACxC,gBAAM,cAAc,OAAO,0BAA0B,KAAK;AAC1D,qBAAW,CAAC,KAAK,UAAU,KAAK,OAAO,QAAQ,WAAW,GAAG;AAC3D,gBAAI,cAAc,IAAI,GAAG,EAAG;AAC5B,gBAAI,OAAO,YAAa;AACxB,gBAAI,OAAO,WAAW,UAAU,YAAY;AAC1C,0BAAY,GAAG,IAAIE,QAAO;AAAA,YAC5B;AAAA,UACF;AACA,kBAAQ,OAAO,eAAe,KAAK;AAAA,QACrC;AAEA,QAAAC,gBAAe,UAAU,WAAuC;AAAA,MAClE,WAAW,gBAAgB;AACzB,2BAAmB,UAAU,IAAI;AAAA,MACnC,OAAO;AAEL,QAAAA,gBAAe,QAAQ;AAAA,MACzB;AAGA,eAAS,iBAAiB,MAAM,KAAK,cAAc;AAGnD,eAAS,oBAAoBC;AAAA,QAC3B,MAAM,SAAS,SAAS;AAAA,QACxB,MAAM,KAAK,cAAc;AAAA,QACzB,EAAE,iBAAiB,MAAM;AAAA,MAC3B;AAGA,UAAI;AACF,iBAAS,WAAW;AAAA,MACtB,SAAS,GAAG;AACV,oBAAY,GAAG,EAAE,OAAO,YAAY,MAAM,UAAU,MAAM,YAAY,MAAM,CAAC;AAAA,MAC/E;AAEA,WAAK,MAAM;AAAA,IACb;AAAA,IAEA,oBAAoB;AAClB,YAAM,kBAAkB;AAExB,WAAK,eAAe;AAEpB,UAAI,KAAK,KAAK;AAEZ,aAAK,IAAI,gBAAgB;AAGzB,YAAI;AACF,gBAAM,SAAS,KAAK,IAAI,UAAU;AAClC,cAAI,QAAQ,IAAI,aAAa,gBAAgB,kBAAkB,SAAS;AACtE,oBAAQ;AAAA,cACN,gBAAgB,UAAU,IAAI;AAAA,YAGhC;AAAA,UACF;AACA,eAAK,gBAAgB;AAAA,QACvB,SAAS,GAAG;AACV,sBAAY,GAAG,EAAE,OAAO,WAAW,MAAM,UAAU,MAAM,YAAY,MAAM,CAAC;AAAA,QAC9E;AAAA,MACF;AAAA,IACF;AAAA,IAEA,uBAAuB;AACrB,YAAM,qBAAqB;AAE3B,UAAI,KAAK,KAAK;AAEZ,aAAK,gBAAgB;AAGrB,YAAI;AACF,eAAK,IAAI,YAAY;AAAA,QACvB,SAAS,GAAG;AACV,sBAAY,GAAG,EAAE,OAAO,aAAa,MAAM,UAAU,MAAM,YAAY,MAAM,CAAC;AAAA,QAChF;AAGA,aAAK,IAAI,iBAAiB;AAG1B,aAAK,IAAI,kBAAkB;AAG3B,aAAK,IAAI,oBAAoB;AAAA,MAC/B;AAAA,IACF;AAAA;AAAA,IAGA,cAAc,MAAoB,UAAoB;AACpD,UAAI,QAAQ,KAAK,KAAK;AAEpB,QAAC,KAAK,OAAe,IAAI,IAAK,KAAa,IAAI;AAC/C,aAAK,IAAI,WAAW,KAAK,MAAM;AAAA,MACjC;AACA,aAAO,MAAM,cAAc,MAAM,QAAQ;AAAA,IAC3C;AAAA,IAEA,SAAS;AACP,UAAI,CAAC,KAAK,KAAK;AACb,aAAK,eAAe;AAAA,MACtB;AAEA,UAAI,CAAC,KAAK,KAAK,QAAQ;AACrB,cAAM,IAAI;AAAA,UACR,gBAAgB,UAAU,IAAI;AAAA,QAChC;AAAA,MACF;AAEA,aAAO,KAAK,IAAI,OAAO;AAAA,IACzB;AAAA,EACF;AA5JE;AAAA,gBANI,eAMG,cAAkC,CAAC;AAG1C;AAAA,gBATI,eASG,UAAU,UAAkB;AA4JrC,MAAI,CAAC,eAAe,IAAI,GAAG,GAAG;AAC5B,mBAAe,OAAO,KAAK,aAAa;AAAA,EAC1C;AAEA,SAAO;AACT;AA4BO,SAAS,MACd,KACA,OACA,WACiB;AACjB,QAAM,KAAK,SAAS,cAAc,GAAG;AAErC,MAAI,OAAO;AACT,WAAO,OAAO,IAAI,KAAK;AAAA,EACzB;AAEA,QAAM,SAAS,OAAO,cAAc,WAChC,SAAS,cAAc,SAAS,IAChC,aAAa,SAAS;AAE1B,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI,MAAM,kCAAkC,SAAS,aAAa;AAAA,EAC1E;AAEA,SAAO,YAAY,EAAE;AACrB,SAAO;AACT;","names":["makeObservable","observable","computed","action","reaction","observable","action","computed","reaction","observable","computed","action","makeObservable","reaction"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "mantle-lit",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "A lightweight library for building Lit web components with a simpler class-based API and MobX reactivity built in.",
|
|
5
|
+
"author": "Craig Albert <me@craigalbert.com>",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/craigthings/mantle-lit"
|
|
9
|
+
},
|
|
10
|
+
"homepage": "https://github.com/craigthings/mantle-lit#readme",
|
|
11
|
+
"bugs": {
|
|
12
|
+
"url": "https://github.com/craigthings/mantle-lit/issues"
|
|
13
|
+
},
|
|
14
|
+
"license": "MIT",
|
|
15
|
+
"keywords": [
|
|
16
|
+
"lit",
|
|
17
|
+
"web-components",
|
|
18
|
+
"mobx",
|
|
19
|
+
"viewmodel",
|
|
20
|
+
"mvvm",
|
|
21
|
+
"class-components"
|
|
22
|
+
],
|
|
23
|
+
"type": "module",
|
|
24
|
+
"main": "./dist/index.cjs",
|
|
25
|
+
"module": "./dist/index.js",
|
|
26
|
+
"types": "./dist/index.d.ts",
|
|
27
|
+
"exports": {
|
|
28
|
+
".": {
|
|
29
|
+
"import": {
|
|
30
|
+
"types": "./dist/index.d.ts",
|
|
31
|
+
"default": "./dist/index.js"
|
|
32
|
+
},
|
|
33
|
+
"require": {
|
|
34
|
+
"types": "./dist/index.d.cts",
|
|
35
|
+
"default": "./dist/index.cjs"
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
"files": [
|
|
40
|
+
"dist"
|
|
41
|
+
],
|
|
42
|
+
"sideEffects": false,
|
|
43
|
+
"scripts": {
|
|
44
|
+
"dev": "vite",
|
|
45
|
+
"build": "tsup",
|
|
46
|
+
"prepublishOnly": "npm run build"
|
|
47
|
+
},
|
|
48
|
+
"peerDependencies": {
|
|
49
|
+
"lit": ">=3.0.0",
|
|
50
|
+
"mobx": ">=6.0.0"
|
|
51
|
+
},
|
|
52
|
+
"devDependencies": {
|
|
53
|
+
"@types/node": "^25.2.2",
|
|
54
|
+
"lit": "^3.1.0",
|
|
55
|
+
"mobx": "^6.12.0",
|
|
56
|
+
"tsup": "^8.0.0",
|
|
57
|
+
"typescript": "^5.3.0",
|
|
58
|
+
"vite": "^5.0.0"
|
|
59
|
+
}
|
|
60
|
+
}
|