diff --git a/implementations/javascript/packages/core/src/annotated.ts b/implementations/javascript/packages/core/src/annotated.ts index 8f5af4a..964b466 100644 --- a/implementations/javascript/packages/core/src/annotated.ts +++ b/implementations/javascript/packages/core/src/annotated.ts @@ -4,7 +4,7 @@ import { AsPreserve, PreserveOn } from "./symbols"; import { Value } from "./values"; import { is, isAnnotated, IsPreservesAnnotated } from "./is"; import { stringify } from "./text"; -import { DefaultPointer } from "./pointer"; +import { GenericPointer } from "./pointer"; export interface Position { line?: number; @@ -53,7 +53,7 @@ export function formatPosition(p: Position | null | string): string { } } -export class Annotated { +export class Annotated { readonly annotations: Array>; readonly pos: Position | null; readonly item: Value; @@ -99,17 +99,17 @@ export class Annotated { return true; } - static isAnnotated(x: any): x is Annotated { + static isAnnotated(x: any): x is Annotated { return isAnnotated(x); } } -export function annotate(v0: Value, ...anns: Value[]): Annotated { +export function annotate(v0: Value, ...anns: Value[]): Annotated { const v = Annotated.isAnnotated(v0) ? v0 : new Annotated(v0); anns.forEach((a) => v.annotations.push(a)); return v; } -export function position(v: Value): Position | null { +export function position(v: Value): Position | null { return Annotated.isAnnotated(v) ? v.pos : null; } diff --git a/implementations/javascript/packages/core/src/bytes.ts b/implementations/javascript/packages/core/src/bytes.ts index 63189ed..fa4831e 100644 --- a/implementations/javascript/packages/core/src/bytes.ts +++ b/implementations/javascript/packages/core/src/bytes.ts @@ -2,7 +2,7 @@ import { Tag } from './constants'; import { AsPreserve, PreserveOn } from './symbols'; import { Encoder, Preservable } from './encoder'; import { Value } from './values'; -import { DefaultPointer } from './pointer'; +import { GenericPointer } from './pointer'; const textEncoder = new TextEncoder(); const textDecoder = new TextDecoder(); @@ -127,7 +127,7 @@ export class Bytes implements Preservable { return this.asPreservesText(); } - [AsPreserve](): Value { + [AsPreserve](): Value { return this; } diff --git a/implementations/javascript/packages/core/src/compound.ts b/implementations/javascript/packages/core/src/compound.ts index 650591a..10fc11b 100644 --- a/implementations/javascript/packages/core/src/compound.ts +++ b/implementations/javascript/packages/core/src/compound.ts @@ -1,8 +1,8 @@ import type { Compound, Value } from "./values"; -import type { DefaultPointer } from "./pointer"; +import type { GenericPointer } from "./pointer"; import { Dictionary, Set } from "./dictionary"; -export function isCompound(x: Value): x is Compound +export function isCompound(x: Value): x is Compound { return (Array.isArray(x) || Set.isSet(x) || Dictionary.isDictionary(x)); } diff --git a/implementations/javascript/packages/core/src/dictionary.ts b/implementations/javascript/packages/core/src/dictionary.ts index 0f92f02..c9593ee 100644 --- a/implementations/javascript/packages/core/src/dictionary.ts +++ b/implementations/javascript/packages/core/src/dictionary.ts @@ -6,17 +6,17 @@ import { stringify } from "./text"; import { Value } from "./values"; import { Bytes } from './bytes'; import { fromJS } from "./fromjs"; -import { DefaultPointer } from "./pointer"; +import { GenericPointer } from "./pointer"; export type DictionaryType = 'Dictionary' | 'Set'; export const DictionaryType = Symbol.for('DictionaryType'); -export class KeyedDictionary, V, T = DefaultPointer> extends FlexMap { +export class KeyedDictionary, V, T = GenericPointer> extends FlexMap { get [DictionaryType](): DictionaryType { return 'Dictionary'; } - static isKeyedDictionary, V, T = DefaultPointer>(x: any): x is KeyedDictionary { + static isKeyedDictionary, V, T = GenericPointer>(x: any): x is KeyedDictionary { return x?.[DictionaryType] === 'Dictionary'; } @@ -26,7 +26,7 @@ export class KeyedDictionary, V, T = DefaultPointer> extends super(canonicalString, items); } - mapEntries, R = DefaultPointer>(f: (entry: [K, V]) => [S, W]): KeyedDictionary { + mapEntries, R = GenericPointer>(f: (entry: [K, V]) => [S, W]): KeyedDictionary { const result = new KeyedDictionary(); for (let oldEntry of this.entries()) { const newEntry = f(oldEntry); @@ -75,12 +75,12 @@ export class KeyedDictionary, V, T = DefaultPointer> extends } } -export class Dictionary> extends KeyedDictionary, V, T> { - static isDictionary>(x: any): x is Dictionary { +export class Dictionary> extends KeyedDictionary, V, T> { + static isDictionary>(x: any): x is Dictionary { return x?.[DictionaryType] === 'Dictionary'; } - static fromJS(x: object): Dictionary> { + static fromJS(x: object): Dictionary> { if (Dictionary.isDictionary>(x)) return x; const d = new Dictionary>(); Object.entries(x).forEach(([key, value]) => d.set(key, fromJS(value))); @@ -88,12 +88,12 @@ export class Dictionary> extends KeyedDictionar } } -export class KeyedSet, T = DefaultPointer> extends FlexSet { +export class KeyedSet, T = GenericPointer> extends FlexSet { get [DictionaryType](): DictionaryType { return 'Set'; } - static isKeyedSet, T = DefaultPointer>(x: any): x is KeyedSet { + static isKeyedSet, T = GenericPointer>(x: any): x is KeyedSet { return x?.[DictionaryType] === 'Set'; } @@ -101,7 +101,7 @@ export class KeyedSet, T = DefaultPointer> extends FlexSet super(canonicalString, items); } - map, R = DefaultPointer>(f: (value: K) => S): KeyedSet { + map, R = GenericPointer>(f: (value: K) => S): KeyedSet { return new KeyedSet(_iterMap(this[Symbol.iterator](), f)); } @@ -138,8 +138,8 @@ export class KeyedSet, T = DefaultPointer> extends FlexSet } } -export class Set extends KeyedSet, T> { - static isSet(x: any): x is Set { +export class Set extends KeyedSet, T> { + static isSet(x: any): x is Set { return x?.[DictionaryType] === 'Set'; } } diff --git a/implementations/javascript/packages/core/src/float.ts b/implementations/javascript/packages/core/src/float.ts index 2988c63..b1baedd 100644 --- a/implementations/javascript/packages/core/src/float.ts +++ b/implementations/javascript/packages/core/src/float.ts @@ -2,7 +2,7 @@ import { Encoder, Preservable } from "./encoder"; import { Tag } from "./constants"; import { AsPreserve, PreserveOn } from "./symbols"; import { Value } from "./values"; -import { DefaultPointer } from "./pointer"; +import { GenericPointer } from "./pointer"; export type FloatType = 'Single' | 'Double'; export const FloatType = Symbol.for('FloatType'); @@ -45,7 +45,7 @@ export function floatValue(f: any): number { } export class SingleFloat extends Float implements Preservable { - [AsPreserve](): Value { + [AsPreserve](): Value { return this; } @@ -70,7 +70,7 @@ export function Single(value: number | Float): SingleFloat { } export class DoubleFloat extends Float implements Preservable { - [AsPreserve](): Value { + [AsPreserve](): Value { return this; } diff --git a/implementations/javascript/packages/core/src/fromjs.ts b/implementations/javascript/packages/core/src/fromjs.ts index ee939b0..43a8276 100644 --- a/implementations/javascript/packages/core/src/fromjs.ts +++ b/implementations/javascript/packages/core/src/fromjs.ts @@ -1,11 +1,11 @@ -import { embed, DefaultPointer } from "./pointer"; +import { embed, GenericPointer } from "./pointer"; import { Bytes } from "./bytes"; import { Record, Tuple } from "./record"; import { AsPreserve } from "./symbols"; import { Value } from "./values"; import { Dictionary, Set } from "./dictionary"; -export function fromJS(x: any): Value { +export function fromJS(x: any): Value { switch (typeof x) { case 'number': if (!Number.isInteger(x)) { diff --git a/implementations/javascript/packages/core/src/is.ts b/implementations/javascript/packages/core/src/is.ts index 3bbea91..61ed216 100644 --- a/implementations/javascript/packages/core/src/is.ts +++ b/implementations/javascript/packages/core/src/is.ts @@ -1,9 +1,9 @@ -import type { DefaultPointer } from "./pointer"; +import type { GenericPointer } from "./pointer"; import type { Annotated } from "./annotated"; export const IsPreservesAnnotated = Symbol.for('IsPreservesAnnotated'); -export function isAnnotated(x: any): x is Annotated +export function isAnnotated(x: any): x is Annotated { return !!x?.[IsPreservesAnnotated]; } diff --git a/implementations/javascript/packages/core/src/pointer.ts b/implementations/javascript/packages/core/src/pointer.ts index 1d8e3d0..6dd16c5 100644 --- a/implementations/javascript/packages/core/src/pointer.ts +++ b/implementations/javascript/packages/core/src/pointer.ts @@ -7,8 +7,8 @@ export type PointerType = { decode(s: DecoderState): T; encode(s: EncoderState, v: T): void; - fromValue(v: Value): T; - toValue(v: T): Value; + fromValue(v: Value): T; + toValue(v: T): Value; } export class Pointer { @@ -35,7 +35,7 @@ export function isPointer(v: Value): v is Pointer { return typeof v === 'object' && 'embeddedValue' in v; } -export class DefaultPointer { +export class GenericPointer { generic: Value; constructor(generic: Value) { @@ -51,20 +51,20 @@ export class DefaultPointer { } } -export const genericPointerType: PointerType = { - decode(s: DecoderState): DefaultPointer { - return new DefaultPointer(new Decoder(s, this).next()); +export const genericPointerType: PointerType = { + decode(s: DecoderState): GenericPointer { + return new GenericPointer(new Decoder(s, this).next()); }, - encode(s: EncoderState, v: DefaultPointer): void { + encode(s: EncoderState, v: GenericPointer): void { new Encoder(s, this).push(v.generic); }, - fromValue(v: Value): DefaultPointer { - return new DefaultPointer(strip(v)); + fromValue(v: Value): GenericPointer { + return new GenericPointer(strip(v)); }, - toValue(v: DefaultPointer): Value { + toValue(v: GenericPointer): Value { return v.generic; } }; @@ -78,11 +78,11 @@ export const neverPointerType: PointerType = { throw new Error("Pointers not permitted encoding Preserves document"); }, - fromValue(_v: Value): never { + fromValue(_v: Value): never { throw new Error("Pointers not permitted at this point in Preserves document"); }, - toValue(_v: never): Value { + toValue(_v: never): Value { throw new Error("Pointers not permitted encoding Preserves document"); } }; @@ -107,11 +107,11 @@ export const identityPointerType: PointerType = { new Encoder(s, this).push(pointerId(v)); }, - fromValue(_v: Value): any { + fromValue(_v: Value): any { throw new Error("Cannot decode identityPointerType"); }, - toValue(v: any): Value { + toValue(v: any): Value { return pointerId(v); } }; diff --git a/implementations/javascript/packages/core/src/reader.ts b/implementations/javascript/packages/core/src/reader.ts index 8c7f8de..f9496d7 100644 --- a/implementations/javascript/packages/core/src/reader.ts +++ b/implementations/javascript/packages/core/src/reader.ts @@ -10,7 +10,7 @@ import { Record } from './record'; import { Annotated, newPosition, Position, updatePosition } from './annotated'; import { Double, DoubleFloat, Single, SingleFloat } from './float'; import { stringify } from './text'; -import { embed, DefaultPointer, genericPointerType, neverPointerType, PointerType } from './pointer'; +import { embed, GenericPointer, genericPointerType, neverPointerType, PointerType } from './pointer'; export interface ReaderStateOptions { includeAnnotations?: boolean; @@ -383,7 +383,7 @@ export class Reader { }); } case '!': return embed(this.pointerType.fromValue( - new Reader(this.state, genericPointerType).next())); + new Reader(this.state, genericPointerType).next())); default: this.state.error(`Invalid # syntax: ${c}`, startPos); } diff --git a/implementations/javascript/packages/core/src/record.ts b/implementations/javascript/packages/core/src/record.ts index 23e1099..51df0b9 100644 --- a/implementations/javascript/packages/core/src/record.ts +++ b/implementations/javascript/packages/core/src/record.ts @@ -1,10 +1,10 @@ -import { DefaultPointer } from "./pointer"; +import { GenericPointer } from "./pointer"; import { is } from "./is"; import { Value } from "./values"; export type Tuple = Array | [T]; -export type Record, FieldsType extends Tuple>, T = DefaultPointer> +export type Record, FieldsType extends Tuple>, T = GenericPointer> = FieldsType & { label: LabelType }; export type RecordGetters = { @@ -14,14 +14,14 @@ export type RecordGetters = { export type CtorTypes> = { [K in keyof Names]: Fs[keyof Fs & Names[K]] } & any[]; -export interface RecordConstructor, Fs, Names extends Tuple, T = DefaultPointer> { +export interface RecordConstructor, Fs, Names extends Tuple, T = GenericPointer> { (...fields: CtorTypes): Record, T>; constructorInfo: RecordConstructorInfo; isClassOf(v: any): v is Record, T>; _: RecordGetters, T>>; }; -export interface RecordConstructorInfo, T = DefaultPointer> { +export interface RecordConstructorInfo, T = GenericPointer> { label: L; arity: number; } @@ -46,7 +46,7 @@ export function Record>( } export namespace Record { - export function isRecord, FieldsType extends Tuple>, T = DefaultPointer>(x: any): x is Record { + export function isRecord, FieldsType extends Tuple>, T = GenericPointer>(x: any): x is Record { return Array.isArray(x) && 'label' in x; } @@ -54,19 +54,19 @@ export namespace Record { return ''; } - export function constructorInfo, FieldsType extends Tuple>, T = DefaultPointer>( + export function constructorInfo, FieldsType extends Tuple>, T = GenericPointer>( r: Record): RecordConstructorInfo { return { label: r.label, arity: r.length }; } - export function isClassOf, FieldsType extends Tuple>, T = DefaultPointer>( + export function isClassOf, FieldsType extends Tuple>, T = GenericPointer>( ci: RecordConstructorInfo, v: any): v is Record { return (Record.isRecord(v)) && is(ci.label, v.label) && (ci.arity === v.length); } - export function makeConstructor() + export function makeConstructor() : (, Names extends Tuple>(label: L, fieldNames: Names) => RecordConstructor) { @@ -86,7 +86,7 @@ export namespace Record { Array.prototype.asPreservesText = function (): string { if ('label' in (this as any)) { - const r = this as Record, DefaultPointer>; + const r = this as Record, GenericPointer>; return '<' + r.label.asPreservesText() + (r.length > 0 ? ' ': '') + r.map(f => { try { diff --git a/implementations/javascript/packages/core/src/strip.ts b/implementations/javascript/packages/core/src/strip.ts index 6812498..dce1baa 100644 --- a/implementations/javascript/packages/core/src/strip.ts +++ b/implementations/javascript/packages/core/src/strip.ts @@ -2,17 +2,17 @@ import { Value } from "./values"; import { Annotated } from "./annotated"; import { Record, Tuple } from "./record"; import { Set, Dictionary } from "./dictionary"; -import type { DefaultPointer } from "./pointer"; +import type { GenericPointer } from "./pointer"; -export function unannotate(v: Value): Value { +export function unannotate(v: Value): Value { return Annotated.isAnnotated(v) ? v.item : v; } -export function peel(v: Value): Value { +export function peel(v: Value): Value { return strip(v, 1); } -export function strip( +export function strip( v: Value, depth: number = Infinity): Value { diff --git a/implementations/javascript/packages/core/src/values.ts b/implementations/javascript/packages/core/src/values.ts index aca9246..e4729af 100644 --- a/implementations/javascript/packages/core/src/values.ts +++ b/implementations/javascript/packages/core/src/values.ts @@ -4,9 +4,9 @@ import type { Bytes } from './bytes'; import type { DoubleFloat, SingleFloat } from './float'; import type { Annotated } from './annotated'; import type { Set, Dictionary } from './dictionary'; -import type { Pointer, DefaultPointer } from './pointer'; +import type { Pointer, GenericPointer } from './pointer'; -export type Value = +export type Value = | Atom | Compound | Pointer @@ -19,7 +19,7 @@ export type Atom = | string | Bytes | symbol; -export type Compound = +export type Compound = | (Array> | [Value]) & { label: Value } // ^ expanded from definition of Record<> in record.ts, // because if we use Record, Tuple>, T>, diff --git a/implementations/javascript/packages/core/test/codec.test.ts b/implementations/javascript/packages/core/test/codec.test.ts index 28a4a90..9531dcf 100644 --- a/implementations/javascript/packages/core/test/codec.test.ts +++ b/implementations/javascript/packages/core/test/codec.test.ts @@ -10,7 +10,7 @@ import { fromJS, Constants, Encoder, - DefaultPointer, + GenericPointer, EncoderState, PointerType, DecoderState, @@ -27,9 +27,9 @@ import * as fs from 'fs'; const _discard = Symbol.for('discard'); const _capture = Symbol.for('capture'); const _observe = Symbol.for('observe'); -const Discard = Record.makeConstructor<{}, DefaultPointer>()(_discard, []); -const Capture = Record.makeConstructor<{pattern: Value}, DefaultPointer>()(_capture, ['pattern']); -const Observe = Record.makeConstructor<{pattern: Value}, DefaultPointer>()(_observe, ['pattern']); +const Discard = Record.makeConstructor<{}, GenericPointer>()(_discard, []); +const Capture = Record.makeConstructor<{pattern: Value}, GenericPointer>()(_capture, ['pattern']); +const Observe = Record.makeConstructor<{pattern: Value}, GenericPointer>()(_observe, ['pattern']); describe('record constructors', () => { it('should have constructorInfo', () => { @@ -95,7 +95,7 @@ describe('encoding and decoding pointers', () => { } decode(d: DecoderState): object { - return this.fromValue(new Decoder(d).next()); + return this.fromValue(new Decoder(d).next()); } encode(e: EncoderState, v: object): void { @@ -106,7 +106,7 @@ describe('encoding and decoding pointers', () => { return Object.is(a, b); } - fromValue(v: Value): object { + fromValue(v: Value): object { if (typeof v !== 'number' || v < 0 || v >= this.objects.length) { throw new Error("Unknown pointer target"); } @@ -186,7 +186,7 @@ describe('common test suite', () => { const samples = decodeWithAnnotations(samples_bin, { pointerType: genericPointerType }); const TestCases = Record.makeConstructor<{ - cases: Dictionary + cases: Dictionary }>()(Symbol.for('TestCases'), ['cases']); type TestCases = ReturnType; @@ -196,48 +196,48 @@ describe('common test suite', () => { function D(bs: Bytes) { return decodeWithAnnotations(bs, { pointerType: genericPointerType }); } - function E(v: Value) { + function E(v: Value) { return encodeWithAnnotations(v, { pointerType: genericPointerType }); } interface ExpectedValues { [testName: string]: ({ - value: Value; + value: Value; } | { - forward: Value; - back: Value; + forward: Value; + back: Value; }); } const expectedValues: ExpectedValues = { - annotation1: { forward: annotate(9, "abc"), + annotation1: { forward: annotate(9, "abc"), back: 9 }, - annotation2: { forward: annotate([[], annotate([], "x")], + annotation2: { forward: annotate([[], annotate([], "x")], "abc", "def"), back: [[], []] }, - annotation3: { forward: annotate(5, - annotate(2, 1), - annotate(4, 3)), + annotation3: { forward: annotate(5, + annotate(2, 1), + annotate(4, 3)), back: 5 }, annotation5: { - forward: annotate( + forward: annotate( Record(Symbol.for('R'), - [annotate(Symbol.for('f'), + [annotate(Symbol.for('f'), Symbol.for('af'))]), Symbol.for('ar')), - back: Record, any>(Symbol.for('R'), [Symbol.for('f')]) + back: Record, any>(Symbol.for('R'), [Symbol.for('f')]) }, annotation6: { - forward: Record, any>( - annotate(Symbol.for('R'), + forward: Record, any>( + annotate(Symbol.for('R'), Symbol.for('ar')), - [annotate(Symbol.for('f'), + [annotate(Symbol.for('f'), Symbol.for('af'))]), back: Record(Symbol.for('R'), [Symbol.for('f')]) }, annotation7: { - forward: annotate([], Symbol.for('a'), Symbol.for('b'), Symbol.for('c')), + forward: annotate([], Symbol.for('a'), Symbol.for('b'), Symbol.for('c')), back: [] }, list1: { @@ -257,7 +257,7 @@ describe('common test suite', () => { function runTestCase(variety: Variety, tName: string, binaryForm: Bytes, - annotatedTextForm: Value) + annotatedTextForm: Value) { describe(tName, () => { const textForm = strip(annotatedTextForm); @@ -286,10 +286,10 @@ describe('common test suite', () => { } const tests = (peel(TestCases._.cases(peel(samples) as TestCases)) as - Dictionary); - tests.forEach((t0: Value, tName0: Value) => { + Dictionary); + tests.forEach((t0: Value, tName0: Value) => { const tName = Symbol.keyFor(strip(tName0) as symbol)!; - const t = peel(t0) as Record; + const t = peel(t0) as Record; switch (t.label) { case Symbol.for('Test'): runTestCase('normal', tName, strip(t[0]) as Bytes, t[1]);