mvc-kit 2.5.1 → 2.5.2
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/ViewModel.d.ts.map +1 -1
- package/dist/mvc-kit.cjs +1 -1
- package/dist/mvc-kit.cjs.map +1 -1
- package/dist/mvc-kit.js +146 -143
- package/dist/mvc-kit.js.map +1 -1
- package/package.json +1 -1
package/dist/mvc-kit.js
CHANGED
|
@@ -3,8 +3,8 @@ import { h as B, s as F, t as X, a as Y } from "./singleton-CaEXSbYg.js";
|
|
|
3
3
|
import { C as A } from "./PersistentCollection-BFrgskju.js";
|
|
4
4
|
import { P as U } from "./PersistentCollection-BFrgskju.js";
|
|
5
5
|
class x extends Error {
|
|
6
|
-
constructor(t,
|
|
7
|
-
super(
|
|
6
|
+
constructor(t, e) {
|
|
7
|
+
super(e ?? `HTTP ${t}`), this.status = t, this.name = "HttpError";
|
|
8
8
|
}
|
|
9
9
|
}
|
|
10
10
|
function O(r) {
|
|
@@ -53,17 +53,17 @@ const d = typeof __MVC_KIT_DEV__ < "u" && __MVC_KIT_DEV__;
|
|
|
53
53
|
function M(r) {
|
|
54
54
|
return r !== null && typeof r == "object" && typeof r.subscribe == "function";
|
|
55
55
|
}
|
|
56
|
-
function b(r, t,
|
|
57
|
-
let
|
|
58
|
-
for (;
|
|
59
|
-
const n = Object.getOwnPropertyDescriptors(
|
|
56
|
+
function b(r, t, e) {
|
|
57
|
+
let s = Object.getPrototypeOf(r);
|
|
58
|
+
for (; s && s !== t; ) {
|
|
59
|
+
const n = Object.getOwnPropertyDescriptors(s);
|
|
60
60
|
for (const [o, c] of Object.entries(n))
|
|
61
|
-
o !== "constructor" &&
|
|
62
|
-
|
|
61
|
+
o !== "constructor" && e(o, c, s);
|
|
62
|
+
s = Object.getPrototypeOf(s);
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
65
|
const j = Object.freeze({ loading: !1, error: null, errorCode: null }), m = ["async", "subscribeAsync"], P = /* @__PURE__ */ new Set(["onInit", "onSet", "onDispose"]);
|
|
66
|
-
class
|
|
66
|
+
class y {
|
|
67
67
|
_state;
|
|
68
68
|
_initialState;
|
|
69
69
|
_disposed = !1;
|
|
@@ -132,12 +132,12 @@ class S {
|
|
|
132
132
|
);
|
|
133
133
|
return;
|
|
134
134
|
}
|
|
135
|
-
const
|
|
136
|
-
if (!Object.keys(
|
|
137
|
-
(l) =>
|
|
135
|
+
const e = typeof t == "function" ? t(this._state) : t;
|
|
136
|
+
if (!Object.keys(e).some(
|
|
137
|
+
(l) => e[l] !== this._state[l]
|
|
138
138
|
))
|
|
139
139
|
return;
|
|
140
|
-
const o = this._state, c = Object.freeze({ ...o, ...
|
|
140
|
+
const o = this._state, c = Object.freeze({ ...o, ...e });
|
|
141
141
|
this._state = c, this._revision++, this.onSet?.(o, c);
|
|
142
142
|
for (const l of this._listeners)
|
|
143
143
|
l(c, o);
|
|
@@ -147,8 +147,8 @@ class S {
|
|
|
147
147
|
* Safe to call during dispose cleanup callbacks.
|
|
148
148
|
* @protected
|
|
149
149
|
*/
|
|
150
|
-
emit(t,
|
|
151
|
-
(this._eventBus?.disposed ?? this._disposed) || this.events.emit(t,
|
|
150
|
+
emit(t, e) {
|
|
151
|
+
(this._eventBus?.disposed ?? this._disposed) || this.events.emit(t, e);
|
|
152
152
|
}
|
|
153
153
|
/** Subscribes to state changes. Returns an unsubscribe function. */
|
|
154
154
|
subscribe(t) {
|
|
@@ -174,8 +174,8 @@ class S {
|
|
|
174
174
|
reset(t) {
|
|
175
175
|
if (!this._disposed) {
|
|
176
176
|
this._abortController?.abort(), this._abortController = null, this._teardownSubscriptions(), this._state = t ? Object.freeze({ ...t }) : this._initialState, this._revision++, this._asyncStates.clear(), this._asyncSnapshots.clear(), this._notifyAsync(), this._trackSubscribables();
|
|
177
|
-
for (const
|
|
178
|
-
|
|
177
|
+
for (const e of this._listeners)
|
|
178
|
+
e(this._state, this._state);
|
|
179
179
|
return this.onInit?.();
|
|
180
180
|
}
|
|
181
181
|
}
|
|
@@ -189,9 +189,9 @@ class S {
|
|
|
189
189
|
this._cleanups || (this._cleanups = []), this._cleanups.push(t);
|
|
190
190
|
}
|
|
191
191
|
/** Subscribes to an external Subscribable with automatic cleanup on dispose. @protected */
|
|
192
|
-
subscribeTo(t,
|
|
193
|
-
const
|
|
194
|
-
return this._subscriptionCleanups || (this._subscriptionCleanups = []), this._subscriptionCleanups.push(
|
|
192
|
+
subscribeTo(t, e) {
|
|
193
|
+
const s = t.subscribe(e);
|
|
194
|
+
return this._subscriptionCleanups || (this._subscriptionCleanups = []), this._subscriptionCleanups.push(s), s;
|
|
195
195
|
}
|
|
196
196
|
// ── Async tracking API ──────────────────────────────────────────
|
|
197
197
|
/** Proxy providing `TaskState` (loading, error, errorCode) per async method. */
|
|
@@ -199,18 +199,18 @@ class S {
|
|
|
199
199
|
if (!this._asyncProxy) {
|
|
200
200
|
const t = this;
|
|
201
201
|
this._asyncProxy = new Proxy({}, {
|
|
202
|
-
get(
|
|
203
|
-
return t._asyncSnapshots.get(
|
|
202
|
+
get(e, s) {
|
|
203
|
+
return t._asyncSnapshots.get(s) ?? j;
|
|
204
204
|
},
|
|
205
|
-
has(
|
|
206
|
-
return t._asyncSnapshots.has(
|
|
205
|
+
has(e, s) {
|
|
206
|
+
return t._asyncSnapshots.has(s);
|
|
207
207
|
},
|
|
208
208
|
ownKeys() {
|
|
209
209
|
return Array.from(t._asyncSnapshots.keys());
|
|
210
210
|
},
|
|
211
|
-
getOwnPropertyDescriptor(
|
|
212
|
-
if (t._asyncSnapshots.has(
|
|
213
|
-
return { configurable: !0, enumerable: !0, value: t._asyncSnapshots.get(
|
|
211
|
+
getOwnPropertyDescriptor(e, s) {
|
|
212
|
+
if (t._asyncSnapshots.has(s))
|
|
213
|
+
return { configurable: !0, enumerable: !0, value: t._asyncSnapshots.get(s) };
|
|
214
214
|
}
|
|
215
215
|
});
|
|
216
216
|
}
|
|
@@ -236,7 +236,7 @@ class S {
|
|
|
236
236
|
}
|
|
237
237
|
}
|
|
238
238
|
_guardReservedKeys() {
|
|
239
|
-
b(this,
|
|
239
|
+
b(this, y.prototype, (t) => {
|
|
240
240
|
if (m.includes(t))
|
|
241
241
|
throw new Error(
|
|
242
242
|
`[mvc-kit] "${t}" is a reserved property on ViewModel and cannot be overridden.`
|
|
@@ -249,10 +249,10 @@ class S {
|
|
|
249
249
|
throw new Error(
|
|
250
250
|
`[mvc-kit] "${n}" is a reserved property on ViewModel and cannot be overridden.`
|
|
251
251
|
);
|
|
252
|
-
const t = this,
|
|
253
|
-
d && (this._activeOps = /* @__PURE__ */ new Map()), b(this,
|
|
254
|
-
if (o.get || o.set || typeof o.value != "function" || n.startsWith("_") || P.has(n) ||
|
|
255
|
-
|
|
252
|
+
const t = this, e = /* @__PURE__ */ new Set(), s = [];
|
|
253
|
+
d && (this._activeOps = /* @__PURE__ */ new Map()), b(this, y.prototype, (n, o) => {
|
|
254
|
+
if (o.get || o.set || typeof o.value != "function" || n.startsWith("_") || P.has(n) || e.has(n)) return;
|
|
255
|
+
e.add(n);
|
|
256
256
|
const c = o.value;
|
|
257
257
|
let l = !1;
|
|
258
258
|
const p = function(...g) {
|
|
@@ -309,10 +309,10 @@ class S {
|
|
|
309
309
|
}
|
|
310
310
|
);
|
|
311
311
|
};
|
|
312
|
-
|
|
313
|
-
}),
|
|
312
|
+
s.push(n), t[n] = p;
|
|
313
|
+
}), s.length > 0 && this.addCleanup(() => {
|
|
314
314
|
const n = d && t._activeOps ? new Map(t._activeOps) : null;
|
|
315
|
-
for (const o of
|
|
315
|
+
for (const o of s)
|
|
316
316
|
d ? t[o] = () => {
|
|
317
317
|
console.warn(`[mvc-kit] "${o}" called after dispose — ignored.`);
|
|
318
318
|
} : t[o] = () => {
|
|
@@ -322,9 +322,9 @@ class S {
|
|
|
322
322
|
}
|
|
323
323
|
_scheduleGhostCheck(t) {
|
|
324
324
|
d && setTimeout(() => {
|
|
325
|
-
for (const [
|
|
325
|
+
for (const [e, s] of t)
|
|
326
326
|
console.warn(
|
|
327
|
-
`[mvc-kit] Ghost async operation detected: "${
|
|
327
|
+
`[mvc-kit] Ghost async operation detected: "${e}" had ${s} pending call(s) when the ViewModel was disposed. Consider using disposeSignal to cancel in-flight work.`
|
|
328
328
|
);
|
|
329
329
|
}, this.constructor.GHOST_TIMEOUT);
|
|
330
330
|
}
|
|
@@ -341,13 +341,13 @@ class S {
|
|
|
341
341
|
*/
|
|
342
342
|
_installStateProxy() {
|
|
343
343
|
const t = new Proxy({}, {
|
|
344
|
-
get: (
|
|
344
|
+
get: (e, s) => (this._stateTracking?.add(s), this._state[s]),
|
|
345
345
|
ownKeys: () => Reflect.ownKeys(this._state),
|
|
346
|
-
getOwnPropertyDescriptor: (
|
|
346
|
+
getOwnPropertyDescriptor: (e, s) => Reflect.getOwnPropertyDescriptor(this._state, s),
|
|
347
347
|
set: () => {
|
|
348
348
|
throw new Error("Cannot mutate state directly. Use set() instead.");
|
|
349
349
|
},
|
|
350
|
-
has: (
|
|
350
|
+
has: (e, s) => s in this._state
|
|
351
351
|
});
|
|
352
352
|
Object.defineProperty(this, "state", {
|
|
353
353
|
get: () => this._stateTracking ? t : this._state,
|
|
@@ -372,21 +372,24 @@ class S {
|
|
|
372
372
|
*/
|
|
373
373
|
_trackSubscribables() {
|
|
374
374
|
for (const t of Object.getOwnPropertyNames(this)) {
|
|
375
|
-
const
|
|
376
|
-
if (!M(
|
|
377
|
-
|
|
378
|
-
|
|
375
|
+
const e = this[t];
|
|
376
|
+
if (!M(e)) continue;
|
|
377
|
+
let s;
|
|
378
|
+
const n = () => {
|
|
379
|
+
if (!this._disposed) {
|
|
380
|
+
s.revision++, this._revision++, this._state = Object.freeze({ ...this._state });
|
|
381
|
+
for (const l of this._listeners)
|
|
382
|
+
l(this._state, this._state);
|
|
383
|
+
}
|
|
384
|
+
}, o = e.subscribe(n), c = typeof e.subscribeAsync == "function" ? e.subscribeAsync(n) : void 0;
|
|
385
|
+
s = {
|
|
386
|
+
source: e,
|
|
379
387
|
revision: 0,
|
|
380
|
-
unsubscribe:
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
}
|
|
386
|
-
})
|
|
387
|
-
};
|
|
388
|
-
this._trackedSources.set(t, e), Object.defineProperty(this, t, {
|
|
389
|
-
get: () => (this._sourceTracking?.set(t, e), s),
|
|
388
|
+
unsubscribe: c ? () => {
|
|
389
|
+
o(), c();
|
|
390
|
+
} : o
|
|
391
|
+
}, this._trackedSources.set(t, s), Object.defineProperty(this, t, {
|
|
392
|
+
get: () => (this._sourceTracking?.set(t, s), e),
|
|
390
393
|
configurable: !0,
|
|
391
394
|
enumerable: !1
|
|
392
395
|
});
|
|
@@ -402,8 +405,8 @@ class S {
|
|
|
402
405
|
*/
|
|
403
406
|
_memoizeGetters() {
|
|
404
407
|
const t = /* @__PURE__ */ new Set();
|
|
405
|
-
b(this,
|
|
406
|
-
!
|
|
408
|
+
b(this, y.prototype, (e, s) => {
|
|
409
|
+
!s.get || t.has(e) || (t.add(e), this._wrapGetter(e, s.get));
|
|
407
410
|
});
|
|
408
411
|
}
|
|
409
412
|
/**
|
|
@@ -416,12 +419,12 @@ class S {
|
|
|
416
419
|
* Tier 2 (medium): revision changed but this getter's deps didn't → return cached
|
|
417
420
|
* Tier 3 (slow): at least one dep changed → full recompute with tracking
|
|
418
421
|
*/
|
|
419
|
-
_wrapGetter(t,
|
|
420
|
-
let
|
|
422
|
+
_wrapGetter(t, e) {
|
|
423
|
+
let s, n = -1, o, c, l;
|
|
421
424
|
Object.defineProperty(this, t, {
|
|
422
425
|
get: () => {
|
|
423
426
|
if (this._disposed || n === this._revision)
|
|
424
|
-
return
|
|
427
|
+
return s;
|
|
425
428
|
if (o && c) {
|
|
426
429
|
let i = !0;
|
|
427
430
|
for (const [a, _] of c)
|
|
@@ -438,12 +441,12 @@ class S {
|
|
|
438
441
|
}
|
|
439
442
|
}
|
|
440
443
|
if (i)
|
|
441
|
-
return n = this._revision,
|
|
444
|
+
return n = this._revision, s;
|
|
442
445
|
}
|
|
443
446
|
const p = this._stateTracking, g = this._sourceTracking;
|
|
444
447
|
this._stateTracking = /* @__PURE__ */ new Set(), this._sourceTracking = /* @__PURE__ */ new Map();
|
|
445
448
|
try {
|
|
446
|
-
|
|
449
|
+
s = e.call(this);
|
|
447
450
|
} catch (i) {
|
|
448
451
|
throw this._stateTracking = p, this._sourceTracking = g, i;
|
|
449
452
|
}
|
|
@@ -460,7 +463,7 @@ class S {
|
|
|
460
463
|
l = /* @__PURE__ */ new Map();
|
|
461
464
|
for (const [i, a] of u)
|
|
462
465
|
l.set(i, a.revision);
|
|
463
|
-
return n = this._revision,
|
|
466
|
+
return n = this._revision, s;
|
|
464
467
|
},
|
|
465
468
|
configurable: !0,
|
|
466
469
|
enumerable: !0
|
|
@@ -476,8 +479,8 @@ class $ {
|
|
|
476
479
|
_abortController = null;
|
|
477
480
|
_cleanups = null;
|
|
478
481
|
constructor(t) {
|
|
479
|
-
const
|
|
480
|
-
this._state =
|
|
482
|
+
const e = Object.freeze({ ...t });
|
|
483
|
+
this._state = e, this._committed = e;
|
|
481
484
|
}
|
|
482
485
|
/** Current frozen state object. */
|
|
483
486
|
get state() {
|
|
@@ -531,12 +534,12 @@ class $ {
|
|
|
531
534
|
set(t) {
|
|
532
535
|
if (this._disposed)
|
|
533
536
|
throw new Error("Cannot set state on disposed Model");
|
|
534
|
-
const
|
|
535
|
-
if (!Object.keys(
|
|
536
|
-
(l) =>
|
|
537
|
+
const e = typeof t == "function" ? t(this._state) : t;
|
|
538
|
+
if (!Object.keys(e).some(
|
|
539
|
+
(l) => e[l] !== this._state[l]
|
|
537
540
|
))
|
|
538
541
|
return;
|
|
539
|
-
const o = this._state, c = Object.freeze({ ...o, ...
|
|
542
|
+
const o = this._state, c = Object.freeze({ ...o, ...e });
|
|
540
543
|
this._state = c, this.onSet?.(o, c);
|
|
541
544
|
for (const l of this._listeners)
|
|
542
545
|
l(c, o);
|
|
@@ -559,8 +562,8 @@ class $ {
|
|
|
559
562
|
return;
|
|
560
563
|
const t = this._state;
|
|
561
564
|
this._state = this._committed, this.onSet?.(t, this._state);
|
|
562
|
-
for (const
|
|
563
|
-
|
|
565
|
+
for (const e of this._listeners)
|
|
566
|
+
e(this._state, t);
|
|
564
567
|
}
|
|
565
568
|
/** Subscribes to state changes. Returns an unsubscribe function. */
|
|
566
569
|
subscribe(t) {
|
|
@@ -591,16 +594,16 @@ class $ {
|
|
|
591
594
|
this._cleanups || (this._cleanups = []), this._cleanups.push(t);
|
|
592
595
|
}
|
|
593
596
|
/** Subscribes to an external Subscribable with automatic cleanup on dispose. @protected */
|
|
594
|
-
subscribeTo(t,
|
|
595
|
-
const
|
|
596
|
-
return this.addCleanup(
|
|
597
|
+
subscribeTo(t, e) {
|
|
598
|
+
const s = t.subscribe(e);
|
|
599
|
+
return this.addCleanup(s), s;
|
|
597
600
|
}
|
|
598
|
-
shallowEqual(t,
|
|
599
|
-
const
|
|
600
|
-
if (
|
|
601
|
+
shallowEqual(t, e) {
|
|
602
|
+
const s = Object.keys(t), n = Object.keys(e);
|
|
603
|
+
if (s.length !== n.length)
|
|
601
604
|
return !1;
|
|
602
|
-
for (const o of
|
|
603
|
-
if (t[o] !==
|
|
605
|
+
for (const o of s)
|
|
606
|
+
if (t[o] !== e[o])
|
|
604
607
|
return !1;
|
|
605
608
|
return !0;
|
|
606
609
|
}
|
|
@@ -618,11 +621,11 @@ class v extends A {
|
|
|
618
621
|
/** DEV-only timeout (ms) for detecting ghost async operations after dispose. */
|
|
619
622
|
static GHOST_TIMEOUT = 3e3;
|
|
620
623
|
constructor(t) {
|
|
621
|
-
const
|
|
622
|
-
if (super(
|
|
623
|
-
const
|
|
624
|
-
(
|
|
625
|
-
`[mvc-kit] Resource "${
|
|
624
|
+
const e = t != null && !Array.isArray(t);
|
|
625
|
+
if (super(e ? [] : t ?? []), e && (this._external = t, f)) {
|
|
626
|
+
const s = this.constructor;
|
|
627
|
+
(s.MAX_SIZE > 0 || s.TTL > 0) && console.warn(
|
|
628
|
+
`[mvc-kit] Resource "${s.name}" has MAX_SIZE or TTL set but uses an injected Collection. Configure these on the Collection instead.`
|
|
626
629
|
);
|
|
627
630
|
}
|
|
628
631
|
this._guardReservedKeys();
|
|
@@ -653,8 +656,8 @@ class v extends A {
|
|
|
653
656
|
upsert(...t) {
|
|
654
657
|
this._external ? this._external.upsert(...t) : super.upsert(...t);
|
|
655
658
|
}
|
|
656
|
-
update(t,
|
|
657
|
-
this._external ? this._external.update(t,
|
|
659
|
+
update(t, e) {
|
|
660
|
+
this._external ? this._external.update(t, e) : super.update(t, e);
|
|
658
661
|
}
|
|
659
662
|
remove(...t) {
|
|
660
663
|
this._external ? this._external.remove(...t) : super.remove(...t);
|
|
@@ -696,18 +699,18 @@ class v extends A {
|
|
|
696
699
|
if (!this._asyncProxy) {
|
|
697
700
|
const t = this;
|
|
698
701
|
this._asyncProxy = new Proxy({}, {
|
|
699
|
-
get(
|
|
700
|
-
return t._asyncSnapshots.get(
|
|
702
|
+
get(e, s) {
|
|
703
|
+
return t._asyncSnapshots.get(s) ?? D;
|
|
701
704
|
},
|
|
702
|
-
has(
|
|
703
|
-
return t._asyncSnapshots.has(
|
|
705
|
+
has(e, s) {
|
|
706
|
+
return t._asyncSnapshots.has(s);
|
|
704
707
|
},
|
|
705
708
|
ownKeys() {
|
|
706
709
|
return Array.from(t._asyncSnapshots.keys());
|
|
707
710
|
},
|
|
708
|
-
getOwnPropertyDescriptor(
|
|
709
|
-
if (t._asyncSnapshots.has(
|
|
710
|
-
return { configurable: !0, enumerable: !0, value: t._asyncSnapshots.get(
|
|
711
|
+
getOwnPropertyDescriptor(e, s) {
|
|
712
|
+
if (t._asyncSnapshots.has(s))
|
|
713
|
+
return { configurable: !0, enumerable: !0, value: t._asyncSnapshots.get(s) };
|
|
711
714
|
}
|
|
712
715
|
});
|
|
713
716
|
}
|
|
@@ -739,10 +742,10 @@ class v extends A {
|
|
|
739
742
|
throw new Error(
|
|
740
743
|
`[mvc-kit] "${n}" is a reserved property on Resource and cannot be overridden.`
|
|
741
744
|
);
|
|
742
|
-
const t = this,
|
|
745
|
+
const t = this, e = /* @__PURE__ */ new Set(), s = [];
|
|
743
746
|
f && (this._activeOps = /* @__PURE__ */ new Map()), b(this, v.prototype, (n, o) => {
|
|
744
|
-
if (o.get || o.set || typeof o.value != "function" || n.startsWith("_") || k.has(n) ||
|
|
745
|
-
|
|
747
|
+
if (o.get || o.set || typeof o.value != "function" || n.startsWith("_") || k.has(n) || e.has(n)) return;
|
|
748
|
+
e.add(n);
|
|
746
749
|
const c = o.value;
|
|
747
750
|
let l = !1;
|
|
748
751
|
const p = function(...g) {
|
|
@@ -799,10 +802,10 @@ class v extends A {
|
|
|
799
802
|
}
|
|
800
803
|
);
|
|
801
804
|
};
|
|
802
|
-
|
|
803
|
-
}),
|
|
805
|
+
s.push(n), t[n] = p;
|
|
806
|
+
}), s.length > 0 && this.addCleanup(() => {
|
|
804
807
|
const n = f && t._activeOps ? new Map(t._activeOps) : null;
|
|
805
|
-
for (const o of
|
|
808
|
+
for (const o of s)
|
|
806
809
|
f ? t[o] = () => {
|
|
807
810
|
console.warn(`[mvc-kit] "${o}" called after dispose — ignored.`);
|
|
808
811
|
} : t[o] = () => {
|
|
@@ -812,9 +815,9 @@ class v extends A {
|
|
|
812
815
|
}
|
|
813
816
|
_scheduleGhostCheck(t) {
|
|
814
817
|
f && setTimeout(() => {
|
|
815
|
-
for (const [
|
|
818
|
+
for (const [e, s] of t)
|
|
816
819
|
console.warn(
|
|
817
|
-
`[mvc-kit] Ghost async operation detected: "${
|
|
820
|
+
`[mvc-kit] Ghost async operation detected: "${e}" had ${s} pending call(s) when the Resource was disposed. Consider using disposeSignal to cancel in-flight work.`
|
|
818
821
|
);
|
|
819
822
|
}, this.constructor.GHOST_TIMEOUT);
|
|
820
823
|
}
|
|
@@ -856,9 +859,9 @@ class L {
|
|
|
856
859
|
this._cleanups || (this._cleanups = []), this._cleanups.push(t);
|
|
857
860
|
}
|
|
858
861
|
/** Subscribes to an external Subscribable with automatic cleanup on dispose. @protected */
|
|
859
|
-
subscribeTo(t,
|
|
860
|
-
const
|
|
861
|
-
return this.addCleanup(
|
|
862
|
+
subscribeTo(t, e) {
|
|
863
|
+
const s = t.subscribe(e);
|
|
864
|
+
return this.addCleanup(s), s;
|
|
862
865
|
}
|
|
863
866
|
}
|
|
864
867
|
class V {
|
|
@@ -898,7 +901,7 @@ class V {
|
|
|
898
901
|
this._cleanups || (this._cleanups = []), this._cleanups.push(t);
|
|
899
902
|
}
|
|
900
903
|
}
|
|
901
|
-
const
|
|
904
|
+
const S = typeof __MVC_KIT_DEV__ < "u" && __MVC_KIT_DEV__, R = Object.freeze({
|
|
902
905
|
connected: !1,
|
|
903
906
|
reconnecting: !1,
|
|
904
907
|
attempt: 0,
|
|
@@ -974,10 +977,10 @@ class N {
|
|
|
974
977
|
/** Initiates a connection with automatic reconnection on failure. */
|
|
975
978
|
connect() {
|
|
976
979
|
if (this._disposed) {
|
|
977
|
-
|
|
980
|
+
S && console.warn("[mvc-kit] connect() called after dispose — ignored.");
|
|
978
981
|
return;
|
|
979
982
|
}
|
|
980
|
-
|
|
983
|
+
S && !this._initialized && console.warn("[mvc-kit] connect() called before init()."), !(this._connState === 1 || this._connState === 2) && (this._reconnectTimer !== null && (clearTimeout(this._reconnectTimer), this._reconnectTimer = null), this._attemptConnect(0));
|
|
981
984
|
}
|
|
982
985
|
/** Closes the connection and cancels any pending reconnection. */
|
|
983
986
|
disconnect() {
|
|
@@ -995,15 +998,15 @@ class N {
|
|
|
995
998
|
}
|
|
996
999
|
// ── Subclass signals ────────────────────────────────────────────
|
|
997
1000
|
/** Call from subclass when a message arrives from the transport. @protected */
|
|
998
|
-
receive(t,
|
|
1001
|
+
receive(t, e) {
|
|
999
1002
|
if (this._disposed) {
|
|
1000
|
-
|
|
1003
|
+
S && console.warn(`[mvc-kit] receive("${String(t)}") called after dispose — ignored.`);
|
|
1001
1004
|
return;
|
|
1002
1005
|
}
|
|
1003
|
-
const
|
|
1004
|
-
if (
|
|
1005
|
-
for (const n of
|
|
1006
|
-
n(
|
|
1006
|
+
const s = this._handlers.get(t);
|
|
1007
|
+
if (s)
|
|
1008
|
+
for (const n of s)
|
|
1009
|
+
n(e);
|
|
1007
1010
|
}
|
|
1008
1011
|
/** Call from subclass when the transport connection drops unexpectedly. Triggers reconnection. @protected */
|
|
1009
1012
|
disconnected() {
|
|
@@ -1011,20 +1014,20 @@ class N {
|
|
|
1011
1014
|
}
|
|
1012
1015
|
// ── Consumer API ────────────────────────────────────────────────
|
|
1013
1016
|
/** Subscribes to a specific message type. Returns an unsubscribe function. */
|
|
1014
|
-
on(t,
|
|
1017
|
+
on(t, e) {
|
|
1015
1018
|
if (this._disposed) return () => {
|
|
1016
1019
|
};
|
|
1017
|
-
let
|
|
1018
|
-
return
|
|
1019
|
-
|
|
1020
|
+
let s = this._handlers.get(t);
|
|
1021
|
+
return s || (s = /* @__PURE__ */ new Set(), this._handlers.set(t, s)), s.add(e), () => {
|
|
1022
|
+
s.delete(e);
|
|
1020
1023
|
};
|
|
1021
1024
|
}
|
|
1022
1025
|
/** Subscribes to a message type, auto-removing the handler after the first invocation. */
|
|
1023
|
-
once(t,
|
|
1024
|
-
const
|
|
1025
|
-
|
|
1026
|
+
once(t, e) {
|
|
1027
|
+
const s = this.on(t, (n) => {
|
|
1028
|
+
s(), e(n);
|
|
1026
1029
|
});
|
|
1027
|
-
return
|
|
1030
|
+
return s;
|
|
1028
1031
|
}
|
|
1029
1032
|
// ── Infrastructure ──────────────────────────────────────────────
|
|
1030
1033
|
/** Registers a cleanup function to be called on dispose. @protected */
|
|
@@ -1032,46 +1035,46 @@ class N {
|
|
|
1032
1035
|
this._cleanups || (this._cleanups = []), this._cleanups.push(t);
|
|
1033
1036
|
}
|
|
1034
1037
|
/** Subscribes to an external Subscribable with automatic cleanup on dispose. @protected */
|
|
1035
|
-
subscribeTo(t,
|
|
1036
|
-
const
|
|
1037
|
-
return this.addCleanup(
|
|
1038
|
+
subscribeTo(t, e) {
|
|
1039
|
+
const s = t.subscribe(e);
|
|
1040
|
+
return this.addCleanup(s), s;
|
|
1038
1041
|
}
|
|
1039
1042
|
// ── Backoff ─────────────────────────────────────────────────────
|
|
1040
1043
|
/** Computes the reconnect backoff delay with jitter for the given attempt number. @protected */
|
|
1041
1044
|
_calculateDelay(t) {
|
|
1042
|
-
const
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
+
const e = this.constructor, s = Math.min(
|
|
1046
|
+
e.RECONNECT_BASE * Math.pow(e.RECONNECT_FACTOR, t),
|
|
1047
|
+
e.RECONNECT_MAX
|
|
1045
1048
|
);
|
|
1046
|
-
return Math.random() *
|
|
1049
|
+
return Math.random() * s;
|
|
1047
1050
|
}
|
|
1048
1051
|
// ── Internals ───────────────────────────────────────────────────
|
|
1049
1052
|
_setStatus(t) {
|
|
1050
|
-
const
|
|
1051
|
-
if (!(
|
|
1053
|
+
const e = this._status;
|
|
1054
|
+
if (!(e.connected === t.connected && e.reconnecting === t.reconnecting && e.attempt === t.attempt && e.error === t.error)) {
|
|
1052
1055
|
this._status = Object.freeze(t);
|
|
1053
|
-
for (const
|
|
1054
|
-
|
|
1056
|
+
for (const s of this._listeners)
|
|
1057
|
+
s(this._status, e);
|
|
1055
1058
|
}
|
|
1056
1059
|
}
|
|
1057
1060
|
_attemptConnect(t) {
|
|
1058
1061
|
if (this._disposed) return;
|
|
1059
1062
|
this._connState = 1, this._connectAbort?.abort(), this._connectAbort = new AbortController();
|
|
1060
|
-
const
|
|
1063
|
+
const e = this._abortController ? AbortSignal.any([this._abortController.signal, this._connectAbort.signal]) : this._connectAbort.signal;
|
|
1061
1064
|
this._setStatus({
|
|
1062
1065
|
connected: !1,
|
|
1063
1066
|
reconnecting: t > 0,
|
|
1064
1067
|
attempt: t,
|
|
1065
1068
|
error: null
|
|
1066
1069
|
});
|
|
1067
|
-
let
|
|
1070
|
+
let s;
|
|
1068
1071
|
try {
|
|
1069
|
-
|
|
1072
|
+
s = this.open(e);
|
|
1070
1073
|
} catch (n) {
|
|
1071
1074
|
this._onOpenFailed(t, n);
|
|
1072
1075
|
return;
|
|
1073
1076
|
}
|
|
1074
|
-
|
|
1077
|
+
s && typeof s.then == "function" ? s.then(
|
|
1075
1078
|
() => this._onOpenSucceeded(),
|
|
1076
1079
|
(n) => this._onOpenFailed(t, n)
|
|
1077
1080
|
) : this._onOpenSucceeded();
|
|
@@ -1084,21 +1087,21 @@ class N {
|
|
|
1084
1087
|
error: null
|
|
1085
1088
|
}));
|
|
1086
1089
|
}
|
|
1087
|
-
_onOpenFailed(t,
|
|
1088
|
-
this._disposed || this._connState !== 0 && (this._connectAbort?.abort(), this._connectAbort = null, this._connState = 3, this._scheduleReconnect(t + 1,
|
|
1090
|
+
_onOpenFailed(t, e) {
|
|
1091
|
+
this._disposed || this._connState !== 0 && (this._connectAbort?.abort(), this._connectAbort = null, this._connState = 3, this._scheduleReconnect(t + 1, e));
|
|
1089
1092
|
}
|
|
1090
|
-
_scheduleReconnect(t,
|
|
1091
|
-
const
|
|
1092
|
-
if (t >
|
|
1093
|
+
_scheduleReconnect(t, e) {
|
|
1094
|
+
const s = this.constructor;
|
|
1095
|
+
if (t > s.MAX_ATTEMPTS) {
|
|
1093
1096
|
this._connState = 0, this._setStatus({
|
|
1094
1097
|
connected: !1,
|
|
1095
1098
|
reconnecting: !1,
|
|
1096
1099
|
attempt: t,
|
|
1097
|
-
error:
|
|
1100
|
+
error: e instanceof Error ? e.message : "Max reconnection attempts reached"
|
|
1098
1101
|
});
|
|
1099
1102
|
return;
|
|
1100
1103
|
}
|
|
1101
|
-
const n =
|
|
1104
|
+
const n = e instanceof Error ? e.message : e ? String(e) : null;
|
|
1102
1105
|
this._setStatus({
|
|
1103
1106
|
connected: !1,
|
|
1104
1107
|
reconnecting: !0,
|
|
@@ -1121,7 +1124,7 @@ export {
|
|
|
1121
1124
|
U as PersistentCollection,
|
|
1122
1125
|
v as Resource,
|
|
1123
1126
|
V as Service,
|
|
1124
|
-
|
|
1127
|
+
y as ViewModel,
|
|
1125
1128
|
T as classifyError,
|
|
1126
1129
|
B as hasSingleton,
|
|
1127
1130
|
O as isAbortError,
|