flok 0.0.10 → 0.0.11
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.run2 +3 -0
- data/README.md +5 -16
- data/Rakefile +18 -0
- data/app/drivers/chrome/README.md +65 -0
- data/app/drivers/{browser → chrome}/Rakefile +0 -0
- data/app/drivers/chrome/config.yml +3 -0
- data/app/drivers/chrome/net.js +48 -0
- data/app/drivers/chrome/ui.js +87 -0
- data/app/drivers/{browser → chrome}/vendor/jquery.js +0 -0
- data/app/drivers/iface/ui.js +31 -0
- data/bin/flok +4 -2
- data/docs/architecture.md +18 -0
- data/docs/compilation.md +20 -0
- data/docs/platform_drivers.md +35 -0
- data/docs/project_layout.md +5 -0
- data/lib/flok.rb +9 -3
- data/lib/flok/version.rb +1 -1
- data/lib/js/kernel/pipe.js +30 -24
- data/lib/js/kernel/utils.js +8 -0
- data/lib/js/namespaces.js +2 -0
- data/public/application.js +0 -0
- data/spec/drivers/net_spec.rb +65 -3
- data/spec/helpers.rb +5 -0
- data/ypou +0 -0
- metadata +18 -10
- data/app/drivers/browser/network.js +0 -24
- data/lib/js/kernel/common.js +0 -1
- data/lib/js/kernel/handleCustomEvent.js +0 -8
- data/lib/js/kernel/handleInitEvent.js +0 -4
- data/lib/js/kernel/handleTickEvent.js +0 -2
- data/lib/js/kernel/task.js +0 -24
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a5c7b4bc98442a8926cdedff0a1c7686d8a1682f
|
4
|
+
data.tar.gz: 76c5f330a8d1b8b892d55c88d3e8590e1a99675f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1235a074303d2392ecd72f91e2e11f7e5c8ea989dbcb983a9b6182da279b949dcbef3f3732d8eb2cf83eca64af8704f241d5c5c7a04186af284759c4120a6a42
|
7
|
+
data.tar.gz: 52488120e65e47dba68a985324dfd9c78415b58cc3c740da01fb1aa2115e6728437525ffbc39f0dfbbb81f59c19c446c828ce7ddc277589b015bf25e46d21a33
|
data/.run2
ADDED
data/README.md
CHANGED
@@ -9,23 +9,12 @@
|
|
9
9
|
|
10
10
|
A work in progress
|
11
11
|
|
12
|
-
|
13
|
-
A concept borrowed from [Rails engines](http://guides.rubyonrails.org/engines.html), Flok modules both serve as your project files, all library modules, and gemified instances. That is, a project you create is automatically modular and can be imported in another flok module/project.
|
12
|
+
## Docs
|
14
13
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
The task is the base unit in flok, similar to a rack module except that rack is a stack and flok is a party. Based on concepts borrowed from XNU®, FreeBSD®, and GNU HURD®; tasks are combined in flok to produce behavior by many tasks inter-cooperating. Efficiency has been provided through virtualizing the task communication so that no message passing takes place inside flok and all modules are combined into an efficient monolithic module.
|
20
|
-
|
21
|
-
### Task Facilities
|
22
|
-
Tasks are able to
|
23
|
-
- send and receive events from a global or internal source.
|
24
|
-
- set interval and timeout timers.
|
25
|
-
- store temporary data in it's own heap '$__'
|
26
|
-
|
27
|
-
### Default modules
|
28
|
-
This flok project contains the 'micro-task-kernel', the 'ui', and the 'operations' modules.
|
14
|
+
* [Project Layout](./docs/project_layout.md)
|
15
|
+
* [Platform Drivers](./docs/platform_drivers.md)
|
16
|
+
* [Architecture](./docs/architecture.md)
|
17
|
+
* [Compilation](./docs/compilation.md)
|
29
18
|
|
30
19
|
## Requirements
|
31
20
|
|
data/Rakefile
CHANGED
@@ -36,3 +36,21 @@ task :push do
|
|
36
36
|
`gem push flok-#{version}.gem`
|
37
37
|
`rm flok-#{version}.gem`
|
38
38
|
end
|
39
|
+
|
40
|
+
task :compile do
|
41
|
+
`rm ./products/application.js`
|
42
|
+
`ruby -Ilib ./bin/flok build`
|
43
|
+
`osascript -e 'tell application "Keyboard Maestro Engine" to do script "3B15D84D-30B0-4DC5-91BA-91BBE0AA340B"'`
|
44
|
+
end
|
45
|
+
|
46
|
+
task :test_env do
|
47
|
+
puts ENV["FUCK"]
|
48
|
+
end
|
49
|
+
|
50
|
+
#Update documents to github
|
51
|
+
task :udocs do
|
52
|
+
`git add ./docs/*`
|
53
|
+
`git add README.md`
|
54
|
+
`git commit -a -m "Update docs"`
|
55
|
+
`git push`
|
56
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# CHROME driver
|
2
|
+
This driver supports an internet browser.
|
3
|
+
|
4
|
+
# Installing / Implementation
|
5
|
+
At the completion of the build, the driver directory, typically `products/$PLATFORM/driver` will contain a `chrome.js` file. This must be included
|
6
|
+
before your `application.js` file.
|
7
|
+
|
8
|
+
### HTML conventions
|
9
|
+
There is excatly (1) divider that is used to place everything inside of that is visible. This divider *must* have the following HTML code:
|
10
|
+
```html
|
11
|
+
<!-- Mount point for view hierarchy, fully managed, do not touch -->
|
12
|
+
<div id='root_surface' class='surface'>
|
13
|
+
<div class='view' data-name='main'></div>
|
14
|
+
<div class='view' data-name='hidden' style='display: none'></div>
|
15
|
+
</div>
|
16
|
+
|
17
|
+
<!-- Insert your prototypes inside here -->
|
18
|
+
<div id='surface-prototypes' style='display: none'>
|
19
|
+
</div>
|
20
|
+
|
21
|
+
```
|
22
|
+
|
23
|
+
### Adding a surface prototype
|
24
|
+
You may add surface prototypes like so under your #surface-prototypes divider
|
25
|
+
```html
|
26
|
+
<!-- Insert your prototypes inside here -->
|
27
|
+
<div id='surface-prototypes' style='display: none'>
|
28
|
+
<!-- A tab container with a sub-view -->
|
29
|
+
<div class='surface' data-name='tab_container'>
|
30
|
+
<h1>Title</h1>
|
31
|
+
<button>Back</button>
|
32
|
+
<hr />
|
33
|
+
<div class='view' data-name='main'>
|
34
|
+
</div>
|
35
|
+
|
36
|
+
<!-- A login view -->
|
37
|
+
<div class='surface' data-name='login'>
|
38
|
+
<input type='text' placeholder='email' />
|
39
|
+
<input type='text' placeholder='password' />
|
40
|
+
<button>Login</button>
|
41
|
+
</div>
|
42
|
+
</div>
|
43
|
+
```
|
44
|
+
|
45
|
+
### Binding a Controller to a surface
|
46
|
+
You create a constructor for a controller and then pass `drivers.ui.regController("surface_name", ControllerConstructorName);` and it will
|
47
|
+
automatically be bound when a new surface is created.
|
48
|
+
```js
|
49
|
+
//Constructor for a controller that will automatically bind to a surface with the attribute 'data-name=tab_controller'
|
50
|
+
var TabController = function($sel, info, pipe) {
|
51
|
+
//Assign members
|
52
|
+
this.$sel = $sel;
|
53
|
+
this.info = info;
|
54
|
+
this.pipe = pipe;
|
55
|
+
|
56
|
+
$sel.find("button").on('click', function() {
|
57
|
+
//Do something, like send an event
|
58
|
+
});
|
59
|
+
}
|
60
|
+
|
61
|
+
//Register the new controller
|
62
|
+
$(document).ready(function() {
|
63
|
+
drivers.ui.regController("tab_container", TabController);
|
64
|
+
});
|
65
|
+
```
|
File without changes
|
@@ -0,0 +1,48 @@
|
|
1
|
+
drivers = window.drivers || {}
|
2
|
+
drivers.network = {}
|
3
|
+
|
4
|
+
//$(document).ready(function() {
|
5
|
+
//drivers.network.request("GET", "http://test.services.fittr.com/ping", {}, null);
|
6
|
+
//})
|
7
|
+
|
8
|
+
//All requests are bound to this table and removed when cancelled
|
9
|
+
drivers.network.callbackTable = {}
|
10
|
+
drivers.network.socketIndex = 0 //The current index of the socket, incremented for new sockets
|
11
|
+
|
12
|
+
//A basic get request that supports callbacks
|
13
|
+
drivers.network.request = function(verb, url, params, completion) {
|
14
|
+
//Store callback in the table
|
15
|
+
var socketIndex = drivers.network.socketIndex++
|
16
|
+
drivers.network.callbackTable[socketIndex] = true
|
17
|
+
|
18
|
+
$.ajax({
|
19
|
+
url: url,
|
20
|
+
type: verb,
|
21
|
+
data: params,
|
22
|
+
success: function(data) {
|
23
|
+
data = JSON.parse(data);
|
24
|
+
completion = completion || function() {}
|
25
|
+
if (completion != null) {
|
26
|
+
//Callback if possible
|
27
|
+
if (drivers.network.callbackTable[socketIndex] === true) {
|
28
|
+
delete drivers.network.callbackTable[socketIndex];
|
29
|
+
completion(data, false);
|
30
|
+
}
|
31
|
+
}
|
32
|
+
},
|
33
|
+
error: function(xhr, status, err) {
|
34
|
+
if (drivers.network.callbackTable[socketIndex] === true) {
|
35
|
+
delete drivers.network.callbackTable[socketIndex];
|
36
|
+
completion({"message":status}, true);
|
37
|
+
}
|
38
|
+
}
|
39
|
+
})
|
40
|
+
|
41
|
+
return socketIndex
|
42
|
+
}
|
43
|
+
|
44
|
+
drivers.network.cancel_request = function(socket) {
|
45
|
+
res = drivers.network.callbackTable[socket];
|
46
|
+
//Clear callback
|
47
|
+
delete drivers.network.callbackTable[socket]
|
48
|
+
}
|
@@ -0,0 +1,87 @@
|
|
1
|
+
drivers = window.drivers || {}
|
2
|
+
drivers.ui = {}
|
3
|
+
|
4
|
+
//Create a new surface based on a prototype name and information. Should return a surface pointer
|
5
|
+
drivers.ui.createSurface = function(protoName, info) {
|
6
|
+
var $proto = $("#surface-prototypes").find(".surface[data-name=\'"+protoName+"\']");
|
7
|
+
if ($proto.length === 0) {
|
8
|
+
throw "Couldn't find a surface prototype named: \(protoName)";
|
9
|
+
}
|
10
|
+
|
11
|
+
//Get a UUID, move the surface to the 'body' element and hidden
|
12
|
+
var uuid = UUID()
|
13
|
+
$proto.attr("data-uuid", uuid);
|
14
|
+
$("body").append($proto[0].outerHTML);
|
15
|
+
$proto.removeAttr("data-uuid");
|
16
|
+
|
17
|
+
$sel = $("[data-uuid='" + uuid + "']");
|
18
|
+
$sel.addClass("hidden");
|
19
|
+
|
20
|
+
//Does this have a controller?
|
21
|
+
var scc = drivers.ui.scc[protoName];
|
22
|
+
|
23
|
+
(function() {
|
24
|
+
var _sel = $sel;
|
25
|
+
var p = pipe(function(msg) {
|
26
|
+
console.log("CLICKED!");
|
27
|
+
if (msg === "sign_in_clicked") {
|
28
|
+
var source = drivers.ui.createSurface("nav_container", {color: "blue"});
|
29
|
+
var source2 = drivers.ui.createSurface("login", {color: "blue"});
|
30
|
+
drivers.ui.embedSurface(source, $("#root-surface"), "main", false, null);
|
31
|
+
drivers.ui.embedSurface(source2, source, "content", false, null);
|
32
|
+
|
33
|
+
} else if (msg === "login") {
|
34
|
+
var source = drivers.ui.createSurface("loading");
|
35
|
+
drivers.ui.embedSurface(source, $("#root-surface"), "main", false, null);
|
36
|
+
|
37
|
+
var callback = function() {
|
38
|
+
alert("error!");
|
39
|
+
var source = drivers.ui.createSurface("nav_container", {color: "blue"});
|
40
|
+
var source2 = drivers.ui.createSurface("login", {color: "blue"});
|
41
|
+
drivers.ui.embedSurface(source, $("#root-surface"), "main", false, null);
|
42
|
+
drivers.ui.embedSurface(source2, source, "content", false, null);
|
43
|
+
}
|
44
|
+
setTimeout(callback, 400);
|
45
|
+
|
46
|
+
} else {
|
47
|
+
var source = drivers.ui.createSurface("splash");
|
48
|
+
drivers.ui.embedSurface(source, $("#root-surface"), "main", false, null);
|
49
|
+
}
|
50
|
+
});
|
51
|
+
|
52
|
+
if (scc != undefined) {
|
53
|
+
new scc($sel, info, p);
|
54
|
+
}
|
55
|
+
})();
|
56
|
+
|
57
|
+
//Our surface pointers are selectors
|
58
|
+
return $sel
|
59
|
+
}
|
60
|
+
|
61
|
+
//Delete a surface which removes it from the UI
|
62
|
+
drivers.ui.deleteSurface = function(sp) {
|
63
|
+
sp.remove();
|
64
|
+
}
|
65
|
+
|
66
|
+
//Embed a surface into another surface in the view with the correct name
|
67
|
+
//source_sp - The surface we are embedding
|
68
|
+
//dest_sp - The surface we are embedding into
|
69
|
+
//animated - If true, a segue is allowed to take place
|
70
|
+
//animationDidComplete - Call this funtction if animated is true when you are done animating.
|
71
|
+
drivers.ui.embedSurface = function(source_sp, dest_sp, viewName, animated, animationDidComplete) {
|
72
|
+
//Lookup view selector
|
73
|
+
var $view = dest_sp.find(".view[data-name=" + viewName + "]");
|
74
|
+
if ($view.length === 0) {
|
75
|
+
throw "Found surface, but couldn't find a view *inside* a surface named: " + viewName;
|
76
|
+
}
|
77
|
+
|
78
|
+
$view.html("");
|
79
|
+
source_sp.appendTo($view);
|
80
|
+
source_sp.removeClass('hidden');
|
81
|
+
}
|
82
|
+
|
83
|
+
//Surface controller constructors
|
84
|
+
drivers.ui.scc = {};
|
85
|
+
drivers.ui.regController = function(surfaceName, constructor) {
|
86
|
+
drivers.ui.scc[surfaceName] = constructor;
|
87
|
+
}
|
File without changes
|
@@ -0,0 +1,31 @@
|
|
1
|
+
//Handles displaying UI
|
2
|
+
//Key conceptsr
|
3
|
+
// 1) Surface is like a 'View Controller', a surface contains named views.
|
4
|
+
// 2) Creating a surface will never show anything. You must embed it.
|
5
|
+
// 3) Embedding a surface should only trigger an animation segue if animated is false.
|
6
|
+
// 4) 'sp' stands for 'surface pointer'. This is an opaque type that is platform dependent.
|
7
|
+
// For websites it could be selectors. For iOS, it could be a UIView or UIViewController
|
8
|
+
|
9
|
+
//Surface structure
|
10
|
+
//{
|
11
|
+
// parent: sp The surface that embedded this surface
|
12
|
+
// childs: [sp, sp, sp, ...] An array of surfaces that this embeds. N(childs) =< N(namedViews)
|
13
|
+
//}
|
14
|
+
|
15
|
+
//Create a new surface based on a prototype name and information. Should return a surface pointer
|
16
|
+
drivers.ui.createSurface = function(protoName, info) {
|
17
|
+
return sp;
|
18
|
+
}
|
19
|
+
|
20
|
+
//Delete a surface which removes it from the UI
|
21
|
+
drivers.ui.deleteSurface = function(sp) {
|
22
|
+
}
|
23
|
+
|
24
|
+
//Embed a surface into another surface in the view with the correct name
|
25
|
+
//source_sp - The surface we are embedding
|
26
|
+
//dest_sp - The surface we are embedding into
|
27
|
+
//viewName - The name of the view in the destination surface
|
28
|
+
//animated - If true, a segue is allowed to take place
|
29
|
+
//animationDidComplete - Call this funtction if animated is true when you are done animating.
|
30
|
+
drivers.ui.embedSurface = function(source_sp, dest_sp, viewName, animated, animationDidComplete) {
|
31
|
+
}
|
data/bin/flok
CHANGED
@@ -23,7 +23,8 @@ class FlokCLI < Thor
|
|
23
23
|
desc "build", "Build a flok project, you must be in the root of the project"
|
24
24
|
def build
|
25
25
|
Dir.mkdir("./public") unless File.exists?("./public")
|
26
|
-
FileUtils.touch "./
|
26
|
+
FileUtils.touch "./products/application.js"
|
27
|
+
FileUtils.touch "../FlokTest/app/assets/javascripts/flok.js"
|
27
28
|
|
28
29
|
src = Flok::MergeSource.merge_all
|
29
30
|
|
@@ -32,7 +33,8 @@ class FlokCLI < Thor
|
|
32
33
|
src = Closure::Compiler.new.compile(src)
|
33
34
|
end
|
34
35
|
|
35
|
-
File.write("./
|
36
|
+
File.write("./products/application.js", src)
|
37
|
+
File.write("../FlokTest/app/assets/javascripts/flok.js", src)
|
36
38
|
end
|
37
39
|
end
|
38
40
|
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# Architecture
|
2
|
+
Flok's architecture is a non-pre-emptive (realtime) event-driven tickless monolithic meta-kernel divided into several parts.
|
3
|
+
```
|
4
|
+
#(a) <Platform specific drivers for handling generic/custom interrupts and generic/custom IO>
|
5
|
+
#---------^|------------------------------------
|
6
|
+
#---------||------------------------------------
|
7
|
+
#=========|v==================================== <--------------------- Abstraction barrier
|
8
|
+
#(b) <Standard driver interface> <Custom driver interfaces>
|
9
|
+
#---------^|------------------------------------
|
10
|
+
#---------||------------------------------------
|
11
|
+
#---------|v------------------------------------
|
12
|
+
#(c) <Generic kernel systems (ui, pipes, etc)> <Your Kernel 'tasks'>
|
13
|
+
```
|
14
|
+
|
15
|
+
* (a) - Drivers are written in any languages and must implement (b) the standard driver interface.
|
16
|
+
* (b) - All driver communication must pass directly through this layer
|
17
|
+
* (c) - This layer handles all generic activity like setting up pipes between tasks, etc.
|
18
|
+
|
data/docs/compilation.md
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
# Compliation
|
2
|
+
|
3
|
+
Compilation is handled by the `rake build platform=z` and then end result of that compliation is put in ./products/
|
4
|
+
Compilation *always* results in a `./products/$PLATFORM/application.js` file along with other files in `./products/$PLATFORM/` that
|
5
|
+
were deemed necessary by the platform driver `build` scripts.
|
6
|
+
|
7
|
+
### Build Order
|
8
|
+
*Unless otherwise stated, all files execute in alpha-numerical order. (`0foo.js` would execute before `1foo.js`). Please use this convention only
|
9
|
+
as necessary.*
|
10
|
+
|
11
|
+
### Compilation is accomplished in the following order.
|
12
|
+
|
13
|
+
1. All files in `./app/config/.*.js` are globbed togeather and sent to `./products/$PLATFORM/glob/0config.js`
|
14
|
+
2. `rake build` is run inside `./app/drivers/$PLATFORM` with the environmental variables set to BUILD_PATH=`./produts/$PLATFORM/driver` (and folder
|
15
|
+
3. created)
|
16
|
+
4. All js files in `./app/libkern/` are globbed togeather and sent to `./products/$PLATFORM/glob/1libkern.js`
|
17
|
+
5. All js files in `./app/kern/` are globbed togeather and sent to `./products/$PLATFORM/glob/2kern.js`
|
18
|
+
6. All js files in `./app/user/config/*.js` are globbed togeather and sent to `./products/$PLATFORM/glob/3user_config.js`
|
19
|
+
7. All js files in `./app/user/*.js` are globbed togeather and sent to `./products/$PLATFORM/glob/4user.js`
|
20
|
+
8. All js files are globbed from `./products/$PLATFORM/glob` and combined into `./products/$PLATFORM/application.js`
|
@@ -0,0 +1,35 @@
|
|
1
|
+
#Platform Drivers
|
2
|
+
Each platform has it's own set of drivers. You do not have to implement *all* the drivers on a platform and you may create your own drivers to suite your own needs. Platform drivers sit in `app/drivers/$PLATFORM` and *must* contain at least the following files.
|
3
|
+
|
4
|
+
During compliation all platform drivers must respect enviorenmental variables. For example, for $BUILD_PATH you can read this in your Rakefile via `ENV['BUILD_PATH']`.
|
5
|
+
* $BUILD_PATH - The absolute file path (not including the filename) of where to put build files.
|
6
|
+
|
7
|
+
Your build path may contain additional files as you see fit. These files will be available in the user's project in `./products/$PLATFORM/xxxxx` with the exception of the javascript outputfile which will be merged at the beginning of the complete source.
|
8
|
+
|
9
|
+
Additionally, the full application contains the function `lsdrivers()` which will return an array of all the drivers that are supported`
|
10
|
+
|
11
|
+
|
12
|
+
### $PLATFORM
|
13
|
+
The 'platform' naming convention is for it to be completely upper-case.
|
14
|
+
|
15
|
+
### Testing
|
16
|
+
All drivers must pass the driver test suite located in `./spec/driver_interface/*_spec.rb` for any drivers they have enabled in their config.yml
|
17
|
+
|
18
|
+
In order to run the *interface* driver test suite you must run `rake test:driver_iface` or `rake test:driver_iface PLATFORM=MY_PLATFORM`. For running a test suite for the specific driver, that is accomplished through `rake test:driver PLATFORM=MY_PLATFORM`
|
19
|
+
|
20
|
+
### Files
|
21
|
+
* ./Rakefile - You must at least have the tasks `test` and `build`. Note that if you're writing custom drivers in your own project folder, this does not apply to you. Also, you must observe the rules in the platform's README.md
|
22
|
+
* ./README.md - A description of this platform driver, how to extend it with custom drivers, and how it is deployed correctly.
|
23
|
+
* ./config.yml - Must contain a list of the supported interfaces for a driver.
|
24
|
+
|
25
|
+
### config.yml
|
26
|
+
Your configuration must have a `ifaces` key. This is an array of the supported interfaces. The interface name is just the filename located in
|
27
|
+
`./app/drivers/iface/.*.js`. In the example below there is a `ui.js` and `network.js` in the `./app/drivers/iface/` folder.
|
28
|
+
```yml
|
29
|
+
ifaces:
|
30
|
+
- ui
|
31
|
+
- network
|
32
|
+
```
|
33
|
+
|
34
|
+
### Platform specifics
|
35
|
+
See the ./app/drivers/$PLATFORM/README.md file for information on each individual platforms specifics.
|
@@ -0,0 +1,5 @@
|
|
1
|
+
# Project layout
|
2
|
+
* app/ - All actual pieces of the kernel code sit here.
|
3
|
+
* app/drivers - Parts of (a) and (b)
|
4
|
+
* app/drivers/interfaces - Generic interfaces that are suggested to be implemented.
|
5
|
+
* app/drivers/$PLATFORM - Platform specific way to implement the interface. See *platform drivers* for information.
|
data/lib/flok.rb
CHANGED
@@ -5,17 +5,23 @@ module Flok
|
|
5
5
|
#Merge all the kernel javascript files into one string
|
6
6
|
def self.merge_kernel
|
7
7
|
Dir.chdir(File.dirname(__FILE__)) do
|
8
|
+
#Embed drivers
|
9
|
+
Dir.chdir("../app/drivers/browser") do
|
10
|
+
`rake build`
|
11
|
+
end
|
12
|
+
out = File.read("../products/drivers/browser.js")
|
13
|
+
|
8
14
|
Dir.chdir("./js/kernel/") do
|
9
15
|
js_files = Dir["*.js"]
|
10
|
-
out = ""
|
11
16
|
js_files.each do |js|
|
12
17
|
out << File.read(js)
|
13
18
|
out << "\n"
|
14
19
|
end
|
15
|
-
|
16
|
-
return out
|
17
20
|
end
|
21
|
+
|
22
|
+
return out
|
18
23
|
end
|
24
|
+
|
19
25
|
end
|
20
26
|
|
21
27
|
def self.merge_user_app
|
data/lib/flok/version.rb
CHANGED
data/lib/js/kernel/pipe.js
CHANGED
@@ -1,30 +1,36 @@
|
|
1
|
-
|
2
|
-
var type = event.type;
|
3
|
-
//All events need a type
|
4
|
-
if (type === undefined) { throw "Kernel got an event that had no type!"; }
|
1
|
+
//Pipes handle all communication and provide 1-way channels
|
5
2
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
3
|
+
//All the pipe 'routes'. Each pipe is a number that represents the receiver.
|
4
|
+
//This table looks up the receiving function
|
5
|
+
pipe_routes = {};
|
6
|
+
|
7
|
+
//Create a new pipe to a receiver
|
8
|
+
//will call 'callback' when new data is sent over this pipe
|
9
|
+
//and returns a opaque pipe pointer (pp)
|
10
|
+
function pipe(callback) {
|
11
|
+
var pp = UUID();
|
12
|
+
pipe_routes[pp] = callback;
|
13
|
+
return pp;
|
14
|
+
}
|
15
|
+
|
16
|
+
//Send a message over a pipe
|
17
|
+
function send(pp, msg) {
|
18
|
+
var callback = pipe_routes[pp];
|
19
|
+
if (callback === undefined) {
|
20
|
+
throw "Could not pipe_send because no route existed for pipe with pointer: "+pp+" with msg: "+msg;
|
19
21
|
}
|
20
22
|
|
21
|
-
|
22
|
-
var queue = Kernel.outboundEventQueue;
|
23
|
-
Kernel.outboundEventQueue = [];
|
24
|
-
return queue;
|
23
|
+
callback(msg);
|
25
24
|
}
|
26
25
|
|
27
|
-
|
28
|
-
|
29
|
-
|
26
|
+
//Delete a pipe
|
27
|
+
function close(pp) {
|
28
|
+
delete flock_pipe_routes[pp];
|
29
|
+
}
|
30
|
+
|
31
|
+
//List all pipes
|
32
|
+
function lspipe() {
|
33
|
+
for (pp in pipe_routes) {
|
34
|
+
console.log(pp + " - " + pipe_routes[pp]);
|
35
|
+
}
|
30
36
|
}
|
File without changes
|
data/spec/drivers/net_spec.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
require 'phantomjs'
|
2
|
-
require 'rspec/wait'
|
2
|
+
require 'rspec/wait'
|
3
3
|
require 'webrick'
|
4
4
|
require "./spec/helpers"
|
5
5
|
require 'json'
|
@@ -22,7 +22,7 @@ RSpec.describe "Drivers::Net" do
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
-
|
25
|
+
it "can make a get request" do
|
26
26
|
#Build driver
|
27
27
|
`cd ./app/drivers/browser; rake build`
|
28
28
|
|
@@ -85,7 +85,7 @@ RSpec.describe "Drivers::Net" do
|
|
85
85
|
@killable << @spek2
|
86
86
|
cr.eval %{
|
87
87
|
drivers.network.request('GET', 'http://localhost:#{@spek.port}', {}, function(res) {
|
88
|
-
port = res.port;
|
88
|
+
var port = res.port;
|
89
89
|
drivers.network.request('GET', 'http://localhost:'+port, {});
|
90
90
|
})
|
91
91
|
}
|
@@ -94,4 +94,66 @@ RSpec.describe "Drivers::Net" do
|
|
94
94
|
##Load synchronously, but execute the code asynchronously, quit after it's been running for 3 seconds
|
95
95
|
wait(3).for { called }.to eq(true)
|
96
96
|
end
|
97
|
+
|
98
|
+
it "can make a get and cancel a request that has not yet been received via callback" do
|
99
|
+
#Build driver
|
100
|
+
`cd ./app/drivers/browser; rake build`
|
101
|
+
|
102
|
+
cr = ChromeRunner.new "./products/drivers/browser.js"
|
103
|
+
|
104
|
+
#Setup rspec test server
|
105
|
+
called = false
|
106
|
+
@spek = Webbing.get "/" do |params|
|
107
|
+
{:port => @spek2.port}.to_json
|
108
|
+
end
|
109
|
+
|
110
|
+
@spek2 = Webbing.get "/" do |params|
|
111
|
+
called = true
|
112
|
+
end
|
113
|
+
|
114
|
+
@killable << @spek
|
115
|
+
cr.eval %{
|
116
|
+
socket = drivers.network.request('GET', 'http://localhost:#{@spek.port}', {}, function(res) {
|
117
|
+
var port = res.port;
|
118
|
+
drivers.network.request('GET', 'http://localhost:'+port, {});
|
119
|
+
|
120
|
+
});
|
121
|
+
|
122
|
+
drivers.network.cancel_request(socket);
|
123
|
+
}
|
124
|
+
cr.commit
|
125
|
+
|
126
|
+
#Load synchronously, but execute the code asynchronously, quit after it's been running for 3 seconds
|
127
|
+
sleep 2
|
128
|
+
expect(called).to eq(false)
|
129
|
+
end
|
130
|
+
|
131
|
+
it "returns an error for a non-existant resource" do
|
132
|
+
#Build driver
|
133
|
+
`cd ./app/drivers/browser; rake build`
|
134
|
+
|
135
|
+
cr = ChromeRunner.new "./products/drivers/browser.js"
|
136
|
+
|
137
|
+
#Setup rspec test server
|
138
|
+
@spek = Webbing.get "/" do |params|
|
139
|
+
{:port => @spek2.port}.to_json
|
140
|
+
end
|
141
|
+
|
142
|
+
error = nil
|
143
|
+
@spek2 = Webbing.get "/" do |params|
|
144
|
+
error = params["error"]
|
145
|
+
end
|
146
|
+
|
147
|
+
@killable << @spek
|
148
|
+
cr.eval %{
|
149
|
+
socket = drivers.network.request('GET', 'http://localhost:#{@spek.port}/404', {}, function(res, error) {
|
150
|
+
drivers.network.request('GET', 'http://localhost:'+#{@spek2.port}, {error: error});
|
151
|
+
});
|
152
|
+
}
|
153
|
+
cr.commit
|
154
|
+
|
155
|
+
#Load synchronously, but execute the code asynchronously, quit after it's been running for 3 seconds
|
156
|
+
sleep 2
|
157
|
+
expect(error).to eq("true")
|
158
|
+
end
|
97
159
|
end
|
data/spec/helpers.rb
CHANGED
@@ -73,6 +73,11 @@ module Webbing
|
|
73
73
|
res.header["Access-Control-Allow-Origin"] = "*"
|
74
74
|
res.header["Content-Type"] = "json/text"
|
75
75
|
end
|
76
|
+
@server.mount_proc '/404' do |req, res|
|
77
|
+
res.header["Access-Control-Allow-Origin"] = "*"
|
78
|
+
|
79
|
+
raise WEBrick::HTTPStatus::NotFound
|
80
|
+
end
|
76
81
|
@server.start
|
77
82
|
end
|
78
83
|
|
data/ypou
ADDED
File without changes
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: flok
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- seo
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-04-
|
11
|
+
date: 2015-04-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -160,29 +160,37 @@ extensions: []
|
|
160
160
|
extra_rdoc_files: []
|
161
161
|
files:
|
162
162
|
- ".gitignore"
|
163
|
+
- ".run2"
|
163
164
|
- ".travis.yml"
|
164
165
|
- Gemfile
|
165
166
|
- LICENSE
|
166
167
|
- README.md
|
167
168
|
- Rakefile
|
168
|
-
- app/drivers/
|
169
|
-
- app/drivers/
|
170
|
-
- app/drivers/
|
169
|
+
- app/drivers/chrome/README.md
|
170
|
+
- app/drivers/chrome/Rakefile
|
171
|
+
- app/drivers/chrome/config.yml
|
172
|
+
- app/drivers/chrome/net.js
|
173
|
+
- app/drivers/chrome/ui.js
|
174
|
+
- app/drivers/chrome/vendor/jquery.js
|
175
|
+
- app/drivers/iface/ui.js
|
171
176
|
- bin/flok
|
177
|
+
- docs/architecture.md
|
178
|
+
- docs/compilation.md
|
179
|
+
- docs/platform_drivers.md
|
180
|
+
- docs/project_layout.md
|
172
181
|
- flok.gemspec
|
173
182
|
- lib/flok.rb
|
174
183
|
- lib/flok/version.rb
|
175
|
-
- lib/js/kernel/common.js
|
176
|
-
- lib/js/kernel/handleCustomEvent.js
|
177
|
-
- lib/js/kernel/handleInitEvent.js
|
178
|
-
- lib/js/kernel/handleTickEvent.js
|
179
184
|
- lib/js/kernel/pipe.js
|
180
|
-
- lib/js/kernel/
|
185
|
+
- lib/js/kernel/utils.js
|
186
|
+
- lib/js/namespaces.js
|
181
187
|
- logo.png
|
188
|
+
- public/application.js
|
182
189
|
- spec/cli_spec.rb
|
183
190
|
- spec/drivers/net_spec.rb
|
184
191
|
- spec/helpers.rb
|
185
192
|
- spec/merge_source_spec.rb
|
193
|
+
- ypou
|
186
194
|
homepage: https://github.com/sotownsend/flok
|
187
195
|
licenses:
|
188
196
|
- MIT
|
@@ -1,24 +0,0 @@
|
|
1
|
-
drivers = window.drivers || {}
|
2
|
-
drivers.network = {}
|
3
|
-
|
4
|
-
$(document).ready(function() {
|
5
|
-
//drivers.network.request("GET", "http://test.services.fittr.com/ping", {}, null);
|
6
|
-
})
|
7
|
-
|
8
|
-
//A basic get request that supports callbacks
|
9
|
-
drivers.network.request = function(verb, url, params, completion) {
|
10
|
-
$.ajax({
|
11
|
-
url: url,
|
12
|
-
type: verb,
|
13
|
-
data: params,
|
14
|
-
success: function(data) {
|
15
|
-
data = JSON.parse(data);
|
16
|
-
completion = completion || function() {}
|
17
|
-
if (completion != null) {
|
18
|
-
completion(data);
|
19
|
-
}
|
20
|
-
},
|
21
|
-
error: function(xhr, status, err) {
|
22
|
-
}
|
23
|
-
})
|
24
|
-
}
|
data/lib/js/kernel/common.js
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
Kernel = {}
|
data/lib/js/kernel/task.js
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
//Global task list
|
2
|
-
Kernel.tasks = [];
|
3
|
-
|
4
|
-
Kernel.Task = function(name) {
|
5
|
-
this.name = name;
|
6
|
-
Kernel.tasks.push(this);
|
7
|
-
|
8
|
-
this.sendEvent = function(type, info) {
|
9
|
-
info.type = type;
|
10
|
-
Kernel.sendEvent(info);
|
11
|
-
}
|
12
|
-
|
13
|
-
var handlers = [];
|
14
|
-
this.on = function(name, callback) {
|
15
|
-
handlers[name] = callback;
|
16
|
-
}
|
17
|
-
|
18
|
-
this.handle = function(type, event) {
|
19
|
-
handler = handlers[type];
|
20
|
-
if (handler != undefined) {
|
21
|
-
handler(event)
|
22
|
-
}
|
23
|
-
}
|
24
|
-
}
|