@xpell/core 2.0.0-alpha.10

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.
Files changed (69) hide show
  1. package/CHANGELOG.md +83 -0
  2. package/LICENSE +21 -0
  3. package/README.md +96 -0
  4. package/dist/XCommand.d.ts +84 -0
  5. package/dist/XConst.d.ts +28 -0
  6. package/dist/XData.d.ts +51 -0
  7. package/dist/XError.d.ts +34 -0
  8. package/dist/XEventManager.d.ts +57 -0
  9. package/dist/XLogger.d.ts +32 -0
  10. package/dist/XModule.d.ts +161 -0
  11. package/dist/XNanoCommands.d.ts +42 -0
  12. package/dist/XObject.d.ts +287 -0
  13. package/dist/XObjectManager.d.ts +96 -0
  14. package/dist/XParams.d.ts +60 -0
  15. package/dist/XParser.d.ts +77 -0
  16. package/dist/XProtocol.d.ts +56 -0
  17. package/dist/XUtils.d.ts +100 -0
  18. package/dist/Xpell.d.ts +142 -0
  19. package/dist/index.d.ts +9 -0
  20. package/dist/xpell-core.cjs.js +3 -0
  21. package/dist/xpell-core.es.js +1428 -0
  22. package/docs/Codex.md +138 -0
  23. package/docs/XData 2.md +209 -0
  24. package/docs/api/.nojekyll +1 -0
  25. package/docs/api/assets/hierarchy.js +1 -0
  26. package/docs/api/assets/highlight.css +71 -0
  27. package/docs/api/assets/icons.js +18 -0
  28. package/docs/api/assets/icons.svg +1 -0
  29. package/docs/api/assets/main.js +60 -0
  30. package/docs/api/assets/navigation.js +1 -0
  31. package/docs/api/assets/search.js +1 -0
  32. package/docs/api/assets/style.css +1611 -0
  33. package/docs/api/classes/XCommand.html +23 -0
  34. package/docs/api/classes/XModule.html +57 -0
  35. package/docs/api/classes/XObject.html +133 -0
  36. package/docs/api/classes/XObjectManager.html +36 -0
  37. package/docs/api/classes/XObjectPack.html +6 -0
  38. package/docs/api/classes/XParams.html +8 -0
  39. package/docs/api/classes/XParser.html +21 -0
  40. package/docs/api/classes/XUtils.html +29 -0
  41. package/docs/api/classes/XpellEngine.html +36 -0
  42. package/docs/api/classes/_XData.html +23 -0
  43. package/docs/api/classes/_XEventManager.html +37 -0
  44. package/docs/api/classes/_XLogger.html +17 -0
  45. package/docs/api/hierarchy.html +1 -0
  46. package/docs/api/index.html +3 -0
  47. package/docs/api/interfaces/IXData.html +1 -0
  48. package/docs/api/interfaces/IXObjectData.html +17 -0
  49. package/docs/api/interfaces/XDataXporterHandler.html +1 -0
  50. package/docs/api/interfaces/XEventListener.html +6 -0
  51. package/docs/api/interfaces/XNanoCommand.html +2 -0
  52. package/docs/api/interfaces/XObjectOnEventIndex.html +1 -0
  53. package/docs/api/types/HTMLEventListenersIndex.html +1 -0
  54. package/docs/api/types/XCommandData.html +1 -0
  55. package/docs/api/types/XDataObject.html +1 -0
  56. package/docs/api/types/XDataVariable.html +1 -0
  57. package/docs/api/types/XDataXporter.html +1 -0
  58. package/docs/api/types/XEvent.html +1 -0
  59. package/docs/api/types/XEventListenerOptions.html +1 -0
  60. package/docs/api/types/XModuleData.html +1 -0
  61. package/docs/api/types/XNanoCommandPack.html +2 -0
  62. package/docs/api/types/XObjectData.html +1 -0
  63. package/docs/api/types/XObjectOnEventHandler.html +1 -0
  64. package/docs/api/variables/XData.html +1 -0
  65. package/docs/api/variables/XEventManager.html +1 -0
  66. package/docs/api/variables/XLogger.html +1 -0
  67. package/docs/api/variables/Xpell.html +3 -0
  68. package/docs/architecture/overview.md +190 -0
  69. package/package.json +66 -0
