8.0.0 • Published 8 years ago

doodad-js v8.0.0

Weekly downloads
6
License
Apache-2.0
Repository
github
Last release
8 years ago

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

8.0.0

8 years ago

7.0.0

8 years ago

6.2.1

8 years ago

6.2.0

8 years ago

6.1.0

9 years ago

6.0.1

9 years ago

6.0.0

9 years ago

5.0.1

9 years ago

5.0.0

9 years ago

4.0.0

9 years ago

3.3.1

9 years ago

3.2.0

9 years ago

3.1.5

9 years ago

2.2.0

9 years ago

2.1.0

9 years ago

2.0.0

9 years ago

1.3.1

9 years ago

1.3.0

9 years ago

1.2.0

9 years ago

1.1.14

9 years ago

1.0.5

10 years ago

0.55.1

10 years ago

0.55.0

10 years ago

0.50.1

10 years ago

0.50.0

10 years ago

0.49.0

10 years ago

0.48.3

10 years ago

0.48.2

10 years ago

0.48.1

10 years ago

0.48.0

10 years ago

0.47.1

10 years ago

0.47.0

10 years ago

0.46.9

10 years ago

0.46.8

10 years ago

0.46.7

10 years ago

0.46.6

10 years ago

0.46.5

10 years ago

0.46.4

10 years ago

0.46.3

10 years ago

0.46.2

10 years ago

0.46.1

10 years ago

0.46.0

10 years ago