File tree Expand file tree Collapse file tree 3 files changed +52
-1
lines changed Expand file tree Collapse file tree 3 files changed +52
-1
lines changed Original file line number Diff line number Diff line change @@ -21,6 +21,7 @@ import {AvlMap} from '../../util/trees/avl/AvlMap';
2121import type { JsonNode , JsonNodeView } from '../nodes/types' ;
2222import type { Printable } from '../../util/print/types' ;
2323import type { NodeBuilder } from '../../json-crdt-patch' ;
24+ import type { NodeApi } from './api/nodes' ;
2425
2526export const UNDEFINED = new ConNode ( ORIGIN , undefined ) ;
2627
@@ -291,6 +292,8 @@ export class Model<N extends JsonNode = JsonNode> implements Printable {
291292 if ( isSystemNode ) return ;
292293 const node = this . index . get ( value ) ;
293294 if ( ! node ) return ;
295+ const api = node . api ;
296+ if ( api ) ( api as NodeApi ) . events . onDelete ( ) ;
294297 node . children ( ( child ) => this . deleteNodeTree ( child . id ) ) ;
295298 this . index . del ( value ) ;
296299 }
Original file line number Diff line number Diff line change 1+ import { Model } from '../..' ;
2+
3+ test ( 'does not fire events after node is deleted' , ( ) => {
4+ const model = Model . withLogicalClock ( ) ;
5+ model . api . root ( {
6+ foo : {
7+ bar : {
8+ baz : 'asdf' ,
9+ } ,
10+ } ,
11+ } ) ;
12+ const bar = model . api . obj ( [ 'foo' , 'bar' ] ) ;
13+ let cnt = 0 ;
14+ bar . events . changes . listen ( ( ) => {
15+ cnt ++ ;
16+ } ) ;
17+ expect ( cnt ) . toBe ( 0 ) ;
18+ bar . set ( {
19+ gg : 'wp' ,
20+ } ) ;
21+ expect ( cnt ) . toBe ( 1 ) ;
22+ model . api . obj ( [ 'foo' ] ) . del ( [ 'bar' ] ) ;
23+ model . api . obj ( [ 'foo' ] ) . set ( { gl : 'hf' } ) ;
24+ expect ( cnt ) . toBe ( 1 ) ;
25+ } ) ;
Original file line number Diff line number Diff line change @@ -21,9 +21,12 @@ export interface NodeEventMap {
2121}
2222
2323class ChangesFanOut < N extends JsonNode = JsonNode > extends FanOut < JsonNodeView < N > > {
24+ /** @ignore */
2425 private _v : JsonNodeView < N > | undefined = undefined ;
26+ /** @ignore */
2527 private _u : FanOutUnsubscribe | undefined = undefined ;
2628
29+ /** @ignore */
2730 constructor ( private readonly api : NodeApi < N > ) {
2831 super ( ) ;
2932 }
@@ -45,10 +48,20 @@ class ChangesFanOut<N extends JsonNode = JsonNode> extends FanOut<JsonNodeView<N
4548 unsubscribe ( ) ;
4649 if ( ! this . listeners . size ) {
4750 this . _u ?.( ) ;
48- // this._unsub = this._view = undefined;
51+ this . _u = this . _v = undefined ;
4952 }
5053 } ;
5154 }
55+
56+ /**
57+ * @internal
58+ * @ignore
59+ */
60+ public dispose ( ) {
61+ this . listeners . clear ( ) ;
62+ this . _u ?.( ) ;
63+ this . _u = this . _v = undefined ;
64+ }
5265}
5366
5467export class NodeEvents < N extends JsonNode = JsonNode >
@@ -101,6 +114,16 @@ export class NodeEvents<N extends JsonNode = JsonNode>
101114 super . off ( type , listener , options ) ;
102115 }
103116
117+ /**
118+ * Called when this node is deleted.
119+ *
120+ * @internal
121+ * @ignore
122+ */
123+ public onDelete ( ) {
124+ this . changes . dispose ( ) ;
125+ }
126+
104127 // ---------------------------------------------------------------- SyncStore
105128
106129 public readonly subscribe = ( callback : ( ) => void ) : SyncStoreUnsubscribe => {
You can’t perform that action at this time.
0 commit comments