rx-player 3.28.0-dev.2022062300 → 3.28.0-dev.2022062700
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/CHANGELOG.md +2 -1
- package/VERSION +1 -1
- package/dist/_esm5.processed/core/adaptive/adaptive_representation_selector.js +1 -6
- package/dist/_esm5.processed/core/api/playback_observer.d.ts +47 -35
- package/dist/_esm5.processed/core/api/playback_observer.js +120 -117
- package/dist/_esm5.processed/core/api/public_api.d.ts +4 -1
- package/dist/_esm5.processed/core/api/public_api.js +10 -5
- package/dist/_esm5.processed/core/init/content_time_boundaries_observer.js +1 -1
- package/dist/_esm5.processed/core/init/create_stream_playback_observer.d.ts +1 -1
- package/dist/_esm5.processed/core/init/create_stream_playback_observer.js +23 -6
- package/dist/_esm5.processed/core/init/initial_seek_and_play.js +3 -3
- package/dist/_esm5.processed/core/init/initialize_directfile.js +1 -1
- package/dist/_esm5.processed/core/init/load_on_media_source.js +1 -1
- package/dist/_esm5.processed/core/init/stall_avoider.js +12 -8
- package/dist/_esm5.processed/core/stream/orchestrator/stream_orchestrator.js +5 -4
- package/dist/_esm5.processed/core/stream/period/create_empty_adaptation_stream.js +1 -1
- package/dist/_esm5.processed/core/stream/period/period_stream.js +21 -5
- package/dist/_esm5.processed/core/stream/reload_after_switch.js +1 -1
- package/dist/_esm5.processed/core/stream/representation/append_segment_to_buffer.js +1 -1
- package/dist/_esm5.processed/core/stream/representation/representation_stream.js +1 -1
- package/dist/_esm5.processed/utils/reference.d.ts +2 -2
- package/dist/_esm5.processed/utils/reference.js +5 -4
- package/dist/rx-player.js +241 -179
- package/dist/rx-player.min.js +1 -1
- package/package.json +2 -2
- package/sonar-project.properties +1 -1
- package/src/core/adaptive/adaptive_representation_selector.ts +1 -7
- package/src/core/api/playback_observer.ts +185 -173
- package/src/core/api/public_api.ts +15 -6
- package/src/core/init/content_time_boundaries_observer.ts +1 -1
- package/src/core/init/create_stream_playback_observer.ts +69 -47
- package/src/core/init/initial_seek_and_play.ts +3 -3
- package/src/core/init/initialize_directfile.ts +1 -1
- package/src/core/init/load_on_media_source.ts +1 -1
- package/src/core/init/stall_avoider.ts +12 -9
- package/src/core/stream/orchestrator/stream_orchestrator.ts +5 -4
- package/src/core/stream/period/create_empty_adaptation_stream.ts +1 -1
- package/src/core/stream/period/period_stream.ts +33 -14
- package/src/core/stream/reload_after_switch.ts +1 -1
- package/src/core/stream/representation/append_segment_to_buffer.ts +1 -1
- package/src/core/stream/representation/representation_stream.ts +1 -1
- package/src/utils/reference.ts +7 -5
|
@@ -14,13 +14,11 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
import {
|
|
18
|
-
combineLatest as observableCombineLatest,
|
|
19
|
-
map,
|
|
20
|
-
Observable,
|
|
21
|
-
} from "rxjs";
|
|
22
17
|
import Manifest from "../../manifest";
|
|
23
|
-
import {
|
|
18
|
+
import createSharedReference, {
|
|
19
|
+
IReadOnlySharedReference,
|
|
20
|
+
} from "../../utils/reference";
|
|
21
|
+
import { CancellationSignal } from "../../utils/task_canceller";
|
|
24
22
|
import {
|
|
25
23
|
IPlaybackObservation,
|
|
26
24
|
IReadOnlyPlaybackObserver,
|
|
@@ -47,7 +45,7 @@ export interface IStreamPlaybackObserverArguments {
|
|
|
47
45
|
* @param {Object} manifest
|
|
48
46
|
* @param {Object} playbackObserver
|
|
49
47
|
* @param {Object} args
|
|
50
|
-
* @returns {
|
|
48
|
+
* @returns {Object}
|
|
51
49
|
*/
|
|
52
50
|
export default function createStreamPlaybackObserver(
|
|
53
51
|
manifest : Manifest,
|
|
@@ -58,47 +56,71 @@ export default function createStreamPlaybackObserver(
|
|
|
58
56
|
speed,
|
|
59
57
|
startTime } : IStreamPlaybackObserverArguments
|
|
60
58
|
) : IReadOnlyPlaybackObserver<IStreamOrchestratorPlaybackObservation> {
|
|
61
|
-
return playbackObserver.deriveReadOnlyObserver(function
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
59
|
+
return playbackObserver.deriveReadOnlyObserver(function transform(
|
|
60
|
+
observationRef : IReadOnlySharedReference<IPlaybackObservation>,
|
|
61
|
+
cancellationSignal : CancellationSignal
|
|
62
|
+
) : IReadOnlySharedReference<IStreamOrchestratorPlaybackObservation> {
|
|
63
|
+
const newRef = createSharedReference(constructStreamPlaybackObservation());
|
|
64
|
+
|
|
65
|
+
speed.onUpdate(emitStreamPlaybackObservation, {
|
|
66
|
+
clearSignal: cancellationSignal,
|
|
67
|
+
emitCurrentValue: false,
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
observationRef.onUpdate(emitStreamPlaybackObservation, {
|
|
71
|
+
clearSignal: cancellationSignal,
|
|
72
|
+
emitCurrentValue: false,
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
cancellationSignal.register(() => {
|
|
76
|
+
newRef.finish();
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
return newRef;
|
|
80
|
+
|
|
81
|
+
function constructStreamPlaybackObservation() {
|
|
82
|
+
const observation = observationRef.getValue();
|
|
83
|
+
const lastSpeed = speed.getValue();
|
|
84
|
+
let pendingPosition : number | undefined;
|
|
85
|
+
if (!initialSeekPerformed.getValue()) {
|
|
86
|
+
pendingPosition = startTime;
|
|
87
|
+
} else if (!manifest.isDynamic || manifest.isLastPeriodKnown) {
|
|
88
|
+
// HACK: When the position is actually further than the maximum
|
|
89
|
+
// position for a finished content, we actually want to be loading
|
|
90
|
+
// the last segment before ending.
|
|
91
|
+
// For now, this behavior is implicitely forced by making as if we
|
|
92
|
+
// want to seek one second before the period's end (despite never
|
|
93
|
+
// doing it).
|
|
94
|
+
const lastPeriod = manifest.periods[manifest.periods.length - 1];
|
|
95
|
+
if (lastPeriod !== undefined &&
|
|
96
|
+
lastPeriod.end !== undefined &&
|
|
97
|
+
observation.position > lastPeriod.end)
|
|
98
|
+
{
|
|
99
|
+
pendingPosition = lastPeriod.end - 1;
|
|
83
100
|
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return {
|
|
104
|
+
// TODO more exact according to the current Adaptation chosen?
|
|
105
|
+
maximumPosition: manifest.getMaximumSafePosition(),
|
|
106
|
+
position: {
|
|
107
|
+
last: observation.position,
|
|
108
|
+
pending: pendingPosition,
|
|
109
|
+
},
|
|
110
|
+
duration: observation.duration,
|
|
111
|
+
paused: {
|
|
112
|
+
last: observation.paused,
|
|
113
|
+
pending: initialPlayPerformed.getValue() ? undefined :
|
|
114
|
+
!autoPlay === observation.paused ? undefined :
|
|
115
|
+
!autoPlay,
|
|
116
|
+
},
|
|
117
|
+
readyState: observation.readyState,
|
|
118
|
+
speed: lastSpeed,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
84
121
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
position: {
|
|
89
|
-
last: observation.position,
|
|
90
|
-
pending: pendingPosition,
|
|
91
|
-
},
|
|
92
|
-
duration: observation.duration,
|
|
93
|
-
paused: {
|
|
94
|
-
last: observation.paused,
|
|
95
|
-
pending: initialPlayPerformed.getValue() ? undefined :
|
|
96
|
-
!autoPlay === observation.paused ? undefined :
|
|
97
|
-
!autoPlay,
|
|
98
|
-
},
|
|
99
|
-
readyState: observation.readyState,
|
|
100
|
-
speed: lastSpeed,
|
|
101
|
-
};
|
|
102
|
-
}));
|
|
122
|
+
function emitStreamPlaybackObservation() {
|
|
123
|
+
newRef.setValue(constructStreamPlaybackObservation());
|
|
124
|
+
}
|
|
103
125
|
});
|
|
104
126
|
}
|
|
@@ -83,7 +83,7 @@ export function waitUntilPlayable(
|
|
|
83
83
|
|
|
84
84
|
/**
|
|
85
85
|
* Try to play content then handle autoplay errors.
|
|
86
|
-
* @param {HTMLMediaElement}
|
|
86
|
+
* @param {HTMLMediaElement} mediaElement
|
|
87
87
|
* @returns {Observable}
|
|
88
88
|
*/
|
|
89
89
|
function autoPlay(
|
|
@@ -161,12 +161,12 @@ export default function initialSeekAndPlay(
|
|
|
161
161
|
const seekAndPlay$ = seek$.pipe(
|
|
162
162
|
mergeMap(() : Observable<IWarningEvent | undefined> => {
|
|
163
163
|
if (!shouldValidateMetadata() || mediaElement.duration > 0) {
|
|
164
|
-
return waitUntilPlayable(playbackObserver.
|
|
164
|
+
return waitUntilPlayable(playbackObserver.getReference().asObservable());
|
|
165
165
|
} else {
|
|
166
166
|
const error = new MediaError("MEDIA_ERR_NOT_LOADED_METADATA",
|
|
167
167
|
"Cannot load automatically: your browser " +
|
|
168
168
|
"falsely announced having loaded the content.");
|
|
169
|
-
return waitUntilPlayable(playbackObserver.
|
|
169
|
+
return waitUntilPlayable(playbackObserver.getReference().asObservable())
|
|
170
170
|
.pipe(startWith(EVENTS.warning(error)));
|
|
171
171
|
}
|
|
172
172
|
}),
|
|
@@ -158,7 +158,7 @@ export default function initializeDirectfileContent({
|
|
|
158
158
|
// through a throwing Observable.
|
|
159
159
|
const mediaError$ = throwOnMediaError(mediaElement);
|
|
160
160
|
|
|
161
|
-
const observation$ = playbackObserver.
|
|
161
|
+
const observation$ = playbackObserver.getReference().asObservable();
|
|
162
162
|
|
|
163
163
|
// Set the speed set by the user on the media element while pausing a
|
|
164
164
|
// little longer while the buffer is empty.
|
|
@@ -125,7 +125,7 @@ export default function createMediaSourceLoader(
|
|
|
125
125
|
startTime: initialTime,
|
|
126
126
|
mustAutoPlay: autoPlay });
|
|
127
127
|
|
|
128
|
-
const observation$ = playbackObserver.
|
|
128
|
+
const observation$ = playbackObserver.getReference().asObservable();
|
|
129
129
|
const streamEvents$ = initialPlayPerformed.asObservable().pipe(
|
|
130
130
|
filter((hasPlayed) => hasPlayed),
|
|
131
131
|
mergeMap(() => streamEventsEmitter(manifest, mediaElement, observation$)));
|
|
@@ -139,7 +139,7 @@ export default function StallAvoider(
|
|
|
139
139
|
* order (first ordered by Period's start, then by bufferType in any order.
|
|
140
140
|
*/
|
|
141
141
|
const discontinuitiesStore$ = discontinuityUpdate$.pipe(
|
|
142
|
-
withLatestFrom(playbackObserver.
|
|
142
|
+
withLatestFrom(playbackObserver.getReference().asObservable()),
|
|
143
143
|
scan(
|
|
144
144
|
(discontinuitiesStore, [evt, observation]) =>
|
|
145
145
|
updateDiscontinuitiesStore(discontinuitiesStore, evt, observation),
|
|
@@ -179,7 +179,7 @@ export default function StallAvoider(
|
|
|
179
179
|
* Period handled by that stream to unlock the situation.
|
|
180
180
|
*/
|
|
181
181
|
const unlock$ = lockedStream$.pipe(
|
|
182
|
-
withLatestFrom(playbackObserver.
|
|
182
|
+
withLatestFrom(playbackObserver.getReference().asObservable()),
|
|
183
183
|
tap(([lockedStreamEvt, observation]) => {
|
|
184
184
|
// TODO(PaulB) also skip when the user's wanted speed is set to `0`, as we
|
|
185
185
|
// might not want to seek in that case?
|
|
@@ -211,7 +211,7 @@ export default function StallAvoider(
|
|
|
211
211
|
ignoreElements()
|
|
212
212
|
);
|
|
213
213
|
|
|
214
|
-
const stall$ = playbackObserver.
|
|
214
|
+
const stall$ = playbackObserver.getReference().asObservable().pipe(
|
|
215
215
|
withLatestFrom(discontinuitiesStore$),
|
|
216
216
|
map(([observation, discontinuitiesStore]) => {
|
|
217
217
|
const { buffered,
|
|
@@ -279,12 +279,15 @@ export default function StallAvoider(
|
|
|
279
279
|
if (ignoredStallTimeStamp === null) {
|
|
280
280
|
ignoredStallTimeStamp = now;
|
|
281
281
|
}
|
|
282
|
-
if (isSeekingApproximate &&
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
282
|
+
if (isSeekingApproximate && observation.position < lastSeekingPosition) {
|
|
283
|
+
log.debug("Init: the device appeared to have seeked back by itself.");
|
|
284
|
+
if (now - ignoredStallTimeStamp < FORCE_DISCONTINUITY_SEEK_DELAY) {
|
|
285
|
+
return { type: "stalled" as const,
|
|
286
|
+
value: stalledReason };
|
|
287
|
+
} else {
|
|
288
|
+
log.warn("Init: ignored stall for too long, checking discontinuity",
|
|
289
|
+
now - ignoredStallTimeStamp);
|
|
290
|
+
}
|
|
288
291
|
}
|
|
289
292
|
lastSeekingPosition = null;
|
|
290
293
|
}
|
|
@@ -142,7 +142,7 @@ export default function StreamOrchestrator(
|
|
|
142
142
|
Infinity;
|
|
143
143
|
return BufferGarbageCollector({
|
|
144
144
|
segmentBuffer,
|
|
145
|
-
currentTime$: playbackObserver.
|
|
145
|
+
currentTime$: playbackObserver.getReference().asObservable()
|
|
146
146
|
.pipe(map(o => o.position.pending ?? o.position.last)),
|
|
147
147
|
maxBufferBehind$: maxBufferBehind.asObservable().pipe(
|
|
148
148
|
map(val => Math.min(val, defaultMaxBehind))),
|
|
@@ -264,7 +264,8 @@ export default function StreamOrchestrator(
|
|
|
264
264
|
|
|
265
265
|
// Restart the current Stream when the wanted time is in another period
|
|
266
266
|
// than the ones already considered
|
|
267
|
-
const
|
|
267
|
+
const observation$ = playbackObserver.getReference().asObservable();
|
|
268
|
+
const restartStreamsWhenOutOfBounds$ = observation$.pipe(
|
|
268
269
|
filterMap<
|
|
269
270
|
IStreamOrchestratorPlaybackObservation,
|
|
270
271
|
Period,
|
|
@@ -329,7 +330,7 @@ export default function StreamOrchestrator(
|
|
|
329
330
|
// to reduce the risk of race conditions where the next observation
|
|
330
331
|
// was going to be emitted synchronously.
|
|
331
332
|
nextTickObs().pipe(ignoreElements()),
|
|
332
|
-
playbackObserver.
|
|
333
|
+
playbackObserver.getReference().asObservable().pipe(
|
|
333
334
|
take(1),
|
|
334
335
|
mergeMap((observation) => {
|
|
335
336
|
const shouldAutoPlay = !(observation.paused.pending ??
|
|
@@ -399,7 +400,7 @@ export default function StreamOrchestrator(
|
|
|
399
400
|
const destroyNextStreams$ = new Subject<void>();
|
|
400
401
|
|
|
401
402
|
// Emits when the current position goes over the end of the current Stream.
|
|
402
|
-
const endOfCurrentStream$ = playbackObserver.
|
|
403
|
+
const endOfCurrentStream$ = playbackObserver.getReference().asObservable()
|
|
403
404
|
.pipe(filter(({ position }) =>
|
|
404
405
|
basePeriod.end != null &&
|
|
405
406
|
(position.pending ?? position.last) >= basePeriod.end));
|
|
@@ -48,7 +48,7 @@ export default function createEmptyAdaptationStream(
|
|
|
48
48
|
const { period } = content;
|
|
49
49
|
let hasFinishedLoading = false;
|
|
50
50
|
const wantedBufferAhead$ = wantedBufferAhead.asObservable();
|
|
51
|
-
const observation$ = playbackObserver.
|
|
51
|
+
const observation$ = playbackObserver.getReference().asObservable();
|
|
52
52
|
return observableCombineLatest([observation$,
|
|
53
53
|
wantedBufferAhead$]).pipe(
|
|
54
54
|
mergeMap(([observation, wba]) => {
|
|
@@ -42,7 +42,10 @@ import Manifest, {
|
|
|
42
42
|
import { IAudioTrackSwitchingMode } from "../../../public_types";
|
|
43
43
|
import objectAssign from "../../../utils/object_assign";
|
|
44
44
|
import { getLeftSizeOfRange } from "../../../utils/ranges";
|
|
45
|
-
import {
|
|
45
|
+
import createSharedReference, {
|
|
46
|
+
IReadOnlySharedReference,
|
|
47
|
+
} from "../../../utils/reference";
|
|
48
|
+
import { CancellationSignal } from "../../../utils/task_canceller";
|
|
46
49
|
import WeakMapMemory from "../../../utils/weak_map_memory";
|
|
47
50
|
import { IRepresentationEstimator } from "../../adaptive";
|
|
48
51
|
import { IReadOnlyPlaybackObserver } from "../../api";
|
|
@@ -357,18 +360,34 @@ function createAdaptationStreamPlaybackObserver(
|
|
|
357
360
|
initialPlaybackObserver : IReadOnlyPlaybackObserver<IPeriodStreamPlaybackObservation>,
|
|
358
361
|
segmentBuffer : SegmentBuffer
|
|
359
362
|
) : IReadOnlyPlaybackObserver<IAdaptationStreamPlaybackObservation> {
|
|
360
|
-
return initialPlaybackObserver.deriveReadOnlyObserver(
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
)
|
|
363
|
+
return initialPlaybackObserver.deriveReadOnlyObserver(function transform(
|
|
364
|
+
observationRef : IReadOnlySharedReference<IPeriodStreamPlaybackObservation>,
|
|
365
|
+
cancellationSignal : CancellationSignal
|
|
366
|
+
) : IReadOnlySharedReference<IAdaptationStreamPlaybackObservation> {
|
|
367
|
+
const newRef = createSharedReference(constructAdaptationStreamPlaybackObservation());
|
|
368
|
+
|
|
369
|
+
observationRef.onUpdate(emitAdaptationStreamPlaybackObservation, {
|
|
370
|
+
clearSignal: cancellationSignal,
|
|
371
|
+
emitCurrentValue: false,
|
|
372
|
+
});
|
|
373
|
+
|
|
374
|
+
cancellationSignal.register(() => {
|
|
375
|
+
newRef.finish();
|
|
376
|
+
});
|
|
377
|
+
|
|
378
|
+
return newRef;
|
|
379
|
+
|
|
380
|
+
function constructAdaptationStreamPlaybackObservation(
|
|
381
|
+
) : IAdaptationStreamPlaybackObservation {
|
|
382
|
+
const baseObservation = observationRef.getValue();
|
|
383
|
+
const buffered = segmentBuffer.getBufferedRanges();
|
|
384
|
+
const bufferGap = getLeftSizeOfRange(buffered, baseObservation.position.last);
|
|
385
|
+
return objectAssign({}, baseObservation, { bufferGap });
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
function emitAdaptationStreamPlaybackObservation() {
|
|
389
|
+
newRef.setValue(constructAdaptationStreamPlaybackObservation());
|
|
390
|
+
}
|
|
391
|
+
});
|
|
364
392
|
|
|
365
|
-
function mapObservation(
|
|
366
|
-
baseObservation : IPeriodStreamPlaybackObservation
|
|
367
|
-
) : IAdaptationStreamPlaybackObservation {
|
|
368
|
-
const buffered = segmentBuffer.getBufferedRanges();
|
|
369
|
-
return objectAssign({},
|
|
370
|
-
baseObservation,
|
|
371
|
-
{ bufferGap: getLeftSizeOfRange(buffered,
|
|
372
|
-
baseObservation.position.last) });
|
|
373
|
-
}
|
|
374
393
|
}
|
|
@@ -62,7 +62,7 @@ export default function reloadAfterSwitch(
|
|
|
62
62
|
// It can happen when `reloadAfterSwitch` is called as a side-effect of the
|
|
63
63
|
// same event that triggers the playback observation to be emitted.
|
|
64
64
|
return nextTickObs().pipe(
|
|
65
|
-
mergeMap(() => playbackObserver.
|
|
65
|
+
mergeMap(() => playbackObserver.getReference().asObservable()),
|
|
66
66
|
map((observation) => {
|
|
67
67
|
const currentTime = playbackObserver.getCurrentTime();
|
|
68
68
|
const pos = currentTime + deltaPos;
|
|
@@ -61,7 +61,7 @@ export default function appendSegmentToBuffer<T>(
|
|
|
61
61
|
throw new MediaError("BUFFER_APPEND_ERROR", reason);
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
return playbackObserver.
|
|
64
|
+
return playbackObserver.getReference().asObservable().pipe(
|
|
65
65
|
take(1),
|
|
66
66
|
mergeMap((observation) => {
|
|
67
67
|
const currentPos = observation.position.pending ??
|
|
@@ -166,7 +166,7 @@ export default function RepresentationStream<TSegmentDataType>({
|
|
|
166
166
|
|
|
167
167
|
/** Observable emitting the stream "status" and filling `lastSegmentQueue`. */
|
|
168
168
|
const status$ = observableCombineLatest([
|
|
169
|
-
playbackObserver.
|
|
169
|
+
playbackObserver.getReference().asObservable(),
|
|
170
170
|
bufferGoal$,
|
|
171
171
|
maxBufferSize$,
|
|
172
172
|
terminate$.pipe(take(1),
|
package/src/utils/reference.ts
CHANGED
|
@@ -101,8 +101,8 @@ export interface ISharedReference<T> {
|
|
|
101
101
|
onUpdate(
|
|
102
102
|
cb : (val : T) => void,
|
|
103
103
|
options? : {
|
|
104
|
-
clearSignal?: CancellationSignal;
|
|
105
|
-
emitCurrentValue?: boolean;
|
|
104
|
+
clearSignal?: CancellationSignal | undefined;
|
|
105
|
+
emitCurrentValue?: boolean | undefined;
|
|
106
106
|
},
|
|
107
107
|
) : void;
|
|
108
108
|
/**
|
|
@@ -217,10 +217,10 @@ export function createSharedReference<T>(initialValue : T) : ISharedReference<T>
|
|
|
217
217
|
setValue(newVal : T) : void {
|
|
218
218
|
if (isFinished) {
|
|
219
219
|
if (__ENVIRONMENT__.CURRENT_ENV === __ENVIRONMENT__.DEV as number) {
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
return;
|
|
220
|
+
/* eslint-disable-next-line no-console */
|
|
221
|
+
console.error("Finished shared references cannot be updated");
|
|
223
222
|
}
|
|
223
|
+
return;
|
|
224
224
|
}
|
|
225
225
|
value = newVal;
|
|
226
226
|
|
|
@@ -344,10 +344,12 @@ export function createSharedReference<T>(initialValue : T) : ISharedReference<T>
|
|
|
344
344
|
if (!cbObj.hasBeenCleared) {
|
|
345
345
|
cbObj.complete();
|
|
346
346
|
}
|
|
347
|
+
cbObj.hasBeenCleared = true;
|
|
347
348
|
} catch (_) {
|
|
348
349
|
/* nothing */
|
|
349
350
|
}
|
|
350
351
|
}
|
|
352
|
+
cbs.length = 0;
|
|
351
353
|
},
|
|
352
354
|
};
|
|
353
355
|
}
|