@but212/atom-effect 0.2.0 → 0.2.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/README.md +8 -45
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +59 -65
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -2
package/dist/index.mjs
CHANGED
|
@@ -80,7 +80,7 @@ class y extends _ {
|
|
|
80
80
|
super(e, t, !1), this.name = "SchedulerError";
|
|
81
81
|
}
|
|
82
82
|
}
|
|
83
|
-
function
|
|
83
|
+
function g(i, e, t) {
|
|
84
84
|
if (i instanceof TypeError)
|
|
85
85
|
return new e(`Type error (${t}): ${i.message}`, i);
|
|
86
86
|
if (i instanceof ReferenceError)
|
|
@@ -93,7 +93,7 @@ function D(i, e, t) {
|
|
|
93
93
|
function P(i) {
|
|
94
94
|
return i != null && typeof i.then == "function";
|
|
95
95
|
}
|
|
96
|
-
const
|
|
96
|
+
const o = {
|
|
97
97
|
// ─────────────────────────────────────────────────────────────────
|
|
98
98
|
// Computed errors
|
|
99
99
|
// ─────────────────────────────────────────────────────────────────
|
|
@@ -357,17 +357,17 @@ class v {
|
|
|
357
357
|
this.maxFlushIterations = e;
|
|
358
358
|
}
|
|
359
359
|
}
|
|
360
|
-
const
|
|
360
|
+
const D = new v();
|
|
361
361
|
function Y(i) {
|
|
362
362
|
if (typeof i != "function")
|
|
363
363
|
throw new _("Batch callback must be a function");
|
|
364
|
-
|
|
364
|
+
D.startBatch();
|
|
365
365
|
try {
|
|
366
366
|
return i();
|
|
367
367
|
} catch (e) {
|
|
368
368
|
throw new _("Error occurred during batch execution", e);
|
|
369
369
|
} finally {
|
|
370
|
-
|
|
370
|
+
D.endBatch();
|
|
371
371
|
}
|
|
372
372
|
}
|
|
373
373
|
const S = {
|
|
@@ -544,10 +544,10 @@ const a = {
|
|
|
544
544
|
}
|
|
545
545
|
};
|
|
546
546
|
let k = 1;
|
|
547
|
-
const
|
|
547
|
+
const F = () => k++;
|
|
548
548
|
class N {
|
|
549
549
|
constructor() {
|
|
550
|
-
this.subscribers = null
|
|
550
|
+
this.subscribers = null;
|
|
551
551
|
}
|
|
552
552
|
/**
|
|
553
553
|
* Adds a subscriber and returns an unsubscribe function
|
|
@@ -556,7 +556,7 @@ class N {
|
|
|
556
556
|
* Duplicate subscribers are ignored (idempotent).
|
|
557
557
|
*
|
|
558
558
|
* @param subscriber - Function to add as subscriber
|
|
559
|
-
* @returns Unsubscribe function
|
|
559
|
+
* @returns Unsubscribe function
|
|
560
560
|
*
|
|
561
561
|
* @example
|
|
562
562
|
* ```ts
|
|
@@ -566,39 +566,33 @@ class N {
|
|
|
566
566
|
* ```
|
|
567
567
|
*/
|
|
568
568
|
add(e) {
|
|
569
|
-
if (this.subscribers || (this.subscribers = []
|
|
569
|
+
if (this.subscribers || (this.subscribers = []), this.subscribers.indexOf(e) !== -1)
|
|
570
570
|
return () => {
|
|
571
571
|
};
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
let s = !1;
|
|
572
|
+
this.subscribers.push(e);
|
|
573
|
+
let t = !1;
|
|
575
574
|
return () => {
|
|
576
|
-
|
|
575
|
+
t || (t = !0, this.remove(e));
|
|
577
576
|
};
|
|
578
577
|
}
|
|
579
578
|
/**
|
|
580
579
|
* Removes a subscriber using swap-and-pop optimization
|
|
581
580
|
*
|
|
582
|
-
*
|
|
583
|
-
*
|
|
584
|
-
*
|
|
585
|
-
* - Updates index mapping
|
|
581
|
+
* Linear search + O(1) swap-and-pop removal.
|
|
582
|
+
* For small arrays, this is faster than hash-based approaches
|
|
583
|
+
* due to cache locality.
|
|
586
584
|
*
|
|
587
585
|
* @param subscriber - Subscriber to remove
|
|
588
586
|
* @returns True if removed, false if not found
|
|
589
587
|
*/
|
|
590
588
|
remove(e) {
|
|
591
|
-
if (!this.subscribers
|
|
589
|
+
if (!this.subscribers)
|
|
592
590
|
return !1;
|
|
593
|
-
const t = this.
|
|
594
|
-
if (t ===
|
|
591
|
+
const t = this.subscribers.indexOf(e);
|
|
592
|
+
if (t === -1)
|
|
595
593
|
return !1;
|
|
596
594
|
const s = this.subscribers.length - 1;
|
|
597
|
-
|
|
598
|
-
const n = this.subscribers[s];
|
|
599
|
-
this.subscribers[t] = n, this.subscriberIndex.set(n, t);
|
|
600
|
-
}
|
|
601
|
-
return this.subscribers.pop(), this.subscriberIndex.delete(e), !0;
|
|
595
|
+
return t !== s && (this.subscribers[t] = this.subscribers[s]), this.subscribers.pop(), !0;
|
|
602
596
|
}
|
|
603
597
|
/**
|
|
604
598
|
* Checks if a subscriber is registered
|
|
@@ -607,7 +601,7 @@ class N {
|
|
|
607
601
|
* @returns True if registered
|
|
608
602
|
*/
|
|
609
603
|
has(e) {
|
|
610
|
-
return this.
|
|
604
|
+
return this.subscribers ? this.subscribers.indexOf(e) !== -1 : !1;
|
|
611
605
|
}
|
|
612
606
|
/**
|
|
613
607
|
* Iterates over all subscribers with a callback
|
|
@@ -670,7 +664,7 @@ class N {
|
|
|
670
664
|
* Subsequent operations will re-initialize lazily.
|
|
671
665
|
*/
|
|
672
666
|
clear() {
|
|
673
|
-
this.subscribers
|
|
667
|
+
this.subscribers = null;
|
|
674
668
|
}
|
|
675
669
|
/**
|
|
676
670
|
* Gets a copy of all subscribers as an array
|
|
@@ -692,7 +686,7 @@ class z {
|
|
|
692
686
|
* @param sync - Whether to notify subscribers synchronously
|
|
693
687
|
*/
|
|
694
688
|
constructor(e, t) {
|
|
695
|
-
this._isNotificationScheduled = !1, this.id =
|
|
689
|
+
this._isNotificationScheduled = !1, this.id = F() & I, this.version = 0, this.flags = 0, this._lastSeenEpoch = -1, this._value = e, this._functionSubscribers = new N(), this._objectSubscribers = new N(), this._sync = t, this._notifyTask = this._flushNotifications.bind(this), a.attachDebugInfo(this, "atom", this.id);
|
|
696
690
|
}
|
|
697
691
|
/**
|
|
698
692
|
* Gets the current value and registers the atom as a dependency
|
|
@@ -761,7 +755,7 @@ class z {
|
|
|
761
755
|
* but don't schedule a new task. The pending task will see the latest value.
|
|
762
756
|
*/
|
|
763
757
|
_notify(e, t, s) {
|
|
764
|
-
this._isNotificationScheduled || (this._pendingOldValue = t, this._isNotificationScheduled = !0), this._sync && !
|
|
758
|
+
this._isNotificationScheduled || (this._pendingOldValue = t, this._isNotificationScheduled = !0), this._sync && !D.isBatching ? this._flushNotifications() : D.schedule(this._notifyTask);
|
|
765
759
|
}
|
|
766
760
|
/**
|
|
767
761
|
* Executes the pending notifications.
|
|
@@ -772,10 +766,10 @@ class z {
|
|
|
772
766
|
const e = this._pendingOldValue, t = this._value;
|
|
773
767
|
this._pendingOldValue = void 0, this._isNotificationScheduled = !1, this._functionSubscribers.forEachSafe(
|
|
774
768
|
(s) => s(t, e),
|
|
775
|
-
(s) => console.error(new _(
|
|
769
|
+
(s) => console.error(new _(o.ATOM_INDIVIDUAL_SUBSCRIBER_FAILED, s))
|
|
776
770
|
), this._objectSubscribers.forEachSafe(
|
|
777
771
|
(s) => s.execute(),
|
|
778
|
-
(s) => console.error(new _(
|
|
772
|
+
(s) => console.error(new _(o.ATOM_INDIVIDUAL_SUBSCRIBER_FAILED, s))
|
|
779
773
|
);
|
|
780
774
|
}
|
|
781
775
|
/**
|
|
@@ -795,7 +789,7 @@ class z {
|
|
|
795
789
|
*/
|
|
796
790
|
subscribe(e) {
|
|
797
791
|
if (typeof e != "function")
|
|
798
|
-
throw new _(
|
|
792
|
+
throw new _(o.ATOM_SUBSCRIBER_MUST_BE_FUNCTION);
|
|
799
793
|
return this._functionSubscribers.add(e);
|
|
800
794
|
}
|
|
801
795
|
/**
|
|
@@ -832,9 +826,9 @@ class z {
|
|
|
832
826
|
function $(i, e = {}) {
|
|
833
827
|
return new z(i, e.sync ?? !1);
|
|
834
828
|
}
|
|
835
|
-
let
|
|
829
|
+
let O = 0;
|
|
836
830
|
function M() {
|
|
837
|
-
return
|
|
831
|
+
return O = (O + 1 | 0) & I, O;
|
|
838
832
|
}
|
|
839
833
|
const f = process.env.NODE_ENV !== "production", l = Object.freeze([]);
|
|
840
834
|
class V {
|
|
@@ -884,8 +878,8 @@ const E = new V();
|
|
|
884
878
|
class w {
|
|
885
879
|
constructor(e, t = {}) {
|
|
886
880
|
if (typeof e != "function")
|
|
887
|
-
throw new b(
|
|
888
|
-
if (this.id =
|
|
881
|
+
throw new b(o.COMPUTED_MUST_BE_FUNCTION);
|
|
882
|
+
if (this.id = F() & I, this.version = 0, this.flags = 0, this._lastSeenEpoch = -1, this._value = void 0, this._stateFlags = c.DIRTY | c.IDLE, this._error = null, this._promiseId = 0, this._equal = t.equal ?? Object.is, this._fn = e, this._defaultValue = "defaultValue" in t ? t.defaultValue : U, this._hasDefaultValue = this._defaultValue !== U, this._onError = t.onError ?? null, this.MAX_PROMISE_ID = Number.MAX_SAFE_INTEGER - 1, this._functionSubscribers = new N(), this._objectSubscribers = new N(), this._dependencies = l, this._subscriptions = /* @__PURE__ */ new Map(), this._recomputeJob = () => {
|
|
889
883
|
if (this._isDirty())
|
|
890
884
|
try {
|
|
891
885
|
this._recompute();
|
|
@@ -921,7 +915,7 @@ class w {
|
|
|
921
915
|
}
|
|
922
916
|
subscribe(e) {
|
|
923
917
|
if (typeof e != "function")
|
|
924
|
-
throw new b(
|
|
918
|
+
throw new b(o.COMPUTED_SUBSCRIBER_MUST_BE_FUNCTION);
|
|
925
919
|
return this._functionSubscribers.add(e);
|
|
926
920
|
}
|
|
927
921
|
peek() {
|
|
@@ -1014,7 +1008,7 @@ class w {
|
|
|
1014
1008
|
let n = 0;
|
|
1015
1009
|
const r = (h) => {
|
|
1016
1010
|
h._lastSeenEpoch !== s && (h._lastSeenEpoch = s, n < t.length ? t[n] = h : t.push(h), n++);
|
|
1017
|
-
},
|
|
1011
|
+
}, u = this._trackable.addDependency;
|
|
1018
1012
|
this._trackable.addDependency = r;
|
|
1019
1013
|
let d = !1;
|
|
1020
1014
|
try {
|
|
@@ -1027,7 +1021,7 @@ class w {
|
|
|
1027
1021
|
} catch (h) {
|
|
1028
1022
|
t.length = n, this._syncDependencies(e, t, s), this._dependencies = t, d = !0, this._handleComputationError(h);
|
|
1029
1023
|
} finally {
|
|
1030
|
-
this._trackable.addDependency =
|
|
1024
|
+
this._trackable.addDependency = u, d ? e !== l && E.release(e) : E.release(t);
|
|
1031
1025
|
}
|
|
1032
1026
|
}
|
|
1033
1027
|
/**
|
|
@@ -1039,16 +1033,16 @@ class w {
|
|
|
1039
1033
|
for (let n = 0; n < e.length; n++) {
|
|
1040
1034
|
const r = e[n];
|
|
1041
1035
|
if (r && r._lastSeenEpoch !== s) {
|
|
1042
|
-
const
|
|
1043
|
-
|
|
1036
|
+
const u = this._subscriptions.get(r.id);
|
|
1037
|
+
u && (u(), this._subscriptions.delete(r.id));
|
|
1044
1038
|
}
|
|
1045
1039
|
}
|
|
1046
1040
|
for (let n = 0; n < t.length; n++) {
|
|
1047
1041
|
const r = t[n];
|
|
1048
1042
|
if (r && !this._subscriptions.has(r.id)) {
|
|
1049
1043
|
a.checkCircular(r, this);
|
|
1050
|
-
const
|
|
1051
|
-
this._subscriptions.set(r.id,
|
|
1044
|
+
const u = r.subscribe(() => this._markDirty());
|
|
1045
|
+
this._subscriptions.set(r.id, u);
|
|
1052
1046
|
}
|
|
1053
1047
|
}
|
|
1054
1048
|
}
|
|
@@ -1070,29 +1064,29 @@ class w {
|
|
|
1070
1064
|
this._value = e, this._clearDirty(), this._setResolved(), this._error = null, this._setRecomputing(!1), t && this._notifySubscribers();
|
|
1071
1065
|
}
|
|
1072
1066
|
_handleAsyncRejection(e) {
|
|
1073
|
-
const t =
|
|
1067
|
+
const t = g(e, b, o.COMPUTED_ASYNC_COMPUTATION_FAILED);
|
|
1074
1068
|
if (this._error = t, this._setRejected(), this._clearDirty(), this._setRecomputing(!1), this._onError && typeof this._onError == "function")
|
|
1075
1069
|
try {
|
|
1076
1070
|
this._onError(t);
|
|
1077
1071
|
} catch (s) {
|
|
1078
|
-
console.error(
|
|
1072
|
+
console.error(o.CALLBACK_ERROR_IN_ERROR_HANDLER, s);
|
|
1079
1073
|
}
|
|
1080
1074
|
this._notifySubscribers();
|
|
1081
1075
|
}
|
|
1082
1076
|
_handleComputationError(e) {
|
|
1083
|
-
const t =
|
|
1077
|
+
const t = g(e, b, o.COMPUTED_COMPUTATION_FAILED);
|
|
1084
1078
|
if (this._error = t, this._setRejected(), this._clearDirty(), this._setRecomputing(!1), this._onError && typeof this._onError == "function")
|
|
1085
1079
|
try {
|
|
1086
1080
|
this._onError(t);
|
|
1087
1081
|
} catch (s) {
|
|
1088
|
-
console.error(
|
|
1082
|
+
console.error(o.CALLBACK_ERROR_IN_ERROR_HANDLER, s);
|
|
1089
1083
|
}
|
|
1090
1084
|
throw t;
|
|
1091
1085
|
}
|
|
1092
1086
|
_handlePending() {
|
|
1093
1087
|
if (this._hasDefaultValue)
|
|
1094
1088
|
return this._defaultValue;
|
|
1095
|
-
throw new b(
|
|
1089
|
+
throw new b(o.COMPUTED_ASYNC_PENDING_NO_DEFAULT);
|
|
1096
1090
|
}
|
|
1097
1091
|
_handleRejected() {
|
|
1098
1092
|
if (this._error?.recoverable && this._hasDefaultValue)
|
|
@@ -1103,10 +1097,10 @@ class w {
|
|
|
1103
1097
|
// (Replaced by _syncDependencies and inline pool logic)
|
|
1104
1098
|
// === PRIVATE: Subscriber Management ===
|
|
1105
1099
|
_markDirty() {
|
|
1106
|
-
this._isRecomputing() || this._isDirty() || (this._setDirty(), this._setIdle(), (this._functionSubscribers.hasSubscribers || this._objectSubscribers.hasSubscribers) &&
|
|
1100
|
+
this._isRecomputing() || this._isDirty() || (this._setDirty(), this._setIdle(), (this._functionSubscribers.hasSubscribers || this._objectSubscribers.hasSubscribers) && D.schedule(this._recomputeJob));
|
|
1107
1101
|
}
|
|
1108
1102
|
_notifySubscribers() {
|
|
1109
|
-
!this._functionSubscribers.hasSubscribers && !this._objectSubscribers.hasSubscribers ||
|
|
1103
|
+
!this._functionSubscribers.hasSubscribers && !this._objectSubscribers.hasSubscribers || D.schedule(this._notifyJob);
|
|
1110
1104
|
}
|
|
1111
1105
|
_registerTracking() {
|
|
1112
1106
|
const e = S.getCurrent();
|
|
@@ -1127,7 +1121,7 @@ class j {
|
|
|
1127
1121
|
constructor(e, t = {}) {
|
|
1128
1122
|
this.run = () => {
|
|
1129
1123
|
if (this.isDisposed)
|
|
1130
|
-
throw new p(
|
|
1124
|
+
throw new p(o.EFFECT_MUST_BE_FUNCTION);
|
|
1131
1125
|
this.execute();
|
|
1132
1126
|
}, this.dispose = () => {
|
|
1133
1127
|
if (!this.isDisposed && (this._setDisposed(), this._safeCleanup(), this._dependencies !== l)) {
|
|
@@ -1147,22 +1141,22 @@ class j {
|
|
|
1147
1141
|
if (this.isDisposed || this.isExecuting) return;
|
|
1148
1142
|
const s = Date.now();
|
|
1149
1143
|
this._recordExecution(s), this._setExecuting(!0), this._safeCleanup(), this._modifiedDeps.clear();
|
|
1150
|
-
const n = this._dependencies, r = E.acquire(),
|
|
1151
|
-
this._nextDeps = r, this._currentEpoch =
|
|
1144
|
+
const n = this._dependencies, r = E.acquire(), u = M();
|
|
1145
|
+
this._nextDeps = r, this._currentEpoch = u;
|
|
1152
1146
|
let d = !1;
|
|
1153
1147
|
try {
|
|
1154
1148
|
const h = S.run(this, this._fn);
|
|
1155
|
-
this._syncDependencies(n,
|
|
1149
|
+
this._syncDependencies(n, u), this._dependencies = r, d = !0, this._checkLoopWarnings(), P(h) ? h.then((R) => {
|
|
1156
1150
|
!this.isDisposed && typeof R == "function" && (this._cleanup = R);
|
|
1157
1151
|
}).catch((R) => {
|
|
1158
|
-
console.error(
|
|
1152
|
+
console.error(g(R, p, o.EFFECT_EXECUTION_FAILED));
|
|
1159
1153
|
}) : this._cleanup = typeof h == "function" ? h : null;
|
|
1160
1154
|
} catch (h) {
|
|
1161
|
-
this._syncDependencies(n,
|
|
1155
|
+
this._syncDependencies(n, u), this._dependencies = r, d = !0, console.error(g(h, p, o.EFFECT_EXECUTION_FAILED)), this._cleanup = null;
|
|
1162
1156
|
} finally {
|
|
1163
1157
|
this._setExecuting(!1), this._nextDeps = null, d ? n !== l && E.release(n) : E.release(r);
|
|
1164
1158
|
}
|
|
1165
|
-
}, this._id =
|
|
1159
|
+
}, this._id = F() & I, this._flags = 0, this._currentEpoch = -1, this._fn = e, this._sync = t.sync ?? !1, this._maxExecutions = t.maxExecutionsPerSecond ?? L.MAX_EXECUTIONS_PER_SECOND, this._trackModifications = t.trackModifications ?? !1, this._cleanup = null, this._dependencies = l, this._subscriptions = /* @__PURE__ */ new Map(), this._nextDeps = null, this._modifiedDeps = /* @__PURE__ */ new Set(), this._historyCapacity = this._maxExecutions + 5, this._history = new Float64Array(this._historyCapacity), this._historyIdx = 0, this._historyCount = 0, this._executionCount = 0, a.attachDebugInfo(this, "effect", this._id);
|
|
1166
1160
|
}
|
|
1167
1161
|
/**
|
|
1168
1162
|
* Synchronizes subscriptions by unsubscribing from removed dependencies.
|
|
@@ -1184,11 +1178,11 @@ class j {
|
|
|
1184
1178
|
_subscribeTo(e) {
|
|
1185
1179
|
try {
|
|
1186
1180
|
const t = e.subscribe(() => {
|
|
1187
|
-
this._trackModifications && this.isExecuting && this._modifiedDeps.add(e), this._sync ? this.execute() :
|
|
1181
|
+
this._trackModifications && this.isExecuting && this._modifiedDeps.add(e), this._sync ? this.execute() : D.schedule(this.execute);
|
|
1188
1182
|
});
|
|
1189
1183
|
this._subscriptions.set(e.id, t);
|
|
1190
1184
|
} catch (t) {
|
|
1191
|
-
console.error(
|
|
1185
|
+
console.error(g(t, p, o.EFFECT_EXECUTION_FAILED));
|
|
1192
1186
|
}
|
|
1193
1187
|
}
|
|
1194
1188
|
/**
|
|
@@ -1298,7 +1292,7 @@ class j {
|
|
|
1298
1292
|
try {
|
|
1299
1293
|
this._cleanup();
|
|
1300
1294
|
} catch (e) {
|
|
1301
|
-
console.error(
|
|
1295
|
+
console.error(g(e, p, o.EFFECT_CLEANUP_FAILED));
|
|
1302
1296
|
}
|
|
1303
1297
|
this._cleanup = null;
|
|
1304
1298
|
}
|
|
@@ -1329,9 +1323,9 @@ class j {
|
|
|
1329
1323
|
for (let r = 0; r < this._historyCount && !(this._history[n] < t); r++)
|
|
1330
1324
|
s++, n = (n - 1 + this._historyCapacity) % this._historyCapacity;
|
|
1331
1325
|
if (s > this._maxExecutions) {
|
|
1332
|
-
const r = `Effect executed ${s} times within 1 second. Infinite loop suspected`,
|
|
1333
|
-
if (this.dispose(), console.error(
|
|
1334
|
-
throw
|
|
1326
|
+
const r = `Effect executed ${s} times within 1 second. Infinite loop suspected`, u = new p(r);
|
|
1327
|
+
if (this.dispose(), console.error(u), a.enabled)
|
|
1328
|
+
throw u;
|
|
1335
1329
|
}
|
|
1336
1330
|
}
|
|
1337
1331
|
/**
|
|
@@ -1362,7 +1356,7 @@ class j {
|
|
|
1362
1356
|
}
|
|
1363
1357
|
function H(i, e = {}) {
|
|
1364
1358
|
if (typeof i != "function")
|
|
1365
|
-
throw new p(
|
|
1359
|
+
throw new p(o.EFFECT_MUST_BE_FUNCTION);
|
|
1366
1360
|
const t = new j(i, e);
|
|
1367
1361
|
return t.execute(), t;
|
|
1368
1362
|
}
|
|
@@ -1397,7 +1391,7 @@ export {
|
|
|
1397
1391
|
G as isAtom,
|
|
1398
1392
|
W as isComputed,
|
|
1399
1393
|
K as isEffect,
|
|
1400
|
-
|
|
1394
|
+
D as scheduler,
|
|
1401
1395
|
Q as untracked
|
|
1402
1396
|
};
|
|
1403
1397
|
//# sourceMappingURL=index.mjs.map
|