@@ -0,0 +1,142 @@
1
+ /**
2
+ * Xpell — Core Runtime Engine
3
+ *
4
+ * Entry point for the Xpell runtime.
5
+ *
6
+ * Xpell is a real-time application platform for JavaScript,
7
+ * providing a unified runtime for UI, data, navigation,
8
+ * and real-time communication across browsers and devices.
9
+ *
10
+ * ---
11
+ *
12
+ * ## Core Modules
13
+ *
14
+ * - **XUI** — User Interface engine (HTML / CSS / DOM)
15
+ * - **XVM** — View Manager (navigation, regions, history)
16
+ * - **XDB** — Data engine (entities, semantics, vectors)
17
+ * - **Wormholes** — Real-time transport and sessions
18
+ *
19
+ * ---
20
+ *
21
+ * Xpell coordinates these modules into a single,
22
+ * deterministic runtime environment.
23
+ *
24
+ * Xpell turns UI, data, and AI into a live runtime.
25
+ *
26
+ * @packageDocumentation
27
+ * @file xpell.ts
28
+ * @since 2022-07-22
29
+ * @author Tamir Fridman
30
+ * @copyright © 2022–present Aime Technologies. All rights reserved.
31
+ * @license MIT
32
+ */
33
+ /** interface */
34
+ import XCommand, { XCommandData } from "./XCommand";
35
+ import { XFrameScheduler } from "./XUtils";
36
+ import XParser from "./XParser";
37
+ import XModule from "./XModule";
38
+ export declare const XD_FRAME_NUMBER = "engine:frame-number";
39
+ export declare const XD_FPS = "engine:fps";
40
+ /**
41
+ * @class Xpell main engine
42
+ */
43
+ export declare class XpellEngine {
44
+ _version: string;
45
+ _engine_id: string;
46
+ _frame_number: number;
47
+ _log_rules: {};
48
+ private _fps_calc;
49
+ private _modules;
50
+ private _schedule_frame;
51
+ parser: typeof XParser;
52
+ constructor(opts?: {
53
+ _target_fps?: number;
54
+ _schedule_frame?: XFrameScheduler;
55
+ });
56
+ /**
57
+ * @deprecated use _verbose instead
58
+ * Enable Xpell logs to console
59
+ */
60
+ set verbose(val: boolean);
61
+ /**
62
+ * Enable Xpell logs to console
63
+ */
64
+ set _verbose(val: boolean);
65
+ /**
66
+ * Logs message to console using Xpell logger
67
+ * make sure to enable verbose mode to see the logs
68
+ * this method is a wrapper for XLogger.log
69
+ * @param msg
70
+ * @param optionalParams
71
+ */
72
+ log(message?: any, ...optionalParams: any[]): void;
73
+ /**
74
+ * Delay the execution of the next command
75
+ * @param ms - delay in milliseconds
76
+ * @returns
77
+ */
78
+ delay(ms: number): Promise<unknown>;
79
+ /**
80
+ * Loads Xpell module into the engine
81
+ * @param {XModule} xModule
82
+ */
83
+ loadModule(xModule: XModule): void;
84
+ /**
85
+ * Loads multiple module at ones
86
+ * @param {Array<XModule>} xModulesArray
87
+ */
88
+ loadModules(...xModulesArray: Array<XModule>): void;
89
+ /**
90
+ * Display information about the Xpell engine to the console
91
+ */
92
+ info(): void;
93
+ /**
94
+ * Run textual xCommand -
95
+ * @param {cmd} - text command
96
+ */
97
+ run(stringXCommand: string): any;
98
+ /**
99
+ * Execute Xpell Command
100
+ * @param {XCommand}
101
+ */
102
+ execute(xcmd: XCommand | XCommandData): any;
103
+ /**
104
+ * Main onFrame method
105
+ * calls all the sub-modules onFrame methods (if implemented)
106
+ */
107
+ onFrame(): void;
108
+ /**
109
+ * Gets Xpell module by name
110
+ * @param {string} moduleName - name of the loaded module
111
+ * @returns {XModule}
112
+ */
113
+ getModule(moduleName: string): XModule;
114
+ /**
115
+ * Start Xpell engine for web browsers using requestAnimationFrame
116
+ */
117
+ start(): void;
118
+ /**
119
+ * deprecated - use XData._o directly
120
+ */
121
+ getParam(name: string, defaultValue?: string): any;
122
+ }
123
+ /**
124
+ * Xpell Engine instance
125
+ * @public Xpell Engine instance
126
+ */
127
+ export declare const Xpell: XpellEngine;
128
+ export default Xpell;
129
+ export { Xpell as _x };
130
+ export { XUtils, XUtils as _xu, _XUtils, type XFrameScheduler } from "./XUtils";
131
+ export { XData, XData as _xd, type XDataStore, _XData } from "./XData";
132
+ export { XParser } from "./XParser";
133
+ export { XCommand, type XCommandData } from "./XCommand";
134
+ export { XLogger, XLogger as _xlog, _XLogger } from "./XLogger";
135
+ export { XModule, type XModuleData, } from "./XModule";
136
+ export { XObject, XObjectPack, type XValue, type IXData, type XDataXporter, type XDataXporterHandler, type XObjectData, type XObjectOnEventIndex, type XObjectOnEventHandler } from "./XObject";
137
+ export { XObjectManager } from "./XObjectManager";
138
+ export { XEventManager, XEventManager as _xem, _XEventManager, type XEventListener, type XEventListenerOptions, } from "./XEventManager.js";
139
+ export { type XNanoCommandPack, type XNanoCommand } from "./XNanoCommands";
140
+ export { XParams } from "./XParams";
141
+ export { XError, type XErrorOptions, type XErrorLevel, type XErrorMeta } from "./XError";
142
+ export { type XResponseData, XResponse, XResponseOK, XResponseError } from "./XProtocol";
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Xpell — Core Runtime Package
3
+ *
4
+ * Public entry point for the Xpell core runtime.
5
+ *
6
+ * @packageDocumentation
7
+ */
8
+ export * from "./Xpell";
9
+ export { default } from "./Xpell";
@@ -0,0 +1,3 @@
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});class x{createIgnoreList(t,e){if(!t)return e;const s=t.split(",").map(i=>i.trim()).filter(Boolean);for(const i of s)e[i]="";return e}guid(){const e=globalThis.crypto;if(e&&typeof e.randomUUID=="function")return e.randomUUID();if(e&&typeof e.getRandomValues=="function"){const r=new Uint8Array(16);e.getRandomValues(r),r[6]=r[6]&15|64,r[8]=r[8]&63|128;const a=Array.from(r,_=>_.toString(16).padStart(2,"0"));return a.slice(0,4).join("")+"-"+a.slice(4,6).join("")+"-"+a.slice(6,8).join("")+"-"+a.slice(8,10).join("")+"-"+a.slice(10,16).join("")}const s="0123456789abcdef".split(""),i=[];let n;i[8]=i[13]=i[18]=i[23]="-",i[14]="4";for(let r=0;r<36;r++)i[r]||(n=(0|Math.random()*16)>>>0,i[r]=s[r===19?n&3|8:n&15]);return i.join("")}mergeDefaultsWithData(t,e,s=!1){if(!t)return e;t._id||(t._id=t.id??this.guid());for(const i of Object.keys(e))(!(i in t)||s)&&(t[i]=e[i]);return t}encode(t){const e=globalThis;if(typeof e.btoa=="function"){const s=encodeURIComponent(String(t)).replace(/%([0-9A-F]{2})/g,(i,n)=>String.fromCharCode(parseInt(n,16)));return e.btoa(s)}if(e.Buffer&&typeof e.Buffer.from=="function")return e.Buffer.from(String(t),"utf8").toString("base64");throw new Error("Base64 encode not supported in this environment")}decode(t){const e=globalThis;if(typeof e.atob=="function"){const s=e.atob(String(t)),i=Array.prototype.map.call(s,n=>"%"+n.charCodeAt(0).toString(16).padStart(2,"0")).join("");return decodeURIComponent(i)}if(e.Buffer&&typeof e.Buffer.from=="function")return e.Buffer.from(String(t),"base64").toString("utf8");throw new Error("Base64 decode not supported in this environment")}getRandomInt(t,e){return t=Math.ceil(t),e=Math.floor(e),Math.floor(Math.random()*(e-t+1))+t}getParam(t,e,s=0){return t?._params?.[e]??s}createDefaultScheduler(t){const e=globalThis;if(typeof e.requestAnimationFrame=="function")return n=>e.requestAnimationFrame(n);const s=typeof t=="number"&&isFinite(t)&&t>0?t:60;if(typeof e.setImmediate=="function"&&(!t||t>=60))return n=>e.setImmediate(n);const i=Math.max(1,Math.round(1e3/s));return n=>e.setTimeout(n,i)}}const f=new x;class N{#t=0;#e=0;#s=0;#i;#n;constructor(t=.05,e=1){const s=Number(t);this.#i=Number.isFinite(s)?Math.min(1,Math.max(.001,s)):.05;const i=Number(e);this.#n=Number.isFinite(i)?Math.max(0,Math.floor(i)):1}now(){const t=globalThis.performance;return t&&typeof t.now=="function"?t.now():Date.now()}calc(){const t=this.now();if(this.#s===0)return this.#s=t,this.#t;const e=t-this.#s;if(this.#s=t,!Number.isFinite(e)||e<=0)return this.#t;this.#e===0?this.#e=e:this.#e=(1-this.#i)*this.#e+this.#i*e;const s=1e3/this.#e;if(!Number.isFinite(s)||s<=0)return this.#t;const i=Math.round(s);return this.#t!==0&&this.#n>0&&Math.abs(i-this.#t)<this.#n?this.#t:(this.#t=i,this.#t)}reset(){this.#t=0,this.#e=0,this.#s=0}}class E{constructor(t){this._enabled=!0,this._show_date=!1,this._show_time=!0,this._debug=!1,t&&this.configure(t)}configure(t){typeof t._enabled=="boolean"&&(this._enabled=t._enabled),typeof t._show_date=="boolean"&&(this._show_date=t._show_date),typeof t._show_time=="boolean"&&(this._show_time=t._show_time),typeof t._debug=="boolean"&&(this._debug=t._debug)}_dt(){const t=new Date,e=this._show_date?`${t.getDate()}.${t.getMonth()}.${t.getFullYear()} `:"",s=this._show_time?`${t.getHours()}:${t.getMinutes()}:${t.getSeconds()}.${t.getMilliseconds()}|`:"";return e+s}log(t,...e){this._enabled&&console.log(this._dt(),t,...e)}warn(t,...e){this._enabled&&console.warn(this._dt(),t,...e)}error(t,...e){this._enabled&&console.error(this._dt(),t,...e)}debug(t,...e){!this._enabled||!this._debug||console.debug(this._dt(),t,...e)}}const c=new E,D=typeof process<"u"&&!!process?.env&&process.env.NODE_ENV==="production";D||console.info("[Xpell] _xlog is redirected to console in development mode. Tip: enable 'Show timestamps' in DevTools → Console for timed logs.");const w=D?c:console;class k{constructor(){this._objects={},this._listeners=new Map,this._any_listeners=new Set,this._compat_writes=!0,this._warn_legacy_writes=!0,this._verbose=!1,this._compat_legacy_keys=!0,this._o_proxy=null,this._objects={}}get _o(){return!this._compat_writes&&!this._warn_legacy_writes?this._objects:(this._o_proxy||(this._o_proxy=new Proxy(this._objects,{set:(t,e,s)=>{const i=String(e);return this._warn_legacy_writes&&console.warn(`[XData] Legacy write: _o["${i}"] = ... ; prefer XData.set("${i}", value).`),this._compat_writes?this.set(i,s,{source:"legacy:_o"}):t[i]=s,!0},deleteProperty:(t,e)=>{const s=String(e);return this._warn_legacy_writes&&console.warn(`[XData] Legacy delete: delete _o["${s}"] ; prefer XData.delete("${s}").`),this._compat_writes?this.delete(s,{source:"legacy:_o"}):delete t[s],!0}})),this._o_proxy)}get(t){return this._objects[t]}set(t,e,s){const i=this._objects[t];this._objects[t]=e,this._emit({key:t,value:e,prev:i,ts:Date.now(),op:"set",meta:s})}patch(t,e,s){const i=this._objects[t],r={...i&&typeof i=="object"?i:{},...e};this._objects[t]=r,this._emit({key:t,value:r,prev:i,ts:Date.now(),op:"patch",meta:s})}touch(t,e){const s=this._objects[t];this._emit({key:t,value:s,prev:s,ts:Date.now(),op:"touch",meta:e})}has(t){return Object.prototype.hasOwnProperty.call(this._objects,t)}delete(t,e){const s=this._objects[t];delete this._objects[t],this._emit({key:t,value:void 0,prev:s,ts:Date.now(),op:"delete",meta:e})}pick(t,e){const s=this._objects[t];return this.delete(t,e),s}clean(){this._objects={}}on(t,e){let s=this._listeners.get(t);return s||this._listeners.set(t,s=new Set),s.add(e),()=>this.off(t,e)}off(t,e){const s=this._listeners.get(t);s&&(s.delete(e),s.size===0&&this._listeners.delete(t))}onAny(t){return this._any_listeners.add(t),()=>this._any_listeners.delete(t)}_emit(t){this._verbose&&t.meta?.trace&&(t.stack=new Error().stack);const e=this._listeners.get(t.key);if(e)for(const s of e)s(t);for(const s of this._any_listeners)s(t)}}const u=new k;class F{constructor(t){t&&Object.keys(t).forEach(e=>{this[e]=t[e]}),this.d||(this.d=Date.now())}getParam(t,e,s){return this._params?.hasOwnProperty(e)?this._params[e]:this._params?.hasOwnProperty(t)?this._params[t]:s}}const v={type:"_type",children:"_children"},p=class p{static addHtml2XpellMapItem(t,e){p.html2XMap.elements[t]=e}static parse(t,e){const s=t.split(" ");let i=new F;if(e?(i._module=e,i._op=s[0]):(i._module=s[0],i._op=s[1]),i._params={},s.length>1)for(let n=2;n<s.length;++n){const r=s[n];if(r.indexOf(":")>-1){const _=r.split(":");i._params[_[0]]=_[1]}else i._params[n-1]=s[n]}return i}static replaceSpacesInQuotes(t,e="_%20_"){return t.replace(/(['"])(.*?)\1/g,(s,i,n)=>{const r=String(n).replace(/\s/g,e);return`${i}${r}${i}`})}static parseObjectCommand(t,e){t=p.replaceSpacesInQuotes(t);const s=t.trim().split(/\s+/),i=e||s.shift();if(!i)throw new Error("Missing module name");let n;if(s[0]?.startsWith("#")&&(n=s.shift().slice(1),!n))throw new Error("Invalid object selector '#'. Use '#<id>'");const r=s.shift();if(!r)throw new Error("Missing operation");const a={};let _=null,h=null;if(s.forEach(l=>{if(h){if(h+=` ${l}`,l.endsWith(h[0])){const b=h.slice(1,-1).replace(/_%20_/g," ");a[_]=b,h=null}return}if(l.startsWith('"')||l.startsWith("'")){if(h=l,l.endsWith(l[0])&&l.length>1){const b=l.slice(1,-1).replace(/_%20_/g," ");a[_]=b,h=null}return}if(l.includes(":")){const b=l.split(":"),$=b[0],R=b.slice(1).join(":").replace(/_%20_/g," ");a[$]=R,_=null;return}_=l.replace(/_%20_/g," ")}),h)throw new Error("Unclosed quoted parameter value");return{_module:i,_object:n,_op:r,_params:a}}static xmlString2Xpell(t){const s=new DOMParser().parseFromString(t,"text/xml");return s.childNodes.length>0?p.xml2Xpell(s.childNodes[0]):{}}static xml2Xpell(t,e){const s=p.html2XMap;let i={};i._children=[];const n=t.nodeName,r=t.nodeName;let a=e;if(e?(i[v.type]="xhtml",i._html_ns="http://www.w3.org/2000/svg"):i._type=s.elements[n]?s.elements[n]:n,t.attributes)for(let _=0;_<t.attributes.length;++_){const h=t.attributes[_],l=s.attributes[h.name]?s.attributes[h.name]:h.name;i[l]=h.value}if(t?.firstChild?.nodeValue&&(i.text=t?.firstChild.nodeValue.trim()),i[v.type]=="xhtml"?i._html_tag=r:i[v.type]=="svg"&&(a=!0,i._html_ns="http://www.w3.org/2000/svg"),t?.childNodes.length>0)for(let _=0;_<t.childNodes.length;++_){const h=t.childNodes[_];h.nodeName.startsWith("#")||i[v.children].push(p.xml2Xpell(h,a))}return i}};p.html2XMap={elements:{div:"view",a:"link",b:"xhtml",h1:"xhtml",h2:"xhtml",h3:"xhtml",h4:"xhtml",h5:"xhtml",p:"xhtml",small:"xhtml",aside:"xhtml",span:"xhtml",table:"xhtml",th:"xhtml",td:"xhtml",tr:"xhtml",thead:"xhtml",tbody:"xhtml",ul:"xhtml",li:"xhtml",ol:"xhtml",canvas:"xhtml",img:"image"},attributes:{id:"_id"}};let m=p;class M{constructor(){this._log_rules={register:!1,remove:!1,fire:!1},this._events={},this._listener_index={}}on(t,e,s={},i){this._events[t]||(this._events[t]=[]);const n=s?._owner??i,r=f.guid(),a={_id:r,_callback:e,_options:s,_owner:n,_tag:s?._tag};return this._events[t].push(a),this._listener_index[r]=t,this._log_rules.register&&w.log("XEM Register",t,r),r}once(t,e,s){return this.on(t,e,{_once:!0,_owner:s})}async fire(t,e){const s=this._events[t];if(!s||s.length===0)return;this._log_rules.fire&&w.log("XEM Fire",t,e);const i=s.slice(),n=[];for(const r of i){try{r&&r._callback&&r._callback(e)}catch(a){w.error(a)}r?._options?._once&&n.push(r._id)}for(const r of n)this.remove(r)}remove(t){const e=this._listener_index[t];if(!e)return;const s=this._events[e];if(s&&s.length){const i=s.findIndex(n=>n?._id===t);i>=0&&s.splice(i,1),s.length===0&&delete this._events[e]}delete this._listener_index[t],this._log_rules.remove&&w.log("XEM Remove",e,t)}removeOwner(t){if(!t)return;const e=[];for(const s of Object.values(this._events))for(const i of s)(i?._owner??i?._options?._owner)===t&&e.push(i._id);e.forEach(s=>this.remove(s))}clear(){this._events={},this._listener_index={}}}const g=new M;class S{#t;#e;#s;constructor(){this.#t={},this.#e={},this.#s={}}get _objects(){return this.#e}hasObject(t){return this.#e.hasOwnProperty(t)}registerObjects(t){Object.keys(t).forEach(s=>this.registerObject(s,t[s]))}registerObject(t,e){this.#t[t]=e}hasObjectClass(t){return this.#t.hasOwnProperty(t)}getObjectClass(t){return this.#t[t]}getAllClasses(){return this.#t}get _classes(){return this.#t}addObject(t){t&&t._id?(this.#e[t._id]=t,(!t._name||t._name.length==0)&&(t._name=t._id),this.#s[t._name]=t._id):c.log("unable to add object")}removeObject(t){const e=this.#e[t];e&&(delete this.#s[e?._name],delete this.#e[t])}getObject(t){return this.#e[t]}go(t){return this.getObject(t)}getObjectByName(t){return this.#s[t]?this.getObject(this.#s[t]):null}}const U={info:(o,t)=>{c.log("XObject id "+t?._id)},log:(o,t)=>{o._params&&o._params[1]?c.log(o._params[1]):c.log(t)},fire:(o,t)=>{o._params&&o._params[1]?g.fire(o._params[1],o._params[2]):o._params&&o._params.event&&g.fire(o._params.event,o._params.data)}},j={_children:"child nodes"};class y{constructor(t,e,s){this._children=[],this._parent=null,this._on={},this._once={},this._process_frame=!0,this._process_data=!0,this._nano_commands={},this._event_listeners_ids={},this._event_parsed=!1,this._mounted=!1,this._xporter={_ignore_fields:["_to_xdata_ignore_fields","_xporter","_children","_on","_once","_on_create","_on_mount","_on_frame","_on_data","_process_frame","_process_data","_parent","_event_listeners_ids","_event_parsed","_mounted","_debug"],_instance_xporters:{}},e&&f.mergeDefaultsWithData(t,e),this._id=t&&t._id?t._id:"xo-"+f.guid(),this._type="object",this._children=[],this._nano_commands={},this.addNanoCommandPack(U),t&&t.hasOwnProperty("_nano_commands")&&t._nano_commands&&(this.addNanoCommandPack(t._nano_commands),delete t._nano_commands),this.addXporterDataIgnoreFields(["_nano_commands"]),this.addXporterInstanceXporter(y,i=>i.toXData()),this._xem_options={},!s&&t&&this.parse(t,j)}log(t,...e){this._debug&&t&&c.log(this._type+"->"+this._id+"]",t,...e)}init(t,e){!e&&t&&this.parse(t,j)}parseEvents(t){if(!this._event_parsed){t||(t=this._xem_options),Object.keys(this._on).forEach(s=>{this.addEventListener(s,this._on[s],t)});const e={};Object.assign(e,t),e._once=!0,Object.keys(this._once).forEach(s=>{this.addEventListener(s,this._once[s],e)}),this._event_parsed=!0}}addEventListener(t,e,s){s||(s=this._xem_options);let i;if(typeof e=="function")i=async r=>{e(this,r)};else if(typeof e=="string")i=async r=>{const a=this._id+" "+e+" event-data='"+JSON.stringify(r).replace(/'/g,"\\'")+"'";await this.run(a)};else throw new Error("event handler must be a function");const n=g.on(t,i,s,this);this._event_listeners_ids[t]||(this._event_listeners_ids[t]=[]),this._event_listeners_ids[t].push(n)}removeEventListener(t){const e=this._event_listeners_ids[t];e&&e.length&&(e.forEach(s=>{g.remove(s)}),delete this._event_listeners_ids[t])}removeAllEventListeners(){Object.keys(this._event_listeners_ids).forEach(e=>this.removeEventListener(e))}append(t){this._children?.push(t),t._parent=this}addNanoCommand(t,e){typeof e=="function"&&(this._nano_commands[t]=e)}addNanoCommandPack(t){t&&Object.keys(t).forEach(e=>{this.addNanoCommand(e,t[e])})}addXporterDataIgnoreFields(t){this._xporter._ignore_fields=this._xporter._ignore_fields.concat(t)}addXporterInstanceXporter(t,e){const s=f.guid();this._xporter._instance_xporters[s]={cls:t,handler:e}}parse(t,e=j){Object.keys(t).forEach(i=>{!e.hasOwnProperty(i)&&t.hasOwnProperty(i)&&(this[i]=t[i])})}parseFieldsFromXDataObject(t,e){Object.keys(e).forEach(i=>{t.hasOwnProperty(i)?this[i]=t[i]:this[i]=e[i]})}parseFields(t,e,s){e.forEach(i=>{if(t.hasOwnProperty(i))this[i]=t[i];else if(s&&i.startsWith("_")){const n=i.substring(1);t.hasOwnProperty(n)&&(this[i]=t[n],this[n]=t[n])}})}async onCreate(){this._on_create?this.checkAndRunInternalFunction(this._on_create):this._on&&this._on.create?this.checkAndRunInternalFunction(this._on.create):this._once&&this._once.create&&this.checkAndRunInternalFunction(this._once.create)}async checkAndRunInternalFunction(t,...e){if(typeof t=="function")await t(this,...e);else if(typeof t=="string")if(e.length>0){const s=e[0],i=JSON.stringify(s).replace(/'/g,"\\'");await this.run(`${this._id} ${t} data:'${i}'`)}else await this.run(`${this._id} ${t}`)}async onMount(){if(!this._mounted){this.parseEvents(this._xem_options),this._process_data&&typeof this._data_source=="string"&&this._data_source.length>0&&this.bindDataSource(this._data_source,{initial:!0}),this._on_mount?await this.checkAndRunInternalFunction(this._on_mount):this._on&&this._on.mount?await this.checkAndRunInternalFunction(this._on.mount):this._once&&this._once.mount&&await this.checkAndRunInternalFunction(this._once.mount),this._mounted=!0;for(const t of this._children)t.onMount&&typeof t.onMount=="function"&&t.onMount()}}emptyDataSource(){const t=this._data_source;if(typeof t!="string"||t.length===0)return;const e=this._type??this.constructor.name,s=this._id??"no-id";u.delete(t,{source:`${e}#${s}.emptyDataSource`})}async onData(t){this._process_data&&(this._on_data?this.checkAndRunInternalFunction(this._on_data,t):this._on&&this._on.data?this.checkAndRunInternalFunction(this._on.data,t):this._once&&this._once.data&&this.checkAndRunInternalFunction(this._once.data,t))}async onFrame(t){this._process_frame&&(this._on_frame?this.checkAndRunInternalFunction(this._on_frame,t):this._on&&this._on.frame?this.checkAndRunInternalFunction(this._on.frame,t):this._once&&this._once.frame&&this.checkAndRunInternalFunction(this._once.frame,t));for(const e of this._children)e.onFrame&&typeof e.onFrame=="function"&&e.onFrame(t)}async run(t,e=!0){let s=this._cache_cmd_txt&&this._cache_cmd_txt==t?this._cache_jcmd:m.parseObjectCommand(t);e&&(this._cache_cmd_txt=t,this._cache_jcmd=s),await this.execute(s)}async execute(t){if(t._op&&this._nano_commands[t._op])try{await this._nano_commands[t._op](t,this)}catch(e){c.error(this._id+" has error with command name "+t._op+" "+e)}else c.error(this._id+" has no command name "+t._op)}toXData(){const t={};return Object.keys(this).forEach(e=>{if(!this._xporter._ignore_fields.includes(e)&&this.hasOwnProperty(e)&&this[e]!==void 0){const s=this[e];if(typeof s=="function")return;if(typeof s=="object"){const i=Object.keys(this._xporter._instance_xporters);let n=!0;i.forEach(r=>{this._xporter._instance_xporters[r],s instanceof this._xporter._instance_xporters[r].cls&&(t[e]=this._xporter._instance_xporters[r].handler(s),n=!1)}),n&&(t[e]=s)}else t[e]=s}}),t._children=[],this._children.length>0&&this._children.forEach(e=>{typeof e.toXData=="function"&&t._children?.push(e.toXData())}),t}toString(){return JSON.stringify(this.toXData())}clearAttributes(t){t.forEach(e=>{this.hasOwnProperty(e)&&(this[e]=null,delete this[e])})}bindDataSource(t,e){const s=e?.initial??!0,i=t??this._data_source;typeof i!="string"||i.length===0||this._process_data&&(this._xd_bound_key===i&&this._xd_unsub||(this.unbindDataSource(),this._data_source=i,this._xd_bound_key=i,this._type??this.constructor.name,this._id,this._xd_unsub=u.on(i,async n=>{await this.onData(n.value)}),s&&u.has(i)&&this.onData(u.get(i))))}unbindDataSource(){this._xd_unsub?.(),this._xd_unsub=void 0,this._xd_bound_key=void 0}async dispose(){if(this.unbindDataSource(),this._parent){const t=this._parent._children.indexOf(this);t>-1&&this._parent._children.splice(t,1)}this._process_data=!1,this._process_frame=!1,this.removeAllEventListeners(),this.clearAttributes(["_cache_cmd_txt","_cache_jcmd","_nano_commands","_event_listeners_ids","_parent","_on","_once","_xem_options","_xporter"]),this._children&&this._children.forEach(t=>{typeof t.dispose=="function"&&t.dispose()}),this._children=[]}removeChild(t,e=!1){if(e)t.dispose();else{const s=this._children.indexOf(t);s>-1&&this._children.splice(s,1),t._parent=null}}addChild(t){this.append(t)}}class L{static getObjects(){return{object:y}}}const B="engine:module:num-of-objects:";class C{constructor(t){this._log_rules={createObject:!1,removeObject:!1},this.#t=new S,this._name=t._name,this._id=f.guid()}#t;load(){c.log("Module "+this._name+" loaded")}create(t){let e;if(t.hasOwnProperty("_type"))if(this.#t.hasObjectClass(t._type)){let s=this.#t.getObjectClass(t._type);s.hasOwnProperty("defaults")&&f.mergeDefaultsWithData(t,s.defaults),e=new s(t)}else throw"Xpell object '"+t._type+"' not found";else e=new y(t);return this.#t.addObject(e),t._children&&t._children.forEach(s=>{const i=this.create(s);e.append(i)}),e.onCreate(),e}remove(t){const e=this.#t.getObject(t);if(!e)return;const s=[],i=n=>{n?._id&&(s.push(n._id),(n._children??[]).forEach(r=>i(r)))};i(e),typeof e.dispose=="function"&&e.dispose(),s.reverse().forEach(n=>this.#t.removeObject(n))}_info(t){c.log("module info")}async run(t){if(t){let e=t.trim();e.startsWith(this._name)||(e=this._name+" "+e);let s=m.parse(e);return await this.execute(s)}else throw"Unable to parse Xpell Command"}async execute(t){if(!t||!t._op)throw new Error(`Invalid XCommand: missing _op (module: ${this._name})`);const e=t._object;if(e){const n=this.#t.getObject(e);if(!n)throw new Error(`Module '${this._name}' cant find object id: ${e}`);return await n.execute(t)}const s="_"+t._op.replaceAll("-","_"),i=this[s];if(typeof i=="function")return await i.call(this,t);throw new Error(`Module '${this._name}' cant find op: ${t._op}`)}async onFrame(t){const e=this.#t._objects,s=Object.keys(e);s.forEach(i=>{const n=e[i];n&&n.onFrame&&typeof n.onFrame=="function"&&n?.onFrame(t)}),u.set(B+this._id,s.length,{source:"xmodule"})}get om(){return this.#t}get _object_manager(){return this.#t}getObject(t){return this.#t.getObject(t)}get _o(){return this.#t._objects}importObjectPack(t){this.#t.registerObjects(t.getObjects())}importObjects(t){this.importObjectPack(t)}importObject(t,e){this.#t.registerObject(t,e)}async _help(t){const e=t?._params?._op??t?._params?._command??"";return this.help(e)}help(t){return{module:this._name,usage:`${this._name} help`,ops:["help"],note:"No help() implemented for this module."}}}class T{static get(t,e,s){if(!t?._params)return s;const i=t._params[e];return i!==void 0?i:s}static has(t,e){return t?._params&&t._params[e]!==void 0}static str(t,...e){for(const s of e){const i=t?._params?.[s];if(i!=null)return String(i)}}static bool(t,e,s=!1){const i=this.get(t,e,s);if(typeof i=="boolean")return i;if(typeof i=="number")return i!==0;if(typeof i=="string"){const n=i.toLowerCase();if(["1","true","yes","on"].includes(n))return!0;if(["0","false","no","off"].includes(n))return!1}return!!i}static int(t,e,s=0){const i=this.get(t,e,s),n=parseInt(String(i),10);return Number.isFinite(n)?n:s}static json(t,e,s){const i=this.get(t,e,s);if(i==null)return s;if(typeof i=="object")return i;if(typeof i=="string")try{return JSON.parse(i)}catch{return s}return s}}class O extends Error{constructor(t,e,s){super(e),this.name="XError",this._code=t,this._level=s?._level??"error",this._meta=s?._meta,this._cause=s?._cause}toXData(){return{_code:this._code,_level:this._level,_meta:this._meta,_cause:this._cause,name:this.name,message:this.message}}toJSON(){return{...this.toXData(),stack:this.stack}}}class d{constructor(t){this._ok=!1,this._ts=Date.now(),this._pt=0,t&&this.setXData(t)}static create(t){return new d(t)}static ok(t){return new d({_ok:!0,_result:t})}static error(t){if(t instanceof O)return new d({_ok:!1,_result:t.toXData()});const e=new O("E_INTERNAL",t?.message??String(t),{_cause:t});return new d({_ok:!1,_result:e.toXData()})}stopProcessTimeCounter(){this._pt=Date.now()-this._ts}toXData(){return this.stopProcessTimeCounter(),{_ok:this._ok,_ts:this._ts,_pt:this._pt,_result:this._result}}toString(){return JSON.stringify(this.toXData())}setXData(t){t&&("_ok"in t&&(this._ok=!!t._ok),"_ts"in t&&typeof t._ts=="number"&&(this._ts=t._ts),"_pt"in t&&typeof t._pt=="number"&&(this._pt=t._pt),"_result"in t&&(this._result=t._result))}}class W extends d{constructor(t){super(d.error(t).toXData())}}class J extends d{constructor(t){super({_ok:!0,_result:t})}}const I="engine:frame-number",P="engine:fps";class A{constructor(t){this._log_rules={},this._modules={},this._schedule_frame=t?._schedule_frame??f.createDefaultScheduler(t?._target_fps),this._version="0.0.1",this._engine_id=f.guid(),this._frame_number=0,this._fps_calc=new N,this.parser=m,this._modules={},g.fire("xpell-init"),c._enabled=!1}set verbose(t){c._enabled=t}set _verbose(t){c._enabled=t}log(t,...e){c.log(t,...e)}async delay(t){return new Promise(e=>setTimeout(e,t))}loadModule(t){this._modules.hasOwnProperty(t._name)?c.log("Module "+t._name+" already loaded"):(this._modules[t._name]=t,t.load())}loadModules(...t){t.forEach(e=>this.loadModule(e))}info(){c.log(`Xpell information:
2
+ - Engine Id: `+this._engine_id+`
3
+ - Version `+this._version)}run(t){if(t?.length>2){let e=m.parse(t);return this.execute(e)}else throw"Unable to parse Xpell command"}execute(t){if(t&&t._module&&this._modules[t._module])return this._modules[t._module].execute(t);throw"Xpell module "+t._module+" not loaded"}onFrame(){this._frame_number++;for(const e of Object.keys(this._modules)){const s=this._modules[e];s?.onFrame&&typeof s.onFrame=="function"&&s.onFrame(this._frame_number)}const t=this._fps_calc.calc();u.set(I,this._frame_number,{source:"engine"}),u.set(P,t,{source:"engine"}),u._compat_legacy_keys&&(u.set("frame-number",this._frame_number,{source:"engine:legacy"}),u.set("fps",t,{source:"engine:legacy"})),this._schedule_frame(()=>this.onFrame())}getModule(t){return this._modules[t]}start(){c.log("Starting Xpell"),this.onFrame()}getParam(t,e){return t in u._o?u._o[t]:e}}const X=new A;exports.XCommand=F;exports.XD_FPS=P;exports.XD_FRAME_NUMBER=I;exports.XData=u;exports.XError=O;exports.XEventManager=g;exports.XLogger=c;exports.XModule=C;exports.XObject=y;exports.XObjectManager=S;exports.XObjectPack=L;exports.XParams=T;exports.XParser=m;exports.XResponse=d;exports.XResponseError=W;exports.XResponseOK=J;exports.XUtils=f;exports.Xpell=X;exports.XpellEngine=A;exports._XData=k;exports._XEventManager=M;exports._XLogger=E;exports._XUtils=x;exports._x=X;exports._xd=u;exports._xem=g;exports._xlog=c;exports._xu=f;exports.default=X;