Finitio 0.4.x

Imports

Since 0.4 a schema can be split across several files and pull definitions from elsewhere. An import is a line starting with @import, and imports come first, before any type definition:

@import finitio/data
@import ./measures

{ taken: Date, values: [Measure] }

The standard library

The most common import by far, and the one nearly every 0.4 schema starts with:

@import finitio/data

It brings String, Integer, Date and the rest into scope. See the standard library for what it contains and where the two implementations differ.

Relative imports

A path starting with ./ or ../ is resolved relative to the file the schema was loaded from:

@import ./measures
@import ../shared/units

Write the path without the .fio extension. The extension is added by the resolver, so @import ./measures.fio looks for measures.fio.fio and fails.

Relative to what?

A relative import needs to know where the schema came from, and a schema parsed from a bare string does not. Load it from a file instead:

# Ruby
require 'pathname'
system = Finitio.system(Pathname.new('schemas/parent.fio'))
// JavaScript
const world = Finitio.world({ sourceUrl: `file://${path}` })
const system = Finitio.system(fs.readFileSync(path, 'utf8'), world)

Passing the source as a plain string with no context raises an error such as Unable to resolve './measures'.

Imports are not re-exported

An imported type is usable inside the importing schema, but is not passed on to schemas that in turn import it. Given:

# child.fio
@import finitio/data
Posint = Integer( i | i >= 0 )
# parent.fio
@import ./child
Byte = Posint( i | i <= 255 )     # fine: Posint is in scope here

then a third schema importing parent sees Byte but not Posint:

@import ./parent
Byte      # fine
Posint    # error: No such type `Posint`

This keeps a schema's surface deliberate: what a file exports is what it defines, not everything it happens to depend on. If Posint should be part of the public surface of parent.fio, define an alias for it there.

Qualified imports

An import can be given a qualifier, so its definitions are reached through a prefix rather than merged into the current scope:

@import finitio/data as d

{ name: d.String }

Bundling

Imports are resolved when the schema is loaded, which means the files must be reachable at that moment. That is fine on a server and awkward in a browser, where there is no filesystem.