Skip to content

Latest commit

 

History

History
933 lines (646 loc) · 26.1 KB

CHANGELOG.md

File metadata and controls

933 lines (646 loc) · 26.1 KB

Changelog

All notable changes to this project will be documented in this file.

This project adheres to Semantic Versioning. The format of this changelog is a variant of Keep a Changelog. New entries must be placed in a section entitled Unreleased.

0.16.0 (2024-11-02)

  • BREAKING CHANGES: require Node.js 20.0.0 or above

    This allows us to use the built-in Node.js CLI parser and then to remove the Commander.js dependency. This reduces the standalone binary size from 77KB to 45KB (42%).

  • Support require(esm) in Node.js v22.10 and above

    This package now has the new exports condition module-sync. This allows users of Node.js v22.10 and above to import the ESM version of the package using require. This avoids the issues of dual-package hazard.

  • Remove package.json main and module fields

    The main and module fields supplemented by the exports fields. exports is supported since Node.js v12.7.0 Since we require Node.js v20.0.0 or above, we can safely remove main.

    All major bundlers now support exports. Hence, we can also remove the module field.

0.15.0 (2023-10-19)

  • BREAKING CHANGES: require Node.js 16.9.0 or above

  • BREAKING CHANGES: promote regular comments to doc-comments

    Previously, bare-ts introduced a special syntax for doc-comments:

    type Gender enum {
        ## Be inclusive :)
        FLUID
        MALE
        ## One is not born, but becomes a woman
        ##                  -- Simone de Beauvoir
        FEMALE
    }
    
    ## A Person with:
    ## - a name
    ## - a gender
    type Person {
        ## person's name
        name: str
        ## person's gender
        gender: optional<Gender>
    }
    

    This syntax is not part of the BARE specification. Thus, the syntax is not portable between BARE_ implementations. To avoid this issue, bare-ts_ now uses regular comments as doc-comments. Every comment that precedes a type definition, an enum value, or a field is a doc-comment. The previous schema can now be written as follows:

    type Gender enum {
        # Be inclusive :)
        FLUID
        MALE
        # One is not born, but becomes a woman
        #                  -- Simone de Beauvoir
        FEMALE
    }
    
    # A Person with:
    # - a name
    # - a gender
    type Person {
        # person's name
        name: str
        # person's gender
        gender: optional<Gender>
    }
    
  • BREAKING CHANGES: remove option --import-config

    Instead of importing a custom config, you can now pass the config through any encode function.

    For instance, using the example of the README:

    const payload = encodeContacts(contacts, {
        initialBufferLength: 256 /* bytes */,
        maxBufferLength: 512 /* bytes */,
    })

    A default configuration is applied if no one is passed:

    const payload = encodeContacts(contacts) // use the default config
  • BREAKING CHANGES: replace locations with offsets

    Previously, every node and compiler errors carried a loc or location property. A location object contained a filename, line, col, and offset properties.

    The filename property is now contained in the AST root in the property filename. loc and location are replaced by offset.

    The line and column numbers must now be computed using the offset.

0.14.0 (2023-06-19)

  • BREAKING CHANGES: enum member names in PascalCase instead of CONSTANT_CASE

    In a bare schema, an enum variant must be in CONSTANT_CASE:

    type Status enum {
        OPEN = 0
        CLOSE = 1
    }
    

    Previously, bare-ts preserved the case:

    export enum Status {
        OPEN = "OPEN",
        CLOSE = "CLOSE",
    }

    To follow the TypeScript convention, the case is now in PascalCase. Thus, bare-ts generates the following code:

    export enum Status {
        Open = "Open",
        Close = "Close",
    }
  • BREAKING CHANGES: remove option --import-factory

    Previously, bare-ts allowed external factory functions to build struct objects. For now, there is no replacement for this feature.

  • BREAKING CHANGES: remove option --use-quoted-property

    Previously, bare-ts allowed emitting JavaScript code with all object properties quoted. This feature was under-used and against the JavaScript conventions.

  • Fix name clashes

    Previously, bare-ts did not support the use of aliases like Map or Uint8Array. Now, it properly handles these aliases and uses globalThis when necessary.

0.13.0 (2023-02-20)

