@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.
Files changed (76) hide show
  1. package/README.md +42 -27
  2. package/dist/Action.js +15 -0
  3. package/dist/AsyncAction.js +91 -0
  4. package/dist/AsyncScheduler.js +37 -0
  5. package/dist/ObjectUnsubscribedError.js +11 -0
  6. package/dist/Observable.js +103 -0
  7. package/dist/OperatorSubscriber.js +62 -0
  8. package/dist/Scheduler.js +17 -0
  9. package/dist/Subject.js +162 -0
  10. package/dist/Subscriber.js +153 -0
  11. package/dist/Subscription.js +144 -0
  12. package/dist/UnsubscriptionError.js +14 -0
  13. package/dist/args.js +10 -0
  14. package/dist/arrRemove.js +8 -0
  15. package/dist/async.js +6 -0
  16. package/dist/config.js +4 -0
  17. package/dist/createErrorClass.js +12 -0
  18. package/dist/dateTimestampProvider.js +6 -0
  19. package/dist/debounceTime.js +46 -0
  20. package/dist/distinctUntilChanged.js +25 -0
  21. package/dist/enhancers/devtools/devtools.js +11 -5
  22. package/dist/enhancers/time-travel/time-travel.js +11 -5
  23. package/dist/errorContext.js +7 -0
  24. package/dist/executeSchedule.js +19 -0
  25. package/dist/filter.js +11 -0
  26. package/dist/from.js +8 -0
  27. package/dist/identity.js +5 -0
  28. package/dist/index.js +4 -0
  29. package/dist/innerFrom.js +145 -0
  30. package/dist/intervalProvider.js +17 -0
  31. package/dist/isArrayLike.js +3 -0
  32. package/dist/isAsyncIterable.js +7 -0
  33. package/dist/isFunction.js +5 -0
  34. package/dist/isInteropObservable.js +8 -0
  35. package/dist/isIterable.js +8 -0
  36. package/dist/isObservable.js +8 -0
  37. package/dist/isPromise.js +7 -0
  38. package/dist/isReadableStreamLike.js +40 -0
  39. package/dist/isScheduler.js +7 -0
  40. package/dist/iterator.js +9 -0
  41. package/dist/lib/internals/intercept-leaf-signals.js +4 -2
  42. package/dist/lib/markers/async-query.js +134 -0
  43. package/dist/lib/markers/async-source.js +122 -0
  44. package/dist/lib/rxjs-interop/rx-method.js +50 -0
  45. package/dist/lib/write-context.js +15 -0
  46. package/dist/lift.js +22 -0
  47. package/dist/noop.js +3 -0
  48. package/dist/observable2.js +3 -0
  49. package/dist/observeOn.js +12 -0
  50. package/dist/of.js +13 -0
  51. package/dist/pipe.js +15 -0
  52. package/dist/reportUnhandledError.js +11 -0
  53. package/dist/rxjs-interop.js +1 -0
  54. package/dist/scheduleArray.js +20 -0
  55. package/dist/scheduleAsyncIterable.js +25 -0
  56. package/dist/scheduleIterable.js +34 -0
  57. package/dist/scheduleObservable.js +9 -0
  58. package/dist/schedulePromise.js +9 -0
  59. package/dist/scheduleReadableStreamLike.js +8 -0
  60. package/dist/scheduled.js +39 -0
  61. package/dist/subscribeOn.js +10 -0
  62. package/dist/switchMap.js +26 -0
  63. package/dist/tap.js +42 -0
  64. package/dist/throwUnobservableError.js +5 -0
  65. package/dist/timeoutProvider.js +17 -0
  66. package/package.json +6 -1
  67. package/src/index.d.ts +5 -1
  68. package/src/lib/internals/intercept-leaf-signals.d.ts +4 -1
  69. package/src/lib/markers/async-query.d.ts +31 -0
  70. package/src/lib/markers/async-source.d.ts +27 -0
  71. package/src/lib/markers/index.d.ts +2 -0
  72. package/src/lib/rxjs-interop/index.d.ts +1 -0
  73. package/src/lib/rxjs-interop/rx-method.d.ts +11 -0
  74. package/src/lib/types.d.ts +8 -0
  75. package/src/lib/write-context.d.ts +3 -0
  76. 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); // requires @signaltree/callable-syntax transform
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()) // Performance optimization
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(serialization({ // Auto-save to localStorage
745
- autoSave: true,
746
- storage: 'localStorage',
747
- }))
748
- .with(timeTravel()); // Undo/redo support
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()) // Requires: core, provides: batching
780
- .with(devTools()); // Requires: core, provides: debugging
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()) // Performance
1657
- .with(serialization({ // State persistence
1658
- autoSave: true,
1659
- storage: 'localStorage',
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(devTools({ // Debug tools (dev only)
1663
- name: 'MyApp',
1664
- enableTimeTravel: true,
1665
- includePaths: ['app.*', 'ui.*'],
1666
- formatPath: (path) => path.replace(/\.(\d+)/g, '[$1]'),
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
- Measured from a production Angular mobile application migrating from NgRx Signal Store to SignalTree. Results reflect one team's experience; your mileage will vary depending on app complexity and existing architecture.
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 };
@@ -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 };