Skip to content

Releases: mint-lang/mint

0.12.0

13 Apr 08:23
Compare
Choose a tag to compare

This release brings language server support and asset handling to Mint!

Language Server 🎉

One of the highly requested features the language server is now available using the mint ls command.

Having this shipped allows us to incrementally implement other features such as showing errors and goto declaration / implementation.

Format on save

The files are formatted when saved if they don't contain any errors.

format-on-save

Hover Provider

The type information of most entities can be checked by hovering over them also, if available the documentation is displayed as well.

hover

Completion

Completions are provided for entities in stores, components, modules and also in scope variables (depending on where to cursor is).

completion

New App Template

A new application template has been implemented!

App Template

Language Features

The asset directive was implemented also support for constants in tests.

Asset Directive

The asset directive allows you to reference an asset (image, stylesheet, video, etc..) - relative to the current file. These assets are bundled in the production build.

component Main {
  fun render : Html {
    /* The image should be in the same directory as this file. */
    <img src={@asset(some-image.jpg)}/>
  }
}

Only those assets get bundled which are touched during type checking, for example if a component references some assets then those assets are only bundled if that component is used.

Constants in Tests

Constants can now be used in tests:

suite "Some tests" {
  const VALUE = "Hello"

  test "Constant equals Hello" {
    VALUE == "Hello"
  }
}

Runtime

  • Fixed Preact to 10.4.4 (last known working version).
  • Don't use shouldComponentUpdate in components #316.
  • Normalize dataTransfer and clipboardData fields in events.
  • Properly resolve page position after navigation (hash jump, scroll to top).
  • Don't handle links that point out of the current frame.

Formatter

  • Implemented missing CSS keyframes formatter.
  • Properly format Html body when there are only comments inside.
  • Open modules now format properly (not duplicating entities).
  • Format Html body properly if it's children has new lines.
  • Format inline functions as multiline if they contain new lines.
  • Format state statements as multiline if appropriate.

Housekeeping

  • Crystal 1.0 compatibility.
  • Builds now use the latest crystal version.
  • #375 Contribution guide has been updated (@itsgreggreg).
  • #383 Github actions has been improved (@Sija).

Standard Library

  • Added Map.fromArray.
  • Added String.wrap.
  • Added String.indent.
  • Added String.indentWithOptions.
  • Added Time.nextWeek.
  • Added Time.previousWeek.
  • Added Function.debounce1.
  • Added Html.Portals.Head component.
  • String.parameterize now converts titlecase to dash case.
  • Window.isActiveURL now ignores search (query) parameters and the hash.
  • Window.open now works again #390.
  • Make sure the copy clipboard function does not scroll the page.

Minor changes / fixes

  • Use Array(Char) instead of String in the parser which speeds up parsing in some cases.
  • #385 Rename manifest.json to manifest.webmanifest (@jonathanoberg).

Fixed issues

  • #371 Case does not unify branches which can lead to unexpected behaviour.
  • #372 Make sure that module functions are resolved in the proper scope.
  • #373 Convert string literals in CSS values to string unless they contain interpolations.
  • #376, #358 Make sure that error messages render properly.
  • #381 Try now can return a result directly (@itsgreggreg).
  • #366 Gracefully shut down the test runner in case of uncaught exceptions in JavaScript (@Sam647254).

0.11.0

07 Jan 13:51
Compare
Choose a tag to compare

This release focused on bug fixes, although there are some new language features.

Language Features

Regular Expression Literal #250

Mint now supports regular expression literals:

Regexp.match("abbc", /ab+c/i) == true

Open Modules #265

Modules now can be defined in multiple places allowing to define constants and functions.

module Greeter {
  fun greet (name : String) {
    "Hello #{name}!"
  }
}

module Greeter {
  fun greetPolitely (name : String) {
    "Have a nice day Mr. #{name}!"
  }
}

This is mostly useful if you want to extend a module in the standard library (like Array).

Or operator