This release widely improves the usage of unions and flat unions.

  • BREAKING CHANGES: use strings tags for union of aliases

    Now, bare-ts outputs string tags for unions of aliases. You can obtain the previous behavior using the option --use-int-tag.

    The following schema ...

    type Person struct { name: str }
    type Organization struct { name: str }
    type Contact union { Person | Organization }
    

    ... generates the following types:

    export type Person = { readonly name: string }
    export type Organization = { readonly name: string }
    export type Contact =
        | { tag: "Person"; val: Person }
        | { tag: "Organization"; val: Organization }

    This makes code more readable and allows assignments between compatible unions.

    Using the option --use-int-tag, you obtain the previous output:

    export type Person = { readonly name: string }
    export type Organization = { readonly name: string }
    export type Contact =
        | { tag: 0; val: Person }
        | { tag: 1; val: Organization }
  • BREAKING CHANGES: use type alias as tag's value for flat unions of structs

    bare-ts allows flat unions of aliased structs. Previously, it used the type alias in underscore_case as tag's value. Now, it uses the type alias in its original case.

    For instance, the following union ...

    type BoxedU32 struct { val: u32 }
    type BoxedStr struct { val: str }
    type Boxed union { BoxedU32 | BoxedStr }
    

    ... can be flatten (under --use-flat-union) to:

    export type BoxedU32 = {
    -   readonly tag: "BOXED_U32", // Previous output
    +   readonly tag: "BoxedU32", // New output
        readonly val: u32,
    }
    
    export type BoxedStr = {
    -   readonly tag: "BOXED_STR", // Previous output
    +   readonly tag: "BoxedStr", // New output
        readonly val: string,
    }
    
    export type Boxed = BoxedU32 | BoxedStr
  • BREAKING CHANGES: split --use-flat-union into --use-primitive-flat-union and --use-struct-flat-union

    Use --use-primitive-flat-union and --use-struct-flat-union instead of --use-flat-union.

  • Flatten unions when possible under --use-primitive-flat-union and --use-struct-flat-union

    bare-ts is able to flatten unions that consist of:

    1. basic types (bool, u8, str, ...) that have distinct typeof values
    2. aliased structs
    3. (anonymous) structs

    Previously, use-flat-union required that all unions could be flattened. This avoided the introduction of a "best-effort approach". However, this was too restrictive. A "best-effort approach" seems acceptable since it is opted in. Now, bare-ts attempts to flatten a union and falls back to a tagged union.

    Under --use-struct-flat-union, the following schema ...

    type A union { bool | f64 | str }
    type B union { f64 | i32 }
    

    ... compiles to the following types:

    type A = boolean | number | string
    type B = { tag: 0; val: number } | { tag: 1; val: number }

    Note that B is not flatten because f64 and i32 have the same typeof value (number).

    Under --use-struct-flat-union, the following schema ...

    type X struct { ... }
    type Y struct { ... }
    type XY union { X | Y }
    type Z Y
    type XZ union { X | Z }
    type Anonymous union { struct { ... } | struct { ... } }
    

    ... compiles to the following types:

    type X = { tag: "X", ... }
    type Y = { tag: "Y", ... }
    type XY = X | Y
    type Z = Y
    type XZ = { tag: "X", val: X } | { tag: "Z", val: "Z" }
    type Anonymous = { tag: 0, ... } | { tag: 1, ... }

    Note that the union XZ is not flatten, because one of the elements is not a struct or an aliased struct. Indeed, Z is an aliased alias.

  • Support flat unions of aliased structs and anonymous structs

    Under the option --use-struct-flat-union, the following schema ...

    type Person struct { name: str }
    type Entity union {
        | Person
        # Anonymous entity
        | struct { name: str }
    }
    

    ... compiles to the following types

    export type Person = {
        readonly tag: "Person"
        readonly name: string
    }
    export type Entity =
        | Person
        | {
              readonly tag: 1
              readonly name: string
          }

    We introduce this change for consistency purpose. You should avoid mixing aliased structs with anonymous structs

