subfork 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +40 -25
- package/dist/badge.min.js +15 -0
- package/dist/subfork.min.js +2 -1
- package/dist/subfork.min.js.map +1 -0
- package/dist/subfork.mjs +2566 -0
- package/dist/subfork.mjs.map +1 -0
- package/package.json +25 -7
- package/dist/subfork.js +0 -442
- package/subfork.js +0 -442
package/dist/subfork.js
DELETED
|
@@ -1,442 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
Copyright (c) Subfork. All rights reserved.
|
|
3
|
-
|
|
4
|
-
TODO:
|
|
5
|
-
- replace post-request with non-jquery function
|
|
6
|
-
- refactor to immediately-invoked function expression (IIFE)
|
|
7
|
-
|
|
8
|
-
const Subfork = (() => {
|
|
9
|
-
...
|
|
10
|
-
return {
|
|
11
|
-
subfork: Subfork
|
|
12
|
-
}
|
|
13
|
-
})();
|
|
14
|
-
|
|
15
|
-
Instantiate client:
|
|
16
|
-
|
|
17
|
-
const subfork = Subfork();
|
|
18
|
-
|
|
19
|
-
or pass in some config values:
|
|
20
|
-
|
|
21
|
-
const subfork = Subfork({
|
|
22
|
-
host: "test.fork.io",
|
|
23
|
-
on: {
|
|
24
|
-
"message": function(msg) {
|
|
25
|
-
console.log(msg);
|
|
26
|
-
},
|
|
27
|
-
}
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
Connect "test" task "done" event callback:
|
|
31
|
-
|
|
32
|
-
subfork.task("test").on("done", function(e) {
|
|
33
|
-
console.log(e.message + ": " + e.task.results);
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
Create a "test" task with some data:
|
|
37
|
-
|
|
38
|
-
subfork.task("test").create({t:2});
|
|
39
|
-
|
|
40
|
-
Set on "done" callback when creating task:
|
|
41
|
-
|
|
42
|
-
subfork.task("test").create({
|
|
43
|
-
"t": 3
|
|
44
|
-
}).on("done", function(event) {
|
|
45
|
-
console.log(event);
|
|
46
|
-
});
|
|
47
|
-
*/
|
|
48
|
-
|
|
49
|
-
// define some constants
|
|
50
|
-
const version = "0.1.1";
|
|
51
|
-
const api_version = "api";
|
|
52
|
-
const hostname = window.location.hostname;
|
|
53
|
-
const port = window.location.port;
|
|
54
|
-
const protocol = window.location.protocol;
|
|
55
|
-
const socket_script = "https://code.subfork.com/socket.io.min.js";
|
|
56
|
-
const wait_time = 100;
|
|
57
|
-
|
|
58
|
-
// init some variables
|
|
59
|
-
var message;
|
|
60
|
-
var server;
|
|
61
|
-
var socket;
|
|
62
|
-
var socket_loaded = false;
|
|
63
|
-
|
|
64
|
-
// async returns a sha256 string (only works with https)
|
|
65
|
-
async function sha256(message) {
|
|
66
|
-
const msgBuffer = new TextEncoder("utf-8").encode(message);
|
|
67
|
-
// hash the message
|
|
68
|
-
const hashBuffer = await window.crypto.subtle.digest("SHA-256", msgBuffer);
|
|
69
|
-
// convert ArrayBuffer to Array
|
|
70
|
-
const hashArray = Array.from(new Uint8Array(hashBuffer));
|
|
71
|
-
// convert bytes to hex string
|
|
72
|
-
const hashHex = hashArray.map(b => ("00" + b.toString(16)).slice(-2)).join("");
|
|
73
|
-
return hashHex;
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
// load socket library (required for events)
|
|
77
|
-
function load_socket_library(host, callback) {
|
|
78
|
-
if (socket_loaded) {
|
|
79
|
-
callback(host);
|
|
80
|
-
} else {
|
|
81
|
-
var script = document.createElement("script");
|
|
82
|
-
script.src = socket_script;
|
|
83
|
-
document.head.appendChild(script);
|
|
84
|
-
script.onload = function () {
|
|
85
|
-
socket_loaded = true;
|
|
86
|
-
callback(host);
|
|
87
|
-
};
|
|
88
|
-
};
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
// waits for condition to be true
|
|
92
|
-
function wait_for(condition, callback) {
|
|
93
|
-
if(!condition()) {
|
|
94
|
-
window.setTimeout(wait_for.bind(null, condition, callback), wait_time);
|
|
95
|
-
} else {
|
|
96
|
-
callback();
|
|
97
|
-
};
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
// returns a local api url, e.g.: /api/task/create
|
|
101
|
-
function build_url(endpoint) {
|
|
102
|
-
return "/" + api_version + "/" + endpoint;
|
|
103
|
-
};
|
|
104
|
-
|
|
105
|
-
// returns true if is running locally
|
|
106
|
-
function is_local() {
|
|
107
|
-
return (
|
|
108
|
-
(protocol === "http:") &&
|
|
109
|
-
(hostname === "localhost" || hostname === "0.0.0.0" || hostname === "127.0.0.1") &&
|
|
110
|
-
(port === "8000" || port === "8080")
|
|
111
|
-
);
|
|
112
|
-
};
|
|
113
|
-
|
|
114
|
-
// post request to server
|
|
115
|
-
// function _request(url, data={}) {
|
|
116
|
-
// fetch(url, {
|
|
117
|
-
// method: "POST",
|
|
118
|
-
// headers: {
|
|
119
|
-
// "Accept": "application/json",
|
|
120
|
-
// "Content-Type': 'application/json"
|
|
121
|
-
// },
|
|
122
|
-
// body: JSON.stringify(data)
|
|
123
|
-
// })
|
|
124
|
-
// .then(response => response.json())
|
|
125
|
-
// .then(response => console.log(JSON.stringify(response)))
|
|
126
|
-
// };
|
|
127
|
-
function post_request(url, data={}, func=null, async=true) {
|
|
128
|
-
$.ajax({
|
|
129
|
-
type: "POST",
|
|
130
|
-
contentType: "application/json; charset=utf-8",
|
|
131
|
-
url: url,
|
|
132
|
-
async: async,
|
|
133
|
-
data: JSON.stringify(data),
|
|
134
|
-
success: function (resp) {
|
|
135
|
-
if (func) {
|
|
136
|
-
func(resp);
|
|
137
|
-
} else {
|
|
138
|
-
console.debug("no callback");
|
|
139
|
-
};
|
|
140
|
-
},
|
|
141
|
-
dataType: "json"
|
|
142
|
-
});
|
|
143
|
-
};
|
|
144
|
-
|
|
145
|
-
// datatype class
|
|
146
|
-
class Datatype {
|
|
147
|
-
constructor(name) {
|
|
148
|
-
this.name = name;
|
|
149
|
-
}
|
|
150
|
-
create(data, callback=null) {
|
|
151
|
-
let row_data = {
|
|
152
|
-
"collection": this.name,
|
|
153
|
-
"data": data,
|
|
154
|
-
"version": version,
|
|
155
|
-
};
|
|
156
|
-
let success = false;
|
|
157
|
-
let url = build_url("data/create");
|
|
158
|
-
post_request(url, data=row_data, function(resp) {
|
|
159
|
-
if (callback) {
|
|
160
|
-
callback(resp);
|
|
161
|
-
};
|
|
162
|
-
})
|
|
163
|
-
return success;
|
|
164
|
-
}
|
|
165
|
-
delete(params, callback=null) {
|
|
166
|
-
let data = {
|
|
167
|
-
"collection": this.name,
|
|
168
|
-
"params": params,
|
|
169
|
-
"version": version,
|
|
170
|
-
};
|
|
171
|
-
let success = false;
|
|
172
|
-
let url = build_url("data/delete");
|
|
173
|
-
post_request(url, data=data, function(resp) {
|
|
174
|
-
if (callback) {
|
|
175
|
-
callback(resp);
|
|
176
|
-
};
|
|
177
|
-
})
|
|
178
|
-
return success;
|
|
179
|
-
}
|
|
180
|
-
find(params, callback=null, expand=false, async=true) {
|
|
181
|
-
let data = {
|
|
182
|
-
"collection": this.name,
|
|
183
|
-
"expand": expand,
|
|
184
|
-
"params": params,
|
|
185
|
-
"version": version,
|
|
186
|
-
};
|
|
187
|
-
let success = false;
|
|
188
|
-
let url = build_url("data/get");
|
|
189
|
-
post_request(url, data=data, function(resp) {
|
|
190
|
-
if (callback) {
|
|
191
|
-
callback(resp);
|
|
192
|
-
};
|
|
193
|
-
}, async=async)
|
|
194
|
-
return success;
|
|
195
|
-
}
|
|
196
|
-
update(id, data, callback=null) {
|
|
197
|
-
let row_data = {
|
|
198
|
-
"collection": this.name,
|
|
199
|
-
"id": id,
|
|
200
|
-
"data": data,
|
|
201
|
-
"version": version,
|
|
202
|
-
};
|
|
203
|
-
let success = false;
|
|
204
|
-
let url = build_url("data/update");
|
|
205
|
-
post_request(url, data=row_data, function(resp) {
|
|
206
|
-
if (callback) {
|
|
207
|
-
callback(resp);
|
|
208
|
-
};
|
|
209
|
-
})
|
|
210
|
-
return success;
|
|
211
|
-
}
|
|
212
|
-
};
|
|
213
|
-
|
|
214
|
-
// event class
|
|
215
|
-
class SubforkEvent {
|
|
216
|
-
constructor(event_name, event_data) {
|
|
217
|
-
this.name = event_name;
|
|
218
|
-
this.type = event_data.type;
|
|
219
|
-
this.message = event_data.message;
|
|
220
|
-
this.event_data = event_data;
|
|
221
|
-
}
|
|
222
|
-
data() {
|
|
223
|
-
if (this.type == "data") {
|
|
224
|
-
return new Datatype(this.name);
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
task() {
|
|
228
|
-
if (this.type == "task") {
|
|
229
|
-
let queue = new SubforkTaskQueue(this.event_data.queue);
|
|
230
|
-
return new SubforkTask(queue, this.event_data.task);
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
user() {
|
|
234
|
-
if (this.type == "user") {
|
|
235
|
-
return new SubforkUser(queue, this.event_data.task);
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
};
|
|
239
|
-
|
|
240
|
-
// task class
|
|
241
|
-
class SubforkTask {
|
|
242
|
-
constructor(queue, data) {
|
|
243
|
-
this.queue = queue;
|
|
244
|
-
this.data = data;
|
|
245
|
-
}
|
|
246
|
-
get_error() {
|
|
247
|
-
return this.data.error;
|
|
248
|
-
}
|
|
249
|
-
get_results() {
|
|
250
|
-
try {
|
|
251
|
-
return JSON.parse(this.data.results);
|
|
252
|
-
} catch {
|
|
253
|
-
return this.data.results;
|
|
254
|
-
};
|
|
255
|
-
}
|
|
256
|
-
// TODO: hash the event signature
|
|
257
|
-
on(event_name, callback) {
|
|
258
|
-
return this.queue.on(event_name, callback);
|
|
259
|
-
}
|
|
260
|
-
};
|
|
261
|
-
|
|
262
|
-
// task queue class
|
|
263
|
-
class SubforkTaskQueue {
|
|
264
|
-
constructor(conn, name) {
|
|
265
|
-
this.conn = conn;
|
|
266
|
-
this.name = name;
|
|
267
|
-
}
|
|
268
|
-
// create and enqueue new task
|
|
269
|
-
create(data) {
|
|
270
|
-
var t = new SubforkTask(this, data);
|
|
271
|
-
if (this.enqueue(t)) {
|
|
272
|
-
return t;
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
// enqueue a task
|
|
276
|
-
enqueue(task) {
|
|
277
|
-
let data = {
|
|
278
|
-
"queue": this.name,
|
|
279
|
-
"data": task.data,
|
|
280
|
-
"version": version,
|
|
281
|
-
};
|
|
282
|
-
let success = false;
|
|
283
|
-
let url = build_url("task/create");
|
|
284
|
-
post_request(url, data=data, function(resp) {
|
|
285
|
-
if (resp.success) {
|
|
286
|
-
success = true;
|
|
287
|
-
};
|
|
288
|
-
})
|
|
289
|
-
return success;
|
|
290
|
-
}
|
|
291
|
-
// find and return a task by id
|
|
292
|
-
get(taskid) {
|
|
293
|
-
let data = {
|
|
294
|
-
"queue": this.name,
|
|
295
|
-
"taskid": taskid,
|
|
296
|
-
"version": version,
|
|
297
|
-
};
|
|
298
|
-
let url = build_url("task/get");
|
|
299
|
-
var task;
|
|
300
|
-
post_request(url, data=data, function(resp) {
|
|
301
|
-
if (resp.success) {
|
|
302
|
-
task = new SubforkTask(this, resp.data);
|
|
303
|
-
} else {
|
|
304
|
-
console.error(resp.error);
|
|
305
|
-
};
|
|
306
|
-
}, async=false);
|
|
307
|
-
return task;
|
|
308
|
-
}
|
|
309
|
-
// listen for task events
|
|
310
|
-
// TODO: hash the event signature
|
|
311
|
-
on(event_name, callback) {
|
|
312
|
-
let sig = this.conn.session.sessionid + ":task:" + this.name + ":" + event_name;
|
|
313
|
-
socket.on(sig, function(event_data, cb) {
|
|
314
|
-
let event = new SubforkEvent(event_name, event_data);
|
|
315
|
-
callback(event);
|
|
316
|
-
});
|
|
317
|
-
return true;
|
|
318
|
-
}
|
|
319
|
-
};
|
|
320
|
-
|
|
321
|
-
// user class
|
|
322
|
-
class SubforkUser {
|
|
323
|
-
constructor(data) {
|
|
324
|
-
this.data = data;
|
|
325
|
-
}
|
|
326
|
-
};
|
|
327
|
-
|
|
328
|
-
// in-memory only data cache class
|
|
329
|
-
class SubforkCache {
|
|
330
|
-
constructor(parent) {
|
|
331
|
-
this.parent = parent;
|
|
332
|
-
this._cache = {};
|
|
333
|
-
}
|
|
334
|
-
add(type, name, value) {
|
|
335
|
-
if (!(type in this._cache)) {
|
|
336
|
-
this._cache[type] = {};
|
|
337
|
-
};
|
|
338
|
-
this._cache[type][name] = value;
|
|
339
|
-
}
|
|
340
|
-
clear() {
|
|
341
|
-
Object.keys(this._cache).forEach(key => {
|
|
342
|
-
delete this._cache[key];
|
|
343
|
-
});
|
|
344
|
-
}
|
|
345
|
-
del(type, name) {
|
|
346
|
-
if (type in this._cache && name in this._cache[type]) {
|
|
347
|
-
delete this._cache[type][name];
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
get(type, name) {
|
|
351
|
-
if (type in this._cache && name in this._cache[type]) {
|
|
352
|
-
return this._cache[type][name];
|
|
353
|
-
};
|
|
354
|
-
}
|
|
355
|
-
update(type, other) {
|
|
356
|
-
if (!(type in this._cache)) {
|
|
357
|
-
this._cache[type] = {};
|
|
358
|
-
};
|
|
359
|
-
Object.assign(this._cache[type], other);
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
// subfork client class
|
|
364
|
-
class Subfork {
|
|
365
|
-
constructor(config={}) {
|
|
366
|
-
this.cache = new SubforkCache(this);
|
|
367
|
-
this.session = {};
|
|
368
|
-
this.set_config(config);
|
|
369
|
-
this.connect();
|
|
370
|
-
}
|
|
371
|
-
// checks config values for default overrides
|
|
372
|
-
set_config(config) {
|
|
373
|
-
this.config = config;
|
|
374
|
-
this.config.host = this.config["host"] ?? window.location.hostname;
|
|
375
|
-
this.config.port = this.config["port"] ?? window.location.port;
|
|
376
|
-
}
|
|
377
|
-
// connect to event server
|
|
378
|
-
connect() {
|
|
379
|
-
this.session = this.get_session_data();
|
|
380
|
-
console.debug("sessionid", this.session.sessionid);
|
|
381
|
-
load_socket_library(this.config.host, function(host) {
|
|
382
|
-
socket = io("https://events.fork.io");
|
|
383
|
-
console.debug("connected to event server");
|
|
384
|
-
});
|
|
385
|
-
}
|
|
386
|
-
// get session data from the server
|
|
387
|
-
get_session_data() {
|
|
388
|
-
let data = {"source": this.config.host, "version": api_version};
|
|
389
|
-
let session_data = {};
|
|
390
|
-
let url = build_url("get_session_data");
|
|
391
|
-
post_request(url, data, function(resp) {
|
|
392
|
-
if (resp.success && resp.data) {
|
|
393
|
-
session_data = resp.data;
|
|
394
|
-
} else {
|
|
395
|
-
console.error(resp.error);
|
|
396
|
-
};
|
|
397
|
-
}, false);
|
|
398
|
-
return session_data;
|
|
399
|
-
};
|
|
400
|
-
// datatype accessor
|
|
401
|
-
data(name) {
|
|
402
|
-
if (!(this.cache.get("data", name))) {
|
|
403
|
-
var dt = new Datatype(name);
|
|
404
|
-
this.cache.add("data", name, dt);
|
|
405
|
-
};
|
|
406
|
-
return this.cache.get("data", name);
|
|
407
|
-
}
|
|
408
|
-
// return true if connected to event server
|
|
409
|
-
is_connected() {
|
|
410
|
-
return (socket_loaded && socket.connected);
|
|
411
|
-
}
|
|
412
|
-
// on ready wait for socket connection
|
|
413
|
-
ready(callback) {
|
|
414
|
-
wait_for(() => window.socket, () => callback());
|
|
415
|
-
}
|
|
416
|
-
// task queue accessor
|
|
417
|
-
task(name) {
|
|
418
|
-
if (!(this.cache.get("task", name))) {
|
|
419
|
-
var q = new SubforkTaskQueue(this, name);
|
|
420
|
-
this.cache.add("task", name, q);
|
|
421
|
-
};
|
|
422
|
-
return this.cache.get("task", name);
|
|
423
|
-
}
|
|
424
|
-
// user accessor
|
|
425
|
-
user(username) {
|
|
426
|
-
if (!(this.cache.get("user", username))) {
|
|
427
|
-
let data = {
|
|
428
|
-
"username": username,
|
|
429
|
-
"version": version,
|
|
430
|
-
};
|
|
431
|
-
let url = build_url("user/get");
|
|
432
|
-
var user;
|
|
433
|
-
post_request(url, data=data, function(resp) {
|
|
434
|
-
if (resp.success) {
|
|
435
|
-
user = new SubforkUser(resp.data);
|
|
436
|
-
};
|
|
437
|
-
}, false);
|
|
438
|
-
this.cache.add("user", username, user);
|
|
439
|
-
};
|
|
440
|
-
return this.cache.get("user", username);
|
|
441
|
-
}
|
|
442
|
-
};
|