Security News
RubyGems.org Adds New Maintainer Role
RubyGems.org has added a new "maintainer" role that allows for publishing new versions of gems. This new permission type is aimed at improving security for gem owners and the service overall.
The NoGap framework delivers RPC + asset management + some other good stuff for Host <-> Client comunication.
The NoGap framework delivers RPC + asset management + some other good stuff for enjoyable Host <-> Client architecture development.
This module is called No
Gap
because it removes the typical gap that exists between
host and client and that makes a client<->server architecture so cumbersome to develop.
NoGap's primary use case is to develop rich client-side applications while alleviating the typical hassles of doing so.
Have a look at the Samples for reference.
If you want to get serious, take a look at the Getting Started section to figure out how to build a complete Node-based web application with NoGap.
Note that currently, the only dependency of NoGap is Node
and some of its modules but even that is planned to be removed in the future.
Add to PATH
during GUI-based installation.Ctrl+R
-> Type cmd
-> Enter
npm install nogap
The Samples highlight some (soon, all!) features of the NoGap framework and how they are used. To run the samples:
node_modules/nogap
subfolder.cd node_modules/nogap/samples/HelloWorld
(or any other sample)npm install
(will automatically download and install the sample's dependencies)npm start
(this will run the app defined in the sample's package.json
)localhost:1234
(or whatever port you are using)var NoGapDef = require('nogap').Def;
module.exports = NoGapDef.component({
Client: NoGapDef.defHost(function(Tools, Instance, Context) {
return {
initClient: function() {
document.body.innerHTML = 'Hello World!';
}
};
});
});
Def
helper: var NoGapDef = require('nogap').Def;
NoGapDef.component({ ... });
Client
definition to the component: Client: NoGapDef.defClient(function(Tools, Instance, Context) { ... })
initClient
method to Client
Client
code is automatically deployed to the clientinitClient
is then automatically called on the client, right after installationvar NoGapDef = require('nogap').Def;
NoGapDef.component({
Host: NoGapDef.defHost(function(SharedTools, Shared, SharedContext) {
var iAttempt = 0;
return {
Public: {
tellClientSomething: function() {
this.client.showHostMessage('We have exchanged ' + ++iAttempt + ' messages.');
}
}
};
}),
Client: NoGapDef.defClient(function(Tools, Instance, Context) {
return {
initClient: function() {
window.clickMe = function() {
document.body.innerHTML +='Button was clicked.<br />';
this.host.tellClientSomething();
}.bind(this);
document.body.innerHTML += '<button onclick="window.clickMe();">Click Me!</button><br />';
},
Public: {
showHostMessage: function(msg) {
document.body.innerHTML +='Server said: ' + msg + '<br />';
}
}
};
})
});
Client
definition to the component: Client: NoGapDef.defClient(function(Tools, Instance, Context) { ... })
Client.initClient
Host
definition to the component: Host: NoGapDef.defHost(function(SharedTools, Shared, SharedContext) { ... })
Host.Public
Client.Public
this.host
gives us an object on which we can call Public
methods on the host
tellClientSomething
which is a method that was defined in Host.Public
this.client.showHostMessage
this.host
vs.this.client
Now that our code keeps growing and you are starting to get the picture, let us just focus on code snippets from now on.
Imagine the server had to do an asynchronous operation in tellClientSomething
.
For example, it needs to read a file, or get something from the database.
tellClientSomething: function() {
this.Tools.keepOpen();
// wait 500 milliseconds before replying
setTimeout(function() {
this.client.showHostMessage('We have exchanged ' + ++iAttempt + ' messages.');
this.Tools.flush();
}.bind(this), 500);
}
this.Tools.keepOpen()
, so the client connection will not be closed automaticallythis.Tools.flush()
Base: NoGapDef.defBase(function(SharedTools, Shared, SharedContext) { return {
validateText: function(text) {
if (text.indexOf('a') >= 0 || text.indexOf('A') >= 0) {
return null;
}
return text.trim();
}
};}),
Host: NoGapDef.defHost(function(SharedTools, Shared, SharedContext) { return {
Public: {
setValue: function(value) {
this.value = this.Shared.validateText(value);
// ...
}
}
};}),
Client: NoGapDef.defClient(function(Tools, Instance, Context) { return {
// ...
value = this.validateText(value);
// ...
};})
Base
definition is merged into both Client
and Host
NoGapDef.component({
Host: NoGapDef.defHost(function(SharedTools, Shared, SharedContext) { return {
Assets: {
AutoIncludes: {
js: [
// jquery
'//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js'
],
css: [
// bootstrap
'//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css'
]
},
Files: {
string: {
view: 'template.html'
}
}
}
};}),
Client: NoGapDef.defClient(function(Tools, Instance, Context) { return {
initClient: function() {
document.body.innerHTML += this.assets.view;
}
};})
});
AutoIncludes
defines lists of js
and css
files that will be automatically included in the client headerFiles
will be read and it's contents will be available through the clients assets
variable.
code
, image
and more more more...This Sample is not done yet, but the Simple Sample App already does this.
Shared.ComponentA.say('hello');
this.Instance.ComponentB.client.somePublicMethod(some, data);
TODO: Sample not done yet...
this.Tools.requestClientComponents(names, callback);
This App shows how to start building a real application with NoGap. It uses Angular
, Boostrap
and Font-Awesome
to do some real client-side rendering. Important to note: None of these are required. You can build your frontend and backend any way you want.
optional methods
that will be called during important events./**
* A complete Component skeleton
*/
"use strict";
var NoGapDef = require('nogap').Def;
module.exports = NoGapDef.component({
/**
* If no name is given, NoGap will use the filename as name.
* If you define more than one unnamed component per file, you will see an error.
*/
Name = undefined,
/**
* The `Base` definition is merged into both, `Host` and `Client`
*/
Base: NoGapDef.defBase(function(SharedTools, Shared, SharedContext) {
return {
/**
* Called right before `__ctor` of `Host` and `Client`
*/
__ctor: function() {
},
/**
* Called right before `initHost` and `initClient`.
*/
initBase: function() {
},
/**
* Private instance members.
*/
Private: {
},
/**
* Public instance methods that can be called by the other side.
*/
Public: {
}
};
}),
Host: NoGapDef.defHost(function(SharedTools, Shared, SharedContext) {
return {
__ctor: function () {
},
initHost: function() {
},
/**
* Private instance members.
*/
Private: {
__ctor: function () {
},
/**
* Called when a client connected.
*/
onNewClient: function() {
},
/**
* Called after `onNewClient`, once this component is bootstrapped on the client side.
* Since components can be deployed dynamically, this might happen much later, or never.
*/
onClientBootstrap: function() {
}
},
/**
* Public instance methods that can be called by the other side.
*/
Public: {
},
};
}),
Client: NoGapDef.defClient(function(Tools, Instance, Context) {
return {
__ctor: function () {
},
initClient: function() {
},
Public: {
}
};
})
});
This tutorial is aimed at those who are new to NoGap
, and new to Node
in general.
It should help you bridge the gap from the Code Snippets to a real-world application.
Note that the Simple Sample App is also following these guidelines.
.
+-- components/
| +-- models/
| +-- ui/
+-- lib/
+-- pub/
+-- app.js
+-- appConfig.js
+-- package.json
This is the recommended file structure for the average web application. As always, the structure might look vastly different for special purpose applications.
components/
This folder contains your NoGap
components, and possibly (some of) their assets. You can name it anything you want.
NOTE: Placing assets (such as *.html templates, stylesheets, images etc.) next to code is actually good style, if it supports modularization. If your components have a sufficiently modular design, you can simply copy their folder, to deploy them and their assets in other places.
components/models/
This folder contains the interface with your DB and possibly other storage systems. They provide CRUD functionality to the rest of the application.
components/ui/
This folder contains UI-related components. That is UI controller and view code. Views are in separate files from the code, but they can be in the same folder to support modularity.
app.js
This defines your actual application. You can name it anything you want. Usually, this file only does three things:
NoGap
express
serverExpress is the standard Node way of starting a HTTP server and let clients connect. Once it is running you can connect to it with your browser on the specified port.
NOTE: When using NoGap
you will not need to work with express anymore (other than starting the server). You can use it, but you are recommended to use components instead.
appConfig.js
This is your custom configuration file. You can name it anything you want.
It contains some basic constant data that your application needs, such as database login and other setup information.
The following is an example of a NoGap
configuration. It requires at least two entries:
baseFolder
app.js
) where you defined all NoGap components.files
publicFolder
(Default = pub/
)
NoGap
support (they are not defined as components).endpointImplementation.name
(Default = HttpPost
)
HttpPostImpl
in ComponentCommunications.js
There are more, optional parameters. Documentation will come soon.
"nogap": {
"baseFolder" : "components",
"publicFolder" : "pub",
"files" : [
// list all components here:
// utilities
"ValidationUtil",
// pages for guests
"Guest",
// pages for users
"Main",
"Home"
]
}
This is the standard Node
configuration file. Here you can declare your app's basic metadata and, most importantly, your dependencies.
If you need one of the thousands over thousands of publicly available Node
modules, two steps are required:
dependencies
npm install
Done. Now the new module is available in your code via:
var someModule = require('some-module');
where some-module
is the name you gave it in the package.json file.
Check out NPM JS to see all available modules.
Good luck! You are recommended to take a look at the NoGap Sample App
for a slightly more complete example of using NoGap
.
In case of questions, feel free to contact me.
FAQs
NoGap is a full-stack (spans Host and Client) JavaScript framework, featuring RPC + simple code sharing + basic asset management + full-stack Promise chains and more...
The npm package nogap receives a total of 7 weekly downloads. As such, nogap popularity was classified as not popular.
We found that nogap demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
RubyGems.org has added a new "maintainer" role that allows for publishing new versions of gems. This new permission type is aimed at improving security for gem owners and the service overall.
Security News
Node.js will be enforcing stricter semver-major PR policies a month before major releases to enhance stability and ensure reliable release candidates.
Security News
Research
Socket's threat research team has detected five malicious npm packages targeting Roblox developers, deploying malware to steal credentials and personal data.