Skip to content

Commit

Permalink
feat(json-crdt-extensions): 馃幐 define Peritext extension
Browse files Browse the repository at this point in the history
  • Loading branch information
streamich committed May 2, 2024
1 parent 07f4c8a commit 032bab1
Show file tree
Hide file tree
Showing 10 changed files with 112 additions and 2 deletions.
7 changes: 7 additions & 0 deletions src/json-crdt-extensions/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,10 @@ export const enum ExtensionId {
peritext = 2,
quill = 3,
}

export enum ExtensionName {
mval = ExtensionId.mval,
cnt = ExtensionId.cnt,
peritext = ExtensionId.peritext,
quill = ExtensionId.quill,
}
1 change: 1 addition & 0 deletions src/json-crdt-extensions/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './mval';
export * from './cnt';
export * from './peritext';
6 changes: 6 additions & 0 deletions src/json-crdt-extensions/peritext/PeritextApi.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import {NodeApi} from '../../json-crdt/model/api/nodes';
import type {PeritextNode} from './PeritextNode';
import type {ExtensionApi} from '../../json-crdt';

export class PeritextApi extends NodeApi<PeritextNode> implements ExtensionApi<PeritextNode> {
}
43 changes: 43 additions & 0 deletions src/json-crdt-extensions/peritext/PeritextNode.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import {printTree} from 'tree-dump/lib/printTree';
import {MNEMONIC} from './constants';
import type {ITimestampStruct} from '../../json-crdt-patch/clock';
import type {ExtensionJsonNode, JsonNode} from '../../json-crdt';
import type {Printable} from 'tree-dump/lib/types';
import type {PeritextDataNode} from './types';

export class PeritextNode implements ExtensionJsonNode, Printable {
public readonly id: ITimestampStruct;

constructor(public readonly data: PeritextDataNode) {
this.id = data.id;
}

// -------------------------------------------------------- ExtensionJsonNode

public name(): string {
return MNEMONIC;
}

public view(): string {
const str = this.data.get(0)!;
return str.view();
}

public children(callback: (node: JsonNode) => void): void {}

public child?(): PeritextDataNode {
return this.data;
}

public container(): JsonNode | undefined {
return this.data.container();
}

public api: undefined | unknown = undefined;

// ---------------------------------------------------------------- Printable

public toString(tab?: string): string {
return this.name() + printTree(tab, [(tab) => this.data.toString(tab)]);
}
}
26 changes: 26 additions & 0 deletions src/json-crdt-extensions/peritext/constants.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,29 @@
import {nodes, s} from "../../json-crdt-patch";
import {ExtensionId, ExtensionName} from "../constants";
import {SliceSchema} from "./slice/types";

export const enum Chars {
BlockSplitSentinel = '\n',
}

export const MNEMONIC = ExtensionName[ExtensionId.peritext];

export const BUILD_SCHEMA = (text: string) => (
s.vec<[
/**
* The text of the node. All rich-text textual data is stored in this node.
*/
str: nodes.str<string>,

/**
* The slices of the node. All rich-text annotations are stored in this
* node.
*/
slices: nodes.arr<SliceSchema>,
]>(
s.str<string>(text),
s.arr<SliceSchema>([]),
)
);

export const SCHEMA = BUILD_SCHEMA('');
2 changes: 1 addition & 1 deletion src/json-crdt-extensions/peritext/editor/Editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import type {MarkerSlice} from '../slice/MarkerSlice';
import type {Slices} from '../slice/Slices';

/**
* Rename to `PeritextApi`.
* @todo Rename to `PeritextApi`.
*/
export class Editor implements Printable {
/**
Expand Down
15 changes: 15 additions & 0 deletions src/json-crdt-extensions/peritext/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import {ext} from '../../json-crdt/extensions';
import {ExtensionId} from '../constants';
import {PeritextNode} from './PeritextNode';
import {PeritextApi} from './PeritextApi';
import {BUILD_SCHEMA, MNEMONIC} from './constants';
import type {PeritextDataNode} from './types';
import type {ExtensionDefinition} from '../../json-crdt';

export const PeritextExt: ExtensionDefinition<PeritextDataNode, PeritextNode, PeritextApi> = {
id: ExtensionId.peritext,
name: MNEMONIC,
new: (text: string) => ext(ExtensionId.peritext, BUILD_SCHEMA(text)),
Node: PeritextNode,
Api: PeritextApi,
};
1 change: 1 addition & 0 deletions src/json-crdt-extensions/peritext/slice/Slices.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ export class Slices implements Stateful, Printable {
if (data !== undefined) tupleKeysUpdate.push([SliceTupleIndex.Data, builder.json(data)]);
builder.insVec(tupleId, tupleKeysUpdate);
const chunkId = builder.insArr(set.id, set.id, [tupleId]);
// TODO: Consider using `s` schema here.
api.apply();
const tuple = model.index.get(tupleId) as VecNode;
const chunk = set.findById(chunkId)!;
Expand Down
8 changes: 8 additions & 0 deletions src/json-crdt-extensions/peritext/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import type {SchemaToJsonNode} from "../../json-crdt/schema/types";
import type {SCHEMA} from "./constants";

/**
* Represents an object which state can change over time.
*
* @todo Move to /src/utils.
*/
export interface Stateful {
/**
Expand All @@ -13,3 +18,6 @@ export interface Stateful {
*/
refresh(): number;
}

export type PeritextDataNodeSchema = typeof SCHEMA;
export type PeritextDataNode = SchemaToJsonNode<PeritextDataNodeSchema>;
5 changes: 4 additions & 1 deletion src/json-crdt/extensions/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import {PatchBuilder} from '../../json-crdt-patch/PatchBuilder';
import {NodeBuilder} from '../../json-crdt-patch/builder/DelayedValueBuilder';
import {konst} from '../../json-crdt-patch/builder/Konst';
import {ITimestampStruct} from '../../json-crdt-patch/clock';
import type {ITimestampStruct} from '../../json-crdt-patch/clock';

/**
* @todo Replace this by `s` builder.
*/
export const ext = (extensionId: number, nodeBuilder: NodeBuilder) =>
new NodeBuilder((builder: PatchBuilder): ITimestampStruct => {
// Extension tuple starts with a 3-byte header:
Expand Down

0 comments on commit 032bab1

Please sign in to comment.