Skip to content

Commit ea2693a

Browse files
committed
feat(json-crdt): 🎸 add .toBinary() for File
1 parent 76bb748 commit ea2693a

File tree

3 files changed

+56
-0
lines changed

3 files changed

+56
-0
lines changed

src/json-crdt/file/File.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ import {Encoder as StructuralEncoderCompact} from '../codec/structural/compact/E
66
import {Encoder as StructuralEncoderVerbose} from '../codec/structural/verbose/Encoder';
77
import {encode as encodeCompact} from '../../json-crdt-patch/codec/compact/encode';
88
import {encode as encodeVerbose} from '../../json-crdt-patch/codec/verbose/encode';
9+
import {Writer} from '../../util/buffers/Writer';
10+
import {CborEncoder} from '../../json-pack/cbor/CborEncoder';
11+
import {JsonEncoder} from '../../json-pack/json/JsonEncoder';
912
import {printTree} from '../../util/print/printTree';
1013
import type * as types from './types';
1114
import type {Printable} from '../../util/print/types';
@@ -78,6 +81,26 @@ export class File implements Printable {
7881
return [view, metadata, model, history];
7982
}
8083

84+
public toBinary(params: types.FileEncodingParams): Uint8Array {
85+
const sequence = this.serialize(params);
86+
const writer = new Writer(16 * 1024);
87+
switch (params.format) {
88+
case 'ndjson': {
89+
const json = new JsonEncoder(writer);
90+
for (const component of sequence) {
91+
json.writeAny(component);
92+
json.writer.u8('\n'.charCodeAt(0));
93+
}
94+
return json.writer.flush();
95+
}
96+
case 'seq.cbor': {
97+
const cbor = new CborEncoder(writer);
98+
for (const component of sequence) cbor.writeAny(component);
99+
return cbor.writer.flush();
100+
}
101+
}
102+
}
103+
81104
// ---------------------------------------------------------------- Printable
82105

83106
public toString(tab?: string) {

src/json-crdt/file/__tests__/File.spec.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,15 @@
11
import {s} from '../../../json-crdt-patch';
22
import {Model} from '../../model';
33
import {File} from '../File';
4+
import {JsonDecoder} from '../../../json-pack/json/JsonDecoder';
5+
import {CborDecoder} from '../../../json-pack/cbor/CborDecoder';
6+
7+
const setup = (view: unknown) => {
8+
const model = Model.withServerClock();
9+
model.api.root(view);
10+
const file = File.fromModel(model);
11+
return {model, file};
12+
};
413

514
test('can create File from new model', () => {
615
const model = Model.withServerClock().setSchema(
@@ -18,3 +27,23 @@ test('can create File from new model', () => {
1827

1928
test.todo('patches are flushed and stored in memory');
2029
test.todo('can replay history');
30+
31+
describe('.toBinary()', () => {
32+
describe('can read first value as view', () => {
33+
test('.ndjson', () => {
34+
const {file} = setup({foo: 'bar'});
35+
const blob = file.toBinary({format: 'ndjson', model: 'compact', history: 'compact'});
36+
const decoder = new JsonDecoder();
37+
const view = decoder.read(blob);
38+
expect(view).toEqual({foo: 'bar'});
39+
});
40+
41+
test('.seq.cbor', () => {
42+
const {file} = setup({foo: 'bar'});
43+
const blob = file.toBinary({format: 'seq.cbor'});
44+
const decoder = new CborDecoder();
45+
const view = decoder.read(blob);
46+
expect(view).toEqual({foo: 'bar'});
47+
});
48+
});
49+
});

src/json-crdt/file/types.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,7 @@ export interface FileSerializeParams {
1818
model?: 'sidecar' | 'binary' | 'compact' | 'verbose';
1919
history?: 'binary' | 'compact' | 'verbose';
2020
}
21+
22+
export interface FileEncodingParams extends FileSerializeParams {
23+
format: 'ndjson' | 'seq.cbor';
24+
}

0 commit comments

Comments
 (0)