Skip to content

Commit 79c8f8f

Browse files
authored
Merge pull request #667 from streamich/string-store
Stor sub-binding functionality
2 parents 223a9d8 + 680d47f commit 79c8f8f

File tree

2 files changed

+47
-0
lines changed

2 files changed

+47
-0
lines changed

src/json-crdt/json-patch/JsonPatchStore.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import {SyncStore} from '../../util/events/sync-store';
22
import {JsonNodeApi} from '../model/api/types';
33
import {JsonPatch} from './JsonPatch';
4+
import {toPath} from '../../json-pointer/util';
45
import type {Path} from '../../json-pointer/types';
56
import type {Model} from '../model';
67
import type {Operation} from '../../json-patch';
@@ -28,6 +29,10 @@ export class JsonPatchStore<N extends JsonNode = JsonNode<any>> implements SyncS
2829
this.patcher.apply(ops);
2930
};
3031

32+
public bind(path: string | Path): JsonPatchStore<N> {
33+
return new JsonPatchStore(this.model, this.path.concat(toPath(path)));
34+
}
35+
3136
// ---------------------------------------------------------------- SyncStore
3237

3338
public readonly subscribe = (callback: () => void) => this.api.events.onChanges.listen(() => callback());

src/json-crdt/json-patch/__tests__/JsonPatchStore.spec.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,3 +61,45 @@ test('can subscribe and unsubscribe to changes', async () => {
6161
counter: 123,
6262
});
6363
});
64+
65+
test('can bind to a sub-path', async () => {
66+
const model = Model.create(
67+
s.obj({
68+
ui: s.obj({
69+
state: s.obj({
70+
text: s.str('abc'),
71+
counter: s.con(123),
72+
}),
73+
}),
74+
}),
75+
);
76+
const store = new JsonPatchStore(model, ['ui']);
77+
const store2 = store.bind(['state']);
78+
expect(store2.getSnapshot()).toEqual({
79+
text: 'abc',
80+
counter: 123,
81+
});
82+
store2.update({op: 'str_ins', path: '/text', pos: 3, str: 'x'});
83+
expect(store2.getSnapshot()).toEqual({
84+
text: 'abcx',
85+
counter: 123,
86+
});
87+
});
88+
89+
test('can bind store to a "str" node', async () => {
90+
const model = Model.create(
91+
s.obj({
92+
ui: s.obj({
93+
state: s.obj({
94+
text: s.str('abc'),
95+
counter: s.con(123),
96+
}),
97+
}),
98+
}),
99+
);
100+
const store = new JsonPatchStore(model, ['ui']);
101+
const store2 = store.bind('/state/text');
102+
expect(store2.getSnapshot()).toEqual('abc');
103+
store2.update({op: 'str_ins', path: '', pos: 3, str: 'x'});
104+
expect(store2.getSnapshot()).toEqual('abcx');
105+
});

0 commit comments

Comments
 (0)