// custom_values_generators.js /** * Custom Values Generators Definitions * * This file contains generator functions for each block defined in * custom_values_blocks.js. Each generator translates a Blockly block * into a JSON object representing custom value operations. * * Note: This file assumes that `json_base_generator.js` has been loaded * before it, which initializes `Blockly.JSON` and attaches helper functions. */ export function defineCustomValuesGenerators() { /** * Generator for 'last_candle_value' Block * * Description: * Generates a JSON object to retrieve a specific part of the last candle (Open, High, Low, Close) * from a given source. Handles chaining with the 'NEXT' input if connected. */ Blockly.JSON['last_candle_value'] = function(block) { // Retrieve the selected candle part from the dropdown const candlePart = block.getFieldValue('candle_part'); // 'open', 'high', 'low', 'close' // Retrieve and parse the 'source' input const sourceCode = Blockly.JSON.valueToCode(block, 'source', Blockly.JSON.ORDER_ATOMIC); let source; try { source = Blockly.JSON.safeParse(sourceCode); if (!source) { throw new Error('Source input could not be parsed.'); } } catch (e) { console.warn(`Error parsing source input in last_candle_value block: ${e.message}`); source = { time_frame: '1m', exchange: '', symbol: '' }; // Default source } const json = { type: 'last_candle_value', candle_part: candlePart, source: source }; // Handle 'NEXT' input for chaining if applicable // Note: According to block definitions, 'last_candle_value' does not have a 'NEXT' input // If in the future a 'NEXT' input is added, uncomment the following lines: /* const nextCode = Blockly.JSON.valueToCode(block, 'NEXT', Blockly.JSON.ORDER_ATOMIC); if (nextCode) { try { const nextJson = JSON.parse(nextCode); if (Array.isArray(nextJson)) { json.next = [...nextJson]; } else { json.next = [nextJson]; } } catch (e) { console.warn(`Failed to parse NEXT input in last_candle_value block: ${e.message}`); } } */ return JSON.stringify(json); }; /** * Generator for 'source' Block * * Description: * Generates a JSON object defining the data source based on Time Frame (TF), * Exchange (EXC), and Symbol (SYM). This source can be used with blocks that * expect a 'source' type input. */ Blockly.JSON['source'] = function(block) { // Retrieve dropdown values const tf = block.getFieldValue('TF'); // Time Frame const exc = block.getFieldValue('EXC'); // Exchange const sym = block.getFieldValue('SYM'); // Symbol // Validate dropdown selections against available data const validTFs = bt_data && bt_data.intervals ? bt_data.intervals : []; const validExchanges = window.UI && window.UI.exchanges && window.UI.exchanges.connected_exchanges ? window.UI.exchanges.connected_exchanges : []; const validSymbols = bt_data && bt_data.symbols ? bt_data.symbols : []; if (!validTFs.includes(tf)) { console.warn(`Invalid Time Frame "${tf}" in source block. Defaulting to '1m'.`); } if (!validExchanges.includes(exc)) { console.warn(`Invalid Exchange "${exc}" in source block. Defaulting to ''.`); } if (!validSymbols.includes(sym)) { console.warn(`Invalid Symbol "${sym}" in source block. Defaulting to ''.`); } const json = { type: 'source', time_frame: validTFs.includes(tf) ? tf : '1m', exchange: validExchanges.includes(exc) ? exc : '', symbol: validSymbols.includes(sym) ? sym : '' }; return JSON.stringify(json); }; }