Skip to content

Commit 35c4ee9

Browse files
committed
feat(json-crdt): 🎸 implement .add() method for "arr" nodes
1 parent 9bd5bb2 commit 35c4ee9

File tree

2 files changed

+77
-0
lines changed

2 files changed

+77
-0
lines changed

src/json-crdt/model/api/__tests__/NodeApi.spec.ts

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,4 +118,67 @@ describe('.add()', () => {
118118
expect(doc.api.read('/str')).toBe(null);
119119
});
120120
});
121+
122+
describe('"arr" node', () => {
123+
test('can add element to the end of array', () => {
124+
const doc = createTypedModel();
125+
expect(doc.api.read('/arr/2')).toBe(undefined);
126+
const success = doc.api.add('/arr/2', 'newValue');
127+
expect(doc.api.read('/arr/2')).toBe('newValue');
128+
expect(success).toBe(true);
129+
});
130+
131+
test('can add element to the end of array when index too high', () => {
132+
const doc = createTypedModel();
133+
expect(doc.api.read('/arr/2')).toBe(undefined);
134+
const success = doc.api.add('/arr/9999', 'newValue');
135+
expect(doc.api.read('/arr/2')).toBe('newValue');
136+
expect(success).toBe(true);
137+
});
138+
139+
test('can add element to the end of array when index is "-"', () => {
140+
const doc = createTypedModel();
141+
expect(doc.api.read('/arr/2')).toBe(undefined);
142+
const success = doc.api.add('/arr/-', 'newValue');
143+
expect(doc.api.read('/arr/2')).toBe('newValue');
144+
expect(success).toBe(true);
145+
});
146+
147+
test('can add element to the beginning of array', () => {
148+
const doc = createTypedModel();
149+
expect(doc.api.read('/arr/0')).toBe('asdf');
150+
const success = doc.api.add('/arr/0', 0);
151+
expect(doc.api.read('/arr/0')).toBe(0);
152+
expect(doc.api.read('/arr/1')).toBe('asdf');
153+
expect(success).toBe(true);
154+
});
155+
156+
test('can add element to the middle of array', () => {
157+
const doc = createTypedModel();
158+
expect(doc.api.read('/arr/1')).toBe(0);
159+
const success = doc.api.add('/arr/1', 123);
160+
expect(doc.api.read('/arr/1')).toBe(123);
161+
expect(doc.api.read('/arr/2')).toBe(0);
162+
expect(success).toBe(true);
163+
});
164+
165+
test('returns "false" when cannot insert into array', () => {
166+
const doc = createTypedModel();
167+
const success1 = doc.api.add('/arr/1.1', 123);
168+
const success2 = doc.api.add('/arr/adsf', 123);
169+
const success3 = doc.api.add('/arr/Infinity', 123);
170+
expect(success1).toBe(false);
171+
expect(success2).toBe(false);
172+
expect(success3).toBe(false);
173+
});
174+
});
175+
176+
test.todo('"vec" node');
177+
test.todo('"str" node');
178+
test.todo('"bin" node');
179+
test.todo('"val" node');
180+
test.todo('"con" node');
121181
});
182+
183+
test.todo('.merge()');
184+
test.todo('.shallowMerge()');

src/json-crdt/model/api/nodes.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,20 @@ export class NodeApi<N extends JsonNode = JsonNode> implements Printable {
206206
if (node instanceof ObjApi) {
207207
node.set({[key]: value});
208208
return true;
209+
} else if (node instanceof ArrApi) {
210+
const length = node.length();
211+
let index: number = 0;
212+
if (typeof key === 'number') index = key;
213+
else if (key === '-') index = length;
214+
else {
215+
index = ~~key;
216+
if (index + '' !== key) return false;
217+
}
218+
if (index !== index) return false;
219+
if (index < 0) index = 0;
220+
if (index > length) index = length;
221+
node.ins(index, [value]);
222+
return true;
209223
}
210224
} catch {}
211225
return false;

0 commit comments

Comments
 (0)