Added the or operator as an alias to Maybe.withDefault:

Maybe.withDefault("Hello", Maybe::Just("Value")) /* "Value" */
Maybe.withDefault("Hello", Maybe::Nothing)       /* "Hello" */

Maybe::Just("Value") or "Hello" /* "Value" */
Maybe::Nothing or "Hello"       /* "Hello" */

[] access on tuples

It is now possible to use [] on tuples:

{"Name", "Joe"}[0] == "Name"

Only literal numbers are valid since it's the only way we can only determine the type.

Formatter

  • Format the type signature of the inline JavaScript if given.
  • Format the type signature of an array literal if given.

Housekeeping

  • Moved the CI from Travis to Github actions.

Standard Library

  • #288 - Added API wrapper for DataTransfer and added dataTransfer to Html.Event.
  • Added return types to all functions @s0kil
  • Added Array.uniq

Minor changes / fixes

  • Fixed compiling of calls when the expression is an anonymous function.
  • Fixed compiling of referenced html elements.
  • Compile empty HTML fragments as nil.

Fixed issues

  • #249 #319 - Disallow referencing other entities from the same top level entity in the default value of a state or property.
  • #277 - Added clean command to delete compiler and package artifacts @s0kil
  • #278 - Format code from STDIN if --stdin flag is passed @s0kil
  • #302 - Added error message for ambiguous pipe operators
  • #305 - Allow parsing string literals in css definitions
  • #317 - Throw error when record does not have a record definition @s0kil
  • #320 - Set manifest.json as relative path when --relative flag is set @s0kil
  • #326 - Refactor encoding to be explicit
  • #327 - Confusing error when trying to add styles to custom components @matthewmcgarvey
  • #330 - Make sure inlined variable names are not conflicting with generated ones
  • #332 - Add the record type as the last parameter in record constructor functions
  • #338 - Allow trailing comment in record definitions.
  • #339 - Better error message for NextCallStateTypeMismatch @s0kil
  • #341 - Update documentation viewer to handle inferred types @s0kil
  • #349 - Allow prefixing CSS classes using mint.json

0.10.0

13 Sep 09:47
a95a27d
Compare
Choose a tag to compare

Language Features

Providers

Providers got overhauled in this release, it is possible to write a provider entirely in Mint.

Providers now work like stores they can have states, constants and getters, the next keyword can also be used.

All providers need to implement the update function which is called any time the subscriptions for that provider change. This allows changing the state accordingly, for example by adding or removing event listeners from entities (window, document, etc...)

If you are curious about them you can check the currently available providers here: https://github.com/mint-lang/mint/tree/master/core/source/Provider

Directives

This release adds the @svg, @format and @documentation directives.

Directives are processed at compile time. They interact with entities both in the code or outside of them (for example files).

The @svg directive embeds the SVG at the given path (relative to the file) as Html so it can be used directly in components.

<div>
  <{ @svg(../path/to/file) }>
</div>

The @format directive returns the formatted string version of the code it's given and the result of the code in a tuple Tuple(a, String). This is created to make it easy to display a simple example of Mint code:

try {
  {result, code} =
    @format {
      <div>
        "Hello There!"
      </div>
    }

  <div>
    <{ result }>

    <pre>
      <code>
        <{ code }>
      </code>
    </pre>
  </div>
}

The @documentation directive compiles the JSON documentation of the given entity into the resulting JavaScript code so it can be used to display information about the entity.

record Component {
  name : String
}

try {
  decoded =
    decode @documentation(Main) as Component

  decoded.name
}

Enums

Enums now can have named parameters:

enum Item {
  Link(name : String, href : String)
}

Item::Link(name = "Home", href = "/")

This way there is no need to define a record for an enum item.

