diff --git a/src/json-crdt-extensions/peritext/block/types.ts b/src/json-crdt-extensions/peritext/block/types.ts index 25bae54df1..f5d96e1736 100644 --- a/src/json-crdt-extensions/peritext/block/types.ts +++ b/src/json-crdt-extensions/peritext/block/types.ts @@ -1,4 +1,4 @@ -import {SliceBehavior} from '../slice/constants'; +import type {SliceBehavior} from '../slice/constants'; export type PeritextMlNode = string | PeritextMlElement; diff --git a/src/json-crdt-extensions/peritext/lazy/__tests__/import-export-html.spec.ts b/src/json-crdt-extensions/peritext/lazy/__tests__/import-export-html.spec.ts index b63b2742cc..e03afe6eda 100644 --- a/src/json-crdt-extensions/peritext/lazy/__tests__/import-export-html.spec.ts +++ b/src/json-crdt-extensions/peritext/lazy/__tests__/import-export-html.spec.ts @@ -10,7 +10,5 @@ test('a single paragraph', () => { peritext.editor.import(0, rangeView); peritext.refresh(); const json = peritext.blocks.toJson(); - expect(json).toEqual(['', null, - [CommonSliceType.p, null, 'Hello world'], - ]); + expect(json).toEqual(['', null, [CommonSliceType.p, null, 'Hello world']]); }); diff --git a/src/json-crdt-extensions/peritext/lazy/__tests__/import-html.spec.ts b/src/json-crdt-extensions/peritext/lazy/__tests__/import-html.spec.ts index 646215ed44..29ca73b29f 100644 --- a/src/json-crdt-extensions/peritext/lazy/__tests__/import-html.spec.ts +++ b/src/json-crdt-extensions/peritext/lazy/__tests__/import-html.spec.ts @@ -7,22 +7,13 @@ describe('.fromHtml()', () => { test('a single paragraph', () => { const html = '

Hello world

'; const peritextMl = fromHtml(html); - expect(peritextMl).toEqual([ - '', - null, - [CommonSliceType.p, null, 'Hello world'], - ]); + expect(peritextMl).toEqual(['', null, [CommonSliceType.p, null, 'Hello world']]); }); test('a paragraph with trailing text', () => { const html = '

Hello world

more text'; const peritextMl = fromHtml(html); - expect(peritextMl).toEqual([ - '', - null, - [CommonSliceType.p, null, 'Hello world'], - ' more text', - ]); + expect(peritextMl).toEqual(['', null, [CommonSliceType.p, null, 'Hello world'], ' more text']); }); test('text formatted as italic', () => { @@ -33,10 +24,12 @@ describe('.fromHtml()', () => { null, [CommonSliceType.p, null, 'Hello world'], '\n', - [CommonSliceType.p, null, - [CommonSliceType.i, {behavior: SliceBehavior.One, inline:true}, 'italic'], + [ + CommonSliceType.p, + null, + [CommonSliceType.i, {behavior: SliceBehavior.One, inline: true}, 'italic'], ' text, ', - [CommonSliceType.i, {behavior: SliceBehavior.One, inline:true}, 'more italic'], + [CommonSliceType.i, {behavior: SliceBehavior.One, inline: true}, 'more italic'], ], ]); }); @@ -61,31 +54,47 @@ describe('.toViewRange()', () => { const html = '

Hello world

Goodbye world

'; const peritextMl = fromHtml(html); const view = toViewRange(peritextMl); - expect(view).toEqual(['\nHello world\nGoodbye world', 0, [ - [0, 0, 0, 0], - [0, 12, 12, 0], - ]]); + expect(view).toEqual([ + '\nHello world\nGoodbye world', + 0, + [ + [0, 0, 0, 0], + [0, 12, 12, 0], + ], + ]); }); test('two paragraphs with whitespace gap', () => { const html = '

Hello world

\n

Goodbye world

'; const peritextMl = fromHtml(html); const view = toViewRange(peritextMl); - expect(view).toEqual(['\nHello world\nGoodbye world', 0, [ - [0, 0, 0, 0], - [0, 12, 12, 0], - ]]); + expect(view).toEqual([ + '\nHello world\nGoodbye world', + 0, + [ + [0, 0, 0, 0], + [0, 12, 12, 0], + ], + ]); }); test('single inline annotation', () => { const html = 'here is some italic text'; const peritextMl = fromHtml(html); const view = toViewRange(peritextMl); - expect(view).toEqual(['here is some italic text', 0, [ - [(SliceBehavior.One << SliceHeaderShift.Behavior) + - (Anchor.Before << SliceHeaderShift.X1Anchor) + - (Anchor.After << SliceHeaderShift.X2Anchor), - 13, 19, CommonSliceType.i], - ]]); + expect(view).toEqual([ + 'here is some italic text', + 0, + [ + [ + (SliceBehavior.One << SliceHeaderShift.Behavior) + + (Anchor.Before << SliceHeaderShift.X1Anchor) + + (Anchor.After << SliceHeaderShift.X2Anchor), + 13, + 19, + CommonSliceType.i, + ], + ], + ]); }); -}); \ No newline at end of file +}); diff --git a/src/json-crdt-extensions/peritext/lazy/import-html.ts b/src/json-crdt-extensions/peritext/lazy/import-html.ts index 871cdaa098..b29be1cd45 100644 --- a/src/json-crdt-extensions/peritext/lazy/import-html.ts +++ b/src/json-crdt-extensions/peritext/lazy/import-html.ts @@ -18,7 +18,7 @@ class ViewRangeBuilder { private text = ''; private slices: ViewSlice[] = []; - constructor (private registry: SliceRegistry) {} + constructor(private registry: SliceRegistry) {} private build0(node: PeritextMlNode, depth = 0): void { const skipWhitespace = depth < 2; @@ -32,7 +32,8 @@ class ViewRangeBuilder { const length = node.length; const inline = !!attr?.inline; if (!!type || type === 0) { - let end: number = 0, header: number = 0; + let end: number = 0, + header: number = 0; if (!inline) { this.text += '\n'; end = start; @@ -48,7 +49,8 @@ class ViewRangeBuilder { } for (let i = 2; i < length; i++) this.build0(node[i] as PeritextMlNode, depth + 1); if (!!type || type === 0) { - let end: number = 0, header: number = 0; + let end: number = 0, + header: number = 0; if (inline) { end = this.text.length; const behavior: SliceBehavior = attr?.behavior ?? SliceBehavior.Many; @@ -56,10 +58,10 @@ class ViewRangeBuilder { (behavior << SliceHeaderShift.Behavior) + (Anchor.Before << SliceHeaderShift.X1Anchor) + (Anchor.After << SliceHeaderShift.X2Anchor); - const slice: ViewSlice = [header, start, end, type]; - const data = attr?.data; - if (data) slice.push(data); - this.slices.push(slice); + const slice: ViewSlice = [header, start, end, type]; + const data = attr?.data; + if (data) slice.push(data); + this.slices.push(slice); } } } @@ -102,7 +104,7 @@ export const fromJsonMl = (jsonml: JsonMlNode, registry: SliceRegistry = default node[1] = attr; } return node; -} +}; export const fromHast = (hast: THtmlToken, registry?: SliceRegistry): PeritextMlNode => { const jsonml = _fromHast(hast); diff --git a/src/json-crdt-extensions/peritext/lazy/import-markdown.ts b/src/json-crdt-extensions/peritext/lazy/import-markdown.ts index c8116dc007..2fce411e90 100644 --- a/src/json-crdt-extensions/peritext/lazy/import-markdown.ts +++ b/src/json-crdt-extensions/peritext/lazy/import-markdown.ts @@ -15,5 +15,5 @@ export const fromMdast = (mdast: IRoot, registry: SliceRegistry = defaultRegistr export const fromMarkdown = (markdown: string, registry?: SliceRegistry): PeritextMlNode => { const mdast = block.parsef(markdown); - return fromMdast(mdast, registry); + return fromMdast(mdast, registry); }; diff --git a/src/json-crdt-extensions/peritext/registry/SliceRegistry.ts b/src/json-crdt-extensions/peritext/registry/SliceRegistry.ts index e1125b054f..0205b06f4f 100644 --- a/src/json-crdt-extensions/peritext/registry/SliceRegistry.ts +++ b/src/json-crdt-extensions/peritext/registry/SliceRegistry.ts @@ -1,5 +1,5 @@ -import {PeritextMlElement} from '../block/types'; -import {NodeBuilder} from '../../../json-crdt-patch'; +import type {PeritextMlElement} from '../block/types'; +import type {NodeBuilder} from '../../../json-crdt-patch'; import {SliceBehavior} from '../slice/constants'; import type {JsonMlElement} from 'very-small-parser/lib/html/json-ml/types'; import type {FromHtmlConverter, SliceTypeDefinition, ToHtmlConverter} from './types'; @@ -7,9 +7,12 @@ import type {FromHtmlConverter, SliceTypeDefinition, ToHtmlConverter} from './ty export class SliceRegistry { private map: Map> = new Map(); private toHtmlMap: Map> = new Map(); - private fromHtmlMap: Map, converter: FromHtmlConverter][]> = new Map(); + private fromHtmlMap: Map, converter: FromHtmlConverter][]> = + new Map(); - public add(def: SliceTypeDefinition): void { + public add( + def: SliceTypeDefinition, + ): void { const {type, toHtml, fromHtml} = def; this.map.set(type, def); if (toHtml) this.toHtmlMap.set(type, toHtml); @@ -47,7 +50,7 @@ export class SliceRegistry { const result = converter(el); if (result) { const attr = result[1] ?? (result[1] = {}); - attr.inline = def.inline ?? (def.type < 0); + attr.inline = def.inline ?? def.type < 0; attr.behavior = !attr.inline ? SliceBehavior.Marker : (def.behavior ?? SliceBehavior.Many); return result; } diff --git a/src/json-crdt-extensions/peritext/registry/registry.ts b/src/json-crdt-extensions/peritext/registry/registry.ts index aa892b35f1..6bf610712d 100644 --- a/src/json-crdt-extensions/peritext/registry/registry.ts +++ b/src/json-crdt-extensions/peritext/registry/registry.ts @@ -1,9 +1,9 @@ -import {s} from "../../../json-crdt-patch"; -import {JsonNodeView} from "../../../json-crdt/nodes"; -import {SchemaToJsonNode} from "../../../json-crdt/schema/types"; -import {CommonSliceType} from "../slice"; +import {s} from '../../../json-crdt-patch'; +import type {JsonNodeView} from '../../../json-crdt/nodes'; +import type {SchemaToJsonNode} from '../../../json-crdt/schema/types'; +import {CommonSliceType} from '../slice'; import {SliceBehavior} from '../slice/constants'; -import {SliceRegistry} from "./SliceRegistry"; +import {SliceRegistry} from './SliceRegistry'; const undefSchema = s.con(undefined); @@ -56,12 +56,12 @@ registry.def(CommonSliceType.a, aSchema, SliceBehavior.Many, true, { title: attr.title ?? '', }; return [CommonSliceType.a, {data, inline: true}]; - } + }, }, }); // TODO: add more default annotations -// comment = SliceTypeCon.comment, +// comment = SliceTypeCon.comment, // font = SliceTypeCon.font, // col = SliceTypeCon.col, // bg = SliceTypeCon.bg, diff --git a/src/json-crdt-extensions/peritext/registry/types.ts b/src/json-crdt-extensions/peritext/registry/types.ts index e13414c521..1dd486fc31 100644 --- a/src/json-crdt-extensions/peritext/registry/types.ts +++ b/src/json-crdt-extensions/peritext/registry/types.ts @@ -5,7 +5,11 @@ import type {PeritextMlElement} from '../block/types'; import type {JsonMlElement} from 'very-small-parser/lib/html/json-ml/types'; import type {SliceBehavior} from '../slice/constants'; -export interface SliceTypeDefinition { +export interface SliceTypeDefinition< + Type extends number | string = number | string, + Schema extends NodeBuilder = NodeBuilder, + Inline extends boolean = true, +> { type: Type; schema: Schema; behavior?: SliceBehavior; @@ -16,8 +20,10 @@ export interface SliceTypeDefinition = PeritextMlElement> = - (element: El) => [tag: string, attr: Record | null]; +export type ToHtmlConverter< + El extends PeritextMlElement = PeritextMlElement, +> = (element: El) => [tag: string, attr: Record | null]; -export type FromHtmlConverter = PeritextMlElement> = - (jsonml: JsonMlElement) => El; +export type FromHtmlConverter< + El extends PeritextMlElement = PeritextMlElement, +> = (jsonml: JsonMlElement) => El; diff --git a/src/json-crdt-patch/builder/schema.ts b/src/json-crdt-patch/builder/schema.ts index c60315f2e8..433498f86d 100644 --- a/src/json-crdt-patch/builder/schema.ts +++ b/src/json-crdt-patch/builder/schema.ts @@ -132,9 +132,9 @@ export namespace nodes { * age: s.con(0), * }); * ``` - * + * * Specify optional keys as the second argument: - * + * * ```ts * s.obj( * { @@ -145,9 +145,9 @@ export namespace nodes { * }, * ) * ``` - * + * * Or, specify only the type, using the `optional` method: - * + * * ```ts * s.obj({ * href: s.str('https://example.com'),