@signaltree/core 9.2.2 → 9.5.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/README.md +42 -27
- package/dist/Action.js +15 -0
- package/dist/AsyncAction.js +91 -0
- package/dist/AsyncScheduler.js +37 -0
- package/dist/ObjectUnsubscribedError.js +11 -0
- package/dist/Observable.js +103 -0
- package/dist/OperatorSubscriber.js +62 -0
- package/dist/Scheduler.js +17 -0
- package/dist/Subject.js +162 -0
- package/dist/Subscriber.js +153 -0
- package/dist/Subscription.js +144 -0
- package/dist/UnsubscriptionError.js +14 -0
- package/dist/args.js +10 -0
- package/dist/arrRemove.js +8 -0
- package/dist/async.js +6 -0
- package/dist/config.js +4 -0
- package/dist/createErrorClass.js +12 -0
- package/dist/dateTimestampProvider.js +6 -0
- package/dist/debounceTime.js +46 -0
- package/dist/distinctUntilChanged.js +25 -0
- package/dist/enhancers/devtools/devtools.js +11 -5
- package/dist/enhancers/time-travel/time-travel.js +11 -5
- package/dist/errorContext.js +7 -0
- package/dist/executeSchedule.js +19 -0
- package/dist/filter.js +11 -0
- package/dist/from.js +8 -0
- package/dist/identity.js +5 -0
- package/dist/index.js +4 -0
- package/dist/innerFrom.js +145 -0
- package/dist/intervalProvider.js +17 -0
- package/dist/isArrayLike.js +3 -0
- package/dist/isAsyncIterable.js +7 -0
- package/dist/isFunction.js +5 -0
- package/dist/isInteropObservable.js +8 -0
- package/dist/isIterable.js +8 -0
- package/dist/isObservable.js +8 -0
- package/dist/isPromise.js +7 -0
- package/dist/isReadableStreamLike.js +40 -0
- package/dist/isScheduler.js +7 -0
- package/dist/iterator.js +9 -0
- package/dist/lib/internals/intercept-leaf-signals.js +4 -2
- package/dist/lib/markers/async-query.js +134 -0
- package/dist/lib/markers/async-source.js +122 -0
- package/dist/lib/rxjs-interop/rx-method.js +50 -0
- package/dist/lib/write-context.js +15 -0
- package/dist/lift.js +22 -0
- package/dist/noop.js +3 -0
- package/dist/observable2.js +3 -0
- package/dist/observeOn.js +12 -0
- package/dist/of.js +13 -0
- package/dist/pipe.js +15 -0
- package/dist/reportUnhandledError.js +11 -0
- package/dist/rxjs-interop.js +1 -0
- package/dist/scheduleArray.js +20 -0
- package/dist/scheduleAsyncIterable.js +25 -0
- package/dist/scheduleIterable.js +34 -0
- package/dist/scheduleObservable.js +9 -0
- package/dist/schedulePromise.js +9 -0
- package/dist/scheduleReadableStreamLike.js +8 -0
- package/dist/scheduled.js +39 -0
- package/dist/subscribeOn.js +10 -0
- package/dist/switchMap.js +26 -0
- package/dist/tap.js +42 -0
- package/dist/throwUnobservableError.js +5 -0
- package/dist/timeoutProvider.js +17 -0
- package/package.json +6 -1
- package/src/index.d.ts +5 -1
- package/src/lib/internals/intercept-leaf-signals.d.ts +4 -1
- package/src/lib/markers/async-query.d.ts +31 -0
- package/src/lib/markers/async-source.d.ts +27 -0
- package/src/lib/markers/index.d.ts +2 -0
- package/src/lib/rxjs-interop/index.d.ts +1 -0
- package/src/lib/rxjs-interop/rx-method.d.ts +11 -0
- package/src/lib/types.d.ts +8 -0
- package/src/lib/write-context.d.ts +3 -0
- package/src/rxjs-interop.d.ts +1 -0
package/README.md
CHANGED
|
@@ -305,7 +305,7 @@ console.log(tree.$.message()); // 'Hello World'
|
|
|
305
305
|
// tree.$.message.set('Updated!');
|
|
306
306
|
// tree.$.count.update((n) => n + 1);
|
|
307
307
|
// See: https://github.com/JBorgia/signaltree/blob/main/packages/callable-syntax/README.md
|
|
308
|
-
tree.$.count(5);
|
|
308
|
+
tree.$.count(5); // requires @signaltree/callable-syntax transform
|
|
309
309
|
tree.$.message('Updated!'); // requires @signaltree/callable-syntax transform
|
|
310
310
|
|
|
311
311
|
// Use in an Angular component
|
|
@@ -343,6 +343,10 @@ const tree = signalTree({
|
|
|
343
343
|
});
|
|
344
344
|
|
|
345
345
|
// Access nested signals with full type safety
|
|
346
|
+
// Requires @signaltree/callable-syntax. Without the transform, use:
|
|
347
|
+
// tree.$.user.name.set('Jane Doe');
|
|
348
|
+
// tree.$.user.preferences.theme.set('light');
|
|
349
|
+
// tree.$.ui.loading.set(true);
|
|
346
350
|
tree.$.user.name('Jane Doe');
|
|
347
351
|
tree.$.user.preferences.theme('light');
|
|
348
352
|
tree.$.ui.loading(true);
|
|
@@ -500,6 +504,8 @@ const tree = signalTree<AppState>({
|
|
|
500
504
|
});
|
|
501
505
|
|
|
502
506
|
// Complex updates with type safety
|
|
507
|
+
// Requires @signaltree/callable-syntax. Without the transform, use
|
|
508
|
+
// tree.set((state) => ({ ... })) or leaf .set() / .update() calls instead.
|
|
503
509
|
tree((state) => ({
|
|
504
510
|
auth: {
|
|
505
511
|
...state.auth,
|
|
@@ -671,16 +677,15 @@ All enhancers are exported directly from `@signaltree/core`:
|
|
|
671
677
|
```typescript
|
|
672
678
|
import { signalTree, effects } from '@signaltree/core';
|
|
673
679
|
|
|
674
|
-
const tree = signalTree({ count: 0, user: { name: 'Alice' } })
|
|
675
|
-
.with(effects());
|
|
680
|
+
const tree = signalTree({ count: 0, user: { name: 'Alice' } }).with(effects());
|
|
676
681
|
|
|
677
682
|
// Subscribe with automatic cleanup on destroy
|
|
678
|
-
const unsub = tree.subscribe(state => {
|
|
683
|
+
const unsub = tree.subscribe((state) => {
|
|
679
684
|
console.log('State changed:', state.count);
|
|
680
685
|
});
|
|
681
686
|
|
|
682
687
|
// Effect with cleanup callback
|
|
683
|
-
const cleanup = tree.effect(state => {
|
|
688
|
+
const cleanup = tree.effect((state) => {
|
|
684
689
|
console.log('Count:', state.count);
|
|
685
690
|
return () => console.log('Previous effect cleaned up');
|
|
686
691
|
});
|
|
@@ -708,7 +713,7 @@ import { signalTree, batching, devTools } from '@signaltree/core';
|
|
|
708
713
|
|
|
709
714
|
// Apply enhancers by chaining — each .with() takes a single enhancer
|
|
710
715
|
const tree = signalTree({ count: 0 })
|
|
711
|
-
.with(batching())
|
|
716
|
+
.with(batching()) // Performance optimization
|
|
712
717
|
.with(devTools()); // Development tools
|
|
713
718
|
```
|
|
714
719
|
|
|
@@ -721,8 +726,7 @@ import { signalTree, batching } from '@signaltree/core';
|
|
|
721
726
|
const tree = signalTree({
|
|
722
727
|
products: entityMap<Product>(),
|
|
723
728
|
ui: { loading: false },
|
|
724
|
-
})
|
|
725
|
-
.with(batching()); // Batch updates for optimal rendering
|
|
729
|
+
}).with(batching()); // Batch updates for optimal rendering
|
|
726
730
|
|
|
727
731
|
// Entity CRUD operations
|
|
728
732
|
tree.$.products.addOne(newProduct);
|
|
@@ -741,11 +745,14 @@ const tree = signalTree({
|
|
|
741
745
|
user: null as User | null,
|
|
742
746
|
preferences: { theme: 'light' },
|
|
743
747
|
})
|
|
744
|
-
.with(
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
748
|
+
.with(
|
|
749
|
+
serialization({
|
|
750
|
+
// Auto-save to localStorage
|
|
751
|
+
autoSave: true,
|
|
752
|
+
storage: 'localStorage',
|
|
753
|
+
})
|
|
754
|
+
)
|
|
755
|
+
.with(timeTravel()); // Undo/redo support
|
|
749
756
|
|
|
750
757
|
// For async operations, use manual async or async helpers
|
|
751
758
|
async function fetchUser(id: string) {
|
|
@@ -776,8 +783,8 @@ Enhancers can declare metadata for automatic dependency resolution:
|
|
|
776
783
|
```typescript
|
|
777
784
|
// Chain enhancers — each .with() takes a single enhancer
|
|
778
785
|
const tree = signalTree(state)
|
|
779
|
-
.with(batching())
|
|
780
|
-
.with(devTools());
|
|
786
|
+
.with(batching()) // Requires: core, provides: batching
|
|
787
|
+
.with(devTools()); // Requires: core, provides: debugging
|
|
781
788
|
```
|
|
782
789
|
|
|
783
790
|
#### Core Stubs
|
|
@@ -1159,6 +1166,8 @@ LoadingState.Error; // 'error'
|
|
|
1159
1166
|
|
|
1160
1167
|
Auto-syncs state to localStorage with versioning and migration support.
|
|
1161
1168
|
|
|
1169
|
+
> ⚠️ **Read first:** [Persistence and Security](../../docs/guides/persistence-and-security.md) covers the threat model and what `stored()` is — and isn't — appropriate for. Short version: fine for UI prefs, never for tokens, secrets, or PII.
|
|
1170
|
+
|
|
1162
1171
|
```typescript
|
|
1163
1172
|
import { signalTree, stored, createStorageKeys, clearStoragePrefix } from '@signaltree/core';
|
|
1164
1173
|
|
|
@@ -1653,18 +1662,24 @@ const tree = signalTree({
|
|
|
1653
1662
|
data: { users: [], posts: [] },
|
|
1654
1663
|
},
|
|
1655
1664
|
})
|
|
1656
|
-
.with(batching())
|
|
1657
|
-
.with(
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1665
|
+
.with(batching()) // Performance
|
|
1666
|
+
.with(
|
|
1667
|
+
serialization({
|
|
1668
|
+
// State persistence
|
|
1669
|
+
autoSave: true,
|
|
1670
|
+
storage: 'localStorage',
|
|
1671
|
+
})
|
|
1672
|
+
)
|
|
1661
1673
|
.with(timeTravel({ maxHistorySize: 50 })) // Undo/redo
|
|
1662
|
-
.with(
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1674
|
+
.with(
|
|
1675
|
+
devTools({
|
|
1676
|
+
// Debug tools (dev only)
|
|
1677
|
+
name: 'MyApp',
|
|
1678
|
+
enableTimeTravel: true,
|
|
1679
|
+
includePaths: ['app.*', 'ui.*'],
|
|
1680
|
+
formatPath: (path) => path.replace(/\.(\d+)/g, '[$1]'),
|
|
1681
|
+
})
|
|
1682
|
+
);
|
|
1668
1683
|
|
|
1669
1684
|
// Rich feature set available
|
|
1670
1685
|
async function fetchUser(id: string) {
|
|
@@ -2159,7 +2174,7 @@ Consider separate packages when you need:
|
|
|
2159
2174
|
|
|
2160
2175
|
### Case Study
|
|
2161
2176
|
|
|
2162
|
-
|
|
2177
|
+
Snapshot from one production Angular mobile app's NgRx Signal Store → SignalTree migration. Original migration measured ~11,700 → ~2,800 lines of state code (~76%) and ~50KB → ~27KB gzipped state bundle (~46%). Both codebases have continued to evolve; re-measuring today the same scope yields a 60–70% reduction depending on definition (apps-only vs apps+libs, narrow vs broad import filter). The directional finding is reproducible — the exact percentages are not. **YMMV** — your migration's reduction depends on app complexity, prior architecture, and how heavily the original code leaned on custom `withX` helpers. The single biggest driver of the savings is cross-cutting concerns (devtools, error banners, telemetry, refresh handling) moving from per-store composition to tree-level enhancers.
|
|
2163
2178
|
|
|
2164
2179
|
| Metric | NgRx | SignalTree | Change |
|
|
2165
2180
|
| --- | --- | --- | --- |
|
package/dist/Action.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { __extends } from 'tslib';
|
|
2
|
+
import { Subscription } from './Subscription.js';
|
|
3
|
+
|
|
4
|
+
var Action = (function (_super) {
|
|
5
|
+
__extends(Action, _super);
|
|
6
|
+
function Action(scheduler, work) {
|
|
7
|
+
return _super.call(this) || this;
|
|
8
|
+
}
|
|
9
|
+
Action.prototype.schedule = function (state, delay) {
|
|
10
|
+
return this;
|
|
11
|
+
};
|
|
12
|
+
return Action;
|
|
13
|
+
}(Subscription));
|
|
14
|
+
|
|
15
|
+
export { Action };
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { __extends } from 'tslib';
|
|
2
|
+
import { Action } from './Action.js';
|
|
3
|
+
import { intervalProvider } from './intervalProvider.js';
|
|
4
|
+
import { arrRemove } from './arrRemove.js';
|
|
5
|
+
|
|
6
|
+
var AsyncAction = (function (_super) {
|
|
7
|
+
__extends(AsyncAction, _super);
|
|
8
|
+
function AsyncAction(scheduler, work) {
|
|
9
|
+
var _this = _super.call(this, scheduler, work) || this;
|
|
10
|
+
_this.scheduler = scheduler;
|
|
11
|
+
_this.work = work;
|
|
12
|
+
_this.pending = false;
|
|
13
|
+
return _this;
|
|
14
|
+
}
|
|
15
|
+
AsyncAction.prototype.schedule = function (state, delay) {
|
|
16
|
+
var _a;
|
|
17
|
+
if (delay === void 0) { delay = 0; }
|
|
18
|
+
if (this.closed) {
|
|
19
|
+
return this;
|
|
20
|
+
}
|
|
21
|
+
this.state = state;
|
|
22
|
+
var id = this.id;
|
|
23
|
+
var scheduler = this.scheduler;
|
|
24
|
+
if (id != null) {
|
|
25
|
+
this.id = this.recycleAsyncId(scheduler, id, delay);
|
|
26
|
+
}
|
|
27
|
+
this.pending = true;
|
|
28
|
+
this.delay = delay;
|
|
29
|
+
this.id = (_a = this.id) !== null && _a !== void 0 ? _a : this.requestAsyncId(scheduler, this.id, delay);
|
|
30
|
+
return this;
|
|
31
|
+
};
|
|
32
|
+
AsyncAction.prototype.requestAsyncId = function (scheduler, _id, delay) {
|
|
33
|
+
if (delay === void 0) { delay = 0; }
|
|
34
|
+
return intervalProvider.setInterval(scheduler.flush.bind(scheduler, this), delay);
|
|
35
|
+
};
|
|
36
|
+
AsyncAction.prototype.recycleAsyncId = function (_scheduler, id, delay) {
|
|
37
|
+
if (delay === void 0) { delay = 0; }
|
|
38
|
+
if (delay != null && this.delay === delay && this.pending === false) {
|
|
39
|
+
return id;
|
|
40
|
+
}
|
|
41
|
+
if (id != null) {
|
|
42
|
+
intervalProvider.clearInterval(id);
|
|
43
|
+
}
|
|
44
|
+
return undefined;
|
|
45
|
+
};
|
|
46
|
+
AsyncAction.prototype.execute = function (state, delay) {
|
|
47
|
+
if (this.closed) {
|
|
48
|
+
return new Error('executing a cancelled action');
|
|
49
|
+
}
|
|
50
|
+
this.pending = false;
|
|
51
|
+
var error = this._execute(state, delay);
|
|
52
|
+
if (error) {
|
|
53
|
+
return error;
|
|
54
|
+
}
|
|
55
|
+
else if (this.pending === false && this.id != null) {
|
|
56
|
+
this.id = this.recycleAsyncId(this.scheduler, this.id, null);
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
AsyncAction.prototype._execute = function (state, _delay) {
|
|
60
|
+
var errored = false;
|
|
61
|
+
var errorValue;
|
|
62
|
+
try {
|
|
63
|
+
this.work(state);
|
|
64
|
+
}
|
|
65
|
+
catch (e) {
|
|
66
|
+
errored = true;
|
|
67
|
+
errorValue = e ? e : new Error('Scheduled action threw falsy error');
|
|
68
|
+
}
|
|
69
|
+
if (errored) {
|
|
70
|
+
this.unsubscribe();
|
|
71
|
+
return errorValue;
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
AsyncAction.prototype.unsubscribe = function () {
|
|
75
|
+
if (!this.closed) {
|
|
76
|
+
var _a = this, id = _a.id, scheduler = _a.scheduler;
|
|
77
|
+
var actions = scheduler.actions;
|
|
78
|
+
this.work = this.state = this.scheduler = null;
|
|
79
|
+
this.pending = false;
|
|
80
|
+
arrRemove(actions, this);
|
|
81
|
+
if (id != null) {
|
|
82
|
+
this.id = this.recycleAsyncId(scheduler, id, null);
|
|
83
|
+
}
|
|
84
|
+
this.delay = null;
|
|
85
|
+
_super.prototype.unsubscribe.call(this);
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
return AsyncAction;
|
|
89
|
+
}(Action));
|
|
90
|
+
|
|
91
|
+
export { AsyncAction };
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { __extends } from 'tslib';
|
|
2
|
+
import { Scheduler } from './Scheduler.js';
|
|
3
|
+
|
|
4
|
+
var AsyncScheduler = (function (_super) {
|
|
5
|
+
__extends(AsyncScheduler, _super);
|
|
6
|
+
function AsyncScheduler(SchedulerAction, now) {
|
|
7
|
+
if (now === void 0) { now = Scheduler.now; }
|
|
8
|
+
var _this = _super.call(this, SchedulerAction, now) || this;
|
|
9
|
+
_this.actions = [];
|
|
10
|
+
_this._active = false;
|
|
11
|
+
return _this;
|
|
12
|
+
}
|
|
13
|
+
AsyncScheduler.prototype.flush = function (action) {
|
|
14
|
+
var actions = this.actions;
|
|
15
|
+
if (this._active) {
|
|
16
|
+
actions.push(action);
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
var error;
|
|
20
|
+
this._active = true;
|
|
21
|
+
do {
|
|
22
|
+
if ((error = action.execute(action.state, action.delay))) {
|
|
23
|
+
break;
|
|
24
|
+
}
|
|
25
|
+
} while ((action = actions.shift()));
|
|
26
|
+
this._active = false;
|
|
27
|
+
if (error) {
|
|
28
|
+
while ((action = actions.shift())) {
|
|
29
|
+
action.unsubscribe();
|
|
30
|
+
}
|
|
31
|
+
throw error;
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
return AsyncScheduler;
|
|
35
|
+
}(Scheduler));
|
|
36
|
+
|
|
37
|
+
export { AsyncScheduler };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { createErrorClass } from './createErrorClass.js';
|
|
2
|
+
|
|
3
|
+
var ObjectUnsubscribedError = createErrorClass(function (_super) {
|
|
4
|
+
return function ObjectUnsubscribedErrorImpl() {
|
|
5
|
+
_super(this);
|
|
6
|
+
this.name = 'ObjectUnsubscribedError';
|
|
7
|
+
this.message = 'object unsubscribed';
|
|
8
|
+
};
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
export { ObjectUnsubscribedError };
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { SafeSubscriber, Subscriber } from './Subscriber.js';
|
|
2
|
+
import { isSubscription } from './Subscription.js';
|
|
3
|
+
import { observable } from './observable2.js';
|
|
4
|
+
import { pipeFromArray } from './pipe.js';
|
|
5
|
+
import { config } from './config.js';
|
|
6
|
+
import { isFunction } from './isFunction.js';
|
|
7
|
+
import { errorContext } from './errorContext.js';
|
|
8
|
+
|
|
9
|
+
var Observable = (function () {
|
|
10
|
+
function Observable(subscribe) {
|
|
11
|
+
if (subscribe) {
|
|
12
|
+
this._subscribe = subscribe;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
Observable.prototype.lift = function (operator) {
|
|
16
|
+
var observable = new Observable();
|
|
17
|
+
observable.source = this;
|
|
18
|
+
observable.operator = operator;
|
|
19
|
+
return observable;
|
|
20
|
+
};
|
|
21
|
+
Observable.prototype.subscribe = function (observerOrNext, error, complete) {
|
|
22
|
+
var _this = this;
|
|
23
|
+
var subscriber = isSubscriber(observerOrNext) ? observerOrNext : new SafeSubscriber(observerOrNext, error, complete);
|
|
24
|
+
errorContext(function () {
|
|
25
|
+
var _a = _this, operator = _a.operator, source = _a.source;
|
|
26
|
+
subscriber.add(operator
|
|
27
|
+
?
|
|
28
|
+
operator.call(subscriber, source)
|
|
29
|
+
: source
|
|
30
|
+
?
|
|
31
|
+
_this._subscribe(subscriber)
|
|
32
|
+
:
|
|
33
|
+
_this._trySubscribe(subscriber));
|
|
34
|
+
});
|
|
35
|
+
return subscriber;
|
|
36
|
+
};
|
|
37
|
+
Observable.prototype._trySubscribe = function (sink) {
|
|
38
|
+
try {
|
|
39
|
+
return this._subscribe(sink);
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
42
|
+
sink.error(err);
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
Observable.prototype.forEach = function (next, promiseCtor) {
|
|
46
|
+
var _this = this;
|
|
47
|
+
promiseCtor = getPromiseCtor(promiseCtor);
|
|
48
|
+
return new promiseCtor(function (resolve, reject) {
|
|
49
|
+
var subscriber = new SafeSubscriber({
|
|
50
|
+
next: function (value) {
|
|
51
|
+
try {
|
|
52
|
+
next(value);
|
|
53
|
+
}
|
|
54
|
+
catch (err) {
|
|
55
|
+
reject(err);
|
|
56
|
+
subscriber.unsubscribe();
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
error: reject,
|
|
60
|
+
complete: resolve,
|
|
61
|
+
});
|
|
62
|
+
_this.subscribe(subscriber);
|
|
63
|
+
});
|
|
64
|
+
};
|
|
65
|
+
Observable.prototype._subscribe = function (subscriber) {
|
|
66
|
+
var _a;
|
|
67
|
+
return (_a = this.source) === null || _a === void 0 ? void 0 : _a.subscribe(subscriber);
|
|
68
|
+
};
|
|
69
|
+
Observable.prototype[observable] = function () {
|
|
70
|
+
return this;
|
|
71
|
+
};
|
|
72
|
+
Observable.prototype.pipe = function () {
|
|
73
|
+
var operations = [];
|
|
74
|
+
for (var _i = 0; _i < arguments.length; _i++) {
|
|
75
|
+
operations[_i] = arguments[_i];
|
|
76
|
+
}
|
|
77
|
+
return pipeFromArray(operations)(this);
|
|
78
|
+
};
|
|
79
|
+
Observable.prototype.toPromise = function (promiseCtor) {
|
|
80
|
+
var _this = this;
|
|
81
|
+
promiseCtor = getPromiseCtor(promiseCtor);
|
|
82
|
+
return new promiseCtor(function (resolve, reject) {
|
|
83
|
+
var value;
|
|
84
|
+
_this.subscribe(function (x) { return (value = x); }, function (err) { return reject(err); }, function () { return resolve(value); });
|
|
85
|
+
});
|
|
86
|
+
};
|
|
87
|
+
Observable.create = function (subscribe) {
|
|
88
|
+
return new Observable(subscribe);
|
|
89
|
+
};
|
|
90
|
+
return Observable;
|
|
91
|
+
}());
|
|
92
|
+
function getPromiseCtor(promiseCtor) {
|
|
93
|
+
var _a;
|
|
94
|
+
return (_a = promiseCtor !== null && promiseCtor !== void 0 ? promiseCtor : config.Promise) !== null && _a !== void 0 ? _a : Promise;
|
|
95
|
+
}
|
|
96
|
+
function isObserver(value) {
|
|
97
|
+
return value && isFunction(value.next) && isFunction(value.error) && isFunction(value.complete);
|
|
98
|
+
}
|
|
99
|
+
function isSubscriber(value) {
|
|
100
|
+
return (value && value instanceof Subscriber) || (isObserver(value) && isSubscription(value));
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export { Observable };
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { __extends } from 'tslib';
|
|
2
|
+
import { Subscriber } from './Subscriber.js';
|
|
3
|
+
|
|
4
|
+
function createOperatorSubscriber(destination, onNext, onComplete, onError, onFinalize) {
|
|
5
|
+
return new OperatorSubscriber(destination, onNext, onComplete, onError, onFinalize);
|
|
6
|
+
}
|
|
7
|
+
var OperatorSubscriber = (function (_super) {
|
|
8
|
+
__extends(OperatorSubscriber, _super);
|
|
9
|
+
function OperatorSubscriber(destination, onNext, onComplete, onError, onFinalize, shouldUnsubscribe) {
|
|
10
|
+
var _this = _super.call(this, destination) || this;
|
|
11
|
+
_this.onFinalize = onFinalize;
|
|
12
|
+
_this.shouldUnsubscribe = shouldUnsubscribe;
|
|
13
|
+
_this._next = onNext
|
|
14
|
+
? function (value) {
|
|
15
|
+
try {
|
|
16
|
+
onNext(value);
|
|
17
|
+
}
|
|
18
|
+
catch (err) {
|
|
19
|
+
destination.error(err);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
: _super.prototype._next;
|
|
23
|
+
_this._error = onError
|
|
24
|
+
? function (err) {
|
|
25
|
+
try {
|
|
26
|
+
onError(err);
|
|
27
|
+
}
|
|
28
|
+
catch (err) {
|
|
29
|
+
destination.error(err);
|
|
30
|
+
}
|
|
31
|
+
finally {
|
|
32
|
+
this.unsubscribe();
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
: _super.prototype._error;
|
|
36
|
+
_this._complete = onComplete
|
|
37
|
+
? function () {
|
|
38
|
+
try {
|
|
39
|
+
onComplete();
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
42
|
+
destination.error(err);
|
|
43
|
+
}
|
|
44
|
+
finally {
|
|
45
|
+
this.unsubscribe();
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
: _super.prototype._complete;
|
|
49
|
+
return _this;
|
|
50
|
+
}
|
|
51
|
+
OperatorSubscriber.prototype.unsubscribe = function () {
|
|
52
|
+
var _a;
|
|
53
|
+
if (!this.shouldUnsubscribe || this.shouldUnsubscribe()) {
|
|
54
|
+
var closed_1 = this.closed;
|
|
55
|
+
_super.prototype.unsubscribe.call(this);
|
|
56
|
+
!closed_1 && ((_a = this.onFinalize) === null || _a === void 0 ? void 0 : _a.call(this));
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
return OperatorSubscriber;
|
|
60
|
+
}(Subscriber));
|
|
61
|
+
|
|
62
|
+
export { OperatorSubscriber, createOperatorSubscriber };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { dateTimestampProvider } from './dateTimestampProvider.js';
|
|
2
|
+
|
|
3
|
+
var Scheduler = (function () {
|
|
4
|
+
function Scheduler(schedulerActionCtor, now) {
|
|
5
|
+
if (now === void 0) { now = Scheduler.now; }
|
|
6
|
+
this.schedulerActionCtor = schedulerActionCtor;
|
|
7
|
+
this.now = now;
|
|
8
|
+
}
|
|
9
|
+
Scheduler.prototype.schedule = function (work, delay, state) {
|
|
10
|
+
if (delay === void 0) { delay = 0; }
|
|
11
|
+
return new this.schedulerActionCtor(this, work).schedule(state, delay);
|
|
12
|
+
};
|
|
13
|
+
Scheduler.now = dateTimestampProvider.now;
|
|
14
|
+
return Scheduler;
|
|
15
|
+
}());
|
|
16
|
+
|
|
17
|
+
export { Scheduler };
|
package/dist/Subject.js
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { __extends, __values } from 'tslib';
|
|
2
|
+
import { Observable } from './Observable.js';
|
|
3
|
+
import { EMPTY_SUBSCRIPTION, Subscription } from './Subscription.js';
|
|
4
|
+
import { ObjectUnsubscribedError } from './ObjectUnsubscribedError.js';
|
|
5
|
+
import { arrRemove } from './arrRemove.js';
|
|
6
|
+
import { errorContext } from './errorContext.js';
|
|
7
|
+
|
|
8
|
+
var Subject = (function (_super) {
|
|
9
|
+
__extends(Subject, _super);
|
|
10
|
+
function Subject() {
|
|
11
|
+
var _this = _super.call(this) || this;
|
|
12
|
+
_this.closed = false;
|
|
13
|
+
_this.currentObservers = null;
|
|
14
|
+
_this.observers = [];
|
|
15
|
+
_this.isStopped = false;
|
|
16
|
+
_this.hasError = false;
|
|
17
|
+
_this.thrownError = null;
|
|
18
|
+
return _this;
|
|
19
|
+
}
|
|
20
|
+
Subject.prototype.lift = function (operator) {
|
|
21
|
+
var subject = new AnonymousSubject(this, this);
|
|
22
|
+
subject.operator = operator;
|
|
23
|
+
return subject;
|
|
24
|
+
};
|
|
25
|
+
Subject.prototype._throwIfClosed = function () {
|
|
26
|
+
if (this.closed) {
|
|
27
|
+
throw new ObjectUnsubscribedError();
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
Subject.prototype.next = function (value) {
|
|
31
|
+
var _this = this;
|
|
32
|
+
errorContext(function () {
|
|
33
|
+
var e_1, _a;
|
|
34
|
+
_this._throwIfClosed();
|
|
35
|
+
if (!_this.isStopped) {
|
|
36
|
+
if (!_this.currentObservers) {
|
|
37
|
+
_this.currentObservers = Array.from(_this.observers);
|
|
38
|
+
}
|
|
39
|
+
try {
|
|
40
|
+
for (var _b = __values(_this.currentObservers), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
41
|
+
var observer = _c.value;
|
|
42
|
+
observer.next(value);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
46
|
+
finally {
|
|
47
|
+
try {
|
|
48
|
+
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
49
|
+
}
|
|
50
|
+
finally { if (e_1) throw e_1.error; }
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
};
|
|
55
|
+
Subject.prototype.error = function (err) {
|
|
56
|
+
var _this = this;
|
|
57
|
+
errorContext(function () {
|
|
58
|
+
_this._throwIfClosed();
|
|
59
|
+
if (!_this.isStopped) {
|
|
60
|
+
_this.hasError = _this.isStopped = true;
|
|
61
|
+
_this.thrownError = err;
|
|
62
|
+
var observers = _this.observers;
|
|
63
|
+
while (observers.length) {
|
|
64
|
+
observers.shift().error(err);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
};
|
|
69
|
+
Subject.prototype.complete = function () {
|
|
70
|
+
var _this = this;
|
|
71
|
+
errorContext(function () {
|
|
72
|
+
_this._throwIfClosed();
|
|
73
|
+
if (!_this.isStopped) {
|
|
74
|
+
_this.isStopped = true;
|
|
75
|
+
var observers = _this.observers;
|
|
76
|
+
while (observers.length) {
|
|
77
|
+
observers.shift().complete();
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
};
|
|
82
|
+
Subject.prototype.unsubscribe = function () {
|
|
83
|
+
this.isStopped = this.closed = true;
|
|
84
|
+
this.observers = this.currentObservers = null;
|
|
85
|
+
};
|
|
86
|
+
Object.defineProperty(Subject.prototype, "observed", {
|
|
87
|
+
get: function () {
|
|
88
|
+
var _a;
|
|
89
|
+
return ((_a = this.observers) === null || _a === void 0 ? void 0 : _a.length) > 0;
|
|
90
|
+
},
|
|
91
|
+
enumerable: false,
|
|
92
|
+
configurable: true
|
|
93
|
+
});
|
|
94
|
+
Subject.prototype._trySubscribe = function (subscriber) {
|
|
95
|
+
this._throwIfClosed();
|
|
96
|
+
return _super.prototype._trySubscribe.call(this, subscriber);
|
|
97
|
+
};
|
|
98
|
+
Subject.prototype._subscribe = function (subscriber) {
|
|
99
|
+
this._throwIfClosed();
|
|
100
|
+
this._checkFinalizedStatuses(subscriber);
|
|
101
|
+
return this._innerSubscribe(subscriber);
|
|
102
|
+
};
|
|
103
|
+
Subject.prototype._innerSubscribe = function (subscriber) {
|
|
104
|
+
var _this = this;
|
|
105
|
+
var _a = this, hasError = _a.hasError, isStopped = _a.isStopped, observers = _a.observers;
|
|
106
|
+
if (hasError || isStopped) {
|
|
107
|
+
return EMPTY_SUBSCRIPTION;
|
|
108
|
+
}
|
|
109
|
+
this.currentObservers = null;
|
|
110
|
+
observers.push(subscriber);
|
|
111
|
+
return new Subscription(function () {
|
|
112
|
+
_this.currentObservers = null;
|
|
113
|
+
arrRemove(observers, subscriber);
|
|
114
|
+
});
|
|
115
|
+
};
|
|
116
|
+
Subject.prototype._checkFinalizedStatuses = function (subscriber) {
|
|
117
|
+
var _a = this, hasError = _a.hasError, thrownError = _a.thrownError, isStopped = _a.isStopped;
|
|
118
|
+
if (hasError) {
|
|
119
|
+
subscriber.error(thrownError);
|
|
120
|
+
}
|
|
121
|
+
else if (isStopped) {
|
|
122
|
+
subscriber.complete();
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
Subject.prototype.asObservable = function () {
|
|
126
|
+
var observable = new Observable();
|
|
127
|
+
observable.source = this;
|
|
128
|
+
return observable;
|
|
129
|
+
};
|
|
130
|
+
Subject.create = function (destination, source) {
|
|
131
|
+
return new AnonymousSubject(destination, source);
|
|
132
|
+
};
|
|
133
|
+
return Subject;
|
|
134
|
+
}(Observable));
|
|
135
|
+
var AnonymousSubject = (function (_super) {
|
|
136
|
+
__extends(AnonymousSubject, _super);
|
|
137
|
+
function AnonymousSubject(destination, source) {
|
|
138
|
+
var _this = _super.call(this) || this;
|
|
139
|
+
_this.destination = destination;
|
|
140
|
+
_this.source = source;
|
|
141
|
+
return _this;
|
|
142
|
+
}
|
|
143
|
+
AnonymousSubject.prototype.next = function (value) {
|
|
144
|
+
var _a, _b;
|
|
145
|
+
(_b = (_a = this.destination) === null || _a === void 0 ? void 0 : _a.next) === null || _b === void 0 ? void 0 : _b.call(_a, value);
|
|
146
|
+
};
|
|
147
|
+
AnonymousSubject.prototype.error = function (err) {
|
|
148
|
+
var _a, _b;
|
|
149
|
+
(_b = (_a = this.destination) === null || _a === void 0 ? void 0 : _a.error) === null || _b === void 0 ? void 0 : _b.call(_a, err);
|
|
150
|
+
};
|
|
151
|
+
AnonymousSubject.prototype.complete = function () {
|
|
152
|
+
var _a, _b;
|
|
153
|
+
(_b = (_a = this.destination) === null || _a === void 0 ? void 0 : _a.complete) === null || _b === void 0 ? void 0 : _b.call(_a);
|
|
154
|
+
};
|
|
155
|
+
AnonymousSubject.prototype._subscribe = function (subscriber) {
|
|
156
|
+
var _a, _b;
|
|
157
|
+
return (_b = (_a = this.source) === null || _a === void 0 ? void 0 : _a.subscribe(subscriber)) !== null && _b !== void 0 ? _b : EMPTY_SUBSCRIPTION;
|
|
158
|
+
};
|
|
159
|
+
return AnonymousSubject;
|
|
160
|
+
}(Subject));
|
|
161
|
+
|
|
162
|
+
export { AnonymousSubject, Subject };
|