0.12.0 (2023-02-04)

  • BREAKING CHANGES: emit TypeSCript's type aliases instead of interfaces

    The following schema ...

    type Person struct { name: str }
    

    ... compiles to a type alias instead of an interface:

    - export interface Person {
    + export type Person = {
          readonly tag: "Person"
          readonly name: string
      }
  • BREAKING CHANGES: Emit ES2020

    bare-ts now publishes ES2020 builds. This outputs smaller builds. This should cause no issue since we require a Node.js version ^14.18 or >=16.

  • Add option --lib to prevent decode and encode generation

    A decoder and an encoder are generated for every root type that doesn't resolve to void. The --lib flag prevents this generation.

    This is particularly useful for libraries that export only readers and writers.

  • Allow root types that resolve to void

    Since the 0.9.0 version, root types that resolve to void are forbidden.

    To conform with the BARE specification, they are now allowed. This makes valid the following schema:

    type Root void
    

0.11.0 (2022-07-06)

  • BREAKING CHANGES: Remove option --use-lax-optional

    This avoids breaking bijective encoding.

0.10.0 (2022-06-22)

  • BREAKING CHANGES: Forbid flat unions of transitively aliased classes

    Previously, bare-ts allowed flat unions of transitively aliased classes. It now rejects the following schema under the option --use-flat-union:

    type Named struct { name: str }
    type Person Named
    type Message union { Person }
    
  • BREAKING CHANGES: Require Node.js >=14.18.0

    This enables bare-ts to internally use node: prefixes for importing nodes' built-ins.

  • Automatically discriminate aliased structs in flat unions

    bare-ts is now able to add a discriminator field for aliased structs in flat union.

    The name of the discriminator field is tag. For now, it is not possible to flatten aliased structs with at least one field named tag.

    Thus, under the option --use-flat-union, the following BARE schema ...

    type X struct { ... }
    type Y struct { ... }
    type XY union { X | Y }
    

    ... compiles to the following types:

    export interface X { readonly tag: "X"; ... }
    export interface Y { readonly tag: "Y"; ... }
    export type XY = X | Y
  • Allow flat unions of anonymous structs

    bare-ts now accepts flat unions of anonymous structs. It automatically uses the union tags to discriminate the structs.

    Under the option --use-flat-union, the following BARE schema ...

    type XY union { struct { ... } | struct { ... } }
    

    ... compiles to the following types:

    export type XY = { readonly tag: 0, ... } | { readonly tag: 1, ... }

0.9.0 (2022-05-12)

  • BREAKING CHANGES: Rename bare-ts CLI to bare

  • BREAKING CHANGES: Rename --legacy-syntax to --legacy

  • BREAKING CHANGES: Remove options --main and --no-main

    The previous version introduced automatic promotion of root type as main type. Root type aliases are type aliases that are not referred by a type in the schema. Main type aliases are types aliases used to decode and encode messages.

    For the sake of simplicity, main type aliases and root types aliases are now identical.

    In the following schema, Post is the only root and main type alias.

    type Person struct { name: str }
    type Post struct { author: Person }
    
  • BREAKING CHANGES: Forbid use-before-definition

    In the last BARE draft, use-before-definition are disallowed. As a consequence, it also disallows recursive types. bare-ts now rejects the following schema:

    type Y X
    type X u8
    

    To enable this schema and recursive types, use the option --legacy.

  • BREAKING CHANGES: Forbid root types that resolve to void

    The following schema is now invalid:

    type Root void
    

    This is not part of the BARE specification.

  • BREAKING CHANGES: Do not emit read/write for types resolving to void

  • Annotate your schema with doc-comments

    A BARE doc-comment consists in two comment marks ##. Doc-comments can only document:

    • type definitions
    • enum values
    • struct fields

    The following schema documents these three kinds of object:

    type Gender enum {
        ## Be inclusive :)
        FLUID
        MALE
        ## One is not born, but becomes a woman
        ##                  -- Simone de Beauvoir
        FEMALE
    }
    
    ## A Person with:
    ## - a name
    ## - a gender
    type Person {
        ## person's name
        name: str
        ## person's gender
        gender: optional<Gender>
    }
    

    Note that this syntax is not part of the BARE specification. Thus, this is not portable between distinct implementations.

  • Add BARE code generator

    This gives a basic way to format a schema. Note that comments (except doc comments) are stripped out.

    bare-ts compile schema.bare -o schema.bare
    bare-ts compile schema.bare --generator 'bare'

0.8.0 (2022-04-29)

  • BREAKING CHANGES: Require @bare-ts/lib v0.3.x

  • BREAKING CHANGES: Forbid f32 and f64 as map key type

    According to IEEE-754 2019: NaN (Not a Number) is not equal to any value, including itself.

    This inequality leads to different implementations:

    1. Implementations that "follows" the standard

      An unbounded number of values may be bind to the key NaN and cannot be accessed. This is the implementation chosen by Golang.

    2. Implementations that normalize NaNs and consider that NaN is equal to itself

      This is the implementation chosen by JavaScript

    3. Implementations that rely on the binary comparison of NaNs

    These make complex the support of f32 and f64 as map key type.

    To avoid this complexity, the ongoing BARE draft forbids their usage as map key type.

  • Automatically promote root type as main type

    bare-ts generates encoders and decoders for main types. Main types can be selected with the option --main:

    bare-ts compile schema.bare --main Post
    # schema.bare
    type Person struct { name: str }
    type Post struct { author: Person }
    

    If the option --main is not set, then bare-ts promotes root types as main types. Root types are type aliases that are not referred by a type in the schema.

    In the previous schema, Post is a root type, while Person is not. The following command has now the same effect as the previous one:

    bare-ts compile schema.bare

    It promotes Post as a main type.

    To avoid the promotion of root types, you must use the option --no-main:

    bare-ts compile schema.bare --no-main

    --no-main and --main cannot be both set.

  • Allow leading and trailing pipes in unions

    The following schema is now valid:

    type LeadingPipe union {
        | u8
    }
    
    type TrailingPipe union {
        u8 |
    }
    
  • Do not emit trailing spaces in code generation

0.7.0 (2022-04-24)

  • BREAKING CHANGES: require Node.js versions that support ESM

    bare-ts requires now a node versions that support ECMAScript Modules.

    Note that, bare-ts still exports a CommonJS build.

  • Add pure annotations in generated code

    Pure annotations enable bundler to detect pure function calls. bare-ts adds now these annotations in top-level function calls.

  • Allow circular references where possible

    bare-ts was previously conservative about circular references. It now allows all circular references that can encode at least one finite message. It now accepts the following circular references:

    type A list<A>
    type B map<str><B>
    type C list<optional<C>>[2]
    type D list<union { D | str }>[2]
    type E optional<E>
    type F union { F | str }
    

    It still rejects the following circular references:

    type X list<A>[2]
    type Y union { Y }
    type Z struct { field: Z }
    

0.6.0 (2022-03-31)

  • BREAKING CHANGES: Update BARE syntax

    bare-ts now supports the new syntax for BARE schema It reports legacy syntax as an error.

    Use the option --legacy-syntax for allowing legacy syntax.

0.5.0 (2022-03-30)

  • Forbid circular references with fixed lists

    bare-ts now correctly rejects the following schema:

    struct Person {
        bestFriends: [2]Person
    }
    
  • Allow enums and aliased types for map key type

    The following schema is now valid:

    enum Gender {
        FLUID
        MALE
        FEMALE
    }
    type GenderNames map[Gender] string
    
  • Allow unsorted tags for unions and enums

    bare-ts now accepts the following schemas:

    enum Gender {
        FLUID = 1
        MALE = 0
               ^ error was reported here
        FEMALE = 2
    }
    
    type UnsignedInt (u8 = 1 | u16 = 0 | u32 = 2 | u64 = 3)
                                     ^ error was reported here
    

    Use the option --pedantic for rejecting these schemas.

0.4.0 (2022-03-26)

  • BREAKING CHANGES: Forbid main codecs resolving to void

    The following BARE schema is no longer valid when 'Message' is a main codec:

    type Message void
         ^ error is now reported here
    
  • BREAKING CHANGES: Forbid flat unions which cannot be automatically flatten

    bare-ts is able to automatically compute the tag of simple flat unions without any help. A simple union is either:

    • a union of base or void types that can be discriminated by their typeof value, or
    • a union of classes (requires the option --use-class).

    Previously, bare-ts asked the user to provide a tagging function for complex flat unions. Now, bare-ts throws an error when it encounters a complex flat union. Thus, it no longer supports complex flat unions.

  • Add pedantic mode (option --pedantic)

    The pedantic mode requires initializing enum tags and union tags.

  • Better code generation

    bare-ts has a normalization step where it alias some types, including anonymous structs, data arrays, and typed arrays. bare-ts is now able to generate reader and writer without aliasing these types.

0.3.0 (2022-03-02)

  • BREAKING CHANGES: Forbid BARE schema in which a union repeats a type

    Now, bare-ts correctly rejects the following schema:

    type X (u8 | u8)
    
  • BREAKING CHANGES: Default to null instead of undefined for optional types

    The use of null seems more common than the use of undefined.

    The option --use-null is removed. A new option --use-undefined is added.

  • Deduplicate readers and writers of complex non-aliased types

    bare-ts generates readers and writers for complex non-aliased types. These readers and writers are now deduplicated.

  • Make configurable the emitted type for void

    BARE allows void types in unions. For example:

    type Union (u8 | void)
    

    Previously, bare-ts emitted the type undefined for void. Now, it relies on options --use-undefined and --use-lax-optional to choose between null, undefined, and null | undefined. Note that these options also modify the emitted types for optionals.

  • Support for quoted properties

    The option --use-quoted-property enables to output quoted properties instead of unquoted properties.

    This can be useful when using a minifier that differently handles quoted properties.

0.2.0 (2022-02-20)

  • BREAKING CHANGES: Forbid BARE schema with undefined aliases

  • BREAKING CHANGES: Forbid BARE schema in which length and tags are too large

    Length of fixed data and (typed) array must be an unsigned 32bits integer. This is a limitation of the ECMAScript standard.

    Tags of enums and unions must be safe integers. In the future, this requirement could be relaxed by switching to bigint for larger integers.

  • BREAKING CHANGES: Forbid BARE schema in which the length of a fixed data is 0

    The following schema is now invalid:

    type EmptyData data<0>
    
  • BREAKING CHANGES: Forbid BARE schema in which a union repeats a type

    The following schema is now invalid:

    type X (u8 | u8)
    

    Note that the following schema is still valid:

    type Y u8
    type X (u8 | Y)
    

    Y is a user-defined type.

  • BREAKING CHANGES: Forbid enum members with the same name

    The following schema is now invalid:

    enum Gender {
        FLUID
        FEMALE
        MALE
        FLUID
    }
    
  • BREAKING CHANGES: Forbid struct that has several fields with the same name

    The following schema is now invalid:

    struct Person {
        name: string
        name: string
    }
    
  • BREAKING CHANGES: Forbid BARE schema with circular references

  • BREAKING CHANGES: adapt to @bare-ts/lib@0.2.0

    @bare-ts/lib@0.2.0 introduces several breaking changes. As a consequence:

    • all decode/encode are renamed into read/write
    • all pack/unpack are renamed into encode/decode
    • decoders (previously unpackers) no longer accept ArrayBuffer as type of read buffer
  • Make bare-ts library platform-agnostic

    Use your favorite ESM-ready CDN and simply import bare-ts. This was made possible by removing the dependency over node:assert.

  • Add --use-class option

    This generates classes instead of interfaces for struct types.

  • Automatically handle simple flat unions

    By default, bare-ts generates tagged unions. For instance, the following schema ...

    type Union (A | B)

    ... compiles to the following types:

    type Union =
        | { readonly tag: 0; readonly val: A }
        | { readonly tag: 1; readonly val: B }

    You can force the use of flat unions with the option --use-flat-union. However, you have to provide a function that computes the tag of the object. This function must be exported from a file named ext.{js,ts} and placed in the same directory as the file generated by bare-ts.

    export function tagUnion(x: A | B): 0 | 1 {
        // returns 0 if x has type A or 1 if x has type B
    }

    bare-ts is now able to compute the tag of simple flat unions without your help. A simple union is either:

    • a union of types that can be discriminated by their typeof value, or
    • a union of classes (requires the option --use-class).
  • Add @bare-ts/lib as peer dependency

    This informs the users of bare-ts which version of @bare-ts/lib to use.

  • Fix invalid code generation for big tags in enums and unions

    bare-ts applies an optimization when tags can be encoded on 7 bits. It did not test the general case yet. The addition of tests enabled to catch typo errors. The generated code imported non-existing readers and writers.

  • Fix generator choice

    The option --generator specifies which generator to use for generating the output. bare-ts uses ts as default generator. The option --generator should override this default.

    Previously, the option did not override the default.

  • Fix location report upon compilation errors

    Upon errors, bare-ts reports the error and a file location. It previously reported the location at the end of the first involved token. It now reports the location at the start of the first involved token.

    For instance, if a type alias is in lowercase in a BARE schema, then the parser reported an error at the end of the alias. It now reports the error at the start of the alias:

    type lowerCaseAlias u8
                      ^ error was previously reported here
         ^ error is now reported here
    
  • Better diagnostics for reporting unwanted semicolons

0.1.1 (2022-01-05)

  • Fix array encoders

    Previously, array encoders did not encode the first item of a generic array.

0.1.0 (2022-01-03)

  • BARE schema compiler supports all types