KUMOS/SDK/SpiderBasic/KUMOS.sbi
2026-05-02 15:49:06 +02:00

229 lines
9.6 KiB
Plaintext

; ════════════════════════════════════════════════════════════════════════════
; KUMOS.sbi — SpiderBasic SDK for KUMOS third-party apps
;
; Usage:
; IncludeFile "KUMOS.sbi"
; KUMOS::Init() ; call once at startup, before anything else
;
; All async procedures accept a *Callback procedure pointer.
; Callbacks always have the signature: Procedure Cb(Success.i, Data.s)
; Exception: KUMOS::Notify_Confirm uses: Procedure Cb(Result.i)
;
; The "storage.*" namespace is always available.
; "fs.*" requires the "fs.read" / "fs.write" permission in manifest.json.
; "notify.*" requires the "notify" permission in manifest.json.
; ════════════════════════════════════════════════════════════════════════════
DeclareModule KUMOS
; Toast types — pass to Notify_Toast()
Enumeration
#Info
#Success
#Warning
#Error
EndEnumeration
; ── Lifecycle ──────────────────────────────────────────────────────────
Declare Init()
Declare Ready(*Callback) ; Cb(Success, Data) — Data: '{"app_id":"..."}'
Declare Window_SetTitle(Title.s)
Declare Window_Close()
; ── Private storage (always available) ────────────────────────────────
Declare Storage_Read (Path.s, *Callback) ; Cb(Success, Content.s)
Declare Storage_Write (Path.s, Content.s, *Callback); Cb(Success, "")
Declare Storage_List (Path.s, *Callback) ; Cb(Success, JSON array)
Declare Storage_Stat (Path.s, *Callback) ; Cb(Success, JSON object)
Declare Storage_Mkdir (Path.s, *Callback) ; Cb(Success, "")
Declare Storage_Delete(Path.s, *Callback) ; Cb(Success, "")
; ── User filesystem (requires fs.read / fs.write) ─────────────────────
Declare FS_Read (Path.s, *Callback) ; Cb(Success, Content.s)
Declare FS_Write (Path.s, Content.s, *Callback) ; Cb(Success, "")
Declare FS_List (Path.s, *Callback) ; Cb(Success, JSON array)
Declare FS_Stat (Path.s, *Callback) ; Cb(Success, JSON object)
; ── Notifications (requires notify) ───────────────────────────────────
Declare Notify_Toast (Message.s, Type.i = #Info) ; fire-and-forget
Declare Notify_Confirm (Title_.s, Message.s, *Callback) ; Cb(Result.i)
EndDeclareModule
Module KUMOS
EnableExplicit
; Inject the JS runtime once, guarded so multiple IncludeFile calls are safe.
Procedure Init()
!if (window._kumos_sb) { return; }
!window._kumos_sb = {
! pending: {},
! uuid: function() {
! 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);
! });
! },
! send: function(action, args, onSuccess, onError) {
! var kmid = window._kumos_sb.uuid();
! var timer = setTimeout(function() {
! var p = window._kumos_sb.pending[kmid];
! if (p) { delete window._kumos_sb.pending[kmid]; p.onError('Timeout: ' + action); }
! }, 15000);
! window._kumos_sb.pending[kmid] = { onSuccess: onSuccess, onError: onError, timer: timer };
! window.parent.postMessage(
! JSON.stringify({ kmid: kmid, action: action, args: args || {} }), '*'
! );
! }
!};
!window.addEventListener('message', function(e) {
! if (e.source !== window.parent) { return; }
! var msg;
! try { msg = JSON.parse(e.data); } catch(ex) { return; }
! if (!msg || !msg.kmid) { return; }
! var p = window._kumos_sb.pending[msg.kmid];
! if (!p) { return; }
! clearTimeout(p.timer);
! delete window._kumos_sb.pending[msg.kmid];
! if (msg.success) {
! var data = msg.data;
! if (data === null || data === undefined) { data = ''; }
! else if (typeof data === 'object') { data = JSON.stringify(data); }
! else if (typeof data === 'boolean') { data = data ? 'true' : 'false'; }
! else { data = String(data); }
! p.onSuccess(data);
! } else {
! p.onError(msg.error || 'Error');
! }
!});
EndProcedure
; ── Internal send helper ──────────────────────────────────────────────────
; *Callback must be Procedure Cb(Success.i, Data.s)
; *ConfirmCallback must be Procedure Cb(Result.i) [used only for confirm]
Procedure _Send(Action.s, ArgsJSON.s, *Callback)
! var cb = p_callback;
!window._kumos_sb.send(
! v_action,
! (v_argsjson ? JSON.parse(v_argsjson) : {}),
! function(data) { cb(1, data); },
! function(err) { cb(0, err); }
!);
EndProcedure
; ── Args builders ─────────────────────────────────────────────────────────
Procedure.s _PathArgs(Path.s)
ProcedureReturn ~"{\"path\":\"" + ReplaceString(Path, ~"\"", ~"\\\"") + ~"\"}"
EndProcedure
Procedure.s _PathContentArgs(Path.s, Content.s)
ProcedureReturn ~"{\"path\":\"" + ReplaceString(Path, ~"\"", ~"\\\"") + ~"\"," +
~"\"content\":\"" + ReplaceString(Content, ~"\"", ~"\\\"") + ~"\"}"
EndProcedure
Procedure.s _TitleMsgArgs(Title_.s, Message.s)
ProcedureReturn ~"{\"title\":\"" + ReplaceString(Title_, ~"\"", ~"\\\"") + ~"\"," +
~"\"message\":\"" + ReplaceString(Message, ~"\"", ~"\\\"") + ~"\"}"
EndProcedure
Procedure.s _TypeStr(Type.i)
Select Type
Case #Success : ProcedureReturn "success"
Case #Warning : ProcedureReturn "warning"
Case #Error : ProcedureReturn "error"
Default : ProcedureReturn "info"
EndSelect
EndProcedure
; ── Lifecycle ─────────────────────────────────────────────────────────────
Procedure Ready(*Callback)
_Send("window.ready", "{}", *Callback)
EndProcedure
Procedure Window_SetTitle(Title.s)
; Fire-and-forget — no callback needed
! window._kumos_sb.send('window.setTitle',
! { title: v_title }, function(){}, function(){});
EndProcedure
Procedure Window_Close()
! window._kumos_sb.send('window.close', {}, function(){}, function(){});
EndProcedure
; ── Storage ───────────────────────────────────────────────────────────────
Procedure Storage_Read(Path.s, *Callback)
_Send("storage.read", _PathArgs(Path), *Callback)
EndProcedure
Procedure Storage_Write(Path.s, Content.s, *Callback)
_Send("storage.write", _PathContentArgs(Path, Content), *Callback)
EndProcedure
Procedure Storage_List(Path.s, *Callback)
_Send("storage.list", _PathArgs(Path), *Callback)
EndProcedure
Procedure Storage_Stat(Path.s, *Callback)
_Send("storage.stat", _PathArgs(Path), *Callback)
EndProcedure
Procedure Storage_Mkdir(Path.s, *Callback)
_Send("storage.mkdir", _PathArgs(Path), *Callback)
EndProcedure
Procedure Storage_Delete(Path.s, *Callback)
_Send("storage.delete", _PathArgs(Path), *Callback)
EndProcedure
; ── User filesystem ───────────────────────────────────────────────────────
Procedure FS_Read(Path.s, *Callback)
_Send("fs.read", _PathArgs(Path), *Callback)
EndProcedure
Procedure FS_Write(Path.s, Content.s, *Callback)
_Send("fs.write", _PathContentArgs(Path, Content), *Callback)
EndProcedure
Procedure FS_List(Path.s, *Callback)
_Send("fs.list", _PathArgs(Path), *Callback)
EndProcedure
Procedure FS_Stat(Path.s, *Callback)
_Send("fs.stat", _PathArgs(Path), *Callback)
EndProcedure
; ── Notifications ─────────────────────────────────────────────────────────
Procedure Notify_Toast(Message.s, Type.i = #Info)
Protected Args.s = ~"{\"message\":\"" + ReplaceString(Message, ~"\"", ~"\\\"") + ~"\"," +
~"\"type\":\"" + _TypeStr(Type) + ~"\"}"
! window._kumos_sb.send('notify.toast',
! JSON.parse(v_args), function(){}, function(){});
EndProcedure
; *Callback must be Procedure Cb(Result.i) — 1 = OK, 0 = Cancel
Procedure Notify_Confirm(Title_.s, Message.s, *Callback)
Protected Args.s = _TitleMsgArgs(Title_, Message)
! var cb = p_callback;
!window._kumos_sb.send(
! 'notify.confirm',
! JSON.parse(v_args),
! function(data) { cb(data === 'true' ? 1 : 0); },
! function() { cb(0); }
!);
EndProcedure
EndModule
; IDE Options = SpiderBasic 3.20 (Windows - x86)
; CursorPosition = 1
; Folding = ----
; iOSAppOrientation = 0
; AndroidAppCode = 0
; AndroidAppOrientation = 0
; EnableXP
; DPIAware
; CompileSourceDirectory