-
Notifications
You must be signed in to change notification settings - Fork 19
/
Copy pathindex.html
217 lines (203 loc) · 9.32 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
<!doctype html>
<html>
<head>
<title>Local.js 0.6.2</title>
<!-- styling -->
<link rel="stylesheet" href="assets/bootstrap/css/bootstrap.css" />
<link rel="stylesheet" href="assets/css/sitewide.css" />
<link rel="stylesheet" href="assets/prism/prism.css" />
<link rel="icon" type="image/png" href="/assets/favicon.png" />
<link href='http://fonts.googleapis.com/css?family=Roboto:300,400,700' rel='stylesheet' type='text/css'>
<style>
pre[class*="language-"] { background: #fff; border: 0; }
code[class*="language-"] { color: rgb(60, 64, 68); font-size: 14px }
.token.comment, .token.prolog, .token.doctype, .token.cdata { color: #71787C; }
.token.selector, .token.attr-name, .token.string, .token.builtin { color: #0DA500; }
.token.property, .token.tag, .token.boolean, .token.number, .token.constant, .token.symbol { color: #48B63F; }
</style>
</head>
<body>
<div id="hero">
<h1>Local.js</h1>
<h4>An open-source security and IPC framework for socially-shareable Web plugins.</h4>
</div>
<div id="nav">
<div id="logo">Local.js</div>
<ul class="inline"><li class="active"><a target="_top" href="/">Home</a></li><li><a target="_top" href="/docs.html">Documentation</a></li><li><a target="_top" href="https://github.com/pfraze/local">Repo</a></li></ul>
</div>
<div class="container">
<table class="intro">
<tr>
<td><img src="assets/icon-idea.png"></td>
<td><p>Imagine if a <strong>Web application</strong> were more like your <strong>operating system.</strong> You could run programs that add features, choose where your data goes, and share your changes with other users.</p></td>
</tr>
</table>
</div>
<div class="container container-wide">
<table class="overview">
<tr>
<td width="33%"><div><img src="assets/icon-network.png"><p>Inspired by Unix's files, <a href="https://github.com/pfraze/local">Local.js</a> uses HTTP as a universal <a href="http://en.wikipedia.org/wiki/Inter-process_communication">IPC</a> interface for remote and local code.</p></div></td>
<td width="33%"><div><img src="assets/icon-download.png"><p>Server scripts are assigned URLs and loaded into Web Workers on-demand – just like pages are loaded into the browser as you navigate.</p></div></td>
<td width="33%"><div><img src="assets/icon-link.png"><p>Using two-way messaging and typed links, the plug-in servers add new behaviors to the application.</p></div></td>
</tr>
</table>
</div>
<div class="container">
<div class="row">
<div class="span5">
<h3>Ajax-Everywhere</h3>
<!-- <p><strong>Write server functions and send Ajax requests to code within the client.</strong></p> -->
<p>Local.js registers the "httpl://" scheme, enabling functions to respond to requests.</p>
<ul>
<li>Structure page components into loosely-coupled services.</li>
<li>Target links and forms at server functions.</li>
<li>Run local proxies to your backend that degrade gracefully into offline-mode on a connection-drop.</li>
<li>Host scaffold servers to mock behaviors during development.</li>
</ul>
</div>
<div class="span6 offset1">
<pre><code class="language-javascript">// Register a new server in the local hostmap
local.addServer('hello-world', function(req, res) {
res.writeHead(200, 'OK');
res.end('Hello, world!');
}
// Dispatch an ajax request to that function
local.GET('httpl://hello-world')
.then(function(res) {
console.log(res.body);
// => 'Hello, world!'
});</code></pre>
</div>
</div>
<div class="row">
<div class="span5">
<h3>Safe Execution with Worker VMs</h3>
<!-- <p><strong>Load new server functions into contained Worker threads by simply issuing requests to their URLs.</strong></p> -->
<p>Local.js uses a special hostname-format to find server scripts and load them automatically on a request. The Worker is destroyed as soon as it responds.</p>
<ul>
<li>Execute code from any domain with the protection of multi-threaded Virtual Machines.</li>
<li>Contain data safely on the client - Workers can only talk to the page.</li>
<li>Enact or discard requests from Workers by applying a permissions model.</li>
</ul>
</div>
<div class="span6 offset1">
<pre><code class="language-javascript">// http://myserver.com/worker.js
function main(req, res) {
res.writeHead(200, 'OK');
res.end('Hello, other world!');
}
// The page:
local.GET('httpl://myserver.com(/worker.js)/')
.then(function(res) {
console.log(res.body);
// => "Hello, other world!"
});</code></pre>
</div>
</div>
<div class="row">
<div class="span5">
<h3>Semantic API Queries</h3>
<!-- <p><strong>Run queries against typed links to discover and reason about new services.</strong></p> -->
<p>Navigate the Web graph with a headless user-agent, discovering supported APIs through typed links.</p>
<ul>
<li>Built with accepted standards (<a href="http://tools.ietf.org/html/rfc5988">the Link header</a> and <a href="http://tools.ietf.org/html/rfc6570">URI templates</a>).</li>
<li>Reason about endpoints without <a href="http://en.wikipedia.org/wiki/Web_Services_Description_Language">complex IDLs</a>.</li>
<li>Navigate remote servers, local functions, and Worker plugins in a unified graph.</li>
</ul>
</div>
<div class="span6 offset1">
<pre><code class="language-javascript">// Get the Bob user
local.agent('http://myserver.com')
.follow({ rel: 'collection', id: 'users' })
.follow({ rel: 'schema.org/Person', id: 'bob' })
.GET()
.then(function(res) {
console.log(res.body);
/* => {
name: "Bob Robertson",
description: "Project lead",
...
} */
});</code></pre>
</div>
</div>
<hr>
<div class="row">
<div class="span12">
<h3 class="centered">Example: Composable Pipelines</h3>
<p>Let's imagine we're implementing a Unix-style pipes-and-streams interface. We'll want to arrange transformer programs in a sequence, then pipe the output from one program into the input of the next. How do we get started?</p>
<p><strong>First, we'll publish a reltype</strong> which defines the program behavior: <a href="http://httplocal.com/transformer">httplocal.com/transfomer</a>. To summarize, a transformer accepts <code>POST</code> with content-type of <code>text/plain</code> and responds <code>200 OK</code> with the transformed <code>text/plain</code>.</p>
<p>Here's an implementation:</p>
<pre><code class="language-javascript">/**
* httpl://httplocal.com(/examples/toupper.js)/
*/
importScripts('/local.min.js');
function main(req, res) {
// Set headers
res.header('Link', [{ href: '/', rel: 'self httplocal.com/transformer', title: 'To Uppercase' }]);
res.header('Content-Type', 'text/plain');
if (req.method == 'HEAD') {
// Respond with headers only
res.writeHead(204, 'OK, no content').end();
return;
}
if (req.method == 'POST') {
// Apply transformation
res.writeHead(200, 'OK'); // because HTTPL is full-duplex, we can respond while the request is streaming
req.on('data', function(chunk) { res.write(chunk.toUpperCase()); });
req.on('end', function() { res.end(); });
return;
}
// Invalid method
res.writeHead(405, 'Bad Method').end();
}</code></pre>
<p><strong>Next, we'll create the client.</strong> Our pipeline-creator will take URLs and send HEAD requests in order to check the <code>self</code> link. If the self-link asserts that the URL is a transformer, we add the URL to our sequence. To execute the sequence, we'll open <code>POST</code> requests to each entry, passing along the responses.</p>
<pre><code class="language-javascript">// Verify the given URL is a transformer
function verifyTransformer(url) {
return local.HEAD(url).then(function(res) {
var selfLink = local.queryLinks(res, { rel: 'self httplocal.com/transformer' })[0];
if (!selfLink) {
throw 'Not a valid transformer';
}
return selfLink;
});
}</code></pre>
<p><strong>Let's give it a shot!</strong> Try these URLs: <code>httpl://httplocal.com(/examples/toupper.js)/</code>, <code>httpl://httplocal.com(/examples/slugify.js)/</code>, and <code>httpl://httplocal.com(/examples/charcount.js)/</code>.</p>
<div class="row">
<div class="span4">
<form action="httpl://pipes" method="ADD">
<p><strong>URL Entry</strong></p>
<input class="input-block-level" type="url" name="url" id="url-input">
<br>
<input class="btn btn-primary" type="submit" value="Add"><br>
<p id="pipes-errout" class="help-text text-danger"></p>
</form>
</div>
<div class="span4">
<p><strong>Pipeline</strong></p>
<div class="well" id="pipes-sequence">
<em>No URLs Added</em>
</div>
</div>
<div class="span4">
<p><strong>Input</strong>: "Welcome, my son. Welcome... to the machine."</p>
<p><span id="pipes-output"></span></p>
</div>
</div>
</div>
</div>
</div>
<!-- third-party -->
<script src="assets/prism/prism.js"></script>
<!-- environment -->
<script src="assets/jquery-2.1.0.min.js"></script>
<script src="assets/jquery.sticky.js"></script>
<script src="local.js"></script>
<script src="assets/index.js"></script>
<script>
$(document).ready(function(){
$("#nav").sticky({topSpacing:0});
});
</script>
</body>
</html>