Html

  • Html expressions can now be used for attributes:

    <Field label=<{ "Hello" }>/>
  • Html expressions can now be used as expressions:

    try {
      label =
        <{ "Hello" }>
    
      <Field label={label}/>
    }
  • Html expressions now supports multiple expressions (without needing Html expressions):

    <{
      "String"
    
      <div>
        "Hello"
      </div>
    
      if (Html.isNotEmpty(content)) {
        content
      } else {
        <{}>
      }
    }>

Record Update

Record update now supports updating the result of an expression instead of just
updating a record pointing to a variable:

{ { a = "b" } | a = "x" } # { a = "x" }

Constants

  • Constants are now compiled into properties with static value instead of a
    property getter.
  • Constants now can have numbers in them: const SOME_CONSTANT_01 = "A"

References

Component and DOM element references are property returning a Maybe.

Formatter

  • Multiple operations can now be forced to format into multiple lines:

    "Hello" == "True" &&
      "a" == "b" &&
      "c" == "d"
  • Case branches can now be forced to format as multiple by placing the expression in a new line:

    Maybe::Nothing =>
      "Hello There!"
  • Constants can now be forced to format as multiple by placing the expression in a new line:

    const HELLO =
      "Hello There!"
  • Html elements with only a string child will now be formatted in one line:

    <div>"Hello There!"</div>
  • Html fragments and Html expressions are formatted more consistently

CSS

Added the following properties:

  • overscroll-behavior
  • overscroll-behavior-x
  • overscroll-behavior-y

Standard Library

In this release there are a lot of additions to the standard library.

Added

  • Array.findByAndMap
  • Dom.getElementsBySelector
  • Dom.containsMaybe
  • Dom.setAttribute
  • Dom.getTagName
  • Dom.getChildren
  • Dom.getTextContent
  • Dom.getActiveElement
  • Dom.blurActiveElement
  • Dom.getTextWidth
  • Dom.getFocusableElements
  • Dom.focusFirst
  • Dom.smoothScrollTo
  • Dom.scrollTo
  • Dom.getClientWidth
  • Dom.getClientHeight
  • Dom.getScrollLeft
  • Dom.getScrollWidth
  • Dom.getScrollTop
  • Dom.getScrollHeight
  • Dom.getTableOfContents
  • Html.isNotEmpty
  • Map.entries
  • Promise.never1
  • Promise.never2
  • Promise.never3
  • Promise.create
  • String.isNotEmpty
  • String.isBlank
  • String.isNotBlank
  • String.dropLeft
  • String.parameterize
  • Test.Context.spyOn
  • Test.Context.assertFunctionCalled
  • Test.Context.assertFunctionNotCalled
  • Window.alert
  • Window.isActiveURL
  • Window.triggerHashJump
  • Window.addEventListener
  • Window.addMediaQueryListener
  • Window.matchesMediaQuery

Changed

  • String.isAnagarm -> String.isAnagram
  • Http.sendWithID -> Http.sendWithId
  • Test.Html.assertCSSOf -> Test.Html.assertCssOf
  • Dom.getAttribute now returns Maybe(String)
  • Map is now using arrays for the implementation #268
  • Set is now using arrays for the implementation #268

Fixed

  • Dom.getElementFromPoint no longer results in a runtime error
  • Dom.getAttribute no longer results in a runtime error

Web Api Wrappers

  • WebSocket - #285 #276
  • AnimationFrame
  • MutationObserver
  • ResizeObserver
  • IntersectionObserver

New Providers

  • Provider.ElementSize
  • Provider.Intersection
  • Provider.Keydown
  • Provider.Keyup
  • Provider.Mutation
  • Provider.OutsideClick
  • Provider.TabFocus
  • Provider.Url
  • Provider.WebSocket

New Modules

  • Validation

Minor fixes

  • Fix formatting of a global component with a comment
  • Fix formatting of constant access
  • Fix an issue of generating wrong CSS
  • Fix formatting of number literals #263 #247
  • Make sure Tuple(Bool) can be destructured in case branches
  • CSS definitions can now have numbers in them
  • The format command now formats using the given pattern
  • The Main component cannot have properties and will result in a type error
  • Updated scaffolding of a new project to include a head file

