@xuda.io/runtime-bundle 1.0.1363 → 1.0.1365

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.
@@ -47,4 +47,4 @@ var app_obj,progs_obj,_,progs_str,hide_not_in_use_check,is_server,deployments,Ug
47
47
  Example: xu-store="{'temp_var':'@calculated_value','status':'ready'}"
48
48
 
49
49
  - xu-viewport: Handles viewport-based logic during rendering
50
- Example: xu-viewport="@mobile_view"`);const UiElementSchema=z.lazy(()=>z.object({id:z.union([z.literal(`root`),UuidSchema,z.string().regex(/^node-[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i),z.string().regex(/^ui-[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i)]).describe(`Element identifier: "root" for top-level, prefixed UUIDs like "ui-791ca98a-e284-4413-af0a-96e5527c338b"`),type:z.literal(`element`).describe(`Element type - only "element" allowed (no "comment" or "text" types)`),tagName:z.string().describe(`HTML tag name for the element (e.g., "div", "span", "input")`),attributes:UiAttributesSchema.optional().describe(`HTML attributes and Xuda directives (e.g., class, xu-bind, xu-on)`),content:z.string().optional().describe(`Text content for the element (replaces deprecated "text" type)`),text:z.string().optional().describe(`Alternative text property for element content`),children:z.array(UiElementSchema).optional().describe(`Array of child elements nested within this element`),workflow:z.array(WorkflowActionSchema).optional().describe(`Workflow actions associated with this UI element`),path:z.array(z.number()).optional().describe("Array representing the element`s position in the UI tree"),code:z.string().optional().describe(`Generated HTML code representation`),editCode:z.boolean().optional().describe(`Flag indicating if element is in code editing mode`),$folded:z.boolean().optional().describe(`UI editor state - whether element tree is collapsed`)}).describe(`UI element following Himalaya.js structure with Xuda extensions, 1. generate unique id using UUID for every item of the progUi (except the root node, leave the root node as is),2. never use "comment" or "text" type, 3. convert "text" type to "element" and add a text property instead next to the type property `));const DataSourceSchema=z.object({dataSourceType:z.union([z.literal(`table`).describe(`Connect to structured table from global Table Repository`),z.literal(`array`).describe(`Use static or dynamically populated array`),z.literal(`json`).describe(`Load structured data in JSON format`),z.literal(`csv`).describe(`Load data from CSV source`),z.literal(`none`).describe(`No data source attached - self-contained logic unit`),z.literal(``).describe(`Empty string indicating no datasource configured`)]).optional().describe(`Type of data source defining how data is retrieved and processed`),dataSourceFilterModelType:z.union([z.literal(`index`).describe(`Use predefined index with from/to values for fast range filtering`),z.literal(`query`).describe(`Use jQuery Mongo syntax for advanced conditional filters and logical rules`)]).optional().describe(`Filtering approach for table sources`),dataSourceSort:z.union([z.literal(`asc`),z.literal(`desc`)]).optional().describe(`Global sort direction for retrieved data`),dataSourceTableId:z.string().optional().describe(`Reference to table ID in Table Repository when dataSourceType is "table"`),dataSourceIndexId:z.string().optional().describe(`Default index ID used for efficient data lookup and filtering`),dataSourceIndexesObj:z.record(z.record(z.object({from:z.string().describe(`Starting value for index range (can be dynamic expression like @uid_in)`),locate_from:z.string().optional().describe(`Additional locate parameter for range start`),locate_to:z.string().optional().describe(`Additional locate parameter for range end`),to:z.string().describe(`Ending value for index range (can be dynamic expression)`),key:z.string().describe(`Field name being indexed and filtered`)}).describe(`Index field configuration with range values`))).optional().describe(`Index configurations mapped by index ID, defining field ranges and conditions for efficient filtering`),dataSourceReduce:z.boolean().optional().describe(`Whether to reduce results to single aggregated value (count, sum, avg) - requires DBS plugin`),filterModelMongo:z.object({}).optional().describe(`Static MongoDB-style filter query object built using jQuery QueryBuilder`),filterModelMongoFx:z.string().optional().describe(`Dynamic reference to input field containing filter query object (overrides filterModelMongo)`),sortModel:z.array(z.object({field_id:z.string().describe(`Field identifier to sort by`),sort_dir:z.union([z.literal(`asc`),z.literal(`desc`)]).describe(`Sort direction for this specific field`)})).optional().describe(`Array of field-level sorting rules for multi-column sorting`),dataSourceRealtime:z.boolean().optional().describe(`Enable real-time updates when source data changes (table sources only, requires @xuda.io/xuds-dbs-plugin-xuda)`),datafieldsOutputField:z.string().optional().describe(`Field name where raw query results will be stored within parent hierarchy`),dataSourceLimit:z.number().optional().describe(`Maximum number of rows or iterations to return for pagination`),dataSourceSkip:z.number().optional().describe(`Number of rows to skip before returning results, useful for pagination offset`),dataSourceUrl:z.string().optional().describe(`External URL endpoint for loading array/CSV/JSON data from REST APIs or static files`),dataSourceInputField:z.string().optional().describe(`Dynamic field reference in UI or app context for data source values (alternative to external URL)`)}).describe(`Comprehensive data source configuration defining how logic units retrieve, filter, and process data from tables, arrays, APIs, or external sources`);let properties_obj={menuType:z.literal(type).describe(`defines the object category`),menuName:z.string().describe(`Internal name displayed in the Studio interface`)};let properties=z.object(properties_obj).describe(`Core ${type} properties defining behavior, access, and UI framework settings`);const progFields=z.array(ProgFieldSchema).describe(`Defines the internal working fields of the ${type}. These include real and virtual fields used for data binding, user interaction, intermediate logic, and expression evaluation.`);const progEvents=z.array(ProgEventSchema).optional().describe(`Defines all functional logic associated with the ${type}. Events support lifecycle hooks (like on_load, screen_ready, client_interval), event-based workflow, custom utility functions, and conditional logic.`);const progUi=z.array(UiElementSchema).describe(`Describes the rendered interface in a structured JSON format, derived from Himalaya.js (HTML-to-JSON). Each node can be bound to logic via attributes such as xu-exp, bind, for, and trigger. This enables conditional rendering, looping constructs, inline script execution, and seamless integration with workflow.`);const progDataSource=DataSourceSchema.describe(`Defines where the ${type} pulls or binds its data from, such as a database table, external service, or static source.`);let main_obj={_id:z.string().regex(/^[a-zA-Z0-9_]+$/).describe(`Unique ${type} identifier with format constraints`),app_id:z.string().describe(`Reference to the parent application this ${type} belongs to`),stat:z.union([z.literal(1),z.literal(2),z.literal(3),z.literal(4)]).describe(`Document status: 1=draft, 2=review, 3=active, 4=archived`),docType:z.literal(`studio`).describe(`Always "studio" - indicates this is a Studio-authored ${type}`),docDate:TimestampSchema.describe(`Unix timestamp when the ${type} document was created`),ts:TimestampSchema.describe(`Unix timestamp of the most recent modification`),order_ts:TimestampSchema.describe(`Timestamp used for ordering components in the Studio interface`),description:z.string().optional().describe(`Describe in short the ${type}`),studio_meta:StudioMetaSchema};let XudaComponentSchema=z.object(main_obj);main_obj.properties=properties;switch(type){case`globals`:XudaComponentSchema.describe(`The globals object in the Xuda platform defines a universal logic layer shared across all programs, components, and workflows. It provides a centralized and consistent structure for declaring global fields, utility functions, and event-driven logic, ensuring logic reusability and reducing redundancy across the application.`);main_obj.progFields=progFields;main_obj.progEvents=progEvents;break;case`table`:XudaComponentSchema.describe(`The Table Object represents a data entity and serves as the structural definition for interacting with external databases. It supports integration via pluggable connectors, allowing seamless connection to various database engines such as MySQL, CouchDB, and others (see available database plugins for the full list).`);properties_obj.databaseSocket=z.string().default("@xuda.io/xuda-dbs-plugin-xuda").describe("Database driver to use for the table");const XudaFieldType=z.enum(["string","number","boolean","array","object","date"]).describe("Data type for table fields");const IndexDataSchema=z.object({name:z.string().describe("Name of the index"),unique:z.boolean().describe("If true, ensures no duplicates for indexed fields"),keys:z.array(z.string()).describe("List of field names used in this index")});const TableIndexSchema=z.object({id:z.string().uuid().describe("Unique uuid identifier for the index"),data:IndexDataSchema.describe("Contains keys, uniqueness setting, and index name")});const FieldPropsSchema=z.object({fieldType:XudaFieldType.describe('Data type: "string", "number", "boolean", "array", "object", or "date"')});const FieldDataSchema=z.object({field_id:z.string().describe("Field identifier used in logic or database operations")});const TableFieldSchema=z.object({id:z.string().uuid().describe("Unique uuid of the field object"),data:FieldDataSchema.describe("Contains the logical field ID"),props:FieldPropsSchema.describe("Properties of the field including data type")});main_obj.tableIndexes=z.array(TableIndexSchema).describe("Defines indexing rules for efficient lookups and uniqueness constraints");main_obj.tableFields=z.array(TableFieldSchema).describe("Defines each field used in the table and its data type");break;case`folder`:XudaComponentSchema.describe(`The Folder is a non-executable, project-level container represented as a structured JSON object. It is used to define a hierarchical structure for organizing application assets within the Xuda environment. Although it does not execute any logic at runtime, the folder object plays an essential role in shaping the overall architecture of a project by logically grouping related objects such as components, APIs, tables, datasets, and other program entities.`);break;case`component`:XudaComponentSchema.describe(`The component object in the Xuda platform defines a modular, self-contained program unit that encapsulates both front-end presentation and back-end logic. It serves as a reusable UI component that supports a full execution lifecycle, making it ideal for constructing low-code applications that are maintainable, scalable, and highly interactive. A component is engineered to allow seamless integration of logic, data, and rendering, enabling developers to build sophisticated interactive views without redundant code. Each component instance supports input/output parameters, can communicate with other components or programs, and can be dynamically rendered as a page, modal, or embedded panel.`);properties_obj.frameworkProperties=z.object({}).optional().describe(`Framework-specific rendering extensions and configuration`);properties_obj.renderType=z.string().describe(`Component layout type (e.g., "form", "grid", "list")`);properties_obj.rwMode=z.union([z.literal(`R`),z.literal(`W`),z.literal(`RW`)]).describe(`Access mode: R=read-only, W=write-only, RW=read-write`);properties_obj.uiFramework=z.string().describe(`Selected UI framework plugin (e.g., @xuda.io/xuda-framework-plugin-tailwind)`);properties_obj.menuTitle=z.string().optional().describe(`Display title for Studio UI or routing usage`);properties_obj.progParams=z.array(ProgParamSchema).optional().describe(`Array of input/output parameter definitions for ${type} interface`);main_obj.progDataSource=progDataSource;main_obj.progFields=progFields;main_obj.progEvents=progEvents;main_obj.progUi=progUi;break;case`get_data`:XudaComponentSchema.describe(`The Get Data Object defines a lightweight, read-only program unit designed to retrieve data from a structured source such as a table, array, or remote dataset. It is used to extract specific values, perform indexed lookups, and support transformations through reduce or conditional logic. This object is typically used when a logic program requires only data retrieval without the need to iterate or mutate records. It supports output parameter mapping and can be embedded into workflows and alerts for dynamic value extraction.`);properties_obj.frameworkProperties=z.object({}).optional().describe(`Framework-specific rendering extensions and configuration`);properties_obj.progParams=z.array(ProgParamSchema).optional().describe(`Array of input/output parameter definitions for ${type} interface`);main_obj.progDataSource=progDataSource;main_obj.progFields=progFields;main_obj.progEvents=progEvents;break;case`set_data`:XudaComponentSchema.describe(`The set_data object defines a program-level functional unit responsible for writing data to a specified table. It can be invoked from any program and is designed to handle create, update, and delete operations in a structured and reusable way. The object includes properties to determine the type of operation being performed and supports an optional flag to create a new record if one does not already exist. In addition to its core structure, the set_data object includes a parameter interface property that defines input and output parameters. This allows values to be passed into the function and returned to the calling context, enabling flexible, context-aware data handling.`);properties_obj.progParams=z.array(ProgParamSchema).optional().describe(`Array of input/output parameter definitions for ${type} interface`);properties_obj.crudMode=z.enum(["C","U","D"]).describe("Operation mode: C = Create, U = Update, D = Delete");properties_obj.crudMode=z.boolean().describe("If true, allows record creation if not found");main_obj.progDataSource=progDataSource;main_obj.progFields=progFields;main_obj.progEvents=progEvents;break;case`batch`:XudaComponentSchema.describe(`The Batch Object defines a program-level execution unit tailored for iterative, record-by-record operations across datasets. It enables controlled loops over structured data sources or arrays, making it a foundational element for multi-record processing, automation flows, and background job orchestration. The batch object can be invoked from within any Xuda logic program and serves as a reusable execution block for bulk workflows, such as saving multiple records, transforming arrays, or triggering chained program logic. It accepts dynamic input and output parameters, which allow context-aware execution and return values that can be consumed downstream.The batch unit also includes lifecycle hooks and event workflow, enabling custom logic at specific points within the loop (e.g., before/after each record or on error conditions). This supports advanced control, transformation, and external interactions during iterative processing.`);properties_obj.progParams=z.array(ProgParamSchema).optional().describe(`Array of input/output parameter definitions for ${type} interface`);main_obj.progDataSource=progDataSource;main_obj.progFields=progFields;main_obj.progEvents=progEvents;break;case`api`:XudaComponentSchema.describe(`The API Program-Level Logic Unit is a program-level logic unit represented as a structured JSON object that exposes backend functionality through internal or external interfaces. It can be invoked internally via the call_project_api method or externally through the api/mcp endpoint, enabling controlled access to application-level logic and data services. Acting as an orchestration layer, the API unit enables coordination of multiple subordinate logic units such as get_data, set_data, and batch, allowing compound workflows, transactional operations, and conditional executions to be encapsulated within a single, callable endpoint. This design abstracts complexity and promotes composability of business logic across the application. The API unit includes an interface definition for parameter binding, specifying dynamic input and output mappings. This supports stateless, context-aware executions where external values can be passed into the API call, and structured results returned to the calling layer. Response format configuration is also supported, with output types including json, text, html, and others—allowing precise control over the serialization and consumption of API responses.`);properties_obj.progParams=z.array(ProgParamSchema).optional().describe(`Array of input/output parameter definitions for ${type} interface`);const ApiOutputFormat=z.enum(["json","html","text","xml","csv","pdf"]).describe("Format of the API response: json, html, text, xml, csv, pdf, etc.");properties_obj.apiOutput=ApiOutputFormat.describe("Format of the API response: json, html, text, etc.");main_obj.progDataSource=progDataSource;main_obj.progFields=progFields;main_obj.progEvents=progEvents;main_obj.scriptData=z.object({value:z.string().describe("The return payload template as a stringified object. Placeholder bindings (e.g., @CS_Id) are replaced at runtime")});break;case`alert`:XudaComponentSchema.describe(`The Alert Object is a program-level UI unit in the Xuda platform used to deliver contextual messages and notifications to users or developers at runtime. These alerts can be triggered from within logic flows and offer various display formats (such as toast, modal, browser alert, or console message) based on the use case. The alert object is defined using a structured JSON format and can be embedded in broader program logic. It supports both static and dynamic content, and can optionally create log entries to support audit trails and debugging workflows.`);properties_obj.progParams=z.array(ProgParamSchema).optional().describe(`Array of input/output parameter definitions for ${type} interface`);main_obj.alertData=z.object({alertDisplay:AlertDisplay.describe('Mode of display: "toast", "modal", "browser", or "console"'),alertType:AlertType.describe('Type of message: "warning", "error", "info", or "success"'),alertTitle:z.string().describe("Main content of the alert shown to the user"),alertTitleFx:z.string().optional().describe("Optional dynamic override (e.g., @msg_v) for alert content"),createLog:z.boolean().describe("Whether to generate a system log entry associated with the alert")});break;case`javascript`:XudaComponentSchema.describe(`The javascript object is a functional unit designed to execute JavaScript code within the application context. It can be called from any program using methods such as call_native_javascript, call_evaluate_javascript, execute_native_javascript, or execute_evaluate_javascript. This object includes the following key property: Script – Contains the JavaScript code to be executed, along with any declared dependencies required for execution. The javascript object is ideal for performing advanced logic, custom client-side behavior, or dynamic scripting that extends the capabilities of low-code flows. Xuda also exposes a set of built-in API methods that can be easily called from JavaScript units. These include actions like reading from or writing to Drive, interacting with the Studio API, or performing database operations such as create, update, and delete. These ready-to-use APIs simplify common tasks and allow you to focus on building functionality instead of writing boilerplate code. By centralizing script execution in a modular and reusable way, the JavaScript unit enhances flexibility, promotes clean architecture, and empowers developers to go beyond standard configuration with native scripting power.`);properties_obj.progParams=z.array(ProgParamSchema).optional().describe(`Array of input/output parameter definitions for ${type} interface`);main_obj.scriptData=z.object({value:z.string().describe("JavaScript code to be executed"),dependencies:z.record(z.string()).optional().describe("Optional. Key-value map of external packages required")});break;default:break}return XudaComponentSchema};
50
+ Example: xu-viewport="@mobile_view"`);const UiElementSchema=z.lazy(()=>z.object({id:z.union([z.literal(`root`),UuidSchema,z.string().regex(/^node-[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i),z.string().regex(/^ui-[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i)]).describe(`Element identifier: "root" for top-level, prefixed UUIDs like "ui-791ca98a-e284-4413-af0a-96e5527c338b"`),type:z.literal(`element`).describe(`Element type - only "element" allowed (no "comment" or "text" types)`),tagName:z.string().describe(`HTML tag name for the element (e.g., "div", "span", "input")`),attributes:UiAttributesSchema.optional().describe(`HTML attributes and Xuda directives (e.g., class, xu-bind, xu-on)`),content:z.string().optional().describe(`Text content for the element (replaces deprecated "text" type)`),text:z.string().optional().describe(`Alternative text property for element content`),children:z.array(UiElementSchema).optional().describe(`Array of child elements nested within this element`),workflow:z.array(WorkflowActionSchema).optional().describe(`Workflow actions associated with this UI element`),path:z.array(z.number()).optional().describe("Array representing the element`s position in the UI tree"),code:z.string().optional().describe(`Generated HTML code representation`),editCode:z.boolean().optional().describe(`Flag indicating if element is in code editing mode`),$folded:z.boolean().optional().describe(`UI editor state - whether element tree is collapsed`)}).describe(`UI element following Himalaya.js structure with Xuda extensions, 1. generate unique id using UUID for every item of the progUi (except the root node, leave the root node as is),2. never use "comment" or "text" type, 3. convert "text" type to "element" and add a text property instead next to the type property `));const DataSourceSchema=z.object({dataSourceType:z.union([z.literal(`table`).describe(`Connect to structured table from global Table Repository`),z.literal(`array`).describe(`Use static or dynamically populated array`),z.literal(`json`).describe(`Load structured data in JSON format`),z.literal(`csv`).describe(`Load data from CSV source`),z.literal(`none`).describe(`No data source attached - self-contained logic unit`),z.literal(``).describe(`Empty string indicating no datasource configured`)]).optional().describe(`Type of data source defining how data is retrieved and processed`),dataSourceFilterModelType:z.union([z.literal(`index`).describe(`Use predefined index with from/to values for fast range filtering`),z.literal(`query`).describe(`Use jQuery Mongo syntax for advanced conditional filters and logical rules`)]).optional().describe(`Filtering approach for table sources`),dataSourceSort:z.union([z.literal(`asc`),z.literal(`desc`)]).optional().describe(`Global sort direction for retrieved data`),dataSourceTableId:z.string().optional().describe(`Reference to table ID in Table Repository when dataSourceType is "table"`),dataSourceIndexId:z.string().optional().describe(`Default index ID used for efficient data lookup and filtering`),dataSourceIndexesObj:z.record(z.record(z.object({from:z.string().describe(`Starting value for index range (can be dynamic expression like @uid_in)`),locate_from:z.string().optional().describe(`Additional locate parameter for range start`),locate_to:z.string().optional().describe(`Additional locate parameter for range end`),to:z.string().describe(`Ending value for index range (can be dynamic expression)`),key:z.string().describe(`Field name being indexed and filtered`)}).describe(`Index field configuration with range values`))).optional().describe(`Index configurations mapped by index ID, defining field ranges and conditions for efficient filtering`),dataSourceReduce:z.boolean().optional().describe(`Whether to reduce results to single aggregated value (count, sum, avg) - requires DBS plugin`),filterModelMongo:z.object({}).optional().describe(`Static MongoDB-style filter query object built using jQuery QueryBuilder`),filterModelMongoFx:z.string().optional().describe(`Dynamic reference to input field containing filter query object (overrides filterModelMongo)`),sortModel:z.array(z.object({field_id:z.string().describe(`Field identifier to sort by`),sort_dir:z.union([z.literal(`asc`),z.literal(`desc`)]).describe(`Sort direction for this specific field`)})).optional().describe(`Array of field-level sorting rules for multi-column sorting`),dataSourceRealtime:z.boolean().optional().describe(`Enable real-time updates when source data changes (table sources only, requires @xuda.io/xuds-dbs-plugin-xuda)`),datafieldsOutputField:z.string().optional().describe(`Field name where raw query results will be stored within parent hierarchy`),dataSourceLimit:z.number().optional().describe(`Maximum number of rows or iterations to return for pagination`),dataSourceSkip:z.number().optional().describe(`Number of rows to skip before returning results, useful for pagination offset`),dataSourceUrl:z.string().optional().describe(`External URL endpoint for loading array/CSV/JSON data from REST APIs or static files`),dataSourceInputField:z.string().optional().describe(`Dynamic field reference in UI or app context for data source values (alternative to external URL)`)}).describe(`Comprehensive data source configuration defining how logic units retrieve, filter, and process data from tables, arrays, APIs, or external sources`);let properties_obj={menuType:z.literal(type).describe(`defines the object category`),menuName:z.string().describe(`Internal name displayed in the Studio interface`)};let properties=z.object(properties_obj).describe(`Core ${type} properties defining behavior, access, and UI framework settings`);const progFields=z.array(ProgFieldSchema).describe(`Defines the internal working fields of the ${type}. These include real and virtual fields used for data binding, user interaction, intermediate logic, and expression evaluation.`);const progEvents=z.array(ProgEventSchema).optional().describe(`Defines all functional logic associated with the ${type}. Events support lifecycle hooks (like on_load, screen_ready, client_interval), event-based workflow, custom utility functions, and conditional logic.`);const progUi=z.array(UiElementSchema).describe(`Describes the rendered interface in a structured JSON format, derived from Himalaya.js (HTML-to-JSON). Each node can be bound to logic via attributes such as xu-exp, bind, for, and trigger. This enables conditional rendering, looping constructs, inline script execution, and seamless integration with workflow.`);const progDataSource=DataSourceSchema.describe(`Defines where the ${type} pulls or binds its data from, such as a database table, external service, or static source.`);let main_obj={_id:z.string().regex(/^[a-zA-Z0-9_]+$/).describe(`Unique ${type} identifier with format constraints`),app_id:z.string().describe(`Reference to the parent application this ${type} belongs to`),stat:z.union([z.literal(1),z.literal(2),z.literal(3),z.literal(4)]).describe(`Document status: 1=draft, 2=review, 3=active, 4=archived`),docType:z.literal(`studio`).describe(`Always "studio" - indicates this is a Studio-authored ${type}`),docDate:TimestampSchema.describe(`Unix timestamp when the ${type} document was created`),ts:TimestampSchema.describe(`Unix timestamp of the most recent modification`),order_ts:TimestampSchema.describe(`Timestamp used for ordering components in the Studio interface`),description:z.string().optional().describe(`Describe in short the ${type}`),studio_meta:StudioMetaSchema};let XudaComponentSchema=z.object(main_obj);main_obj.properties=properties;switch(type){case`globals`:XudaComponentSchema.describe(`The globals object in the Xuda platform defines a universal logic layer shared across all programs, components, and workflows. It provides a centralized and consistent structure for declaring global fields, utility functions, and event-driven logic, ensuring logic reusability and reducing redundancy across the application.`);main_obj.progFields=progFields;main_obj.progEvents=progEvents;break;case`table`:XudaComponentSchema.describe(`The Table Object represents a data entity and serves as the structural definition for interacting with external databases. It supports integration via pluggable connectors, allowing seamless connection to various database engines such as MySQL, CouchDB, and others (see available database plugins for the full list).`);properties_obj.databaseSocket=z.string().default("@xuda.io/xuda-dbs-plugin-xuda").describe("Database driver to use for the table");const XudaFieldType=z.enum(["string","number","boolean","array","object","date"]).describe("Data type for table fields");const IndexDataSchema=z.object({name:z.string().describe("Name of the index"),unique:z.boolean().describe("If true, ensures no duplicates for indexed fields"),keys:z.array(z.string()).describe("List of field names used in this index"),props:z.object({}).describe("")});const TableIndexSchema=z.object({id:z.string().uuid().describe("Unique uuid identifier for the index"),data:IndexDataSchema.describe("Contains keys, uniqueness setting, and index name")});const FieldPropsSchema=z.object({fieldType:XudaFieldType.describe('Data type: "string", "number", "boolean", "array", "object", or "date"'),label:z.string().describe("the name of the field")});const FieldDataSchema=z.object({field_id:z.string().describe("Field identifier used in logic or database operations")});const TableFieldSchema=z.object({id:z.string().uuid().describe("Unique uuid of the field object"),data:FieldDataSchema.describe("Contains the logical field ID"),props:FieldPropsSchema.describe("Properties of the field including data type")});main_obj.tableIndexes=z.array(TableIndexSchema).describe("Defines indexing rules for efficient lookups and uniqueness constraints");main_obj.tableFields=z.array(TableFieldSchema).describe("Defines each field used in the table and its data type");break;case`folder`:XudaComponentSchema.describe(`The Folder is a non-executable, project-level container represented as a structured JSON object. It is used to define a hierarchical structure for organizing application assets within the Xuda environment. Although it does not execute any logic at runtime, the folder object plays an essential role in shaping the overall architecture of a project by logically grouping related objects such as components, APIs, tables, datasets, and other program entities.`);break;case`component`:XudaComponentSchema.describe(`The component object in the Xuda platform defines a modular, self-contained program unit that encapsulates both front-end presentation and back-end logic. It serves as a reusable UI component that supports a full execution lifecycle, making it ideal for constructing low-code applications that are maintainable, scalable, and highly interactive. A component is engineered to allow seamless integration of logic, data, and rendering, enabling developers to build sophisticated interactive views without redundant code. Each component instance supports input/output parameters, can communicate with other components or programs, and can be dynamically rendered as a page, modal, or embedded panel.`);properties_obj.frameworkProperties=z.object({}).optional().describe(`Framework-specific rendering extensions and configuration`);properties_obj.renderType=z.string().describe(`Component layout type (e.g., "form", "grid", "list")`);properties_obj.rwMode=z.union([z.literal(`R`),z.literal(`W`),z.literal(`RW`)]).describe(`Access mode: R=read-only, W=write-only, RW=read-write`);properties_obj.uiFramework=z.string().describe(`Selected UI framework plugin (e.g., @xuda.io/xuda-framework-plugin-tailwind)`);properties_obj.menuTitle=z.string().optional().describe(`Display title for Studio UI or routing usage`);properties_obj.progParams=z.array(ProgParamSchema).optional().describe(`Array of input/output parameter definitions for ${type} interface`);main_obj.progDataSource=progDataSource;main_obj.progFields=progFields;main_obj.progEvents=progEvents;main_obj.progUi=progUi;break;case`get_data`:XudaComponentSchema.describe(`The Get Data Object defines a lightweight, read-only program unit designed to retrieve data from a structured source such as a table, array, or remote dataset. It is used to extract specific values, perform indexed lookups, and support transformations through reduce or conditional logic. This object is typically used when a logic program requires only data retrieval without the need to iterate or mutate records. It supports output parameter mapping and can be embedded into workflows and alerts for dynamic value extraction.`);properties_obj.frameworkProperties=z.object({}).optional().describe(`Framework-specific rendering extensions and configuration`);properties_obj.progParams=z.array(ProgParamSchema).optional().describe(`Array of input/output parameter definitions for ${type} interface`);main_obj.progDataSource=progDataSource;main_obj.progFields=progFields;main_obj.progEvents=progEvents;break;case`set_data`:XudaComponentSchema.describe(`The set_data object defines a program-level functional unit responsible for writing data to a specified table. It can be invoked from any program and is designed to handle create, update, and delete operations in a structured and reusable way. The object includes properties to determine the type of operation being performed and supports an optional flag to create a new record if one does not already exist. In addition to its core structure, the set_data object includes a parameter interface property that defines input and output parameters. This allows values to be passed into the function and returned to the calling context, enabling flexible, context-aware data handling.`);properties_obj.progParams=z.array(ProgParamSchema).optional().describe(`Array of input/output parameter definitions for ${type} interface`);properties_obj.crudMode=z.enum(["C","U","D"]).describe("Operation mode: C = Create, U = Update, D = Delete");properties_obj.crudMode=z.boolean().describe("If true, allows record creation if not found");main_obj.progDataSource=progDataSource;main_obj.progFields=progFields;main_obj.progEvents=progEvents;break;case`batch`:XudaComponentSchema.describe(`The Batch Object defines a program-level execution unit tailored for iterative, record-by-record operations across datasets. It enables controlled loops over structured data sources or arrays, making it a foundational element for multi-record processing, automation flows, and background job orchestration. The batch object can be invoked from within any Xuda logic program and serves as a reusable execution block for bulk workflows, such as saving multiple records, transforming arrays, or triggering chained program logic. It accepts dynamic input and output parameters, which allow context-aware execution and return values that can be consumed downstream.The batch unit also includes lifecycle hooks and event workflow, enabling custom logic at specific points within the loop (e.g., before/after each record or on error conditions). This supports advanced control, transformation, and external interactions during iterative processing.`);properties_obj.progParams=z.array(ProgParamSchema).optional().describe(`Array of input/output parameter definitions for ${type} interface`);main_obj.progDataSource=progDataSource;main_obj.progFields=progFields;main_obj.progEvents=progEvents;break;case`api`:XudaComponentSchema.describe(`The API Program-Level Logic Unit is a program-level logic unit represented as a structured JSON object that exposes backend functionality through internal or external interfaces. It can be invoked internally via the call_project_api method or externally through the api/mcp endpoint, enabling controlled access to application-level logic and data services. Acting as an orchestration layer, the API unit enables coordination of multiple subordinate logic units such as get_data, set_data, and batch, allowing compound workflows, transactional operations, and conditional executions to be encapsulated within a single, callable endpoint. This design abstracts complexity and promotes composability of business logic across the application. The API unit includes an interface definition for parameter binding, specifying dynamic input and output mappings. This supports stateless, context-aware executions where external values can be passed into the API call, and structured results returned to the calling layer. Response format configuration is also supported, with output types including json, text, html, and others—allowing precise control over the serialization and consumption of API responses.`);properties_obj.progParams=z.array(ProgParamSchema).optional().describe(`Array of input/output parameter definitions for ${type} interface`);const ApiOutputFormat=z.enum(["json","html","text","xml","csv","pdf"]).describe("Format of the API response: json, html, text, xml, csv, pdf, etc.");properties_obj.apiOutput=ApiOutputFormat.describe("Format of the API response: json, html, text, etc.");main_obj.progDataSource=progDataSource;main_obj.progFields=progFields;main_obj.progEvents=progEvents;main_obj.scriptData=z.object({value:z.string().describe("The return payload template as a stringified object. Placeholder bindings (e.g., @CS_Id) are replaced at runtime")});break;case`alert`:XudaComponentSchema.describe(`The Alert Object is a program-level UI unit in the Xuda platform used to deliver contextual messages and notifications to users or developers at runtime. These alerts can be triggered from within logic flows and offer various display formats (such as toast, modal, browser alert, or console message) based on the use case. The alert object is defined using a structured JSON format and can be embedded in broader program logic. It supports both static and dynamic content, and can optionally create log entries to support audit trails and debugging workflows.`);properties_obj.progParams=z.array(ProgParamSchema).optional().describe(`Array of input/output parameter definitions for ${type} interface`);main_obj.alertData=z.object({alertDisplay:AlertDisplay.describe('Mode of display: "toast", "modal", "browser", or "console"'),alertType:AlertType.describe('Type of message: "warning", "error", "info", or "success"'),alertTitle:z.string().describe("Main content of the alert shown to the user"),alertTitleFx:z.string().optional().describe("Optional dynamic override (e.g., @msg_v) for alert content"),createLog:z.boolean().describe("Whether to generate a system log entry associated with the alert")});break;case`javascript`:XudaComponentSchema.describe(`The javascript object is a functional unit designed to execute JavaScript code within the application context. It can be called from any program using methods such as call_native_javascript, call_evaluate_javascript, execute_native_javascript, or execute_evaluate_javascript. This object includes the following key property: Script – Contains the JavaScript code to be executed, along with any declared dependencies required for execution. The javascript object is ideal for performing advanced logic, custom client-side behavior, or dynamic scripting that extends the capabilities of low-code flows. Xuda also exposes a set of built-in API methods that can be easily called from JavaScript units. These include actions like reading from or writing to Drive, interacting with the Studio API, or performing database operations such as create, update, and delete. These ready-to-use APIs simplify common tasks and allow you to focus on building functionality instead of writing boilerplate code. By centralizing script execution in a modular and reusable way, the JavaScript unit enhances flexibility, promotes clean architecture, and empowers developers to go beyond standard configuration with native scripting power.`);properties_obj.progParams=z.array(ProgParamSchema).optional().describe(`Array of input/output parameter definitions for ${type} interface`);main_obj.scriptData=z.object({value:z.string().describe("JavaScript code to be executed"),dependencies:z.record(z.string()).optional().describe("Optional. Key-value map of external packages required")});break;default:break}return XudaComponentSchema};
@@ -3796,6 +3796,7 @@ export const get_zod_schema = function (type) {
3796
3796
  name: z.string().describe('Name of the index'),
3797
3797
  unique: z.boolean().describe('If true, ensures no duplicates for indexed fields'),
3798
3798
  keys: z.array(z.string()).describe('List of field names used in this index'),
3799
+ props: z.object({}).describe(''),
3799
3800
  });
