Skip to content

Commit

Permalink
feat(json-crdt): 馃幐 construct extension API nodes when accessing by proxy
Browse files Browse the repository at this point in the history
  • Loading branch information
streamich committed May 4, 2024
1 parent 14e5b56 commit ef5c581
Show file tree
Hide file tree
Showing 8 changed files with 30 additions and 14 deletions.
4 changes: 3 additions & 1 deletion src/json-crdt-extensions/cnt/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ import type {ExtensionApi} from '../../json-crdt';

const MNEMONIC = ExtensionName[ExtensionId.cnt];

class CntNode extends ExtensionNode<ObjNode> {
class CntNode extends ExtensionNode<ObjNode, number> {
public readonly extId = ExtensionId.cnt;

public name(): string {
return MNEMONIC;
}
Expand Down
3 changes: 3 additions & 0 deletions src/json-crdt-extensions/mval/MvalNode.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import {MNEMONIC} from './constants';
import {ExtensionNode} from '../../json-crdt/extensions/ExtensionNode';
import {ExtensionId} from '../constants';
import type {ArrNode} from '../../json-crdt/nodes/arr/ArrNode';

export class MvalNode extends ExtensionNode<ArrNode> {
public readonly extId = ExtensionId.mval;

public name(): string {
return MNEMONIC;
}
Expand Down
3 changes: 3 additions & 0 deletions src/json-crdt-extensions/peritext/PeritextNode.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import {MNEMONIC} from './constants';
import {ExtensionNode} from '../../json-crdt/extensions/ExtensionNode';
import {ExtensionId} from '../constants';
import type {PeritextDataNode} from './types';

export class PeritextNode extends ExtensionNode<PeritextDataNode> {
public readonly extId = ExtensionId.peritext;

public name(): string {
return MNEMONIC;
}
Expand Down
7 changes: 4 additions & 3 deletions src/json-crdt/extensions/Extension.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import {NodeBuilder, s, type nodes} from '../../json-crdt-patch';
import {ExtensionNode} from './ExtensionNode';
import type {ModelApi} from '../model';
import type {JsonNode} from '../nodes';
import type {JsonNodeToSchema} from '../schema/types';
import type {ExtensionApi, ExtensionJsonNode} from './types';
import type {ExtensionApi} from './types';

export type AnyExtension = Extension<any, any, any, any, any, any>;

export class Extension<
Id extends number,
DataNode extends JsonNode,
ExtNode extends ExtensionJsonNode<DataNode>,
ExtNode extends ExtensionNode<DataNode, any>,
ExtApi extends ExtensionApi<ExtNode>,
DataArgs extends any[] = any[],
DataSchema extends NodeBuilder = JsonNodeToSchema<DataNode>,
Expand All @@ -18,7 +19,7 @@ export class Extension<
public readonly id: Id,
public readonly name: string,
public readonly Node: new (data: DataNode) => ExtNode,
public readonly Api: new (node: ExtNode, api: ModelApi) => ExtApi,
public readonly Api: new (node: ExtNode, api: ModelApi<any>) => ExtApi,
public readonly schema: (...args: DataArgs) => DataSchema,
) {}

Expand Down
7 changes: 4 additions & 3 deletions src/json-crdt/extensions/ExtensionNode.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import {printTs, type ITimestampStruct} from '../../json-crdt-patch/clock';
import type {ExtensionJsonNode, JsonNode} from '..';
import type {JsonNode} from '..';
import type {Printable} from 'tree-dump/lib/types';

export abstract class ExtensionNode<N extends JsonNode> implements ExtensionJsonNode<N>, Printable {
export abstract class ExtensionNode<N extends JsonNode, View = unknown> implements JsonNode<View>, Printable {
public abstract readonly extId: number;
public readonly id: ITimestampStruct;

constructor(public readonly data: N) {
Expand All @@ -12,7 +13,7 @@ export abstract class ExtensionNode<N extends JsonNode> implements ExtensionJson
// -------------------------------------------------------- ExtensionJsonNode

public abstract name(): string;
public abstract view(): unknown;
public abstract view(): View;

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

Expand Down
5 changes: 1 addition & 4 deletions src/json-crdt/extensions/types.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
import type {NodeApi} from '../model/api/nodes';
import type {JsonNode} from '../nodes';
import type {ExtensionNode} from './ExtensionNode';

export type ExtensionValue = [type: Uint8Array, data: unknown];

export interface ExtensionJsonNode<N extends JsonNode> extends ExtensionNode<N> {}

export interface ExtensionApi<EN extends ExtensionJsonNode<any>> extends NodeApi<EN> {}
export interface ExtensionApi<EN extends ExtensionNode<any>> extends NodeApi<EN> {}
10 changes: 9 additions & 1 deletion src/json-crdt/model/api/ModelApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,15 @@ export class ModelApi<N extends JsonNode = JsonNode> implements SyncStore<JsonNo
else if (node instanceof ArrNode) return node.api || (node.api = new ArrApi(node, this));
else if (node instanceof ObjNode) return node.api || (node.api = new ObjApi(node, this));
else if (node instanceof ConNode) return node.api || (node.api = new ConApi(node, this));
else if (node instanceof VecNode) return node.api || (node.api = new VecApi(node, this));
else if (node instanceof VecNode) {
if (node.api) return node.api;
const extensionNode = node.ext();
if (extensionNode) {
const extension = this.model.ext.get(extensionNode.extId)!;
return extensionNode.api = node.api = new extension.Api(extensionNode, this);
}
return node.api = new VecApi(node, this);
}
else throw new Error('UNKNOWN_NODE');
}

Expand Down
5 changes: 3 additions & 2 deletions src/json-crdt/model/api/nodes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@ import {find} from './find';
import {ITimestampStruct, Timestamp} from '../../../json-crdt-patch/clock';
import {Path} from '../../../json-pointer';
import {ObjNode, ArrNode, BinNode, ConNode, VecNode, ValNode, StrNode} from '../../nodes';
import {ExtensionApi, ExtensionJsonNode} from '../../extensions/types';
import {ExtensionApi} from '../../extensions/types';
import {NodeEvents} from './NodeEvents';
import type {Extension} from '../../extensions/Extension';
import type {JsonNode, JsonNodeView} from '../../nodes';
import type * as types from './proxy';
import type {ModelApi} from './ModelApi';
import type {Printable} from 'tree-dump/lib/types';
import type {JsonNodeApi} from './types';
import type {ExtensionNode} from '../../extensions/ExtensionNode';

export type ApiPath = string | number | Path | void;

Expand Down Expand Up @@ -113,7 +114,7 @@ export class NodeApi<N extends JsonNode = JsonNode> implements Printable {
throw new Error('NOT_CONST');
}

public asExt<EN extends ExtensionJsonNode<any>, EApi extends ExtensionApi<EN>>(
public asExt<EN extends ExtensionNode<any, any>, EApi extends ExtensionApi<EN>>(
ext: Extension<any, any, EN, EApi, any, any>,
): EApi {
let node: JsonNode | undefined = this.node;
Expand Down

0 comments on commit ef5c581

Please sign in to comment.