@cascateer/core 2.0.16 → 2.0.18

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cascateer/core",
3
- "version": "2.0.16",
3
+ "version": "2.0.18",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/cascateer/core.git"
package/src/multicast.ts CHANGED
@@ -9,7 +9,7 @@ import {
9
9
  MulticastActionMessage,
10
10
  MulticastClientMessage,
11
11
  MulticastConnectMessageData,
12
- proxy,
12
+ proxyReplaySubject,
13
13
  sequence,
14
14
  } from "./operators";
15
15
 
@@ -23,7 +23,7 @@ declare global {
23
23
 
24
24
  const memoizedSliceActions = memoize(
25
25
  <Seed>({ seed }: MulticastConnectMessageData<Seed>) =>
26
- proxy<MulticastActionMessage<any>>((actions) =>
26
+ proxyReplaySubject<MulticastActionMessage<any>>((actions) =>
27
27
  actions.pipe(
28
28
  startWith({
29
29
  id: v4(),
@@ -42,36 +42,37 @@ self.addEventListener("connect", ({ ports }) => {
42
42
  thru(
43
43
  new Future<Observable<MulticastActionMessage<any>>>(),
44
44
  (sliceActions) =>
45
- proxy<MulticastActionMessage<any>, MulticastClientMessage>((actions) =>
46
- sliceActions.pipe(
47
- mergeAll(),
48
- flatMap(({ origin, ...message }) =>
49
- !message.sameOrigin || origin === port ? message : [],
50
- ),
51
- sequence(([action, previousAction]) =>
52
- action.type === "seedAction"
53
- ? action
54
- : {
55
- ...action,
56
- previousId: nonNullable(previousAction).id,
57
- },
58
- ),
59
- exchangeWith<MulticastClientMessage, MulticastActionMessage<any>>(
60
- port,
61
- ),
62
- flatMap((event) => {
63
- if (event.type === "connect") {
64
- actions.subscribe(
65
- sliceActions.completeWith(memoizedSliceActions(event.data)),
66
- );
45
+ proxyReplaySubject<MulticastActionMessage<any>, MulticastClientMessage>(
46
+ (actions) =>
47
+ sliceActions.pipe(
48
+ mergeAll(),
49
+ flatMap(({ origin, ...message }) =>
50
+ !message.sameOrigin || origin === port ? message : [],
51
+ ),
52
+ sequence(([action, previousAction]) =>
53
+ action.type === "seedAction"
54
+ ? action
55
+ : {
56
+ ...action,
57
+ previousId: nonNullable(previousAction).id,
58
+ },
59
+ ),
60
+ exchangeWith<MulticastClientMessage, MulticastActionMessage<any>>(
61
+ port,
62
+ ),
63
+ flatMap((event) => {
64
+ if (event.type === "connect") {
65
+ actions.subscribe(
66
+ sliceActions.completeWith(memoizedSliceActions(event.data)),
67
+ );
67
68
 
68
- return [];
69
- }
69
+ return [];
70
+ }
70
71
 
71
- return { ...event, origin: port };
72
- }),
73
- tap(actions),
74
- ),
72
+ return { ...event, origin: port };
73
+ }),
74
+ tap(actions),
75
+ ),
75
76
  ),
76
77
  ).subscribe();
77
78
  }
@@ -0,0 +1,14 @@
1
+ import { once } from "lodash";
2
+ import { Observable } from "rxjs";
3
+
4
+ export interface ProxyObservableHandler<T> {
5
+ (target: Observable<T>, receiver: Observable<T>): Observable<T>;
6
+ }
7
+
8
+ export class ProxyObservable<T> extends Observable<T> {
9
+ constructor(target: Observable<T>, handler: ProxyObservableHandler<T>) {
10
+ handler = once(handler);
11
+
12
+ super((subscriber) => handler(target, this).subscribe(subscriber));
13
+ }
14
+ }
@@ -1,11 +1,5 @@
1
1
  import { once } from "lodash";
2
- import {
3
- Observable,
4
- Observer,
5
- ReplaySubject,
6
- Subject,
7
- Unsubscribable,
8
- } from "rxjs";
2
+ import { Observable, Observer, Subject, Unsubscribable } from "rxjs";
9
3
 
10
4
  export interface ProxySubjectHandler<T, U> {
11
5
  (target: Subject<T>, receiver: Observable<U>): Observable<U>;
@@ -32,8 +26,8 @@ export class ProxySubject<T, U = T>
32
26
  }
33
27
 
34
28
  constructor(
29
+ private target: Subject<T>,
35
30
  handler: ProxySubjectHandler<T, U>,
36
- private target: Subject<T> = new ReplaySubject(),
37
31
  ) {
38
32
  handler = once(handler);
39
33
 
@@ -1,26 +1,16 @@
1
- import { once } from "lodash";
2
- import {
3
- BehaviorSubject,
4
- combineLatest,
5
- map,
6
- MonoTypeOperatorFunction,
7
- Observable,
8
- } from "rxjs";
1
+ import { BehaviorSubject, combineLatest, map, Observable } from "rxjs";
9
2
  import { tapSubscription } from "../operators";
3
+ import { ProxyObservable } from "./ProxyObservable";
10
4
 
11
- export interface TapObservable<T> extends Observable<T> {
5
+ export interface TapObservable<T> {
12
6
  loading: Observable<boolean>;
13
7
  }
14
8
 
15
- export class TapObservable<T> extends Observable<T> {
9
+ export class TapObservable<T> extends ProxyObservable<T> {
16
10
  constructor(source: Observable<T>, loading: Observable<boolean>) {
17
11
  const subscribed = new BehaviorSubject(false);
18
12
 
19
- const intercept: MonoTypeOperatorFunction<T> = once((source) =>
20
- source.pipe(tapSubscription(subscribed)),
21
- );
22
-
23
- super((subscriber) => source.pipe(intercept).subscribe(subscriber));
13
+ super(source, (source) => source.pipe(tapSubscription(subscribed)));
24
14
 
25
15
  this.loading = combineLatest([loading, subscribed]).pipe(
26
16
  map((values) => values.every(Boolean)),
@@ -1,4 +1,5 @@
1
1
  export { Future } from "./Future";
2
+ export { ProxyObservable } from "./ProxyObservable";
2
3
  export { ProxySubject } from "./ProxySubject";
3
4
  export { ComputedSignal, Signal } from "./Signal";
4
5
  export { TapObservable } from "./TapObservable";
@@ -10,6 +10,6 @@ export {
10
10
  type MulticastHostMessage,
11
11
  type MulticastSubject,
12
12
  } from "./multicast";
13
- export { proxy } from "./proxy";
13
+ export { proxyReplaySubject } from "./proxyReplaySubject";
14
14
  export { sequence } from "./sequence";
15
15
  export { tapSubscription } from "./tapSubscription";
@@ -1,7 +1,7 @@
1
1
  import { concatMap, shareReplay, startWith, UnaryFunction } from "rxjs";
2
2
  import { v4 } from "uuid";
3
3
  import { ComputedSignal, ProxySubject } from "../observable";
4
- import { exchangeWith, proxy } from "../operators";
4
+ import { exchangeWith, proxyReplaySubject } from "../operators";
5
5
  import { Transform } from "../types";
6
6
 
7
7
  interface MulticastBaseMessage<Type, Data> {
@@ -80,7 +80,7 @@ export const multicast = <Seed>(
80
80
  key: Promise<string>,
81
81
  seed: Seed,
82
82
  ): MulticastSubject =>
83
- proxy((messages) =>
83
+ proxyReplaySubject((messages) =>
84
84
  messages.pipe(
85
85
  startWith(
86
86
  ({ key, id }): MulticastConnectMessage => ({
@@ -1,8 +1,7 @@
1
- import { Subject } from "rxjs";
1
+ import { ReplaySubject } from "rxjs";
2
2
  import { ProxySubject } from "../observable";
3
3
  import { ProxySubjectHandler } from "../observable/ProxySubject";
4
4
 
5
- export const proxy = <T, U = T>(
5
+ export const proxyReplaySubject = <T, U = T>(
6
6
  handler: ProxySubjectHandler<T, U>,
7
- target?: Subject<T>,
8
- ) => new ProxySubject(handler, target);
7
+ ) => new ProxySubject<T, U>(new ReplaySubject(), handler);
@@ -2,10 +2,13 @@ import { MonoTypeOperatorFunction, NextObserver, tap } from "rxjs";
2
2
 
3
3
  export const tapSubscription =
4
4
  <T>(observer?: NextObserver<boolean>): MonoTypeOperatorFunction<T> =>
5
- (source) =>
6
- source.pipe(
5
+ (source) => {
6
+ let subscriptions = 0;
7
+
8
+ return source.pipe(
7
9
  tap({
8
- subscribe: () => observer?.next(true),
9
- unsubscribe: () => observer?.next(false),
10
+ subscribe: () => observer?.next(++subscriptions > 0),
11
+ unsubscribe: () => observer?.next(--subscriptions > 0),
10
12
  }),
11
13
  );
14
+ };
package/src/terminal.ts CHANGED
@@ -10,7 +10,7 @@ import {
10
10
  import { ApiAdapter, ApiEffect } from "./api";
11
11
  import { ExtendableDictionary } from "./lib";
12
12
  import { ComputedSignal, TapObservable } from "./observable";
13
- import { concat, proxy } from "./operators";
13
+ import { concat, proxyReplaySubject } from "./operators";
14
14
  import { asStoreEffects, StoreAdapter, StoreEffects } from "./store";
15
15
  import { Action, Effect, TapEffect } from "./types";
16
16
 
@@ -103,15 +103,16 @@ export class ExtendableTerminalAdapter<
103
103
  (currentEffects) => () =>
104
104
  effects({
105
105
  effect: (constructor) => {
106
- const deps = proxy<TapObservable<any>, boolean>((deps) =>
107
- deps.pipe(
108
- distinct(),
109
- concat(),
110
- switchMap((dep) =>
111
- combineLatest(dep.map((dep) => dep.loading)),
106
+ const deps = proxyReplaySubject<TapObservable<any>, boolean>(
107
+ (deps) =>
108
+ deps.pipe(
109
+ distinct(),
110
+ concat(),
111
+ switchMap((dep) =>
112
+ combineLatest(dep.map((dep) => dep.loading)),
113
+ ),
114
+ map((values) => values.some(Boolean)),
112
115
  ),
113
- map((values) => values.some(Boolean)),
114
- ),
115
116
  );
116
117
 
117
118
  return thru(