~kiito/bare-js

ref: 4bc58daa969ce2a73bd5a40123a707567b6c3de5 bare-js/README.md -rw-r--r-- 4.0 KiB
4bc58daa — Emma Implemented schema converter 7 months ago

#bare-js

This is a work-in-progress JavaScript/Node.js implementation of BARE.

The idea is, that the schema converter runs on node.js, while the resulting JavaScript classes should be usable both in the browser and in other javascript environments.

#What is still missing

  • Union type, this one is difficult to translate to js, so I'm going to have to think about use cases and how to make them convenient to use
  • Conversion error handling and integrity verification.
  • Unit tests, these will come last.

#How to use

#Schema converter

The converter located at converter/bare.js is a runnable node.js script, which takes two arguments: [input, [output]]. If one or both are not given, it will write to stdout, and read from stdin respectively. For now the output is barely formatted, each type gets its own line, some whitespace is added for legibility.

Something to be aware of, is that JavaScript does not like to access a class which is only instantiated later on in the source. Should you define a type and plan to use it in other types, make sure its definition comes before any usage, either in the schema, or by reordering the lines in the output. JS will complain if you do otherwise.

I am thinking about trying to reorder the types in code, but circular dependencies will always need manual intervention, and might not work in JS either way. It would be nice to have, but is rather low priority.

#Resulting module

The output from the converter is a file which only works in conjunction with library/bare.mjs. This file contains all the message conversion logic, whereas the conversion output contains the layout specifics of the types you specified in your schema file.

My default these two are to be used as ES6 Modules. The benefit of this is, that you do not need to have any of the hidden classes in your scope, since they are only needed in the type definitions of the second file. Most browsers support this spec, and so does node.js, if the files end in .mjs.

Should your environment not support this feature, or you don't want to use modules, you can full well remove the import and export statements, and load the two files like regular scripts. (I'm not 100% on this, but you can probably even leave them in)

#Now to the actual how-to for using this in a web page:

If you want to use a bare type in your main.js script file, you need to load it as a module: <script type="module" src="main.js"></script>. The basic gist is, that modules do not share a scope, but read the MDN article above for more details.

Then in this file you can use an import statement to either load all your types in an object: import YourName from './path/to/output.js';. Just make sure that the library/bare.mjs file is in the same folder as the output, or edit the import statement to match its location.

Or you can only load some types directly into your scope: import {Address, Point} from './path/to/output.js';. You can even rename them with Type as OtherName inside those brackets, should that matter in your use case.

#A note about Number and 64 bits

Javascript is a wonderful language, and as such it doesn't use an integer type for numbers. Instead, every single number is stored as a double precision float. This limits the usable range of integers to 53 bits, which means the maximum unsigned value is just over 9 quadrillion (10^15).

There is the BitInt type that allows arbitrary large integers. But it has limitations; you can't use them in Math functions or beside regular Numbers. Keep this in mind when using the variable length, and the 64 bit integer types, since these return a BigInt by default.

The lib provides safeNumber which will convert a BigInt to Number if it fits into 53 bits, or throw an Error if it does not fit, for when you just need a little more headroom.