Fixed issues

  • #241 - Array destructuring conflicting with array access
  • #242 - Required property does not generate a type checker error
  • #243 - Emit compilation error message to the CLI for mint start
  • #248 - Serve Documentation Assets With Proper Content Type
  • #295 - Error message text does not fit in its container
  • #252 - Not enough context in required props error
  • #247, #263 - Mint formatting of Numbers doesn't round-trip
  • #271 - Add entries to Map

0.9.0

06 Apr 06:01
Compare
Choose a tag to compare

This release contains 67 commits from 7 contributors 🎉

Type system changes

There are several improvements relating to the type system (#216)

  • the return type signature of a function is now optional
  • the type signature of a computed property is now optional
  • the type signature of a property is now optional
  • the type signature of a state is now optional
  • the type of an arrays items can be specified using the of keyword
  • the type of an inline javascript can be specified using the as keyword

CSS features

Added support for @font-face, @supports, @keyframes rules #166 #238

Changes / Additions

  • fix whitespace parsing in list type nodes #232
  • added record constructors #191
  • it is now possible to pipe into any expression #228
  • the default value of a property is no optional #132
  • config option to turn off generation of icons #224
  • add Array.min, Array.max now returns Maybe(Number) #229
  • when running mint start if default port is taken, allow return (with no explicit Y) to start dev server
  • fixed exhaustiveness check for case which contains array destructuring #225
  • print alternative link when starting a server if it's different # 230
  • added String.toArray and String.fromArray #178
  • change failing test indicator from red dot to red "F"
  • add Mint::VERSION constant shelled-out to shards version

Special thanks to @Sija for doing an overall code review and many refactors and optimizations.

0.8.0

13 Mar 08:21
Compare
Choose a tag to compare

This release contains 122 commits from 6 contributors 🎉

🚧 Breaking changes 🚧

  • Mint now uses Preact instead of React (this should not break anything though) which will result in smaller compile files.

  • External assets are now handled differently:

    • stylesheets are now supported as well
    • javascripts and stylesheets are now compiled into their own file
    • more information in issues and PRs: #151 #155 #183
  • CSS rules whith multiple selectors are now compiled separately f2eab4b:

    div,
    p {
      color: red;
    }

    now compiles as:

    div {
      color: red;
    }
    
    p {
      color: red;
    }

Additions

  • Implemented constants for stores, components and modules #194

  • Implemented unary minus expression #201

  • Implemented tuples #209

  • Implemented array destructuring #210

  • Allows inline functions to be called recursively #181, #199

  • Added more functions to the core library:

    • Clipboard.set
    • FileSize.format
    • Provider.MediaQuery
    • Provider.Resize
    • Provider.Shortcuts
    • Dom.containedInSelector
    • Dom.getAttribute
    • Dom.setStyle
    • Dom.focus
    • Dom.getElementFromPoint
    • String.trim
    • String.withDefault
    • Window.prompt
    • Window.open
    • Window.getScrollbarWidth
    • Maybe.andThen #197
    • Math.random #190

Fixes and other changes

  • Show error for formatter if the pattern is invalid #157
  • Format files in both source-directories and test-directories #158
  • Allow underscores in environment variable names
  • Fixed an issue when media query provider triggering events for non subscribers
  • Fixed String.trim
  • Fixed Time.range because of DatFNS update
  • Fixed an error when rendering HTML errors on WSL
  • Fixed an issue of resolving function type definitions #212
  • sequence and parallel reserved variable names #185
  • Make host:port configurable for test server #207
  • Show more context for the missing closing tag syntax error #213
  • Display more relevant errors for property and state if the type is a record without definition #188

0.7.1

13 Dec 12:43
Compare
Choose a tag to compare

Update code for Crystal 0.32.0

0.7.0

09 Dec 08:15
Compare
Choose a tag to compare

Global components

Components can be prefixed with the global keyword, this will add them to the DOM automatically and it's methods can be called the same way as a store or module.

It is useful for components that only need one instance in the application,
like modals and notifications:

global component AlertModal {
  state shown : Bool = false

  fun open : Promise(Never, Void) {
    next { shown = true }
  }

  fun close : Promise(Never, Void) {
    next { shown = flase }
  }

  style base {
    position: fixed;
    bottom: 0;
    right: 0;
    left: 0;
    top: 0;
  }

  fun render : Html {
    if (shown) {
      <div::base> 
        <p>
          Are you sure?
        </p>

        <button onClick={close}>
          Ok
        </button>
      </div>
    } else {
      <></>
    }
  }
}

/* Later on somewhere else */
AlertModal.open()

Statically compiled components / HTML

In this release the compiler will detect components and HTML fragments that are essentially static, meaning that subsequent renders would always result in the same virtual DOM structure.

These fragments and components will be cached so to speak, they will only rendered once and get reused after that.

To give you an example, the following component will only be rendered once and is reused after that:

component Icons.Checkmark {
  fun render : Html {
    <svg>
      /* The svg data */
    </svg>
  }
}

component Main {
  fun render : Html {
    <div>
      <Icons.Checkmark/>
      <Icons.Checkmark/>
    </div>
  }
}

New Features

  • Allow omitting else branch of if in HTML
  • Added command to generate the documentation in JSON format
  • Allow "&" for attributes and classes (CSS)
  • Allow embedding the Main component without taking over the body

Miscellaneous

  • Updated documentation of some functions

Bugfixes:

  • Fix compiling of multiple sytles with parameters.
  • Fix compiling of interpolations in css values
  • Properly merge ifs and cases in a style and preseve their order
  • Allow creating records for nested records in encode
  • Don't catch and unbox values from the last returning result in a try expression.
  • Make sure we scope to the entities correctly.

0.6.0

30 Oct 11:42
Compare
Choose a tag to compare

Breaking Changes

  • References of elements and components now return a Maybe
  • Remove pre defined global styles from the generated HTML #125
  • Type variables are not allow in component properties and records
  • Record definitions are needed for records except records for encode

New Features

  • Improvements for the style tag #140 #128
  • String interpolation #141
  • Implemented member access function for records:
    object = Maybe::Just({
      name: "Joe"
    })
    Maybe.map(.name) /* Maybe::Just("Joe") */
  • Implemented safe operators (&. and &() for dealing with Maybe in specific cases:
    Maybe::Just({ name: "Joe" })&.name /* Maybe::Just("Joe") */
    Maybe::Just(() : String { "Joe" })&() /* Maybe::Just("Joe") */
  • Implement static and runtime type checking for route parameters #134

Changes

  • Add chromium as recognized executable name for test runner #116
  • Allow namespaces in HTML attributes #119
  • Allow string style attributes on elements
  • Allow function recursion by using it's static type definition
  • Allow decoding time from a number (unix timestamp) #137
  • Allow decoding Object as itself
  • Parenthesize JS interpolated values to avoid confusion #135
  • Serve files from baked files and public folder with right mime types #129
  • Don't generate links for icons if there aren't any #126
  • Replace native Maybe and Result implementations with enums #133
  • Use static recrod of a component when accessing it as a ref

Bugfixes:

  • Fix formatting of multiline strings #129
  • Fix readonly attribute compiling
  • Fix crash with remainder % operator

Core

  • Added Array.sumBy
  • Added Array.sum
  • Added Dom.focusWhenVisible
  • Added Dom.contains
  • Added Number.format
  • Added String.replace
  • Added Test.Html.assertActiveElement
  • Added Set.size
  • Fix some Set functions
  • Fix Time.month and Time.year comment
  • Fix Array.indexBy by adding tests and using interpolation

0.5.0

15 Apr 06:44
Compare
Choose a tag to compare
0.5.0 Pre-release
Pre-release

JavaScript output optimizations

All generated JavaScript code is now optimized in the following way:

  • top level entity names are now mangled (Components, Stores, Modules, etc.)
  • entity level names are now mangled
  • white space is removed from the generated code (build only)
  • the CSS selectors and variables are now mangled

This change means that inlined JavaScripts no longer can access arguments by name.

This will result in a runtime error because the argument message is mangled:

fun log (message : String) : Void {
  `console.log(message)`
}

To fix this we need to interpolate the argument:

fun log (message : String) : Void {
  `console.log(#{message})`
}

Calls on expressions

Previously the calls to functions were implemented in two forms: call on a
variable and call on a module function.

This meant that calling a function which
is in a record or which is a result of a function call were not possible.

This release makes it possible to make a call on the result of an expression.

This is an example which raises in error in 0.4.0 but compiles properly in 0.5.0:

module Test {
  fun a (message : String) : Function(String) {
    () : String => { message }
  }

  fun b : String {
    a("Hello")()
  }

  fun c : String {
    try {
      record = {
        function = (message : String) : String => { message }
      }

      record.message("Hello")
    }
  }
}

Partial Application

Functions now can be partially applied by calling them with less arguments than
needed.

An example of using partial application:

/* Format a number by thousands, output: 1,000,000 */

"1000000"
|> String.split("")
|> Array.groupsOfFromEnd(3)
|> Array.map(String.join(""))
|> String.join(",")

/* 
  The argument String.join("") (to Array.map) is a partially applied function
  where it's type is Function(Array(String), String)
*/

Warning for unknown CSS properties

CSS properties are now checked against a list and will result in an error if
they are not in the list.

Changes

  • Fixed array access ([]) when an expression is used as an index
  • Default values of properties are now only calculated once when the component is initialized
  • Providers can now be accessed the same a stores, or modules for introspection
  • Records now can be created without type definition. Such records have a temporary type definition created for them during type checking
  • [Runtime] Functions are bound to components and modules only once (in the constructor) instead of using .bind every time they are called

Formatter

  • Inline functions can now be forced to format the body on a new line by adding
    a line break after the opening bracket {
  • Properties can now be forced to format the default values on a new line by
    adding a line break after the equal sign =
  • Added missing formatter for array access ([])

Core

  • Added Array.groupsOfFromEnd which is the same as Array.groupsOf but grouping from the end
  • Added Array.indexBy to get an items index by a function
  • Added Http.requests for inspection purposes
  • Added String.rchop
  • Added String.lchop
  • Html.Event is now wrapped in an actual record, so it can now be safely used in sequence or parallel expression

0.4.0

23 Feb 11:27
Compare
Choose a tag to compare
0.4.0 Pre-release
Pre-release

Breaking Changes

  • Removed => from inline functions
  • mint-core package is now included in the binary (no longer needed as a dependency)

Features

  • Added --skip-service-worker flag to skip generation of service worker #96
  • Added for expression to allow iterating over some types #110
  • Added ability to expose an item of a store with a different name (connect X exposing { y as z })
  • Added formatter-config field in mint.json to allow setting indent-size #10
  • Implemented language feature for loading environment variables using the @VARIABLE syntax
  • Implemented Dead Code Elimination #98
  • Implemented JavaScript interpolation using the #{...} syntax
  • Implemented referencing childen of a component #108
  • Allow passing Map(String, String) to the style attribute of an element.

Bugfixes / Improvements

  • Raise proper exception when parsing type. #95
  • Allow hash to be matched in routes #101
  • Allow whitespace at the end of parameter list of inline function
  • Allow whitespace between parentheses of if condition #100
  • Allow functions without the event parameter to be passed to event attributes.
  • Added progress bar about parsing files in the CLI
  • The type checker now checks for naming conflicts of Types and Enums
  • Added formatter for array access.
  • Automatically break connect exposes if there is at least new line between them.
  • Don't automatically split long strings only if they are split at least once.