forked from cory/tildefriends
		
	Do app -> client communication more like tfrpc so that it's easier to get responses.
git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@3956 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
		
							
								
								
									
										74
									
								
								core/app.js
									
									
									
									
									
								
							
							
						
						
									
										74
									
								
								core/app.js
									
									
									
									
									
								
							@@ -1,7 +1,10 @@
 | 
			
		||||
import * as auth from './auth.js';
 | 
			
		||||
import * as core from './core.js';
 | 
			
		||||
 | 
			
		||||
var gSessionIndex = 0;
 | 
			
		||||
let g_next_id = 1;
 | 
			
		||||
let g_calls = {};
 | 
			
		||||
 | 
			
		||||
let gSessionIndex = 0;
 | 
			
		||||
 | 
			
		||||
function makeSessionId() {
 | 
			
		||||
	return (gSessionIndex++).toString();
 | 
			
		||||
@@ -19,31 +22,45 @@ App.prototype.readOutput = function(callback) {
 | 
			
		||||
 | 
			
		||||
App.prototype.makeFunction = function(api) {
 | 
			
		||||
	let self = this;
 | 
			
		||||
	let id = g_next_id++;
 | 
			
		||||
	while (!id || g_calls[id]) {
 | 
			
		||||
		id = g_next_id++;
 | 
			
		||||
	}
 | 
			
		||||
	let promise = new Promise(function(resolve, reject) {
 | 
			
		||||
		g_calls[id] = {resolve: resolve, reject: reject};
 | 
			
		||||
	});
 | 
			
		||||
	let result = function() {
 | 
			
		||||
		let message = {action: api[0]};
 | 
			
		||||
		for (let i = 1; i < api.length; i++) {
 | 
			
		||||
			message[api[i]] = arguments[i - 1];
 | 
			
		||||
		}
 | 
			
		||||
		let message = {
 | 
			
		||||
			message: 'tfrpc',
 | 
			
		||||
			method: api[0],
 | 
			
		||||
			params: [...arguments],
 | 
			
		||||
			id: id,
 | 
			
		||||
		};
 | 
			
		||||
		self.send(message);
 | 
			
		||||
		return promise;
 | 
			
		||||
	};
 | 
			
		||||
	Object.defineProperty(result, 'name', {value: api[0], writable: false});
 | 
			
		||||
	return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
App.prototype.send = function(message) {
 | 
			
		||||
	if (message) {
 | 
			
		||||
		this._send_queue.push(message);
 | 
			
		||||
	if (this._send_queue) {
 | 
			
		||||
		if (this._on_output) {
 | 
			
		||||
			this._send_queue.forEach(x => this._on_output(x));
 | 
			
		||||
			this._send_queue = null;
 | 
			
		||||
		} else if (message) {
 | 
			
		||||
			this._send_queue.push(message);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if (this._on_output) {
 | 
			
		||||
		this._send_queue.forEach(message => this._on_output(message));
 | 
			
		||||
		this._send_queue = [];
 | 
			
		||||
	if (message && this._on_output) {
 | 
			
		||||
		this._on_output(message);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function socket(request, response, client) {
 | 
			
		||||
	var process;
 | 
			
		||||
	var options = {};
 | 
			
		||||
	var credentials = auth.query(request.headers);
 | 
			
		||||
	let process;
 | 
			
		||||
	let options = {};
 | 
			
		||||
	let credentials = auth.query(request.headers);
 | 
			
		||||
 | 
			
		||||
	response.onClose = async function() {
 | 
			
		||||
		if (process && process.task) {
 | 
			
		||||
@@ -59,7 +76,7 @@ function socket(request, response, client) {
 | 
			
		||||
 | 
			
		||||
	response.onMessage = async function(event) {
 | 
			
		||||
		if (event.opCode == 0x1 || event.opCode == 0x2) {
 | 
			
		||||
			var message;
 | 
			
		||||
			let message;
 | 
			
		||||
			try {
 | 
			
		||||
				message = JSON.parse(event.data);
 | 
			
		||||
			} catch (error) {
 | 
			
		||||
@@ -67,11 +84,11 @@ function socket(request, response, client) {
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
			if (message.action == "hello") {
 | 
			
		||||
				var packageOwner;
 | 
			
		||||
				var packageName;
 | 
			
		||||
				var blobId;
 | 
			
		||||
				var match;
 | 
			
		||||
				var parentApp;
 | 
			
		||||
				let packageOwner;
 | 
			
		||||
				let packageName;
 | 
			
		||||
				let blobId;
 | 
			
		||||
				let match;
 | 
			
		||||
				let parentApp;
 | 
			
		||||
				if (match = /^\/([&%][^\.]{44}(?:\.\w+)?)(\/?.*)/.exec(message.path)) {
 | 
			
		||||
					blobId = match[1];
 | 
			
		||||
				} else if (match = /^\/\~([^\/]+)\/([^\/]+)\/$/.exec(message.path)) {
 | 
			
		||||
@@ -83,7 +100,7 @@ function socket(request, response, client) {
 | 
			
		||||
						return;
 | 
			
		||||
					}
 | 
			
		||||
					if (packageOwner != 'core') {
 | 
			
		||||
						var coreId = await new Database('core').get('path:' + packageName);
 | 
			
		||||
						let coreId = await new Database('core').get('path:' + packageName);
 | 
			
		||||
						parentApp = {
 | 
			
		||||
							path: '/~core/' + packageName + '/',
 | 
			
		||||
							id: coreId,
 | 
			
		||||
@@ -101,7 +118,7 @@ function socket(request, response, client) {
 | 
			
		||||
				options.credentials = credentials;
 | 
			
		||||
				options.packageOwner = packageOwner;
 | 
			
		||||
				options.packageName = packageName;
 | 
			
		||||
				var sessionId = makeSessionId();
 | 
			
		||||
				let sessionId = makeSessionId();
 | 
			
		||||
				if (blobId) {
 | 
			
		||||
					process = await core.getSessionProcessBlob(blobId, sessionId, options);
 | 
			
		||||
				}
 | 
			
		||||
@@ -112,9 +129,9 @@ function socket(request, response, client) {
 | 
			
		||||
					process.app.send();
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				var ping = function() {
 | 
			
		||||
					var now = Date.now();
 | 
			
		||||
					var again = true;
 | 
			
		||||
				let ping = function() {
 | 
			
		||||
					let now = Date.now();
 | 
			
		||||
					let again = true;
 | 
			
		||||
					if (now - process.lastActive < process.timeout) {
 | 
			
		||||
						// Active.
 | 
			
		||||
					} else if (process.lastPing > process.lastActive) {
 | 
			
		||||
@@ -143,6 +160,15 @@ function socket(request, response, client) {
 | 
			
		||||
				}
 | 
			
		||||
			} else if (message.action == 'permission') {
 | 
			
		||||
				core.setPermission(process, message.id, message.granted);
 | 
			
		||||
			} else if (message.message == 'tfrpc') {
 | 
			
		||||
				if (message.id && g_calls[message.id]) {
 | 
			
		||||
					if (message.error !== undefined) {
 | 
			
		||||
						g_calls[message.id].reject(message.error);
 | 
			
		||||
					} else {
 | 
			
		||||
						g_calls[message.id].resolve(message.result);
 | 
			
		||||
					}
 | 
			
		||||
					delete g_calls[message.id];
 | 
			
		||||
				}
 | 
			
		||||
			} else {
 | 
			
		||||
				if (process && process.eventHandlers['message']) {
 | 
			
		||||
					await core.invoke(process.eventHandlers['message'], [message]);
 | 
			
		||||
 
 | 
			
		||||
@@ -438,7 +438,7 @@ function api_localStorageSet(key, value) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function api_localStorageGet(key, value) {
 | 
			
		||||
	send({message: 'localStorage', key: key, value: window.localStorage.getItem('app:' + key)});
 | 
			
		||||
	return window.localStorage.getItem('app:' + key);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function api_requestPermission(permission, id) {
 | 
			
		||||
@@ -594,10 +594,24 @@ function receive(message) {
 | 
			
		||||
			}
 | 
			
		||||
			timeseries.append(now, message.stats[key]);
 | 
			
		||||
		}
 | 
			
		||||
	} else if (message && message.action) {
 | 
			
		||||
		let api = k_api[message.action];
 | 
			
		||||
	} else if (message &&
 | 
			
		||||
		message.message === 'tfrpc' &&
 | 
			
		||||
		message.method) {
 | 
			
		||||
		let api = k_api[message.method];
 | 
			
		||||
		if (api) {
 | 
			
		||||
			api.func(...api.args.map(x => message[x]));
 | 
			
		||||
			Promise.resolve(api.func(...message.params)).then(function(result) {
 | 
			
		||||
				send({
 | 
			
		||||
					message: 'tfrpc',
 | 
			
		||||
					id: message.id,
 | 
			
		||||
					result: result,
 | 
			
		||||
				});
 | 
			
		||||
			}).catch(function(error) {
 | 
			
		||||
				send({
 | 
			
		||||
					message: 'tfrpc',
 | 
			
		||||
					id: message.id,
 | 
			
		||||
					error: error,
 | 
			
		||||
				});
 | 
			
		||||
			});
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -14,6 +14,9 @@ if (k_is_browser) {
 | 
			
		||||
function make_rpc(target, prop, receiver) {
 | 
			
		||||
	return function() {
 | 
			
		||||
		let id = g_next_id++;
 | 
			
		||||
		while (!id || g_calls[id]) {
 | 
			
		||||
			id = g_next_id++;
 | 
			
		||||
		}
 | 
			
		||||
		let promise = new Promise(function(resolve, reject) {
 | 
			
		||||
			g_calls[id] = {resolve: resolve, reject: reject};
 | 
			
		||||
		});
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user