js.component v1.2.3

Welcome to js.component!

js.component is a 4D component comprising 40+ classes with 450+ functions that:

  • Brings several of the most popular and powerful JavaScript packages to 4D
  • Fills many holes in the 4D language
  • Dramatically improves the developer experience
  • Reduces method count, lines of code, and coding time
  • Provides multiple new ways to debug your code
  • Implements key object-oriented techniques that are not widely known in the 4D world

js.component is 100% pure 4D code, 100% preemptive-safe, and 100% guaranteed to make you a more effective, more productive and more happy programmer!

Why js.component?

js.component is not just a loose collection of unrelated utilities; it is an integrated framework that provides you with an entire programming system, from foundational low level utilities borrowed from other languages to world class modules ported from the JavaScript world.

js.component is both broad in scope and deep in functionality. Yet it has minimal impact on your existing projects — there are only ten methods that live in the global namespace! Every function has been carefully designed to provide maximum utility, flexibility, and ease of use.

Installation

NOTE

js.component requires 4D v19 R5 or later.

To install js.component, place it (or an alias/symlink to it) in the Components folder of your database, as you would any other 4D component.

js.component is not compiled so that you can see (and hopefully learn from!) the source code. If your host application is distributed in compiled form, you can open js.component as a project and compile it according to your preferred settings.

Initialization

It is recommended that you add the following lines early in the On Startup and On Server Startup methods (or to methods that are called by them):

// You should call this in the main application process before any other
// processes are started that might use DateTime.
DateTime()

// If you want to use js.component error handling, you MUST do this
// to synchronize error handlers with the host db.
_.setHostOnErrCall(Formula(ON ERR CALL($1)))

// If you don't want to see a debug alert when an uncaught error occurs
// (e.g. when you are running on Server), you should create your own
// uncaught error handler and set it here.
If (Application type=4D Server)
  _.setUncaughtErrorHandler(Formula(uncaughtErrorHandler($1)))
End if

Release notes

For a complete list of what has changed in each release, see the release notes.

Documentation conventions

This documentation follows the format and conventions of the new 4D documentation at developer.4d.comopen in new window, so it should seem familiar. Extensive links have been provided to make navigation easy.

The headers of the documentation (which includes function names) are searchable via the search box in the upper right of the page. On the desktop, pressing / or s focuses the search box.

Callables

Throughout this documentation you will see parameters with the type Callable. A Callable is any object that has both .call() and .apply() properties which are formulas. This is done primarily to allow you to use formulas interchangeably with functors when using js.component. Why use a Functor instead of a formula?

  • Functors are objects that can have properties. Thus they can maintain state and determine what This refers to when called.

  • The implementation of functors can be arbitrarily complex, whereas formulas are limited to a single line of code.

Interfaces

Some of the classes documented here are interfaces, which represent the shape of classes you will define to provide custom functionality. For example, the MochaReporterDelegate interface is not actually a class, but rather a description of the functions that a class must implement in order to be used as a delegate for the MochaReporter class.

Accessing js.component classes

Almost all of js.component’s functionality is provided by classes, along with a very small set of global methods. The publicly accessible classes are available via the .js namespace. For example, to instantiate an instance of the Error class, you would use:

$error:=cs.js.Error.new("Something went wrong")

Using js.component

js.component can broadly be split into several categories of functionality.

TIP

The Lodash class itself contains over 100 functions 🚀 covering a broad range of functionality. It is perhaps the best place to start exploring js.component.

DateTime

DateTime()
DateTime
DateTimeStatic

Errors

DBError
Error
RangeError
ReferenceError
SystemError
SyntaxError
TypeError

i18n

Locale()
Locale
t()
tc()

Language

Binder
Functor

Lodash

_()
lodash()
Lodash

Logging

console()
ConsoleTransport
LogFormats
Logger()
Logger
LoggerStatic
Transport
TransportDelegate

Mocha unit testing framework

ChaiBdd
ChaiAssertionError
MochaHtmlReporter
MochaMultiReporter
MochaReporter
MochaReporterDelegate
MochaRunner
MochaSuite
MochaTest

Singletons

instance()
registerSingleton()
unregisterSingleton()

Timing

Performance
Timeout
Timer

Utility

js_openMethod()
macro_commentBlock()
Regex

Class structure

The classes in this component use a few key object-oriented design patterns:

  • Singleton
  • Facade
  • Handle/implementation
  • Delegate
  • Class statics

Singleton

A singleton class is a class that is designed to be global, and thus have one and only one instance. The following classes in js.component are (or are designed to be) singletons:

ErrorHandler
Lodash and its private friend classes
LogFormats
Logger
LoggerStatic

You manage singletons with the methods in the Singletons category.

Facade

A facade class provides a single API to instances of other classes which provide the facade’s functionality. This allows the functionality to be split up into multiple classes, which can be tested and maintained independently, while still providing a single API to the user.

The Lodash class, for example, is a facade to multiple private classes.

Handle/implementation

A handle/implementation is similar to a facade in that the handle class provides a public API to an instance of the implementation class. Unlike a facade, however, the implementation class is provided by the user. Unlike a delegate, the implementation class provides the functionality of the handle class, rather than just providing a way to customize the behavior of the handle class.

The Functor class and its corresponding implementation class are an example of handle/implementation.

Delegate

A delegate class is provided by the user and serves to customize or augment a subset of the functionality of the parent class. Delegate classes in this documentation are always interfaces and the class name ends with "Delegate".

MochaReporter is an example of a class that uses MochaReporterDelegate as its delegate.

Class statics

In most object oriented languages, there are two types of class methods and properties: instance and static.

TIP

As in many other areas of the language, 4D’s terminology is, shall we say, “unique”: what it calls “methods”, almost every other language calls “functions”, and vice versa.

Instance methods and properties are accessed through individual instances of a class. Static methods and properties are accessed through the class object itself, which makes them global in nature.

4D unfortunately does not natively support static methods or properties. js.component works around this through the following convention:

  • For any given class Foo, a parallel class called FooStatic is created which contains “static” functions and properties.

  • A global method (what 4D calls a “method”) Foo is created which uses the instance() method to return a singleton instance of the FooStatic class.

To access the (pretend) static functions and properties on the Foo class, you would use this:

Foo.bar()
$baz:=Foo.baz

I call them “pretend” statics because if 4D supported native class statics, the code would most likely be like this:

cs.Foo.bar()
$baz:=cs.Foo.baz

js.component uses this trick for DateTime and Logger.

NOTE

You can add properties and functions to a class object in 4D, but they are ephemeral — they will be lost when any classes’ source is modified and 4D internally rebuilds the cs class store. This is why js.component uses a parallel “static” class to hold static properties and functions.

Last Updated:
Contributors: Aparajita