125 lines
5.0 KiB
JavaScript
125 lines
5.0 KiB
JavaScript
/**
|
|
* KUMO.S App SDK — include in your app with:
|
|
* <script src="/kumos.js"></script>
|
|
*
|
|
* All methods return Promises. Call KUMOS.ready() first.
|
|
*
|
|
* Permissions required per namespace:
|
|
* storage.* — always available (private app namespace)
|
|
* fs.* — requires "fs.read" or "fs.write" grant
|
|
* notify.* — requires "notify" grant
|
|
* window.* — always available
|
|
*/
|
|
(function (global) {
|
|
'use strict';
|
|
|
|
var _pending = {}; // kmid → { resolve, reject, timer }
|
|
|
|
// ── Internal helpers ──────────────────────────────────────────────────────
|
|
|
|
function _uuid() {
|
|
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
|
|
var r = Math.random() * 16 | 0;
|
|
return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);
|
|
});
|
|
}
|
|
|
|
function _send(action, args) {
|
|
return new Promise(function (resolve, reject) {
|
|
var kmid = _uuid();
|
|
var timer = setTimeout(function () {
|
|
if (_pending[kmid]) {
|
|
delete _pending[kmid];
|
|
reject(new Error('KUMOS timeout: ' + action));
|
|
}
|
|
}, 15000);
|
|
_pending[kmid] = { resolve: resolve, reject: reject, timer: timer };
|
|
window.parent.postMessage(
|
|
JSON.stringify({ kmid: kmid, action: action, args: args || {} }),
|
|
'*'
|
|
);
|
|
});
|
|
}
|
|
|
|
// Incoming responses from the shell
|
|
window.addEventListener('message', function (e) {
|
|
if (e.source !== window.parent) return;
|
|
var msg;
|
|
try { msg = JSON.parse(e.data); } catch (err) { return; }
|
|
if (!msg || !msg.kmid) return;
|
|
var p = _pending[msg.kmid];
|
|
if (!p) return;
|
|
clearTimeout(p.timer);
|
|
delete _pending[msg.kmid];
|
|
if (msg.success) {
|
|
p.resolve(msg.data !== undefined ? msg.data : null);
|
|
} else {
|
|
p.reject(new Error(msg.error || 'Unknown error'));
|
|
}
|
|
});
|
|
|
|
// ── Public API ────────────────────────────────────────────────────────────
|
|
|
|
var KUMOS = {
|
|
|
|
/**
|
|
* Handshake with the shell. Resolves with { app_id }.
|
|
* Always call this first and await it before using any other APIs.
|
|
*/
|
|
ready: function () {
|
|
return _send('window.ready', {});
|
|
},
|
|
|
|
// ── Private app storage (no extra permission required) ───────────────
|
|
|
|
storage: {
|
|
/** Read a file. Resolves with the content string. */
|
|
read: function (path) { return _send('storage.read', { path: path }); },
|
|
/** Write content to a file. Creates it if it does not exist. */
|
|
write: function (path, content) { return _send('storage.write', { path: path, content: content }); },
|
|
/** List a directory. Resolves with an array of entry objects. */
|
|
list: function (path) { return _send('storage.list', { path: path || '/' }); },
|
|
/** Stat a path. */
|
|
stat: function (path) { return _send('storage.stat', { path: path }); },
|
|
/** Create a directory. */
|
|
mkdir: function (path) { return _send('storage.mkdir', { path: path }); },
|
|
/** Delete a file. */
|
|
delete: function (path) { return _send('storage.delete', { path: path }); }
|
|
},
|
|
|
|
// ── User filesystem (requires fs.read / fs.write permission) ─────────
|
|
|
|
fs: {
|
|
/** Read a file from the user's filesystem. */
|
|
read: function (path) { return _send('fs.read', { path: path }); },
|
|
/** Write content to a file in the user's filesystem. */
|
|
write: function (path, content) { return _send('fs.write', { path: path, content: content }); },
|
|
/** List a directory. */
|
|
list: function (path) { return _send('fs.list', { path: path || '/' }); },
|
|
/** Stat a path. */
|
|
stat: function (path) { return _send('fs.stat', { path: path }); }
|
|
},
|
|
|
|
// ── Notifications (requires notify permission) ────────────────────────
|
|
|
|
notify: {
|
|
/** Show a toast. type: 'info' | 'success' | 'warning' | 'error' */
|
|
toast: function (message, type) { return _send('notify.toast', { message: message, type: type || 'info' }); },
|
|
/** Show a confirm dialog. Resolves with true (OK) or false (Cancel). */
|
|
confirm: function (title, message) { return _send('notify.confirm', { title: title, message: message }); }
|
|
},
|
|
|
|
// ── Window control ────────────────────────────────────────────────────
|
|
|
|
window: {
|
|
/** Update the host window title. */
|
|
setTitle: function (title) { return _send('window.setTitle', { title: title }); },
|
|
/** Close this app instance. */
|
|
close: function () { return _send('window.close', {}); }
|
|
}
|
|
};
|
|
|
|
global.KUMOS = KUMOS;
|
|
|
|
}(window));
|