3800
3801
 
3801
3802
  const TableIndexSchema = z.object({
@@ -3805,6 +3806,7 @@ export const get_zod_schema = function (type) {
3805
3806
 
3806
3807
  const FieldPropsSchema = z.object({
3807
3808
  fieldType: XudaFieldType.describe('Data type: "string", "number", "boolean", "array", "object", or "date"'),
3809
+ label: z.string().describe('the name of the field'),
3808
3810
  });
3809
3811
  const FieldDataSchema = z.object({
3810
3812
  field_id: z.string().describe('Field identifier used in logic or database operations'),
@@ -42766,7 +42766,7 @@ func.index.set_ds_0_proxy = function (SESSION_ID) {
42766
42766
 
42767
42767
  const runHandler = () => {
42768
42768
  const { handler, once } = _session?.watchers?.[watch_path] || {};
42769
- handler(change);
42769
+ if (change) handler(change);
42770
42770
  if (once) {
42771
42771
  delete _session.watchers[watch_path];
42772
42772
  }
@@ -116,4 +116,4 @@
116
116
 
117
117
  </div>
118
118
 
119
- `);setTimeout(()=>{$(`[name="hard_reload"]`).off("click").on("click",async function(){await func.index.delete_pouch(SESSION_ID);location.reload()});$(`[name="reset_worker"]`).off("click").on("click",function(){_session.WORKER_OBJ.jobs[0].stat=null;_session.WORKER_OBJ.stat=null;func.UI.utils.progressScreen.hide(SESSION_ID)});$(`[name="get_support"]`).off("click").on("click",async function(){const get_support=await func.common.get_module(SESSION_ID,"xuda-get-support-module.esm.js");var name,subject;const prompt_name=()=>{name=window.prompt(`Get support from your ${APP_OBJ[app_id].app_general_prop?.app_name} team, \n\nYour Name (required):`);if(name==="")prompt_name()};const prompt_subject=()=>{subject=window.prompt(`When you click on "Ok," you are granting permission to ${APP_OBJ[app_id]?.app_name} team to access your browser. \n\nSubject (required):`);if(subject==="")prompt_subject()};if(!SUPPORT_PEER){try{name=firebase.auth().currentUser.displayName}catch(error){if(_session?.USR_OBJ?.usr_name){name=_session.USR_OBJ.usr_name}else{prompt_name()}}if(name===null)return;prompt_subject();if(subject===null)return;func.common.db(SESSION_ID,"get_support",{name:name,subject:subject});setTimeout(()=>{$("body").addClass("get_support_request");$("body").remove(".get_support_request_title").append("<div class='get_support_request_title'>Support pending</div>")},2e3)}else{get_support.terminate_peer(SESSION_ID)}func.UI.utils.progressScreen.hide(SESSION_ID)})},1e3)}}};if(event.which===27){let SESSION_ID=Object.keys(SESSION_OBJ)[0];func.UI.utils.progressScreen.hide(SESSION_ID)}if(event.ctrlKey&&event.shiftKey){if(keys[event.which]){keys[event.which].fx()}}});$(document).mousemove(function(e){CLIENT_ACTIVITY_TS=Date.now();posX=e.pageX;posY=e.pageY;if(SESSION_OBJ[SESSION_ID]?.DS_GLB?.[0]){SESSION_OBJ[SESSION_ID].DS_GLB[0].data_system["SYS_GLOBAL_OBJ_CLIENT_INFO"].cursor_pos_x=posX;SESSION_OBJ[SESSION_ID].DS_GLB[0].data_system["SYS_GLOBAL_OBJ_CLIENT_INFO"].cursor_pos_y=posY}});$.fn.draggable=function(){CLIENT_ACTIVITY_TS=Date.now();var $this=this,ns="draggable_"+(Math.random()+"").replace(".",""),mm="mousemove."+ns,mu="mouseup."+ns,$w=$(window),isFixed=$this.css("position")==="fixed",adjX=0,adjY=0;$this.mousedown(function(ev){var pos=$this.offset();if(isFixed){adjX=$w.scrollLeft();adjY=$w.scrollTop()}var ox=ev.pageX-pos.left,oy=ev.pageY-pos.top;$this.data(ns,{x:ox,y:oy});$w.on(mm,function(ev){ev.preventDefault();ev.stopPropagation();if(isFixed){adjX=$w.scrollLeft();adjY=$w.scrollTop()}var offset=$this.data(ns);$this.css({left:ev.pageX-adjX-offset.x,top:ev.pageY-adjY-offset.y})});$w.on(mu,function(){$w.off(mm+" "+mu).removeData(ns)})});return this};var heartbeat_attempts=0;var heartbeat_internal=setInterval(async function(){const SESSION_ID=Object.keys(SESSION_OBJ)[0];if(!SESSION_ID)return;let _session=SESSION_OBJ[SESSION_ID];if(!_session)return;if(_session.crawler)return;const set_idle=async function(stat){var datasource_changes={[0]:{["data_system"]:{SYS_GLOBAL_BOL_IDLE:stat}}};await func.datasource.update(SESSION_ID,datasource_changes)};if(Date.now()-CLIENT_ACTIVITY_TS>3e4){set_idle(1)}else{set_idle(0)}if(_session.engine_mode==="live_preview"||!_session.opt.enable_user_assist){return}const ret=await func.common.db(SESSION_ID,"heartbeat",{stat:Date.now()-CLIENT_ACTIVITY_TS>3e4?1:2}).catch(err=>{heartbeat_attempts++;console.warn(err.message);if(heartbeat_attempts<10)return;clearInterval(heartbeat_internal)});heartbeat_attempts=0;if(ret?.session_stat===3){await func.index.delete_pouch();window.top.location.reload()}$("body").removeClass("get_support_request");$("body").find(".get_support_request_title").remove();$("body").removeClass("get_support_online");$("body").find(".get_support_online_title").remove();if(ret?.data?.peer?.peer_status===1){if(ret.data.peer.peer_regional_server){get_support.init_peer(SESSION_ID,ret.data.peer.peer_regional_server)}$("body").addClass("get_support_request");$("body").remove(".get_support_request_title").append("<div class='get_support_request_title'>Support pending</div>")}if(ret?.data?.peer?.peer_status===2){$("body").addClass("get_support_online");$("body").remove(".get_support_online_title").append("<div class='get_support_online_title'>Support online</div>")}_session.res_token=ret.res_token},3e4);glb.WINDOW_LOCATION_SEARCH=window.location.search};func.index.checkConnectivity=async function(){const endpoints=["https://xuda.io/favicon.ico"];const promises=endpoints.map(url=>fetch(url,{method:"HEAD",mode:"no-cors"}).then(()=>true).catch(()=>false));const results=await Promise.all(promises);IS_ONLINE=results.some(result=>result===true);window.addEventListener("online",function(){IS_ONLINE=true;$("body").trigger("set_db_replication_from_server")});window.addEventListener("offline",function(){IS_ONLINE=false})};func.index.init_service_workers=function(){if("serviceWorker"in navigator){navigator.serviceWorker.addEventListener("message",function(event){console.log("serviceWorker message:",event)});navigator.serviceWorker.register("xuda-sw.js").then(function(registration){console.log("ServiceWorker registration successful with scope: ",registration.scope);glb.sw_registration=registration},function(err){console.log("ServiceWorker registration failed: ",err)})}};func.index.delete_pouch=async function(SESSION_ID=Object.keys(SESSION_OBJ)[0]){const db=await func.utils.connect_pouchdb(SESSION_ID);try{return await db.destroy()}catch(err){console.log(err)}};func.index.new_webworker=async function(SESSION_ID,prog_obj,obj){var worker_id=Object.keys(WEB_WORKER[SESSION_ID]).length+1;var _session=SESSION_OBJ[SESSION_ID];if(!_session.engine_mode==="docker"){ver=APP_OBJ[_session.app_id].app_version}var build_id=["live_preview","miniapp"].includes(_session.engine_mode)?"":_session.opt.app_build_id;if(typeof XUDA_BUILD_ID!=="undefined"){build_id=XUDA_BUILD_ID}const worker_name=`${typeof _session.SLIM_BUNDLE==="undefined"||!_session.SLIM_BUNDLE?"":"Slim "}${prog_obj.menuName} worker`+" "+glb.worker_type+": #"+worker_id.toString()+" "+(build_id||"")+" "+_session.domain;const init_worker_session=function(worker_id){var _session=_.cloneDeep(SESSION_OBJ[SESSION_ID]);delete _session.root_element;const get_parent_ds=function(ds){var ds_obj={};if(ds&&_session.DS_GLB[ds].parentDataSourceNo!==null){ds_obj[ds]=func.utils.clean_returned_datasource(SESSION_ID,ds);_.forEach(get_parent_ds(_session.DS_GLB[ds].parentDataSourceNo),function(val,key){ds_obj[key]=val})}else{ds_obj[ds]=func.utils.clean_returned_datasource(SESSION_ID,ds)}return ds_obj};var ds_obj={};if(typeof obj?.data?.parentDataSourceNoP!=="undefined"){ds_obj=get_parent_ds(obj.data.parentDataSourceNoP)}_session.DS_GLB={};_session.WORKER_OBJ={jobs:[],num:1e3,stat:null};var app_id=_session.app_id;var data={SESSION_ID:SESSION_ID,app_id:app_id,APP_OBJ:APP_OBJ[app_id],PROJECT_OBJ:PROJECT_OBJ[app_id],DOCS_OBJ:DOCS_OBJ[app_id],APP_INFO:glb.APP_INFO[app_id],DEBUG_MODE:glb.DEBUG_MODE,DEBUG_INFO_OBJ:glb.DEBUG_INFO_OBJ,WINDOW_LOCATION_SEARCH:glb.WINDOW_LOCATION_SEARCH,ROOT_ELEMENT_ATTRIBUTES:glb.ROOT_ELEMENT_ATTRIBUTES,DS_GLB:ds_obj,SESSION_INFO:JSON.parse(JSON.stringify(_session)),session_id:SESSION_ID,engine_mode:_session.engine_mode,STUDIO_WEBSOCKET_CONNECTION_ID:STUDIO_WEBSOCKET_CONNECTION_ID};if(_session.engine_mode==="live_preview"){data.DOCS_OBJ=DOCS_OBJ[app_id]}delete data.SESSION_INFO.root_element;data.SESSION_INFO.worker_id=worker_id;var ds_arr=[];$.map(_session.DS_GLB,function(val,i){ds_arr.push(i)});WEB_WORKER[SESSION_ID][worker_id].ds_arr=ds_arr;delete data.SESSION_INFO.DS_UI_EVENTS_GLB;if(RUNTIME_SERVER_WEBSOCKET&&RUNTIME_SERVER_WEBSOCKET_CONNECTED&&(!_session.opt.app_computing_mode||_session.opt.app_computing_mode==="server")){WEB_WORKER[SESSION_ID][worker_id].worker.emit("message",{service:"init",data:data,worker_id:worker_id})}else{WEB_WORKER[SESSION_ID][worker_id].worker.postMessage({service:"init",data:JSON.stringify(data),worker_id:worker_id})}};const create_worker=async function(){return new Promise((resolve,reject)=>{if(glb.worker_type==="Dev"){WEB_WORKER[SESSION_ID][worker_id]={worker:new Worker("js/xuda_worker.js",{name:worker_name}),promise_queue:{}}}else{function getWorkerURL(url){const content=`importScripts( "${url}" );`;return URL.createObjectURL(new Blob([content],{type:"text/javascript"}))}const _session=SESSION_OBJ[SESSION_ID];let blob=getWorkerURL(func.common.get_url(SESSION_ID,"dist",func.utils.get_resource_filename(["live_preview","miniapp"].includes(_session.engine_mode)?"":_session?.opt?.app_build_id,"runtime/js/xuda_worker.js")));WEB_WORKER[SESSION_ID][worker_id]={worker:new Worker(blob,{name:worker_name}),promise_queue:{}}}WEB_WORKER[SESSION_ID][worker_id].worker.addEventListener("message",function(e){if(e.data.service==="worker_ready"){return resolve()}worker_functions(e)},false)})};const create_websocket=async function(){return new Promise((resolve,reject)=>{WEB_WORKER[SESSION_ID][worker_id]={worker:RUNTIME_SERVER_WEBSOCKET,promise_queue:{}};WEB_WORKER[SESSION_ID][worker_id].worker.on("message",async e=>{if(["deployment_server","http_call"].includes(e.source))return;worker_functions({data:e})});resolve()})};const worker_functions=async function(e_raw){return new Promise(async(resolve,reject)=>{var e={};e.data=e_raw.data;if(RUNTIME_SERVER_WEBSOCKET&&RUNTIME_SERVER_WEBSOCKET_CONNECTED&&(!_session.opt.app_computing_mode||_session.opt.app_computing_mode==="server")){WEBSOCKET_PROCESS_PID=e.data.process_pid}var val=e.data.params;var fx={init_done:async function(){if(!obj){return _resolve()}},alert:function(){if(val[1]==="save_on"){func.UI.utils.save(SESSION_ID,true);return true}if(val[1]==="save_off"){func.UI.utils.save(SESSION_ID,false);return true}func.utils.alerts.execute(SESSION_ID,val[1],val[2],val[3],val[4]);return _resolve()},progress_on:function(){func.UI.utils.progressScreen.show(SESSION_ID,val,null);return _resolve()},progress_off:function(){func.UI.utils.progressScreen.hide();return _resolve()},worker_busy_on:function(){func.UI.utils.indicator.worker.busy();return _resolve()},worker_busy_off:function(){func.UI.utils.indicator.worker.normal();return _resolve()},screen_blocker_on:function(){func.UI.utils.screen_blocker(true,"Worker");return _resolve()},ajax_error:function(){func.utils.request_error(SESSION_ID,"ajax","Session error");return _resolve()},screen_blocker_off:function(){func.UI.utils.screen_blocker(false,"Worker");return _resolve()},job:function(){func.events.add_to_queue(SESSION_ID,val.typeP,val.eventIdP,val.triggerP,val.functionP,val.refIdP,val.containerP,val.elementP,val.rowP,null,val.descP,null,null,val.dsSessionP,null,null,val.event_propertiesP,val.calling_triggerP,val.paramsP,null,null,val.calling_trigger_prop,val.argumentsP,val.source_event_idP,val.calling_job,val.args);return _resolve()},update_client_eventChangesResults_from_worker:async function(){await func.datasource.update(SESSION_ID,val,true);if(!val.worker_id){return}fx.acknowledged_worker_with_eventChangesResults_done(val.dssession,val.worker_id);for await(const[worker_id,ds_arr]of Object.entries(WEB_WORKER[SESSION_ID])){if(val.worker_id==worker_id)continue;await func.index.call_worker(SESSION_ID,{service:"update_datasource_changes_from_client",data:data},{worker_id:worker_id})}},post_datasource:async function(){if(typeof val.dsSessionP==="undefined"||val.dsSessionP===null)return;if(!SESSION_OBJ[SESSION_ID].DS_GLB[val.dsSessionP]){SESSION_OBJ[SESSION_ID].DS_GLB[val.dsSessionP]=val.ds_obj}else{const update_existing_ds_object=function(old_obj,new_obj){for(const[key,val]of Object.entries(new_obj)){if(typeof val!=="object"){old_obj[key]=val2}else{if(!old_obj[key]){old_obj[key]=val}else update_existing_ds_object(old_obj[key],val)}}};update_existing_ds_object(SESSION_OBJ[SESSION_ID].DS_GLB[val.dsSessionP],val.ds_obj)}var verify_set_parent_ds=function(){var dsSession=val.dsSessionP;for(const[key,val]of Object.entries(SESSION_OBJ[SESSION_ID].DS_GLB[dsSession].parent_ds_chain)){if(SESSION_OBJ[SESSION_ID].DS_GLB[val]){SESSION_OBJ[SESSION_ID].DS_GLB[dsSession].parentDataSourceNo=val;break}}};verify_set_parent_ds();if(val.ds_obj.dataSourceSessionGlobal>SESSION_OBJ[SESSION_ID].dataSourceSessionGlobal)SESSION_OBJ[SESSION_ID].dataSourceSessionGlobal=val.ds_obj.dataSourceSessionGlobal},return_to_data_source:function(type,dsSessionP,ds){var data={session_id:SESSION_ID,dssession:dsSessionP,onscreen_events_active:ds.v.onscreen_events_active,viewEventExec_arr:JSON.stringify(ds.viewEventExec_arr),return_to_data_source_type:type};func.index.call_worker(SESSION_ID,{service:"return_to_data_source",data:data})},acknowledged_worker_with_eventChangesResults_done:async function(dsSessionP,worker_id){var data={session_id:SESSION_ID,dssession:dsSessionP};await func.index.call_worker(SESSION_ID,{service:"acknowledged_worker_with_eventChangesResults_done",data:data},{worker_id:worker_id});return _resolve()},execute_onscreen_view_events:async function(){await fx.post_datasource();var ds=SESSION_OBJ[SESSION_ID].DS_GLB[val.dsSessionP];await func.datasource.execute_onscreen_view_events(SESSION_ID,val.dsSessionP,"onscreen events");if(!ds.v.onscreen_events_active)return;var type=ds.v.onscreen_events_active.type;ds.v.onscreen_events_active=null;fx.return_to_data_source(type,val.dsSessionP,ds);return _resolve()},execute_local_db_query:async function(){await fx.post_datasource();const data=await func.db.get_query(SESSION_ID,val.fileIdP,val.queryP,val.dsSessionP,val.viewSourceDescP,val.sourceP,val.reduceP,val.skipP,val.limitP,val.countP,val.idsP);var msg={};msg.worker_id=worker_id;msg.data={};msg.service="return_from_db_query";msg.data.worker_id=worker_id;msg.data.callback_id=val.callback_id;msg.data.session_id=SESSION_ID;msg.data.data=data;if(RUNTIME_SERVER_WEBSOCKET&&RUNTIME_SERVER_WEBSOCKET_CONNECTED&&(!_session.opt.app_computing_mode||_session.opt.app_computing_mode==="server")){msg.process_pid=WEBSOCKET_PROCESS_PID;WEB_WORKER[SESSION_ID][worker_id].worker.emit("message",msg)}else{WEB_WORKER[SESSION_ID][worker_id].worker.postMessage(msg)}_resolve()},execute_local_sava_data:async function(){await fx.post_datasource();const data=await func.db.save_data(SESSION_ID,val.dsSessionP,val.keyP);var msg={};msg.worker_id=worker_id;msg.data={};msg.service="return_from_sava_data";msg.data.worker_id=worker_id;msg.data.callback_id=val.callback_id;msg.data.session_id=SESSION_ID;msg.data.data=data;if(RUNTIME_SERVER_WEBSOCKET&&RUNTIME_SERVER_WEBSOCKET_CONNECTED&&(!_session.opt.app_computing_mode||_session.opt.app_computing_mode==="server")){msg.process_pid=WEBSOCKET_PROCESS_PID;WEB_WORKER[SESSION_ID][worker_id].worker.emit("message",msg)}else{WEB_WORKER[SESSION_ID][worker_id].worker.postMessage(msg)}_resolve()},write_debug_log:function(params){func.utils.debug.write(SESSION_ID,val.data);_resolve()},write_log:async function(params){if(SESSION_OBJ[SESSION_ID].crawler)return;await func.common.db(SESSION_ID,"write_log",{msg:val.data,source:"runtime",log_type:"error"});_resolve()},change_loaded_image:function(params){const new_image=e.data.params.data;var $img=$("img");$.each($img,function(key,val){var src=$(val).prop("src");if(src.indexOf(new_image)>0){$(val).attr("src",src+"?ts="+(new Date).valueOf())}});_resolve()},send_watch_to_studio_websocket:function(params){STUDIO_WEBSOCKET.emit("message",val);_resolve()},get_doc_from_studio:async function(params){const module=await func.common.get_module(SESSION_ID,`xuda-progs-loader-module.mjs`);const data=await module.get_doc_from_studio(SESSION_ID,SESSION_OBJ[SESSION_ID].app_id,params.params.doc_id);func.index.call_worker(SESSION_ID,{service:"return_doc_from_studio",data:data});_resolve()},get_doc_from_websocket:async function(params){const module=await func.common.get_module(SESSION_ID,`xuda-progs-loader-module.mjs`);const data=await module.get_doc_from_websocket(SESSION_ID,SESSION_OBJ[SESSION_ID].app_id,params.params.doc_id);func.index.call_worker(SESSION_ID,{service:"return_doc_from_websocket",data:data});_resolve()},get_dbs_data_from_websocket:async function(params){const data=await func.common.get_data_from_websocket(SESSION_ID,params.params.service,params.params.data);func.index.call_worker(SESSION_ID,{service:"return_dbs_data_from_websocket",data:{data:data,websocket_queue_num:params.params.websocket_queue_num}});_resolve()},perform_rpi_request_from_studio:async function(params){const data=await func.common.db(SESSION_ID,params.params.service,params.params.data);func.index.call_worker(SESSION_ID,{service:"return_rpi_request_from_studio",data:{data:data.data,table_id:params.params.req_id}});_resolve()},refresh_document_changes_for_realtime_update:async function(params){func.UI.screen.refresh_document_changes_for_realtime_update(SESSION_ID,params.params.doc_change);_resolve()}};const get_promise_queue=function(t,worker_id){if(!WEB_WORKER[SESSION_ID][worker_id]){console.warn("worker job not found");return}return WEB_WORKER[SESSION_ID][worker_id].promise_queue[t]};const promise_ret=await get_promise_queue(e.data.promise_queue_id,e.data.worker_id);const _resolve=function(params){if(!promise_ret)return resolve();promise_ret.resolve(params);setTimeout(function(){if(WEB_WORKER[SESSION_ID][e.data.worker_id])delete WEB_WORKER[SESSION_ID][e.data.worker_id].promise_queue[e.data.promise_queue_id]},1e3)};if(fx[e.data.fx_to_execute]){return await fx[e.data.fx_to_execute](e.data)}if(!promise_ret)return console.error("promise not found");if(!e.data.fx_to_execute){return _resolve(e.data.params)}if(e.data.fx_to_execute==="worker_response"){return _resolve(e.data.params)}})};if(RUNTIME_SERVER_WEBSOCKET&&RUNTIME_SERVER_WEBSOCKET_CONNECTED&&(!_session.opt.app_computing_mode||_session.opt.app_computing_mode==="server")){await create_websocket()}else{await create_worker()}init_worker_session(worker_id);return worker_id};func.index.set_ds_0_proxy=function(SESSION_ID){const _session=SESSION_OBJ[SESSION_ID];let _ds=_session.DS_GLB[0];function createWatchedObject(obj,onChange){const watchers=new WeakMap;function createProxy(target,path=[]){if(watchers.has(target)){return watchers.get(target)}const proxy=new Proxy(target,{set(obj,prop,value){const oldValue=obj[prop];let currentPath=[...path,prop];obj[prop]=value;if(typeof value==="object"&&value!==null){obj[prop]=createProxy(value,currentPath)}if(!_.isEqual(value,oldValue)){currentPath.shift();onChange({path:currentPath.join("."),oldValue:oldValue,newValue:value,type:"set",timestamp:Date.now()})}return true},deleteProperty(obj,prop){const oldValue=obj[prop];const currentPath=[...path,prop];delete obj[prop];onChange({path:currentPath.join("."),oldValue:oldValue,newValue:undefined,type:"delete",timestamp:Date.now()});return true}});for(const[key,value]of Object.entries(target)){if(typeof value==="object"&&value!==null){target[key]=createProxy(value,[...path,key])}}watchers.set(target,proxy);return proxy}return createProxy(obj)}const watchedDs=createWatchedObject({_ref:_ds},async change=>{const{path,newValue,oldValue}=change;try{const _session=SESSION_OBJ[SESSION_ID];let watch_path="data_system."+path;const runHandler=()=>{const{handler,once}=_session?.watchers?.[watch_path]||{};handler(change);if(once){delete _session.watchers[watch_path]}};if(_session?.watchers?.[watch_path]){runHandler()}else{watch_path="data_system.SYS_GLOBAL_OBJ_REFS."+path;runHandler()}if(_.isEqual(newValue,oldValue))return;const _refs=SESSION_OBJ[SESSION_ID].DS_GLB[0].data_system.SYS_GLOBAL_OBJ_REFS;for(const[ref_id,val]of Object.entries(_refs)){const prefix=`${ref_id}.ds.`;if(!path.includes(prefix))continue;const clean_path_prop=path.split(prefix)[1];if(!clean_path_prop.includes("progDataSource"))continue;const _ref=SESSION_OBJ[SESSION_ID].DS_GLB[0].data_system.SYS_GLOBAL_OBJ_REFS[ref_id];if(!_ref)continue;const _ds=_ref.ds;const target_ds=_session.DS_GLB[_ds.dsSession];const target_value=_.get(target_ds,clean_path_prop);if(_.isEqual(target_value,newValue))continue;const datasource_changes={[_ds.dsSession]:{["datasource_main"]:{watcher:{path:clean_path_prop,newValue:newValue}}}};await func.datasource.update(SESSION_ID,datasource_changes)}return}catch(error){}});_session.DS_GLB[0]=watchedDs._ref};glb.CODE_BUNDLE=1;
119
+ `);setTimeout(()=>{$(`[name="hard_reload"]`).off("click").on("click",async function(){await func.index.delete_pouch(SESSION_ID);location.reload()});$(`[name="reset_worker"]`).off("click").on("click",function(){_session.WORKER_OBJ.jobs[0].stat=null;_session.WORKER_OBJ.stat=null;func.UI.utils.progressScreen.hide(SESSION_ID)});$(`[name="get_support"]`).off("click").on("click",async function(){const get_support=await func.common.get_module(SESSION_ID,"xuda-get-support-module.esm.js");var name,subject;const prompt_name=()=>{name=window.prompt(`Get support from your ${APP_OBJ[app_id].app_general_prop?.app_name} team, \n\nYour Name (required):`);if(name==="")prompt_name()};const prompt_subject=()=>{subject=window.prompt(`When you click on "Ok," you are granting permission to ${APP_OBJ[app_id]?.app_name} team to access your browser. \n\nSubject (required):`);if(subject==="")prompt_subject()};if(!SUPPORT_PEER){try{name=firebase.auth().currentUser.displayName}catch(error){if(_session?.USR_OBJ?.usr_name){name=_session.USR_OBJ.usr_name}else{prompt_name()}}if(name===null)return;prompt_subject();if(subject===null)return;func.common.db(SESSION_ID,"get_support",{name:name,subject:subject});setTimeout(()=>{$("body").addClass("get_support_request");$("body").remove(".get_support_request_title").append("<div class='get_support_request_title'>Support pending</div>")},2e3)}else{get_support.terminate_peer(SESSION_ID)}func.UI.utils.progressScreen.hide(SESSION_ID)})},1e3)}}};if(event.which===27){let SESSION_ID=Object.keys(SESSION_OBJ)[0];func.UI.utils.progressScreen.hide(SESSION_ID)}if(event.ctrlKey&&event.shiftKey){if(keys[event.which]){keys[event.which].fx()}}});$(document).mousemove(function(e){CLIENT_ACTIVITY_TS=Date.now();posX=e.pageX;posY=e.pageY;if(SESSION_OBJ[SESSION_ID]?.DS_GLB?.[0]){SESSION_OBJ[SESSION_ID].DS_GLB[0].data_system["SYS_GLOBAL_OBJ_CLIENT_INFO"].cursor_pos_x=posX;SESSION_OBJ[SESSION_ID].DS_GLB[0].data_system["SYS_GLOBAL_OBJ_CLIENT_INFO"].cursor_pos_y=posY}});$.fn.draggable=function(){CLIENT_ACTIVITY_TS=Date.now();var $this=this,ns="draggable_"+(Math.random()+"").replace(".",""),mm="mousemove."+ns,mu="mouseup."+ns,$w=$(window),isFixed=$this.css("position")==="fixed",adjX=0,adjY=0;$this.mousedown(function(ev){var pos=$this.offset();if(isFixed){adjX=$w.scrollLeft();adjY=$w.scrollTop()}var ox=ev.pageX-pos.left,oy=ev.pageY-pos.top;$this.data(ns,{x:ox,y:oy});$w.on(mm,function(ev){ev.preventDefault();ev.stopPropagation();if(isFixed){adjX=$w.scrollLeft();adjY=$w.scrollTop()}var offset=$this.data(ns);$this.css({left:ev.pageX-adjX-offset.x,top:ev.pageY-adjY-offset.y})});$w.on(mu,function(){$w.off(mm+" "+mu).removeData(ns)})});return this};var heartbeat_attempts=0;var heartbeat_internal=setInterval(async function(){const SESSION_ID=Object.keys(SESSION_OBJ)[0];if(!SESSION_ID)return;let _session=SESSION_OBJ[SESSION_ID];if(!_session)return;if(_session.crawler)return;const set_idle=async function(stat){var datasource_changes={[0]:{["data_system"]:{SYS_GLOBAL_BOL_IDLE:stat}}};await func.datasource.update(SESSION_ID,datasource_changes)};if(Date.now()-CLIENT_ACTIVITY_TS>3e4){set_idle(1)}else{set_idle(0)}if(_session.engine_mode==="live_preview"||!_session.opt.enable_user_assist){return}const ret=await func.common.db(SESSION_ID,"heartbeat",{stat:Date.now()-CLIENT_ACTIVITY_TS>3e4?1:2}).catch(err=>{heartbeat_attempts++;console.warn(err.message);if(heartbeat_attempts<10)return;clearInterval(heartbeat_internal)});heartbeat_attempts=0;if(ret?.session_stat===3){await func.index.delete_pouch();window.top.location.reload()}$("body").removeClass("get_support_request");$("body").find(".get_support_request_title").remove();$("body").removeClass("get_support_online");$("body").find(".get_support_online_title").remove();if(ret?.data?.peer?.peer_status===1){if(ret.data.peer.peer_regional_server){get_support.init_peer(SESSION_ID,ret.data.peer.peer_regional_server)}$("body").addClass("get_support_request");$("body").remove(".get_support_request_title").append("<div class='get_support_request_title'>Support pending</div>")}if(ret?.data?.peer?.peer_status===2){$("body").addClass("get_support_online");$("body").remove(".get_support_online_title").append("<div class='get_support_online_title'>Support online</div>")}_session.res_token=ret.res_token},3e4);glb.WINDOW_LOCATION_SEARCH=window.location.search};func.index.checkConnectivity=async function(){const endpoints=["https://xuda.io/favicon.ico"];const promises=endpoints.map(url=>fetch(url,{method:"HEAD",mode:"no-cors"}).then(()=>true).catch(()=>false));const results=await Promise.all(promises);IS_ONLINE=results.some(result=>result===true);window.addEventListener("online",function(){IS_ONLINE=true;$("body").trigger("set_db_replication_from_server")});window.addEventListener("offline",function(){IS_ONLINE=false})};func.index.init_service_workers=function(){if("serviceWorker"in navigator){navigator.serviceWorker.addEventListener("message",function(event){console.log("serviceWorker message:",event)});navigator.serviceWorker.register("xuda-sw.js").then(function(registration){console.log("ServiceWorker registration successful with scope: ",registration.scope);glb.sw_registration=registration},function(err){console.log("ServiceWorker registration failed: ",err)})}};func.index.delete_pouch=async function(SESSION_ID=Object.keys(SESSION_OBJ)[0]){const db=await func.utils.connect_pouchdb(SESSION_ID);try{return await db.destroy()}catch(err){console.log(err)}};func.index.new_webworker=async function(SESSION_ID,prog_obj,obj){var worker_id=Object.keys(WEB_WORKER[SESSION_ID]).length+1;var _session=SESSION_OBJ[SESSION_ID];if(!_session.engine_mode==="docker"){ver=APP_OBJ[_session.app_id].app_version}var build_id=["live_preview","miniapp"].includes(_session.engine_mode)?"":_session.opt.app_build_id;if(typeof XUDA_BUILD_ID!=="undefined"){build_id=XUDA_BUILD_ID}const worker_name=`${typeof _session.SLIM_BUNDLE==="undefined"||!_session.SLIM_BUNDLE?"":"Slim "}${prog_obj.menuName} worker`+" "+glb.worker_type+": #"+worker_id.toString()+" "+(build_id||"")+" "+_session.domain;const init_worker_session=function(worker_id){var _session=_.cloneDeep(SESSION_OBJ[SESSION_ID]);delete _session.root_element;const get_parent_ds=function(ds){var ds_obj={};if(ds&&_session.DS_GLB[ds].parentDataSourceNo!==null){ds_obj[ds]=func.utils.clean_returned_datasource(SESSION_ID,ds);_.forEach(get_parent_ds(_session.DS_GLB[ds].parentDataSourceNo),function(val,key){ds_obj[key]=val})}else{ds_obj[ds]=func.utils.clean_returned_datasource(SESSION_ID,ds)}return ds_obj};var ds_obj={};if(typeof obj?.data?.parentDataSourceNoP!=="undefined"){ds_obj=get_parent_ds(obj.data.parentDataSourceNoP)}_session.DS_GLB={};_session.WORKER_OBJ={jobs:[],num:1e3,stat:null};var app_id=_session.app_id;var data={SESSION_ID:SESSION_ID,app_id:app_id,APP_OBJ:APP_OBJ[app_id],PROJECT_OBJ:PROJECT_OBJ[app_id],DOCS_OBJ:DOCS_OBJ[app_id],APP_INFO:glb.APP_INFO[app_id],DEBUG_MODE:glb.DEBUG_MODE,DEBUG_INFO_OBJ:glb.DEBUG_INFO_OBJ,WINDOW_LOCATION_SEARCH:glb.WINDOW_LOCATION_SEARCH,ROOT_ELEMENT_ATTRIBUTES:glb.ROOT_ELEMENT_ATTRIBUTES,DS_GLB:ds_obj,SESSION_INFO:JSON.parse(JSON.stringify(_session)),session_id:SESSION_ID,engine_mode:_session.engine_mode,STUDIO_WEBSOCKET_CONNECTION_ID:STUDIO_WEBSOCKET_CONNECTION_ID};if(_session.engine_mode==="live_preview"){data.DOCS_OBJ=DOCS_OBJ[app_id]}delete data.SESSION_INFO.root_element;data.SESSION_INFO.worker_id=worker_id;var ds_arr=[];$.map(_session.DS_GLB,function(val,i){ds_arr.push(i)});WEB_WORKER[SESSION_ID][worker_id].ds_arr=ds_arr;delete data.SESSION_INFO.DS_UI_EVENTS_GLB;if(RUNTIME_SERVER_WEBSOCKET&&RUNTIME_SERVER_WEBSOCKET_CONNECTED&&(!_session.opt.app_computing_mode||_session.opt.app_computing_mode==="server")){WEB_WORKER[SESSION_ID][worker_id].worker.emit("message",{service:"init",data:data,worker_id:worker_id})}else{WEB_WORKER[SESSION_ID][worker_id].worker.postMessage({service:"init",data:JSON.stringify(data),worker_id:worker_id})}};const create_worker=async function(){return new Promise((resolve,reject)=>{if(glb.worker_type==="Dev"){WEB_WORKER[SESSION_ID][worker_id]={worker:new Worker("js/xuda_worker.js",{name:worker_name}),promise_queue:{}}}else{function getWorkerURL(url){const content=`importScripts( "${url}" );`;return URL.createObjectURL(new Blob([content],{type:"text/javascript"}))}const _session=SESSION_OBJ[SESSION_ID];let blob=getWorkerURL(func.common.get_url(SESSION_ID,"dist",func.utils.get_resource_filename(["live_preview","miniapp"].includes(_session.engine_mode)?"":_session?.opt?.app_build_id,"runtime/js/xuda_worker.js")));WEB_WORKER[SESSION_ID][worker_id]={worker:new Worker(blob,{name:worker_name}),promise_queue:{}}}WEB_WORKER[SESSION_ID][worker_id].worker.addEventListener("message",function(e){if(e.data.service==="worker_ready"){return resolve()}worker_functions(e)},false)})};const create_websocket=async function(){return new Promise((resolve,reject)=>{WEB_WORKER[SESSION_ID][worker_id]={worker:RUNTIME_SERVER_WEBSOCKET,promise_queue:{}};WEB_WORKER[SESSION_ID][worker_id].worker.on("message",async e=>{if(["deployment_server","http_call"].includes(e.source))return;worker_functions({data:e})});resolve()})};const worker_functions=async function(e_raw){return new Promise(async(resolve,reject)=>{var e={};e.data=e_raw.data;if(RUNTIME_SERVER_WEBSOCKET&&RUNTIME_SERVER_WEBSOCKET_CONNECTED&&(!_session.opt.app_computing_mode||_session.opt.app_computing_mode==="server")){WEBSOCKET_PROCESS_PID=e.data.process_pid}var val=e.data.params;var fx={init_done:async function(){if(!obj){return _resolve()}},alert:function(){if(val[1]==="save_on"){func.UI.utils.save(SESSION_ID,true);return true}if(val[1]==="save_off"){func.UI.utils.save(SESSION_ID,false);return true}func.utils.alerts.execute(SESSION_ID,val[1],val[2],val[3],val[4]);return _resolve()},progress_on:function(){func.UI.utils.progressScreen.show(SESSION_ID,val,null);return _resolve()},progress_off:function(){func.UI.utils.progressScreen.hide();return _resolve()},worker_busy_on:function(){func.UI.utils.indicator.worker.busy();return _resolve()},worker_busy_off:function(){func.UI.utils.indicator.worker.normal();return _resolve()},screen_blocker_on:function(){func.UI.utils.screen_blocker(true,"Worker");return _resolve()},ajax_error:function(){func.utils.request_error(SESSION_ID,"ajax","Session error");return _resolve()},screen_blocker_off:function(){func.UI.utils.screen_blocker(false,"Worker");return _resolve()},job:function(){func.events.add_to_queue(SESSION_ID,val.typeP,val.eventIdP,val.triggerP,val.functionP,val.refIdP,val.containerP,val.elementP,val.rowP,null,val.descP,null,null,val.dsSessionP,null,null,val.event_propertiesP,val.calling_triggerP,val.paramsP,null,null,val.calling_trigger_prop,val.argumentsP,val.source_event_idP,val.calling_job,val.args);return _resolve()},update_client_eventChangesResults_from_worker:async function(){await func.datasource.update(SESSION_ID,val,true);if(!val.worker_id){return}fx.acknowledged_worker_with_eventChangesResults_done(val.dssession,val.worker_id);for await(const[worker_id,ds_arr]of Object.entries(WEB_WORKER[SESSION_ID])){if(val.worker_id==worker_id)continue;await func.index.call_worker(SESSION_ID,{service:"update_datasource_changes_from_client",data:data},{worker_id:worker_id})}},post_datasource:async function(){if(typeof val.dsSessionP==="undefined"||val.dsSessionP===null)return;if(!SESSION_OBJ[SESSION_ID].DS_GLB[val.dsSessionP]){SESSION_OBJ[SESSION_ID].DS_GLB[val.dsSessionP]=val.ds_obj}else{const update_existing_ds_object=function(old_obj,new_obj){for(const[key,val]of Object.entries(new_obj)){if(typeof val!=="object"){old_obj[key]=val2}else{if(!old_obj[key]){old_obj[key]=val}else update_existing_ds_object(old_obj[key],val)}}};update_existing_ds_object(SESSION_OBJ[SESSION_ID].DS_GLB[val.dsSessionP],val.ds_obj)}var verify_set_parent_ds=function(){var dsSession=val.dsSessionP;for(const[key,val]of Object.entries(SESSION_OBJ[SESSION_ID].DS_GLB[dsSession].parent_ds_chain)){if(SESSION_OBJ[SESSION_ID].DS_GLB[val]){SESSION_OBJ[SESSION_ID].DS_GLB[dsSession].parentDataSourceNo=val;break}}};verify_set_parent_ds();if(val.ds_obj.dataSourceSessionGlobal>SESSION_OBJ[SESSION_ID].dataSourceSessionGlobal)SESSION_OBJ[SESSION_ID].dataSourceSessionGlobal=val.ds_obj.dataSourceSessionGlobal},return_to_data_source:function(type,dsSessionP,ds){var data={session_id:SESSION_ID,dssession:dsSessionP,onscreen_events_active:ds.v.onscreen_events_active,viewEventExec_arr:JSON.stringify(ds.viewEventExec_arr),return_to_data_source_type:type};func.index.call_worker(SESSION_ID,{service:"return_to_data_source",data:data})},acknowledged_worker_with_eventChangesResults_done:async function(dsSessionP,worker_id){var data={session_id:SESSION_ID,dssession:dsSessionP};await func.index.call_worker(SESSION_ID,{service:"acknowledged_worker_with_eventChangesResults_done",data:data},{worker_id:worker_id});return _resolve()},execute_onscreen_view_events:async function(){await fx.post_datasource();var ds=SESSION_OBJ[SESSION_ID].DS_GLB[val.dsSessionP];await func.datasource.execute_onscreen_view_events(SESSION_ID,val.dsSessionP,"onscreen events");if(!ds.v.onscreen_events_active)return;var type=ds.v.onscreen_events_active.type;ds.v.onscreen_events_active=null;fx.return_to_data_source(type,val.dsSessionP,ds);return _resolve()},execute_local_db_query:async function(){await fx.post_datasource();const data=await func.db.get_query(SESSION_ID,val.fileIdP,val.queryP,val.dsSessionP,val.viewSourceDescP,val.sourceP,val.reduceP,val.skipP,val.limitP,val.countP,val.idsP);var msg={};msg.worker_id=worker_id;msg.data={};msg.service="return_from_db_query";msg.data.worker_id=worker_id;msg.data.callback_id=val.callback_id;msg.data.session_id=SESSION_ID;msg.data.data=data;if(RUNTIME_SERVER_WEBSOCKET&&RUNTIME_SERVER_WEBSOCKET_CONNECTED&&(!_session.opt.app_computing_mode||_session.opt.app_computing_mode==="server")){msg.process_pid=WEBSOCKET_PROCESS_PID;WEB_WORKER[SESSION_ID][worker_id].worker.emit("message",msg)}else{WEB_WORKER[SESSION_ID][worker_id].worker.postMessage(msg)}_resolve()},execute_local_sava_data:async function(){await fx.post_datasource();const data=await func.db.save_data(SESSION_ID,val.dsSessionP,val.keyP);var msg={};msg.worker_id=worker_id;msg.data={};msg.service="return_from_sava_data";msg.data.worker_id=worker_id;msg.data.callback_id=val.callback_id;msg.data.session_id=SESSION_ID;msg.data.data=data;if(RUNTIME_SERVER_WEBSOCKET&&RUNTIME_SERVER_WEBSOCKET_CONNECTED&&(!_session.opt.app_computing_mode||_session.opt.app_computing_mode==="server")){msg.process_pid=WEBSOCKET_PROCESS_PID;WEB_WORKER[SESSION_ID][worker_id].worker.emit("message",msg)}else{WEB_WORKER[SESSION_ID][worker_id].worker.postMessage(msg)}_resolve()},write_debug_log:function(params){func.utils.debug.write(SESSION_ID,val.data);_resolve()},write_log:async function(params){if(SESSION_OBJ[SESSION_ID].crawler)return;await func.common.db(SESSION_ID,"write_log",{msg:val.data,source:"runtime",log_type:"error"});_resolve()},change_loaded_image:function(params){const new_image=e.data.params.data;var $img=$("img");$.each($img,function(key,val){var src=$(val).prop("src");if(src.indexOf(new_image)>0){$(val).attr("src",src+"?ts="+(new Date).valueOf())}});_resolve()},send_watch_to_studio_websocket:function(params){STUDIO_WEBSOCKET.emit("message",val);_resolve()},get_doc_from_studio:async function(params){const module=await func.common.get_module(SESSION_ID,`xuda-progs-loader-module.mjs`);const data=await module.get_doc_from_studio(SESSION_ID,SESSION_OBJ[SESSION_ID].app_id,params.params.doc_id);func.index.call_worker(SESSION_ID,{service:"return_doc_from_studio",data:data});_resolve()},get_doc_from_websocket:async function(params){const module=await func.common.get_module(SESSION_ID,`xuda-progs-loader-module.mjs`);const data=await module.get_doc_from_websocket(SESSION_ID,SESSION_OBJ[SESSION_ID].app_id,params.params.doc_id);func.index.call_worker(SESSION_ID,{service:"return_doc_from_websocket",data:data});_resolve()},get_dbs_data_from_websocket:async function(params){const data=await func.common.get_data_from_websocket(SESSION_ID,params.params.service,params.params.data);func.index.call_worker(SESSION_ID,{service:"return_dbs_data_from_websocket",data:{data:data,websocket_queue_num:params.params.websocket_queue_num}});_resolve()},perform_rpi_request_from_studio:async function(params){const data=await func.common.db(SESSION_ID,params.params.service,params.params.data);func.index.call_worker(SESSION_ID,{service:"return_rpi_request_from_studio",data:{data:data.data,table_id:params.params.req_id}});_resolve()},refresh_document_changes_for_realtime_update:async function(params){func.UI.screen.refresh_document_changes_for_realtime_update(SESSION_ID,params.params.doc_change);_resolve()}};const get_promise_queue=function(t,worker_id){if(!WEB_WORKER[SESSION_ID][worker_id]){console.warn("worker job not found");return}return WEB_WORKER[SESSION_ID][worker_id].promise_queue[t]};const promise_ret=await get_promise_queue(e.data.promise_queue_id,e.data.worker_id);const _resolve=function(params){if(!promise_ret)return resolve();promise_ret.resolve(params);setTimeout(function(){if(WEB_WORKER[SESSION_ID][e.data.worker_id])delete WEB_WORKER[SESSION_ID][e.data.worker_id].promise_queue[e.data.promise_queue_id]},1e3)};if(fx[e.data.fx_to_execute]){return await fx[e.data.fx_to_execute](e.data)}if(!promise_ret)return console.error("promise not found");if(!e.data.fx_to_execute){return _resolve(e.data.params)}if(e.data.fx_to_execute==="worker_response"){return _resolve(e.data.params)}})};if(RUNTIME_SERVER_WEBSOCKET&&RUNTIME_SERVER_WEBSOCKET_CONNECTED&&(!_session.opt.app_computing_mode||_session.opt.app_computing_mode==="server")){await create_websocket()}else{await create_worker()}init_worker_session(worker_id);return worker_id};func.index.set_ds_0_proxy=function(SESSION_ID){const _session=SESSION_OBJ[SESSION_ID];let _ds=_session.DS_GLB[0];function createWatchedObject(obj,onChange){const watchers=new WeakMap;function createProxy(target,path=[]){if(watchers.has(target)){return watchers.get(target)}const proxy=new Proxy(target,{set(obj,prop,value){const oldValue=obj[prop];let currentPath=[...path,prop];obj[prop]=value;if(typeof value==="object"&&value!==null){obj[prop]=createProxy(value,currentPath)}if(!_.isEqual(value,oldValue)){currentPath.shift();onChange({path:currentPath.join("."),oldValue:oldValue,newValue:value,type:"set",timestamp:Date.now()})}return true},deleteProperty(obj,prop){const oldValue=obj[prop];const currentPath=[...path,prop];delete obj[prop];onChange({path:currentPath.join("."),oldValue:oldValue,newValue:undefined,type:"delete",timestamp:Date.now()});return true}});for(const[key,value]of Object.entries(target)){if(typeof value==="object"&&value!==null){target[key]=createProxy(value,[...path,key])}}watchers.set(target,proxy);return proxy}return createProxy(obj)}const watchedDs=createWatchedObject({_ref:_ds},async change=>{const{path,newValue,oldValue}=change;try{const _session=SESSION_OBJ[SESSION_ID];let watch_path="data_system."+path;const runHandler=()=>{const{handler,once}=_session?.watchers?.[watch_path]||{};if(change)handler(change);if(once){delete _session.watchers[watch_path]}};if(_session?.watchers?.[watch_path]){runHandler()}else{watch_path="data_system.SYS_GLOBAL_OBJ_REFS."+path;runHandler()}if(_.isEqual(newValue,oldValue))return;const _refs=SESSION_OBJ[SESSION_ID].DS_GLB[0].data_system.SYS_GLOBAL_OBJ_REFS;for(const[ref_id,val]of Object.entries(_refs)){const prefix=`${ref_id}.ds.`;if(!path.includes(prefix))continue;const clean_path_prop=path.split(prefix)[1];if(!clean_path_prop.includes("progDataSource"))continue;const _ref=SESSION_OBJ[SESSION_ID].DS_GLB[0].data_system.SYS_GLOBAL_OBJ_REFS[ref_id];if(!_ref)continue;const _ds=_ref.ds;const target_ds=_session.DS_GLB[_ds.dsSession];const target_value=_.get(target_ds,clean_path_prop);if(_.isEqual(target_value,newValue))continue;const datasource_changes={[_ds.dsSession]:{["datasource_main"]:{watcher:{path:clean_path_prop,newValue:newValue}}}};await func.datasource.update(SESSION_ID,datasource_changes)}return}catch(error){}});_session.DS_GLB[0]=watchedDs._ref};glb.CODE_BUNDLE=1;
@@ -20279,7 +20279,7 @@ func.index.set_ds_0_proxy = function (SESSION_ID) {
20279
20279
 
20280
20280
  const runHandler = () => {
20281
20281
  const { handler, once } = _session?.watchers?.[watch_path] || {};
20282
- handler(change);
20282
+ if (change) handler(change);
20283
20283
  if (once) {
20284
20284
  delete _session.watchers[watch_path];
20285
20285
  }
@@ -20280,7 +20280,7 @@ func.index.set_ds_0_proxy = function (SESSION_ID) {
20280
20280
 
20281
20281
  const runHandler = () => {
20282
20282
  const { handler, once } = _session?.watchers?.[watch_path] || {};
20283
- handler(change);
20283
+ if (change) handler(change);
20284
20284
  if (once) {
20285
20285
  delete _session.watchers[watch_path];
20286
20286
  }
@@ -110,4 +110,4 @@
110
110
 
111
111
  </div>
112
112
 
113
- `);setTimeout(()=>{$(`[name="hard_reload"]`).off("click").on("click",async function(){await func.index.delete_pouch(SESSION_ID);location.reload()});$(`[name="reset_worker"]`).off("click").on("click",function(){_session.WORKER_OBJ.jobs[0].stat=null;_session.WORKER_OBJ.stat=null;func.UI.utils.progressScreen.hide(SESSION_ID)});$(`[name="get_support"]`).off("click").on("click",async function(){const get_support=await func.common.get_module(SESSION_ID,"xuda-get-support-module.esm.js");var name,subject;const prompt_name=()=>{name=window.prompt(`Get support from your ${APP_OBJ[app_id].app_general_prop?.app_name} team, \n\nYour Name (required):`);if(name==="")prompt_name()};const prompt_subject=()=>{subject=window.prompt(`When you click on "Ok," you are granting permission to ${APP_OBJ[app_id]?.app_name} team to access your browser. \n\nSubject (required):`);if(subject==="")prompt_subject()};if(!SUPPORT_PEER){try{name=firebase.auth().currentUser.displayName}catch(error){if(_session?.USR_OBJ?.usr_name){name=_session.USR_OBJ.usr_name}else{prompt_name()}}if(name===null)return;prompt_subject();if(subject===null)return;func.common.db(SESSION_ID,"get_support",{name:name,subject:subject});setTimeout(()=>{$("body").addClass("get_support_request");$("body").remove(".get_support_request_title").append("<div class='get_support_request_title'>Support pending</div>")},2e3)}else{get_support.terminate_peer(SESSION_ID)}func.UI.utils.progressScreen.hide(SESSION_ID)})},1e3)}}};if(event.which===27){let SESSION_ID=Object.keys(SESSION_OBJ)[0];func.UI.utils.progressScreen.hide(SESSION_ID)}if(event.ctrlKey&&event.shiftKey){if(keys[event.which]){keys[event.which].fx()}}});$(document).mousemove(function(e){CLIENT_ACTIVITY_TS=Date.now();posX=e.pageX;posY=e.pageY;if(SESSION_OBJ[SESSION_ID]?.DS_GLB?.[0]){SESSION_OBJ[SESSION_ID].DS_GLB[0].data_system["SYS_GLOBAL_OBJ_CLIENT_INFO"].cursor_pos_x=posX;SESSION_OBJ[SESSION_ID].DS_GLB[0].data_system["SYS_GLOBAL_OBJ_CLIENT_INFO"].cursor_pos_y=posY}});$.fn.draggable=function(){CLIENT_ACTIVITY_TS=Date.now();var $this=this,ns="draggable_"+(Math.random()+"").replace(".",""),mm="mousemove."+ns,mu="mouseup."+ns,$w=$(window),isFixed=$this.css("position")==="fixed",adjX=0,adjY=0;$this.mousedown(function(ev){var pos=$this.offset();if(isFixed){adjX=$w.scrollLeft();adjY=$w.scrollTop()}var ox=ev.pageX-pos.left,oy=ev.pageY-pos.top;$this.data(ns,{x:ox,y:oy});$w.on(mm,function(ev){ev.preventDefault();ev.stopPropagation();if(isFixed){adjX=$w.scrollLeft();adjY=$w.scrollTop()}var offset=$this.data(ns);$this.css({left:ev.pageX-adjX-offset.x,top:ev.pageY-adjY-offset.y})});$w.on(mu,function(){$w.off(mm+" "+mu).removeData(ns)})});return this};var heartbeat_attempts=0;var heartbeat_internal=setInterval(async function(){const SESSION_ID=Object.keys(SESSION_OBJ)[0];if(!SESSION_ID)return;let _session=SESSION_OBJ[SESSION_ID];if(!_session)return;if(_session.crawler)return;const set_idle=async function(stat){var datasource_changes={[0]:{["data_system"]:{SYS_GLOBAL_BOL_IDLE:stat}}};await func.datasource.update(SESSION_ID,datasource_changes)};if(Date.now()-CLIENT_ACTIVITY_TS>3e4){set_idle(1)}else{set_idle(0)}if(_session.engine_mode==="live_preview"||!_session.opt.enable_user_assist){return}const ret=await func.common.db(SESSION_ID,"heartbeat",{stat:Date.now()-CLIENT_ACTIVITY_TS>3e4?1:2}).catch(err=>{heartbeat_attempts++;console.warn(err.message);if(heartbeat_attempts<10)return;clearInterval(heartbeat_internal)});heartbeat_attempts=0;if(ret?.session_stat===3){await func.index.delete_pouch();window.top.location.reload()}$("body").removeClass("get_support_request");$("body").find(".get_support_request_title").remove();$("body").removeClass("get_support_online");$("body").find(".get_support_online_title").remove();if(ret?.data?.peer?.peer_status===1){if(ret.data.peer.peer_regional_server){get_support.init_peer(SESSION_ID,ret.data.peer.peer_regional_server)}$("body").addClass("get_support_request");$("body").remove(".get_support_request_title").append("<div class='get_support_request_title'>Support pending</div>")}if(ret?.data?.peer?.peer_status===2){$("body").addClass("get_support_online");$("body").remove(".get_support_online_title").append("<div class='get_support_online_title'>Support online</div>")}_session.res_token=ret.res_token},3e4);glb.WINDOW_LOCATION_SEARCH=window.location.search};func.index.checkConnectivity=async function(){const endpoints=["https://xuda.io/favicon.ico"];const promises=endpoints.map(url=>fetch(url,{method:"HEAD",mode:"no-cors"}).then(()=>true).catch(()=>false));const results=await Promise.all(promises);IS_ONLINE=results.some(result=>result===true);window.addEventListener("online",function(){IS_ONLINE=true;$("body").trigger("set_db_replication_from_server")});window.addEventListener("offline",function(){IS_ONLINE=false})};func.index.init_service_workers=function(){if("serviceWorker"in navigator){navigator.serviceWorker.addEventListener("message",function(event){console.log("serviceWorker message:",event)});navigator.serviceWorker.register("xuda-sw.js").then(function(registration){console.log("ServiceWorker registration successful with scope: ",registration.scope);glb.sw_registration=registration},function(err){console.log("ServiceWorker registration failed: ",err)})}};func.index.delete_pouch=async function(SESSION_ID=Object.keys(SESSION_OBJ)[0]){const db=await func.utils.connect_pouchdb(SESSION_ID);try{return await db.destroy()}catch(err){console.log(err)}};func.index.new_webworker=async function(SESSION_ID,prog_obj,obj){var worker_id=Object.keys(WEB_WORKER[SESSION_ID]).length+1;var _session=SESSION_OBJ[SESSION_ID];if(!_session.engine_mode==="docker"){ver=APP_OBJ[_session.app_id].app_version}var build_id=["live_preview","miniapp"].includes(_session.engine_mode)?"":_session.opt.app_build_id;if(typeof XUDA_BUILD_ID!=="undefined"){build_id=XUDA_BUILD_ID}const worker_name=`${typeof _session.SLIM_BUNDLE==="undefined"||!_session.SLIM_BUNDLE?"":"Slim "}${prog_obj.menuName} worker`+" "+glb.worker_type+": #"+worker_id.toString()+" "+(build_id||"")+" "+_session.domain;const init_worker_session=function(worker_id){var _session=_.cloneDeep(SESSION_OBJ[SESSION_ID]);delete _session.root_element;const get_parent_ds=function(ds){var ds_obj={};if(ds&&_session.DS_GLB[ds].parentDataSourceNo!==null){ds_obj[ds]=func.utils.clean_returned_datasource(SESSION_ID,ds);_.forEach(get_parent_ds(_session.DS_GLB[ds].parentDataSourceNo),function(val,key){ds_obj[key]=val})}else{ds_obj[ds]=func.utils.clean_returned_datasource(SESSION_ID,ds)}return ds_obj};var ds_obj={};if(typeof obj?.data?.parentDataSourceNoP!=="undefined"){ds_obj=get_parent_ds(obj.data.parentDataSourceNoP)}_session.DS_GLB={};_session.WORKER_OBJ={jobs:[],num:1e3,stat:null};var app_id=_session.app_id;var data={SESSION_ID:SESSION_ID,app_id:app_id,APP_OBJ:APP_OBJ[app_id],PROJECT_OBJ:PROJECT_OBJ[app_id],DOCS_OBJ:DOCS_OBJ[app_id],APP_INFO:glb.APP_INFO[app_id],DEBUG_MODE:glb.DEBUG_MODE,DEBUG_INFO_OBJ:glb.DEBUG_INFO_OBJ,WINDOW_LOCATION_SEARCH:glb.WINDOW_LOCATION_SEARCH,ROOT_ELEMENT_ATTRIBUTES:glb.ROOT_ELEMENT_ATTRIBUTES,DS_GLB:ds_obj,SESSION_INFO:JSON.parse(JSON.stringify(_session)),session_id:SESSION_ID,engine_mode:_session.engine_mode,STUDIO_WEBSOCKET_CONNECTION_ID:STUDIO_WEBSOCKET_CONNECTION_ID};if(_session.engine_mode==="live_preview"){data.DOCS_OBJ=DOCS_OBJ[app_id]}delete data.SESSION_INFO.root_element;data.SESSION_INFO.worker_id=worker_id;var ds_arr=[];$.map(_session.DS_GLB,function(val,i){ds_arr.push(i)});WEB_WORKER[SESSION_ID][worker_id].ds_arr=ds_arr;delete data.SESSION_INFO.DS_UI_EVENTS_GLB;if(RUNTIME_SERVER_WEBSOCKET&&RUNTIME_SERVER_WEBSOCKET_CONNECTED&&(!_session.opt.app_computing_mode||_session.opt.app_computing_mode==="server")){WEB_WORKER[SESSION_ID][worker_id].worker.emit("message",{service:"init",data:data,worker_id:worker_id})}else{WEB_WORKER[SESSION_ID][worker_id].worker.postMessage({service:"init",data:JSON.stringify(data),worker_id:worker_id})}};const create_worker=async function(){return new Promise((resolve,reject)=>{if(glb.worker_type==="Dev"){WEB_WORKER[SESSION_ID][worker_id]={worker:new Worker("js/xuda_worker.js",{name:worker_name}),promise_queue:{}}}else{function getWorkerURL(url){const content=`importScripts( "${url}" );`;return URL.createObjectURL(new Blob([content],{type:"text/javascript"}))}const _session=SESSION_OBJ[SESSION_ID];let blob=getWorkerURL(func.common.get_url(SESSION_ID,"dist",func.utils.get_resource_filename(["live_preview","miniapp"].includes(_session.engine_mode)?"":_session?.opt?.app_build_id,"runtime/js/xuda_worker.js")));WEB_WORKER[SESSION_ID][worker_id]={worker:new Worker(blob,{name:worker_name}),promise_queue:{}}}WEB_WORKER[SESSION_ID][worker_id].worker.addEventListener("message",function(e){if(e.data.service==="worker_ready"){return resolve()}worker_functions(e)},false)})};const create_websocket=async function(){return new Promise((resolve,reject)=>{WEB_WORKER[SESSION_ID][worker_id]={worker:RUNTIME_SERVER_WEBSOCKET,promise_queue:{}};WEB_WORKER[SESSION_ID][worker_id].worker.on("message",async e=>{if(["deployment_server","http_call"].includes(e.source))return;worker_functions({data:e})});resolve()})};const worker_functions=async function(e_raw){return new Promise(async(resolve,reject)=>{var e={};e.data=e_raw.data;if(RUNTIME_SERVER_WEBSOCKET&&RUNTIME_SERVER_WEBSOCKET_CONNECTED&&(!_session.opt.app_computing_mode||_session.opt.app_computing_mode==="server")){WEBSOCKET_PROCESS_PID=e.data.process_pid}var val=e.data.params;var fx={init_done:async function(){if(!obj){return _resolve()}},alert:function(){if(val[1]==="save_on"){func.UI.utils.save(SESSION_ID,true);return true}if(val[1]==="save_off"){func.UI.utils.save(SESSION_ID,false);return true}func.utils.alerts.execute(SESSION_ID,val[1],val[2],val[3],val[4]);return _resolve()},progress_on:function(){func.UI.utils.progressScreen.show(SESSION_ID,val,null);return _resolve()},progress_off:function(){func.UI.utils.progressScreen.hide();return _resolve()},worker_busy_on:function(){func.UI.utils.indicator.worker.busy();return _resolve()},worker_busy_off:function(){func.UI.utils.indicator.worker.normal();return _resolve()},screen_blocker_on:function(){func.UI.utils.screen_blocker(true,"Worker");return _resolve()},ajax_error:function(){func.utils.request_error(SESSION_ID,"ajax","Session error");return _resolve()},screen_blocker_off:function(){func.UI.utils.screen_blocker(false,"Worker");return _resolve()},job:function(){func.events.add_to_queue(SESSION_ID,val.typeP,val.eventIdP,val.triggerP,val.functionP,val.refIdP,val.containerP,val.elementP,val.rowP,null,val.descP,null,null,val.dsSessionP,null,null,val.event_propertiesP,val.calling_triggerP,val.paramsP,null,null,val.calling_trigger_prop,val.argumentsP,val.source_event_idP,val.calling_job,val.args);return _resolve()},update_client_eventChangesResults_from_worker:async function(){await func.datasource.update(SESSION_ID,val,true);if(!val.worker_id){return}fx.acknowledged_worker_with_eventChangesResults_done(val.dssession,val.worker_id);for await(const[worker_id,ds_arr]of Object.entries(WEB_WORKER[SESSION_ID])){if(val.worker_id==worker_id)continue;await func.index.call_worker(SESSION_ID,{service:"update_datasource_changes_from_client",data:data},{worker_id:worker_id})}},post_datasource:async function(){if(typeof val.dsSessionP==="undefined"||val.dsSessionP===null)return;if(!SESSION_OBJ[SESSION_ID].DS_GLB[val.dsSessionP]){SESSION_OBJ[SESSION_ID].DS_GLB[val.dsSessionP]=val.ds_obj}else{const update_existing_ds_object=function(old_obj,new_obj){for(const[key,val]of Object.entries(new_obj)){if(typeof val!=="object"){old_obj[key]=val2}else{if(!old_obj[key]){old_obj[key]=val}else update_existing_ds_object(old_obj[key],val)}}};update_existing_ds_object(SESSION_OBJ[SESSION_ID].DS_GLB[val.dsSessionP],val.ds_obj)}var verify_set_parent_ds=function(){var dsSession=val.dsSessionP;for(const[key,val]of Object.entries(SESSION_OBJ[SESSION_ID].DS_GLB[dsSession].parent_ds_chain)){if(SESSION_OBJ[SESSION_ID].DS_GLB[val]){SESSION_OBJ[SESSION_ID].DS_GLB[dsSession].parentDataSourceNo=val;break}}};verify_set_parent_ds();if(val.ds_obj.dataSourceSessionGlobal>SESSION_OBJ[SESSION_ID].dataSourceSessionGlobal)SESSION_OBJ[SESSION_ID].dataSourceSessionGlobal=val.ds_obj.dataSourceSessionGlobal},return_to_data_source:function(type,dsSessionP,ds){var data={session_id:SESSION_ID,dssession:dsSessionP,onscreen_events_active:ds.v.onscreen_events_active,viewEventExec_arr:JSON.stringify(ds.viewEventExec_arr),return_to_data_source_type:type};func.index.call_worker(SESSION_ID,{service:"return_to_data_source",data:data})},acknowledged_worker_with_eventChangesResults_done:async function(dsSessionP,worker_id){var data={session_id:SESSION_ID,dssession:dsSessionP};await func.index.call_worker(SESSION_ID,{service:"acknowledged_worker_with_eventChangesResults_done",data:data},{worker_id:worker_id});return _resolve()},execute_onscreen_view_events:async function(){await fx.post_datasource();var ds=SESSION_OBJ[SESSION_ID].DS_GLB[val.dsSessionP];await func.datasource.execute_onscreen_view_events(SESSION_ID,val.dsSessionP,"onscreen events");if(!ds.v.onscreen_events_active)return;var type=ds.v.onscreen_events_active.type;ds.v.onscreen_events_active=null;fx.return_to_data_source(type,val.dsSessionP,ds);return _resolve()},execute_local_db_query:async function(){await fx.post_datasource();const data=await func.db.get_query(SESSION_ID,val.fileIdP,val.queryP,val.dsSessionP,val.viewSourceDescP,val.sourceP,val.reduceP,val.skipP,val.limitP,val.countP,val.idsP);var msg={};msg.worker_id=worker_id;msg.data={};msg.service="return_from_db_query";msg.data.worker_id=worker_id;msg.data.callback_id=val.callback_id;msg.data.session_id=SESSION_ID;msg.data.data=data;if(RUNTIME_SERVER_WEBSOCKET&&RUNTIME_SERVER_WEBSOCKET_CONNECTED&&(!_session.opt.app_computing_mode||_session.opt.app_computing_mode==="server")){msg.process_pid=WEBSOCKET_PROCESS_PID;WEB_WORKER[SESSION_ID][worker_id].worker.emit("message",msg)}else{WEB_WORKER[SESSION_ID][worker_id].worker.postMessage(msg)}_resolve()},execute_local_sava_data:async function(){await fx.post_datasource();const data=await func.db.save_data(SESSION_ID,val.dsSessionP,val.keyP);var msg={};msg.worker_id=worker_id;msg.data={};msg.service="return_from_sava_data";msg.data.worker_id=worker_id;msg.data.callback_id=val.callback_id;msg.data.session_id=SESSION_ID;msg.data.data=data;if(RUNTIME_SERVER_WEBSOCKET&&RUNTIME_SERVER_WEBSOCKET_CONNECTED&&(!_session.opt.app_computing_mode||_session.opt.app_computing_mode==="server")){msg.process_pid=WEBSOCKET_PROCESS_PID;WEB_WORKER[SESSION_ID][worker_id].worker.emit("message",msg)}else{WEB_WORKER[SESSION_ID][worker_id].worker.postMessage(msg)}_resolve()},write_debug_log:function(params){func.utils.debug.write(SESSION_ID,val.data);_resolve()},write_log:async function(params){if(SESSION_OBJ[SESSION_ID].crawler)return;await func.common.db(SESSION_ID,"write_log",{msg:val.data,source:"runtime",log_type:"error"});_resolve()},change_loaded_image:function(params){const new_image=e.data.params.data;var $img=$("img");$.each($img,function(key,val){var src=$(val).prop("src");if(src.indexOf(new_image)>0){$(val).attr("src",src+"?ts="+(new Date).valueOf())}});_resolve()},send_watch_to_studio_websocket:function(params){STUDIO_WEBSOCKET.emit("message",val);_resolve()},get_doc_from_studio:async function(params){const module=await func.common.get_module(SESSION_ID,`xuda-progs-loader-module.mjs`);const data=await module.get_doc_from_studio(SESSION_ID,SESSION_OBJ[SESSION_ID].app_id,params.params.doc_id);func.index.call_worker(SESSION_ID,{service:"return_doc_from_studio",data:data});_resolve()},get_doc_from_websocket:async function(params){const module=await func.common.get_module(SESSION_ID,`xuda-progs-loader-module.mjs`);const data=await module.get_doc_from_websocket(SESSION_ID,SESSION_OBJ[SESSION_ID].app_id,params.params.doc_id);func.index.call_worker(SESSION_ID,{service:"return_doc_from_websocket",data:data});_resolve()},get_dbs_data_from_websocket:async function(params){const data=await func.common.get_data_from_websocket(SESSION_ID,params.params.service,params.params.data);func.index.call_worker(SESSION_ID,{service:"return_dbs_data_from_websocket",data:{data:data,websocket_queue_num:params.params.websocket_queue_num}});_resolve()},perform_rpi_request_from_studio:async function(params){const data=await func.common.db(SESSION_ID,params.params.service,params.params.data);func.index.call_worker(SESSION_ID,{service:"return_rpi_request_from_studio",data:{data:data.data,table_id:params.params.req_id}});_resolve()},refresh_document_changes_for_realtime_update:async function(params){func.UI.screen.refresh_document_changes_for_realtime_update(SESSION_ID,params.params.doc_change);_resolve()}};const get_promise_queue=function(t,worker_id){if(!WEB_WORKER[SESSION_ID][worker_id]){console.warn("worker job not found");return}return WEB_WORKER[SESSION_ID][worker_id].promise_queue[t]};const promise_ret=await get_promise_queue(e.data.promise_queue_id,e.data.worker_id);const _resolve=function(params){if(!promise_ret)return resolve();promise_ret.resolve(params);setTimeout(function(){if(WEB_WORKER[SESSION_ID][e.data.worker_id])delete WEB_WORKER[SESSION_ID][e.data.worker_id].promise_queue[e.data.promise_queue_id]},1e3)};if(fx[e.data.fx_to_execute]){return await fx[e.data.fx_to_execute](e.data)}if(!promise_ret)return console.error("promise not found");if(!e.data.fx_to_execute){return _resolve(e.data.params)}if(e.data.fx_to_execute==="worker_response"){return _resolve(e.data.params)}})};if(RUNTIME_SERVER_WEBSOCKET&&RUNTIME_SERVER_WEBSOCKET_CONNECTED&&(!_session.opt.app_computing_mode||_session.opt.app_computing_mode==="server")){await create_websocket()}else{await create_worker()}init_worker_session(worker_id);return worker_id};func.index.set_ds_0_proxy=function(SESSION_ID){const _session=SESSION_OBJ[SESSION_ID];let _ds=_session.DS_GLB[0];function createWatchedObject(obj,onChange){const watchers=new WeakMap;function createProxy(target,path=[]){if(watchers.has(target)){return watchers.get(target)}const proxy=new Proxy(target,{set(obj,prop,value){const oldValue=obj[prop];let currentPath=[...path,prop];obj[prop]=value;if(typeof value==="object"&&value!==null){obj[prop]=createProxy(value,currentPath)}if(!_.isEqual(value,oldValue)){currentPath.shift();onChange({path:currentPath.join("."),oldValue:oldValue,newValue:value,type:"set",timestamp:Date.now()})}return true},deleteProperty(obj,prop){const oldValue=obj[prop];const currentPath=[...path,prop];delete obj[prop];onChange({path:currentPath.join("."),oldValue:oldValue,newValue:undefined,type:"delete",timestamp:Date.now()});return true}});for(const[key,value]of Object.entries(target)){if(typeof value==="object"&&value!==null){target[key]=createProxy(value,[...path,key])}}watchers.set(target,proxy);return proxy}return createProxy(obj)}const watchedDs=createWatchedObject({_ref:_ds},async change=>{const{path,newValue,oldValue}=change;try{const _session=SESSION_OBJ[SESSION_ID];let watch_path="data_system."+path;const runHandler=()=>{const{handler,once}=_session?.watchers?.[watch_path]||{};handler(change);if(once){delete _session.watchers[watch_path]}};if(_session?.watchers?.[watch_path]){runHandler()}else{watch_path="data_system.SYS_GLOBAL_OBJ_REFS."+path;runHandler()}if(_.isEqual(newValue,oldValue))return;const _refs=SESSION_OBJ[SESSION_ID].DS_GLB[0].data_system.SYS_GLOBAL_OBJ_REFS;for(const[ref_id,val]of Object.entries(_refs)){const prefix=`${ref_id}.ds.`;if(!path.includes(prefix))continue;const clean_path_prop=path.split(prefix)[1];if(!clean_path_prop.includes("progDataSource"))continue;const _ref=SESSION_OBJ[SESSION_ID].DS_GLB[0].data_system.SYS_GLOBAL_OBJ_REFS[ref_id];if(!_ref)continue;const _ds=_ref.ds;const target_ds=_session.DS_GLB[_ds.dsSession];const target_value=_.get(target_ds,clean_path_prop);if(_.isEqual(target_value,newValue))continue;const datasource_changes={[_ds.dsSession]:{["datasource_main"]:{watcher:{path:clean_path_prop,newValue:newValue}}}};await func.datasource.update(SESSION_ID,datasource_changes)}return}catch(error){}});_session.DS_GLB[0]=watchedDs._ref};glb.SLIM_BUNDLE=1;
113
+ `);setTimeout(()=>{$(`[name="hard_reload"]`).off("click").on("click",async function(){await func.index.delete_pouch(SESSION_ID);location.reload()});$(`[name="reset_worker"]`).off("click").on("click",function(){_session.WORKER_OBJ.jobs[0].stat=null;_session.WORKER_OBJ.stat=null;func.UI.utils.progressScreen.hide(SESSION_ID)});$(`[name="get_support"]`).off("click").on("click",async function(){const get_support=await func.common.get_module(SESSION_ID,"xuda-get-support-module.esm.js");var name,subject;const prompt_name=()=>{name=window.prompt(`Get support from your ${APP_OBJ[app_id].app_general_prop?.app_name} team, \n\nYour Name (required):`);if(name==="")prompt_name()};const prompt_subject=()=>{subject=window.prompt(`When you click on "Ok," you are granting permission to ${APP_OBJ[app_id]?.app_name} team to access your browser. \n\nSubject (required):`);if(subject==="")prompt_subject()};if(!SUPPORT_PEER){try{name=firebase.auth().currentUser.displayName}catch(error){if(_session?.USR_OBJ?.usr_name){name=_session.USR_OBJ.usr_name}else{prompt_name()}}if(name===null)return;prompt_subject();if(subject===null)return;func.common.db(SESSION_ID,"get_support",{name:name,subject:subject});setTimeout(()=>{$("body").addClass("get_support_request");$("body").remove(".get_support_request_title").append("<div class='get_support_request_title'>Support pending</div>")},2e3)}else{get_support.terminate_peer(SESSION_ID)}func.UI.utils.progressScreen.hide(SESSION_ID)})},1e3)}}};if(event.which===27){let SESSION_ID=Object.keys(SESSION_OBJ)[0];func.UI.utils.progressScreen.hide(SESSION_ID)}if(event.ctrlKey&&event.shiftKey){if(keys[event.which]){keys[event.which].fx()}}});$(document).mousemove(function(e){CLIENT_ACTIVITY_TS=Date.now();posX=e.pageX;posY=e.pageY;if(SESSION_OBJ[SESSION_ID]?.DS_GLB?.[0]){SESSION_OBJ[SESSION_ID].DS_GLB[0].data_system["SYS_GLOBAL_OBJ_CLIENT_INFO"].cursor_pos_x=posX;SESSION_OBJ[SESSION_ID].DS_GLB[0].data_system["SYS_GLOBAL_OBJ_CLIENT_INFO"].cursor_pos_y=posY}});$.fn.draggable=function(){CLIENT_ACTIVITY_TS=Date.now();var $this=this,ns="draggable_"+(Math.random()+"").replace(".",""),mm="mousemove."+ns,mu="mouseup."+ns,$w=$(window),isFixed=$this.css("position")==="fixed",adjX=0,adjY=0;$this.mousedown(function(ev){var pos=$this.offset();if(isFixed){adjX=$w.scrollLeft();adjY=$w.scrollTop()}var ox=ev.pageX-pos.left,oy=ev.pageY-pos.top;$this.data(ns,{x:ox,y:oy});$w.on(mm,function(ev){ev.preventDefault();ev.stopPropagation();if(isFixed){adjX=$w.scrollLeft();adjY=$w.scrollTop()}var offset=$this.data(ns);$this.css({left:ev.pageX-adjX-offset.x,top:ev.pageY-adjY-offset.y})});$w.on(mu,function(){$w.off(mm+" "+mu).removeData(ns)})});return this};var heartbeat_attempts=0;var heartbeat_internal=setInterval(async function(){const SESSION_ID=Object.keys(SESSION_OBJ)[0];if(!SESSION_ID)return;let _session=SESSION_OBJ[SESSION_ID];if(!_session)return;if(_session.crawler)return;const set_idle=async function(stat){var datasource_changes={[0]:{["data_system"]:{SYS_GLOBAL_BOL_IDLE:stat}}};await func.datasource.update(SESSION_ID,datasource_changes)};if(Date.now()-CLIENT_ACTIVITY_TS>3e4){set_idle(1)}else{set_idle(0)}if(_session.engine_mode==="live_preview"||!_session.opt.enable_user_assist){return}const ret=await func.common.db(SESSION_ID,"heartbeat",{stat:Date.now()-CLIENT_ACTIVITY_TS>3e4?1:2}).catch(err=>{heartbeat_attempts++;console.warn(err.message);if(heartbeat_attempts<10)return;clearInterval(heartbeat_internal)});heartbeat_attempts=0;if(ret?.session_stat===3){await func.index.delete_pouch();window.top.location.reload()}$("body").removeClass("get_support_request");$("body").find(".get_support_request_title").remove();$("body").removeClass("get_support_online");$("body").find(".get_support_online_title").remove();if(ret?.data?.peer?.peer_status===1){if(ret.data.peer.peer_regional_server){get_support.init_peer(SESSION_ID,ret.data.peer.peer_regional_server)}$("body").addClass("get_support_request");$("body").remove(".get_support_request_title").append("<div class='get_support_request_title'>Support pending</div>")}if(ret?.data?.peer?.peer_status===2){$("body").addClass("get_support_online");$("body").remove(".get_support_online_title").append("<div class='get_support_online_title'>Support online</div>")}_session.res_token=ret.res_token},3e4);glb.WINDOW_LOCATION_SEARCH=window.location.search};func.index.checkConnectivity=async function(){const endpoints=["https://xuda.io/favicon.ico"];const promises=endpoints.map(url=>fetch(url,{method:"HEAD",mode:"no-cors"}).then(()=>true).catch(()=>false));const results=await Promise.all(promises);IS_ONLINE=results.some(result=>result===true);window.addEventListener("online",function(){IS_ONLINE=true;$("body").trigger("set_db_replication_from_server")});window.addEventListener("offline",function(){IS_ONLINE=false})};func.index.init_service_workers=function(){if("serviceWorker"in navigator){navigator.serviceWorker.addEventListener("message",function(event){console.log("serviceWorker message:",event)});navigator.serviceWorker.register("xuda-sw.js").then(function(registration){console.log("ServiceWorker registration successful with scope: ",registration.scope);glb.sw_registration=registration},function(err){console.log("ServiceWorker registration failed: ",err)})}};func.index.delete_pouch=async function(SESSION_ID=Object.keys(SESSION_OBJ)[0]){const db=await func.utils.connect_pouchdb(SESSION_ID);try{return await db.destroy()}catch(err){console.log(err)}};func.index.new_webworker=async function(SESSION_ID,prog_obj,obj){var worker_id=Object.keys(WEB_WORKER[SESSION_ID]).length+1;var _session=SESSION_OBJ[SESSION_ID];if(!_session.engine_mode==="docker"){ver=APP_OBJ[_session.app_id].app_version}var build_id=["live_preview","miniapp"].includes(_session.engine_mode)?"":_session.opt.app_build_id;if(typeof XUDA_BUILD_ID!=="undefined"){build_id=XUDA_BUILD_ID}const worker_name=`${typeof _session.SLIM_BUNDLE==="undefined"||!_session.SLIM_BUNDLE?"":"Slim "}${prog_obj.menuName} worker`+" "+glb.worker_type+": #"+worker_id.toString()+" "+(build_id||"")+" "+_session.domain;const init_worker_session=function(worker_id){var _session=_.cloneDeep(SESSION_OBJ[SESSION_ID]);delete _session.root_element;const get_parent_ds=function(ds){var ds_obj={};if(ds&&_session.DS_GLB[ds].parentDataSourceNo!==null){ds_obj[ds]=func.utils.clean_returned_datasource(SESSION_ID,ds);_.forEach(get_parent_ds(_session.DS_GLB[ds].parentDataSourceNo),function(val,key){ds_obj[key]=val})}else{ds_obj[ds]=func.utils.clean_returned_datasource(SESSION_ID,ds)}return ds_obj};var ds_obj={};if(typeof obj?.data?.parentDataSourceNoP!=="undefined"){ds_obj=get_parent_ds(obj.data.parentDataSourceNoP)}_session.DS_GLB={};_session.WORKER_OBJ={jobs:[],num:1e3,stat:null};var app_id=_session.app_id;var data={SESSION_ID:SESSION_ID,app_id:app_id,APP_OBJ:APP_OBJ[app_id],PROJECT_OBJ:PROJECT_OBJ[app_id],DOCS_OBJ:DOCS_OBJ[app_id],APP_INFO:glb.APP_INFO[app_id],DEBUG_MODE:glb.DEBUG_MODE,DEBUG_INFO_OBJ:glb.DEBUG_INFO_OBJ,WINDOW_LOCATION_SEARCH:glb.WINDOW_LOCATION_SEARCH,ROOT_ELEMENT_ATTRIBUTES:glb.ROOT_ELEMENT_ATTRIBUTES,DS_GLB:ds_obj,SESSION_INFO:JSON.parse(JSON.stringify(_session)),session_id:SESSION_ID,engine_mode:_session.engine_mode,STUDIO_WEBSOCKET_CONNECTION_ID:STUDIO_WEBSOCKET_CONNECTION_ID};if(_session.engine_mode==="live_preview"){data.DOCS_OBJ=DOCS_OBJ[app_id]}delete data.SESSION_INFO.root_element;data.SESSION_INFO.worker_id=worker_id;var ds_arr=[];$.map(_session.DS_GLB,function(val,i){ds_arr.push(i)});WEB_WORKER[SESSION_ID][worker_id].ds_arr=ds_arr;delete data.SESSION_INFO.DS_UI_EVENTS_GLB;if(RUNTIME_SERVER_WEBSOCKET&&RUNTIME_SERVER_WEBSOCKET_CONNECTED&&(!_session.opt.app_computing_mode||_session.opt.app_computing_mode==="server")){WEB_WORKER[SESSION_ID][worker_id].worker.emit("message",{service:"init",data:data,worker_id:worker_id})}else{WEB_WORKER[SESSION_ID][worker_id].worker.postMessage({service:"init",data:JSON.stringify(data),worker_id:worker_id})}};const create_worker=async function(){return new Promise((resolve,reject)=>{if(glb.worker_type==="Dev"){WEB_WORKER[SESSION_ID][worker_id]={worker:new Worker("js/xuda_worker.js",{name:worker_name}),promise_queue:{}}}else{function getWorkerURL(url){const content=`importScripts( "${url}" );`;return URL.createObjectURL(new Blob([content],{type:"text/javascript"}))}const _session=SESSION_OBJ[SESSION_ID];let blob=getWorkerURL(func.common.get_url(SESSION_ID,"dist",func.utils.get_resource_filename(["live_preview","miniapp"].includes(_session.engine_mode)?"":_session?.opt?.app_build_id,"runtime/js/xuda_worker.js")));WEB_WORKER[SESSION_ID][worker_id]={worker:new Worker(blob,{name:worker_name}),promise_queue:{}}}WEB_WORKER[SESSION_ID][worker_id].worker.addEventListener("message",function(e){if(e.data.service==="worker_ready"){return resolve()}worker_functions(e)},false)})};const create_websocket=async function(){return new Promise((resolve,reject)=>{WEB_WORKER[SESSION_ID][worker_id]={worker:RUNTIME_SERVER_WEBSOCKET,promise_queue:{}};WEB_WORKER[SESSION_ID][worker_id].worker.on("message",async e=>{if(["deployment_server","http_call"].includes(e.source))return;worker_functions({data:e})});resolve()})};const worker_functions=async function(e_raw){return new Promise(async(resolve,reject)=>{var e={};e.data=e_raw.data;if(RUNTIME_SERVER_WEBSOCKET&&RUNTIME_SERVER_WEBSOCKET_CONNECTED&&(!_session.opt.app_computing_mode||_session.opt.app_computing_mode==="server")){WEBSOCKET_PROCESS_PID=e.data.process_pid}var val=e.data.params;var fx={init_done:async function(){if(!obj){return _resolve()}},alert:function(){if(val[1]==="save_on"){func.UI.utils.save(SESSION_ID,true);return true}if(val[1]==="save_off"){func.UI.utils.save(SESSION_ID,false);return true}func.utils.alerts.execute(SESSION_ID,val[1],val[2],val[3],val[4]);return _resolve()},progress_on:function(){func.UI.utils.progressScreen.show(SESSION_ID,val,null);return _resolve()},progress_off:function(){func.UI.utils.progressScreen.hide();return _resolve()},worker_busy_on:function(){func.UI.utils.indicator.worker.busy();return _resolve()},worker_busy_off:function(){func.UI.utils.indicator.worker.normal();return _resolve()},screen_blocker_on:function(){func.UI.utils.screen_blocker(true,"Worker");return _resolve()},ajax_error:function(){func.utils.request_error(SESSION_ID,"ajax","Session error");return _resolve()},screen_blocker_off:function(){func.UI.utils.screen_blocker(false,"Worker");return _resolve()},job:function(){func.events.add_to_queue(SESSION_ID,val.typeP,val.eventIdP,val.triggerP,val.functionP,val.refIdP,val.containerP,val.elementP,val.rowP,null,val.descP,null,null,val.dsSessionP,null,null,val.event_propertiesP,val.calling_triggerP,val.paramsP,null,null,val.calling_trigger_prop,val.argumentsP,val.source_event_idP,val.calling_job,val.args);return _resolve()},update_client_eventChangesResults_from_worker:async function(){await func.datasource.update(SESSION_ID,val,true);if(!val.worker_id){return}fx.acknowledged_worker_with_eventChangesResults_done(val.dssession,val.worker_id);for await(const[worker_id,ds_arr]of Object.entries(WEB_WORKER[SESSION_ID])){if(val.worker_id==worker_id)continue;await func.index.call_worker(SESSION_ID,{service:"update_datasource_changes_from_client",data:data},{worker_id:worker_id})}},post_datasource:async function(){if(typeof val.dsSessionP==="undefined"||val.dsSessionP===null)return;if(!SESSION_OBJ[SESSION_ID].DS_GLB[val.dsSessionP]){SESSION_OBJ[SESSION_ID].DS_GLB[val.dsSessionP]=val.ds_obj}else{const update_existing_ds_object=function(old_obj,new_obj){for(const[key,val]of Object.entries(new_obj)){if(typeof val!=="object"){old_obj[key]=val2}else{if(!old_obj[key]){old_obj[key]=val}else update_existing_ds_object(old_obj[key],val)}}};update_existing_ds_object(SESSION_OBJ[SESSION_ID].DS_GLB[val.dsSessionP],val.ds_obj)}var verify_set_parent_ds=function(){var dsSession=val.dsSessionP;for(const[key,val]of Object.entries(SESSION_OBJ[SESSION_ID].DS_GLB[dsSession].parent_ds_chain)){if(SESSION_OBJ[SESSION_ID].DS_GLB[val]){SESSION_OBJ[SESSION_ID].DS_GLB[dsSession].parentDataSourceNo=val;break}}};verify_set_parent_ds();if(val.ds_obj.dataSourceSessionGlobal>SESSION_OBJ[SESSION_ID].dataSourceSessionGlobal)SESSION_OBJ[SESSION_ID].dataSourceSessionGlobal=val.ds_obj.dataSourceSessionGlobal},return_to_data_source:function(type,dsSessionP,ds){var data={session_id:SESSION_ID,dssession:dsSessionP,onscreen_events_active:ds.v.onscreen_events_active,viewEventExec_arr:JSON.stringify(ds.viewEventExec_arr),return_to_data_source_type:type};func.index.call_worker(SESSION_ID,{service:"return_to_data_source",data:data})},acknowledged_worker_with_eventChangesResults_done:async function(dsSessionP,worker_id){var data={session_id:SESSION_ID,dssession:dsSessionP};await func.index.call_worker(SESSION_ID,{service:"acknowledged_worker_with_eventChangesResults_done",data:data},{worker_id:worker_id});return _resolve()},execute_onscreen_view_events:async function(){await fx.post_datasource();var ds=SESSION_OBJ[SESSION_ID].DS_GLB[val.dsSessionP];await func.datasource.execute_onscreen_view_events(SESSION_ID,val.dsSessionP,"onscreen events");if(!ds.v.onscreen_events_active)return;var type=ds.v.onscreen_events_active.type;ds.v.onscreen_events_active=null;fx.return_to_data_source(type,val.dsSessionP,ds);return _resolve()},execute_local_db_query:async function(){await fx.post_datasource();const data=await func.db.get_query(SESSION_ID,val.fileIdP,val.queryP,val.dsSessionP,val.viewSourceDescP,val.sourceP,val.reduceP,val.skipP,val.limitP,val.countP,val.idsP);var msg={};msg.worker_id=worker_id;msg.data={};msg.service="return_from_db_query";msg.data.worker_id=worker_id;msg.data.callback_id=val.callback_id;msg.data.session_id=SESSION_ID;msg.data.data=data;if(RUNTIME_SERVER_WEBSOCKET&&RUNTIME_SERVER_WEBSOCKET_CONNECTED&&(!_session.opt.app_computing_mode||_session.opt.app_computing_mode==="server")){msg.process_pid=WEBSOCKET_PROCESS_PID;WEB_WORKER[SESSION_ID][worker_id].worker.emit("message",msg)}else{WEB_WORKER[SESSION_ID][worker_id].worker.postMessage(msg)}_resolve()},execute_local_sava_data:async function(){await fx.post_datasource();const data=await func.db.save_data(SESSION_ID,val.dsSessionP,val.keyP);var msg={};msg.worker_id=worker_id;msg.data={};msg.service="return_from_sava_data";msg.data.worker_id=worker_id;msg.data.callback_id=val.callback_id;msg.data.session_id=SESSION_ID;msg.data.data=data;if(RUNTIME_SERVER_WEBSOCKET&&RUNTIME_SERVER_WEBSOCKET_CONNECTED&&(!_session.opt.app_computing_mode||_session.opt.app_computing_mode==="server")){msg.process_pid=WEBSOCKET_PROCESS_PID;WEB_WORKER[SESSION_ID][worker_id].worker.emit("message",msg)}else{WEB_WORKER[SESSION_ID][worker_id].worker.postMessage(msg)}_resolve()},write_debug_log:function(params){func.utils.debug.write(SESSION_ID,val.data);_resolve()},write_log:async function(params){if(SESSION_OBJ[SESSION_ID].crawler)return;await func.common.db(SESSION_ID,"write_log",{msg:val.data,source:"runtime",log_type:"error"});_resolve()},change_loaded_image:function(params){const new_image=e.data.params.data;var $img=$("img");$.each($img,function(key,val){var src=$(val).prop("src");if(src.indexOf(new_image)>0){$(val).attr("src",src+"?ts="+(new Date).valueOf())}});_resolve()},send_watch_to_studio_websocket:function(params){STUDIO_WEBSOCKET.emit("message",val);_resolve()},get_doc_from_studio:async function(params){const module=await func.common.get_module(SESSION_ID,`xuda-progs-loader-module.mjs`);const data=await module.get_doc_from_studio(SESSION_ID,SESSION_OBJ[SESSION_ID].app_id,params.params.doc_id);func.index.call_worker(SESSION_ID,{service:"return_doc_from_studio",data:data});_resolve()},get_doc_from_websocket:async function(params){const module=await func.common.get_module(SESSION_ID,`xuda-progs-loader-module.mjs`);const data=await module.get_doc_from_websocket(SESSION_ID,SESSION_OBJ[SESSION_ID].app_id,params.params.doc_id);func.index.call_worker(SESSION_ID,{service:"return_doc_from_websocket",data:data});_resolve()},get_dbs_data_from_websocket:async function(params){const data=await func.common.get_data_from_websocket(SESSION_ID,params.params.service,params.params.data);func.index.call_worker(SESSION_ID,{service:"return_dbs_data_from_websocket",data:{data:data,websocket_queue_num:params.params.websocket_queue_num}});_resolve()},perform_rpi_request_from_studio:async function(params){const data=await func.common.db(SESSION_ID,params.params.service,params.params.data);func.index.call_worker(SESSION_ID,{service:"return_rpi_request_from_studio",data:{data:data.data,table_id:params.params.req_id}});_resolve()},refresh_document_changes_for_realtime_update:async function(params){func.UI.screen.refresh_document_changes_for_realtime_update(SESSION_ID,params.params.doc_change);_resolve()}};const get_promise_queue=function(t,worker_id){if(!WEB_WORKER[SESSION_ID][worker_id]){console.warn("worker job not found");return}return WEB_WORKER[SESSION_ID][worker_id].promise_queue[t]};const promise_ret=await get_promise_queue(e.data.promise_queue_id,e.data.worker_id);const _resolve=function(params){if(!promise_ret)return resolve();promise_ret.resolve(params);setTimeout(function(){if(WEB_WORKER[SESSION_ID][e.data.worker_id])delete WEB_WORKER[SESSION_ID][e.data.worker_id].promise_queue[e.data.promise_queue_id]},1e3)};if(fx[e.data.fx_to_execute]){return await fx[e.data.fx_to_execute](e.data)}if(!promise_ret)return console.error("promise not found");if(!e.data.fx_to_execute){return _resolve(e.data.params)}if(e.data.fx_to_execute==="worker_response"){return _resolve(e.data.params)}})};if(RUNTIME_SERVER_WEBSOCKET&&RUNTIME_SERVER_WEBSOCKET_CONNECTED&&(!_session.opt.app_computing_mode||_session.opt.app_computing_mode==="server")){await create_websocket()}else{await create_worker()}init_worker_session(worker_id);return worker_id};func.index.set_ds_0_proxy=function(SESSION_ID){const _session=SESSION_OBJ[SESSION_ID];let _ds=_session.DS_GLB[0];function createWatchedObject(obj,onChange){const watchers=new WeakMap;function createProxy(target,path=[]){if(watchers.has(target)){return watchers.get(target)}const proxy=new Proxy(target,{set(obj,prop,value){const oldValue=obj[prop];let currentPath=[...path,prop];obj[prop]=value;if(typeof value==="object"&&value!==null){obj[prop]=createProxy(value,currentPath)}if(!_.isEqual(value,oldValue)){currentPath.shift();onChange({path:currentPath.join("."),oldValue:oldValue,newValue:value,type:"set",timestamp:Date.now()})}return true},deleteProperty(obj,prop){const oldValue=obj[prop];const currentPath=[...path,prop];delete obj[prop];onChange({path:currentPath.join("."),oldValue:oldValue,newValue:undefined,type:"delete",timestamp:Date.now()});return true}});for(const[key,value]of Object.entries(target)){if(typeof value==="object"&&value!==null){target[key]=createProxy(value,[...path,key])}}watchers.set(target,proxy);return proxy}return createProxy(obj)}const watchedDs=createWatchedObject({_ref:_ds},async change=>{const{path,newValue,oldValue}=change;try{const _session=SESSION_OBJ[SESSION_ID];let watch_path="data_system."+path;const runHandler=()=>{const{handler,once}=_session?.watchers?.[watch_path]||{};if(change)handler(change);if(once){delete _session.watchers[watch_path]}};if(_session?.watchers?.[watch_path]){runHandler()}else{watch_path="data_system.SYS_GLOBAL_OBJ_REFS."+path;runHandler()}if(_.isEqual(newValue,oldValue))return;const _refs=SESSION_OBJ[SESSION_ID].DS_GLB[0].data_system.SYS_GLOBAL_OBJ_REFS;for(const[ref_id,val]of Object.entries(_refs)){const prefix=`${ref_id}.ds.`;if(!path.includes(prefix))continue;const clean_path_prop=path.split(prefix)[1];if(!clean_path_prop.includes("progDataSource"))continue;const _ref=SESSION_OBJ[SESSION_ID].DS_GLB[0].data_system.SYS_GLOBAL_OBJ_REFS[ref_id];if(!_ref)continue;const _ds=_ref.ds;const target_ds=_session.DS_GLB[_ds.dsSession];const target_value=_.get(target_ds,clean_path_prop);if(_.isEqual(target_value,newValue))continue;const datasource_changes={[_ds.dsSession]:{["datasource_main"]:{watcher:{path:clean_path_prop,newValue:newValue}}}};await func.datasource.update(SESSION_ID,datasource_changes)}return}catch(error){}});_session.DS_GLB[0]=watchedDs._ref};glb.SLIM_BUNDLE=1;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xuda.io/runtime-bundle",
3
- "version": "1.0.1363",
3
+ "version": "1.0.1365",
4
4
  "description": "The Xuda Runtime Bundle refers to a collection of scripts and libraries packaged together to provide the necessary runtime environment for executing plugins or components in the Xuda platform. ",
5
5
  "scripts": {
6
6
  "pub": "npm version patch --force && npm publish --access public"