Technical Document

KFoundation JavaScript API User Guide

2020-09-18 v0.2 Author: "K"

Introduction

KFoundation is a library of essentials for modern programming needs, mostly concerning semantics of data exchange. For example, the (de)serialization module can read and write objects from and to XML, YAML, JSON, and K4 out of the box, and can be extended for more. KFoundation is designed based on the concept of universality, both in technological and geographical senses. It is available on most platforms; it has a very small footprint with no dependency on third-party libraries, and it is highly optimized for CPU and memory usage so that it works smoothly on small devices. It natively supports UTF-8 (as opposed to the host platform's string format), and comes with a rich internationalization toolset.

Other than JavaScript, KFoundation is also available for Scala, Java, and C++. The JavaScript version is just a stub that delegates its functions to an unerlying Scala code which is compiled using Scala.js. If you are considering Scala.js for your project, you are better off linking directly against our Scala.js distribution on Maven Central Repository. See the README.md file for instructions.

In this guide, we are going to see how to obtain, link against, and use KFoundation's JavaScript API.

About Coding Convention — Although it might look alien to some JavaScript developers, we are in favor of immutabilty, and to that end, we use the newly available const keyword as often as possible, and use ALL_CAPS notation to differentiate immutable values from the rest.

Obtaining JavaScript Distribution

KFoundation JavaScript API is distributed through npm registry (here). If you do not have npm yet, you need to install it with Node Version Manager (NVM). See this guide for details.

If your are already working in the Node.js universe, you only need to add a require() call to your source code as you might naturally do, and the library will be downloaded and linked if and when necessary.

const KF = require("kfoundation");

Otherwise, you can download the files using command line:

> npm i kfoundation

Serialization API

KFoundation can serializer/deserialize values to and from virtually any format. Reading and writing to and from JSON, XML, YAML, and K4 is provided out of the box. The latter is a compact and strongly-typped format native to KFoundation (K4 stands for [K]Foundation [For]mat). Support for other formats can be added via 3rd party libraries, if available. Unlike most other solutions, KFoundation deserializers generate native objects directly from raw input stream without creating a DOM. This leads to a significant improvement in CPU usage and memory footprint. But, it requires the structure of the object being read to be known before receiving the stream. But this is trivial in most modern object-oriented languages.

Understanding KFoundation Serialization System Architecture

The reason for dextrity in (de)serializaiton in KFoundation is due to a seperation-of-concerns that is placed at a stratigic point. On one side, there are object serializers and object deserializers which are specialized in translating a raw stream into an object stream, namely, a stream of obejct-specific tokens, such as begin-object, end-object, property-name, etc. On the other side there are value readers and value writers which are specialized in understanding the structure of data types and how to traverse an object stream according to that structure.

In summary, usage of KFoundation serialization system involves defining a reader, or a writer, or both, that are bound to the structure of the desired data type, and interfacing them to the serializer/deserialier of the desired data format.

About JavaScript API Design — There is an important fact about JavaScript that we have to understand and work with. And, that is the fact that it is not a class-based object-oriented language. It is a prototype-based one. This means, the class keyword in merely a synthetic sugar and has little significance as to how the language works; and (2) nothing about the structure of an object can be determined before it is instantiated. So that KFoundation can skip DOM creation, it needs to know the structure of the object to be materialized in advance. On JVM platform, class structure can be easily obtained using reflection. In JavaScript, however, we can only have a prototype, which is not always available nor necesserily reliable since it can change dynamically.

Creating Read-Writers

A value read-writer is an object that can both read and write values of a certain type. Given the nature of JavaScript, there is no need to create readers and writers separatedly. Therefore, we always make read-writers. For the reason expalined above, KFoundation offers an alternaitve way for creating read-writers by defining strongly-typed data structures. It might look a bit cumbersome, but the resulting type-safety and performance makes it worthwhile. To get started, first, obtain a reference to ValueReadWriters for your convenience.

const KF = require("kfoundation");
const R = KF.ValueReadWriters;

Now, R contains read-writers for basic JavaScript types, namely, NUMBER, STRING, and BOOLEAN, plus ofObejct() function which is the star of the show. Here is how to use it:

const A_RW = R.ofObject("A", {
    "a1": R.NUMBER,
    "a2": R.STRING
});

What the above code is saying is that, A_RW is a value read-writer that can process objects of type A, and the type in question consists of two fields named a1 which is a number, and a2 which is a string. You can go ahead and create more complex read-writers using the ones that you already have.

const B_RW = R.ofObject("B", {
    "b1": R.BOOLEAN
})

const C_RW = R.ofObject("C", {
    "c1": A_RW,
    "c2": B_RW
})

How about arrays? Close your eyes and make a wish, and there it is:

const C_ARRAY_RW = R.ofArray(C_RW);

Deserialization

To parse a string of a given format one only needs to call the read() function of the appropriate read-writer and supply it with a deserializer of the desired format together with the input string. The following example parses a K4 string into a JavaScript object of type C as defined above.

let input = "C[c1=A[a1=123.45 a2=\"abc\"] c2=B[b1=false]]"
let c = C_RW.read(KF.Deserializers.K4, input)

Replace K4 in the second line with XML, JSON, or YAML to achieve the same effect for those format.

Serialization

This process is very simliar to deserialzing, only the reverse. For example, the following will convert the value c we obtained from K4 earlier, to YAML.

console.log(C_RW.write(KF.Serializers.YAML, c))

Result:

C:
  c1:
    a2: "abc"
    a1: 123.45
  c2:
    b1: false

Again, replace YAML with JSON, XML, or K4 to achieve the same effect for those formats.

Upcoming Moduels

If you are reading this, then congradulations and thank you for your interest in an early, partial release of KFoundation. There are more modules planned to be added in the near future. Please stay tuned.

See Also