This package has been deprecated

Author message:

Replaced by @doodad-js/core.

doodad-js

8.0.0 • Public • Published

Object-oriented programming framework for Javascript.

NPM Version

<<<< PLEASE UPGRADE TO THE LATEST VERSION AS OFTEN AS POSSIBLE >>>>

Features

  • Classes (not ES6's ones)
  • Inheritance and Composition
  • Interfaces (and Mix-ins and Traits)
  • Class extenders
  • Method and attribute scopes (public, protected and private)
  • Base classes and interfaces
  • Expandable objects (these objects can be extended like a class)
  • Custom events management
  • DOM events management
  • NodeJs events management
  • Exceptions
  • Singletons
  • Polymorphism
  • Static classes
  • Useful utility functions
  • Namespaces and a registry
  • Compatible with most recent browsers and NodeJs.
  • Compatible with Windows, Linux and MacOS X (and Android).
  • Supports browserify and webpack (beta).

Quick Start

Browsers (without a bundler)

Download and extract the .zip file from the latest release.

In your HTML file, load UUID and the Doodad package :

    <script src="lib/uuid/uuid.min.js"></script> 
    <script src="doodad-js.min.js"></script> 

or their debug version :

    <script src="lib/uuid/uuid.js"></script> 
    <script src="doodad-js.js"></script> 

From Javascript, when the scripts are loaded, create the root namespace :

    window.createRoot()
        .then(root => ...)
        .catch(err => {
            console.error(err);
        });

You can create a shortcut to the namespaces this way :

    const doodad = root.Doodad,
        types = doodad.Types,
        tools = doodad.Tools,
        mixins = doodad.MixIns,
        interfaces = doodad.Interfaces,
        extenders = doodad.Extenders,
        namespaces = doodad.Namespaces,
        ... ;

Node.js

Download and install Doodad from NPM using the command prompt (Windows) or your favorite shell (Unix/Linux) :

    npm install doodad-js --save

By default, Doodad is running in production mode, which disables every validations. You may want to activate the development mode by setting the "NODE_ENV" environment variable :

Windows (command prompt) :

    set NODE_ENV=development

Linux/Unix (shell) :

    export NODE_ENV=development

Now, in your Node.js script, create the root namespace :

    require('doodad-js').createRoot()
        .then(root => ...)
        .catch(err => {
            console.error(err);
        });

You can create a shortcut to the namespaces this way :

    const doodad = root.Doodad,
        types = doodad.Types,
        tools = doodad.Tools,
        mixins = doodad.MixIns,
        interfaces = doodad.Interfaces,
        extenders = doodad.Extenders,
        namespaces = doodad.Namespaces,
        ... ;

Source code

Doodad must be built using doodad-js-make and its dependencies.

Scopes

  • doodad.PUBLIC: Accessible from the outside.
  • doodad.PROTECTED: Accessible from the inside only.
  • doodad.PRIVATE: Accessible only from the inside of the prototype. Can't be overriden or replaced.
  • doodad.PROTECTED_DEBUG: Like "doodad.PROTECTED", but will be "doodad.PUBLIC" on debug mode.
  • doodad.PRIVATE_DEBUG: Like "doodad.PRIVATE", but will be "doodad.PUBLIC" on debug mode.

Class Modifiers

Attribute Modifiers :

  • doodad.ATTRIBUTE: Explicitly defines an attribute. Can be used to specify an extender, and/or extender options.
  • doodad.OPTIONS: Defines extender options.
  • doodad.PRE_EXTEND: Tells that an attribute must be extended before normal (non pre-extended) attributes.
  • doodad.TYPE: Attribute is accessible from its Type (ie class).
  • doodad.INSTANCE: Attribute is accessible from an instance of its Type (ie class).
  • doodad.PERSISTENT: Attribute is not deleted on destroy.
  • doodad.READ_ONLY: Attribute can't be modified.
  • doodad.ASYNC: Method will allways returns a Promise.
  • doodad.METHOD: Explicitly defines an attribute as a method.
  • doodad.JS_METHOD: Defines an attribute as a "pure" Javascript function.
  • doodad.PROPERTY: Defines a property (with getter and setter).
  • doodad.EVENT: Defines an event attribute.
  • doodad.ERROR_EVENT: Defines an error event attribute.
  • (client-side only) doodad.JS_EVENT: Defines a DOM event attribute.
  • (server-side only) doodad.NODE_EVENT: Defines a Node.Js event attribute.

Method Modifiers

  • doodad.MUST_OVERRIDE: The method must be overriden within another class.
  • doodad.REPLACE: The method's functions stack gets deleted and replaced by the new function.
  • doodad.OVERRIDE: The new function is appended to the method's functions stack.
  • doodad.CREATE_REPLACE: Same as "doodad.REPLACE", but the method will get created if it doesn't exist.
  • doodad.CREATE_OVERRIDE: Same as "doodad.OVERRIDE", but the method will get created if it doesn't exist.
  • doodad.OBSOLETE: The method is obsolete and will write a warning on the "console" when called for the first time.
  • doodad.CALL_FIRST: Roughly, the function is prepend to the method's functions stack.
  • doodad.CAN_BE_DESTROYED: The method can be called even when the object has been destroyed.
  • doodad.NOT_IMPLEMENTED: The method exists, but it is not implemented until it will get overriden or replaced.
  • doodad.RETURNS: Specifies a validator to the method's returned value.
  • doodad.SUPER: For methods defined with "doodad.JS_METHOD", used to override a method.
  • doodad.BIND: Binds a method to its object.
  • doodad.NON_REENTRANT: The method must exits before being able to call it again.
  • doodad.EXTERNAL: The method can't be called from inside the object.
  • doodad.AFTER: When combined with "doodad.OVERRIDE", the function will get inserted in the stack after the function of the specified class.
  • doodad.BEFORE: When combined with "doodad.OVERRIDE", the function will get inserted in the stack before the function of the specified class.
  • doodad.RENAME_OVERRIDE: Like "doodad.OVERRIDE", but also renames the method. To be used when implementing a Trait.
  • doodad.RENAME_REPLACE: Like "doodad.REPLACE", but also renames the method. To be used when implementing a Trait.

Available extenders

  • extenders.Attribute: (inherits 'extenders.Extender') Extends an attribute with a new value.
  • extenders.Null: (inherits 'extenders.Attribute') Extends an attribute with 'null'.
  • extenders.ClonedAttribute: (inherits 'extenders.Attribute') When an object gets instantiated, the attribute's value is cloned.
  • extenders.ExtendObject: (inherits 'extenders.ClonedAttribute') When overriden, the attribute's object value will get extended instead of replaced.
  • extenders.UniqueArray: (inherits 'extenders.ClonedAttribute') When overriden, the attribute's array value will get appended instead of replaced. Duplicates are removed.
  • extenders.Method: (inherits 'extenders.ClonedAttribute') Extends a method.
  • extenders.JsMethod: (inherits 'extenders.Method') Extends a Javascript method.
  • extenders.Property: (inherits 'extenders.Method') Extends a property.
  • extenders.Event: (inherits 'extenders.Method') Extends an event attribute.
  • (client-side only) extenders.JsEvent: (inherits 'extenders.Event') Extends a DOM event attribute.
  • (server-side only) extenders.NodeEvent: (inherits 'extenders.Event') Extends a Node.Js event attribute.

Pre-built Interfaces and Mix-Ins

  • interfaces.Clonable: (interface) Makes a class clonable.
  • interfaces.Serializable: (interface) Makes a class serializable and desializable.
  • mixins.Creatable: (mix-in) Makes a class creatable.
  • mixins.Translatable: (mix-in) Makes a localized class object.
  • mixins.Configurable: (mix-in) Makes a configurable class object.
  • mixins.Events: (mix-in) Makes a class with events.
  • (client-side only) mixins.JsEvents: (mix-in) Makes a class with managed Javascript events.
  • (server-side only) mixins.NodeEvents: (mix-in) Makes a class with managed NodeJs events.

Pre-built Types

  • types.Type: The base of every types.
  • types.CustomEvent: (inherits 'types.Type') Custom event type for custom event targets.
  • types.CustomEventTarget: (inherits 'types.Type') Custom event targets.
  • types.Namespace: (inherits 'types.CustomEventTarget') Namespace object.

Pre-built Errors

  • types.TypeError: (inherits 'global.TypeError') Raised on invalid value type.
  • types.Error: (inherits 'global.Error') Generic error with message formatting.
  • types.AssertionError: (inherits 'types.Error') Raised when an assertion fail.
  • types.ParseError: (inherits 'types.Error') Raised on parse error.
  • types.NotSupported: (inherits 'types.Error') Raised when something is not supported.
  • types.NotAvailable: (inherits 'types.Error') Raised when something is not available.
  • types.HttpError: (inherits 'types.Error') Raised on HTTP error.
  • types.BufferOverflow: (inherits 'types.Error') Raised on buffer overflow.
  • types.TimeoutError: (inherits 'types.Error') Raised on timeout.
  • types.CanceledError: (inherits 'types.Error') Raised when an operation has been canceled.
  • types.AccessDenied: (inherits 'types.Error') Raised on access denied or not allowed operations.

Pre-built Classes

  • doodad.Class: (inherits 'types.Type') The base of every classes.
  • doodad.Object: (inherits 'doodad.Class', implements 'mixins.Creatable') The base of every object classes.

Pre-built Exceptions

  • doodad.Application: (inherits 'doodad.Error') Application error. An error with a title to be displayed to the end user. Exemple: "This customer is not allowed to buy this product."

Namespaces

  • namespaces.Entries.Namespace: (inherits 'types.Type') Namespace registry entry.
  • namespaces.Entries.Package: (inherits 'namespaces.Entries.Namespace') Package registry entry.
  • namespaces.Entries.Module: (inherits 'namespaces.Entries.Namespace') Module registry entry.
  • namespaces.Entries.Application: (inherits 'namespaces.Entries.Namespace') Application registry entry.
  • namespaces.get: Returns the namespace object of the specified namespace from the registry.
  • namespaces.load: Load modules and get them ready to be used. Usage: namespaces.load(modules, /optional/options, /optional/callback)
  • [namespace].REGISTER: Registers a class in the namespace object.
  • [namespace].UNREGISTER: Unregisters a class from the namespace object.

More documentation

Incomming... In the meantime, you can browse the source files and look at the "DD_DOC" headers.

Examples

Example 1 (inheritance):

    const Turtle1 = types.INIT(doodad.Object.$extend({
        $TYPE_NAME: 'Turtle1',
 
        talk: doodad.PUBLIC(function() {
            return "Hi !";
        }),
    }));
 
    let turtle = new Turtle1();
 
    turtle.talk();
 
    const Turtle2 = types.INIT(Turtle1.$extend({
        $TYPE_NAME: 'Turtle2',
 
        talk: doodad.OVERRIDE(function() {
            return this._super() + " dOOOOdad";
        }),
    }));
 
    turtle = new Turtle2();
 
    console.log(turtle.talk());

Example 2 (interfaces):

    const Turtles = types.INIT(doodad.INTERFACE(doodad.Class.$extend({
        $TYPE_NAME: 'Turtles',
 
        talk: doodad.PUBLIC(doodad.METHOD()),
    })));
 
    const Turtle1 = types.INIT(doodad.Object.$extend(
                Turtles, // Implements "Turtles"
    {
        $TYPE_NAME: 'Turtle1',
 
        talk: doodad.OVERRIDE(function() {
            return "Hi";
        }),
    }));
 
    const Turtle2 = types.INIT(doodad.Object.$extend(
                Turtles, // Implements "Turtles"
    {
        $TYPE_NAME: 'Turtle2',
 
        talk: doodad.OVERRIDE(function() {
            return "Bonjour";
        }),
    }));
 
    console.log(types._implements(Turtle1, Turtles) && types._implements(Turtle2, Turtles));

Example 3 (mix-ins) :

    const Turtles = types.INIT(doodad.MIX_IN(doodad.Class.$extend({
        $TYPE_NAME: 'Turtles',
 
        talk: doodad.PUBLIC(function() {
            return "Hi";
        }),
    })));
 
    const Turtle1 = types.INIT(doodad.Object.$extend(
                Turtles, // Composes "Turtles"
    {
        $TYPE_NAME: 'Turtle1',
    }));
    
    console.log(types._implements(Turtle1, Turtles));

Example 4 (traits) :

    const TAnimals = types.INIT(doodad.TRAIT(doodad.Class.$extend({
        $TYPE_NAME: 'TAnimals',
 
        talk: doodad.PUBLIC(function() {
            return this.getPhrase();
        }),
        
        getPhrase: doodad.PROTECTED(doodad.MUST_OVERRIDE()),
    })));
 
    const Turtle = types.INIT(doodad.Object.$extend(
                TAnimals, // Composes "TAnimals"
    {
        $TYPE_NAME: 'Turtles',
 
        phrase: doodad.PUBLIC(null),
        
        create: doodad.OVERRIDE(function(phrase) {
            this._super();
            this.phrase = phrase;
        }),
        
        talk: doodad.RENAME_OVERRIDE(function slowTalk() {
            return this._super().split('').join('...');
        }),
 
        getPhrase: doodad.OVERRIDE(function() {
            return this.phrase;
        }),
    }));
 
    const turtle = new Turtle("Hi !");
 
    console.log(turtle.talk());
    console.log(turtle.slowTalk());

Example 5 (expandable objects) :

    const IAnimal = types.INIT(doodad.INTERFACE(doodad.Class.$extend({
        $TYPE_NAME: 'IAnimal',
 
        makeNoise: doodad.MUST_OVERRIDE(),
    })));
 
    const perrot = new doodad.Object();
 
    perrot.extend(
            IAnimal, // Implements "IAnimal"
        {
            phrase: null,
            create: doodad.OVERRIDE(function(phrase) {
                this._super();
                this.phrase = phrase;
            }),
            makeNoise: doodad.OVERRIDE(function() {
                return this.phrase;
            }),
       })
       .create("Hello world !");
 
    console.log(perrot.makeNoise());

Future

Maybe I'll try to write a Babel plugin to get something like the following :

    @interface
    class Turtles {
        @returns(types.isString)
        talk()
    }
 
    class SmallTurtle implements Turtles {
        @override
        talk() {
            return "hi";
        }
    }
 
    class GiantTurtle implements Turtles {
        @override
        talk() {
            return "HI";
        }
    }

But I have to wait on what will be feasible after current proposals like "decorators", "public fields" and "private fields".

Other available packages

  • doodad-js: Object-oriented programming framework (release)
  • doodad-js-cluster: Cluster manager (alpha)
  • doodad-js-dates: Dates formatting (beta)
  • doodad-js-http: Http server (alpha)
  • doodad-js-http_jsonrpc: JSON-RPC over http server (alpha)
  • doodad-js-io: I/O module (alpha)
  • doodad-js-ipc: IPC/RPC server (alpha)
  • doodad-js-json: JSON parser (alpha)
  • doodad-js-loader: Scripts loader (beta)
  • doodad-js-locale: Locales (beta)
  • doodad-js-make: Make tools for doodad (alpha)
  • doodad-js-mime: Mime types (beta)
  • doodad-js-minifiers: Javascript minifier used by doodad (alpha)
  • doodad-js-safeeval: SafeEval (beta)
  • doodad-js-server: Servers base module (alpha)
  • doodad-js-templates: HTML page templates (alpha)
  • doodad-js-terminal: Terminal (alpha)
  • doodad-js-test: Test application
  • doodad-js-unicode: Unicode Tools (beta)
  • doodad-js-widgets: Widgets base module (alpha)
  • doodad-js-xml: XML Parser (beta)

License

Apache-2.0

Package Sidebar

Install

npm i doodad-js

Weekly Downloads

5

Version

8.0.0

License

Apache-2.0

Last publish

Collaborators

  • doodadjs