opal-vite 0.2.1 → 0.2.3
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.
- checksums.yaml +4 -4
- data/lib/opal/vite/version.rb +1 -1
- data/opal/opal_vite/concerns/stimulus_helpers.rb +494 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e029e7e67ed9e66aa052a3a3d22270d54dae425acf1a59727258f89a5c4ef958
|
|
4
|
+
data.tar.gz: c49bc230e812d7b59eb27461481ea6b0b0181c1161f06df6e20161d528ff4a5b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d40a68ab5d0014a65fa51a4afd3ed7f464cb3a6c3c31df660197de4c6123e61dfd1c40ede9bde91c9c4cf125d89dce725c0b5c3958efad1be669a98e679f23ad
|
|
7
|
+
data.tar.gz: 1e3f8787982405109068f33b4beff9ca9a9a6860a1069a442bdf09a19f96335997e3a0ba2fe2895a57d7f002f38eaf0217130a7b4dfa44e62b4ea6f7459b019d
|
data/lib/opal/vite/version.rb
CHANGED
|
@@ -790,14 +790,507 @@ module OpalVite
|
|
|
790
790
|
is_nan?(result) ? default_value : result
|
|
791
791
|
end
|
|
792
792
|
|
|
793
|
+
# ===== JavaScript Property Access Methods =====
|
|
794
|
+
|
|
795
|
+
# Get a JavaScript property from the controller (this[name])
|
|
796
|
+
# @param name [Symbol, String] Property name
|
|
797
|
+
# @return [Native] Property value
|
|
798
|
+
def js_prop(name)
|
|
799
|
+
`this[#{name.to_s}]`
|
|
800
|
+
end
|
|
801
|
+
|
|
802
|
+
# Set a JavaScript property on the controller (this[name] = value)
|
|
803
|
+
# @param name [Symbol, String] Property name
|
|
804
|
+
# @param value [Object] Value to set
|
|
805
|
+
def js_set_prop(name, value)
|
|
806
|
+
`this[#{name.to_s}] = #{value}`
|
|
807
|
+
end
|
|
808
|
+
|
|
809
|
+
# Check if controller has a JavaScript property
|
|
810
|
+
# @param name [Symbol, String] Property name
|
|
811
|
+
# @return [Boolean] true if property exists and is truthy
|
|
812
|
+
def js_has_prop?(name)
|
|
813
|
+
`!!this[#{name.to_s}]`
|
|
814
|
+
end
|
|
815
|
+
|
|
816
|
+
# Call a JavaScript method on the controller (this[name](...args))
|
|
817
|
+
# @param name [Symbol, String] Method name
|
|
818
|
+
# @param args [Array] Arguments to pass
|
|
819
|
+
# @return [Native] Method return value
|
|
820
|
+
def js_call(name, *args)
|
|
821
|
+
if args.empty?
|
|
822
|
+
`this[#{name.to_s}]()`
|
|
823
|
+
else
|
|
824
|
+
native_args = args.map { |a| a.respond_to?(:to_n) ? a.to_n : a }
|
|
825
|
+
`this[#{name.to_s}].apply(this, #{native_args})`
|
|
826
|
+
end
|
|
827
|
+
end
|
|
828
|
+
|
|
829
|
+
# Call a method on a JavaScript object
|
|
830
|
+
# @param obj [Native] JavaScript object
|
|
831
|
+
# @param method [Symbol, String] Method name
|
|
832
|
+
# @param args [Array] Arguments to pass
|
|
833
|
+
# @return [Native] Method return value
|
|
834
|
+
def js_call_on(obj, method, *args)
|
|
835
|
+
if args.empty?
|
|
836
|
+
`#{obj}[#{method.to_s}]()`
|
|
837
|
+
else
|
|
838
|
+
native_args = args.map { |a| a.respond_to?(:to_n) ? a.to_n : a }
|
|
839
|
+
`#{obj}[#{method.to_s}].apply(#{obj}, #{native_args})`
|
|
840
|
+
end
|
|
841
|
+
end
|
|
842
|
+
|
|
843
|
+
# Get a property from a JavaScript object
|
|
844
|
+
# @param obj [Native] JavaScript object
|
|
845
|
+
# @param prop [Symbol, String] Property name
|
|
846
|
+
# @return [Native] Property value
|
|
847
|
+
def js_get(obj, prop)
|
|
848
|
+
`#{obj}[#{prop.to_s}]`
|
|
849
|
+
end
|
|
850
|
+
|
|
851
|
+
# Set a property on a JavaScript object
|
|
852
|
+
# @param obj [Native] JavaScript object
|
|
853
|
+
# @param prop [Symbol, String] Property name
|
|
854
|
+
# @param value [Object] Value to set
|
|
855
|
+
def js_set(obj, prop, value)
|
|
856
|
+
`#{obj}[#{prop.to_s}] = #{value}`
|
|
857
|
+
end
|
|
858
|
+
|
|
859
|
+
# ===== JSON Methods =====
|
|
860
|
+
|
|
861
|
+
# Parse JSON string to JavaScript object
|
|
862
|
+
# @param json_string [String] JSON string
|
|
863
|
+
# @return [Native] Parsed JavaScript object
|
|
864
|
+
def json_parse(json_string)
|
|
865
|
+
`JSON.parse(#{json_string})`
|
|
866
|
+
end
|
|
867
|
+
|
|
868
|
+
# Stringify JavaScript object to JSON
|
|
869
|
+
# @param obj [Object] Object to stringify
|
|
870
|
+
# @return [String] JSON string
|
|
871
|
+
def json_stringify(obj)
|
|
872
|
+
native_obj = obj.respond_to?(:to_n) ? obj.to_n : obj
|
|
873
|
+
`JSON.stringify(#{native_obj})`
|
|
874
|
+
end
|
|
875
|
+
|
|
876
|
+
# ===== Console Methods =====
|
|
877
|
+
|
|
878
|
+
# Log to console
|
|
879
|
+
# @param args [Array] Arguments to log
|
|
880
|
+
def console_log(*args)
|
|
881
|
+
`console.log.apply(console, #{args})`
|
|
882
|
+
end
|
|
883
|
+
|
|
884
|
+
# Log warning to console
|
|
885
|
+
# @param args [Array] Arguments to log
|
|
886
|
+
def console_warn(*args)
|
|
887
|
+
`console.warn.apply(console, #{args})`
|
|
888
|
+
end
|
|
889
|
+
|
|
890
|
+
# Log error to console
|
|
891
|
+
# @param args [Array] Arguments to log
|
|
892
|
+
def console_error(*args)
|
|
893
|
+
`console.error.apply(console, #{args})`
|
|
894
|
+
end
|
|
895
|
+
|
|
896
|
+
# ===== String Methods =====
|
|
897
|
+
|
|
898
|
+
# Get character at index from string
|
|
899
|
+
# @param str [String] JavaScript string
|
|
900
|
+
# @param index [Integer] Character index
|
|
901
|
+
# @return [String] Character at index
|
|
902
|
+
def js_string_char_at(str, index)
|
|
903
|
+
`#{str}.charAt(#{index})`
|
|
904
|
+
end
|
|
905
|
+
|
|
906
|
+
# Get substring
|
|
907
|
+
# @param str [String] JavaScript string
|
|
908
|
+
# @param start [Integer] Start index
|
|
909
|
+
# @param end_idx [Integer, nil] End index (optional)
|
|
910
|
+
# @return [String] Substring
|
|
911
|
+
def js_substring(str, start, end_idx = nil)
|
|
912
|
+
if end_idx
|
|
913
|
+
`#{str}.substring(#{start}, #{end_idx})`
|
|
914
|
+
else
|
|
915
|
+
`#{str}.substring(#{start})`
|
|
916
|
+
end
|
|
917
|
+
end
|
|
918
|
+
|
|
919
|
+
# Split string
|
|
920
|
+
# @param str [String] JavaScript string
|
|
921
|
+
# @param separator [String] Separator
|
|
922
|
+
# @return [Native] Array of substrings
|
|
923
|
+
def js_split(str, separator)
|
|
924
|
+
`#{str}.split(#{separator})`
|
|
925
|
+
end
|
|
926
|
+
|
|
927
|
+
# Trim whitespace from string
|
|
928
|
+
# @param str [String] JavaScript string
|
|
929
|
+
# @return [String] Trimmed string
|
|
930
|
+
def js_trim(str)
|
|
931
|
+
`#{str}.trim()`
|
|
932
|
+
end
|
|
933
|
+
|
|
934
|
+
# Check if string includes substring
|
|
935
|
+
# @param str [String] JavaScript string
|
|
936
|
+
# @param search [String] Substring to search for
|
|
937
|
+
# @return [Boolean] true if includes
|
|
938
|
+
def js_includes?(str, search)
|
|
939
|
+
`#{str}.includes(#{search})`
|
|
940
|
+
end
|
|
941
|
+
|
|
942
|
+
# ===== Comparison Methods =====
|
|
943
|
+
|
|
944
|
+
# Check strict equality (===) between two JavaScript values
|
|
945
|
+
# @param a [Native] First value
|
|
946
|
+
# @param b [Native] Second value
|
|
947
|
+
# @return [Boolean] true if strictly equal
|
|
948
|
+
def js_equals?(a, b)
|
|
949
|
+
`#{a} === #{b}`
|
|
950
|
+
end
|
|
951
|
+
|
|
952
|
+
# Check loose equality (==) between two JavaScript values
|
|
953
|
+
# @param a [Native] First value
|
|
954
|
+
# @param b [Native] Second value
|
|
955
|
+
# @return [Boolean] true if loosely equal
|
|
956
|
+
def js_loose_equals?(a, b)
|
|
957
|
+
`#{a} == #{b}`
|
|
958
|
+
end
|
|
959
|
+
|
|
960
|
+
# ===== Math Methods =====
|
|
961
|
+
|
|
962
|
+
# Generate random number between 0 and 1
|
|
963
|
+
# @return [Float] Random number
|
|
964
|
+
def js_random
|
|
965
|
+
`Math.random()`
|
|
966
|
+
end
|
|
967
|
+
|
|
968
|
+
# Get minimum of two numbers
|
|
969
|
+
# @param a [Number] First number
|
|
970
|
+
# @param b [Number] Second number
|
|
971
|
+
# @return [Number] Minimum value
|
|
972
|
+
def js_min(a, b)
|
|
973
|
+
`Math.min(#{a}, #{b})`
|
|
974
|
+
end
|
|
975
|
+
|
|
976
|
+
# Get maximum of two numbers
|
|
977
|
+
# @param a [Number] First number
|
|
978
|
+
# @param b [Number] Second number
|
|
979
|
+
# @return [Number] Maximum value
|
|
980
|
+
def js_max(a, b)
|
|
981
|
+
`Math.max(#{a}, #{b})`
|
|
982
|
+
end
|
|
983
|
+
|
|
984
|
+
# Get absolute value
|
|
985
|
+
# @param num [Number] Number
|
|
986
|
+
# @return [Number] Absolute value
|
|
987
|
+
def js_abs(num)
|
|
988
|
+
`Math.abs(#{num})`
|
|
989
|
+
end
|
|
990
|
+
|
|
991
|
+
# Round number
|
|
992
|
+
# @param num [Number] Number
|
|
993
|
+
# @return [Integer] Rounded number
|
|
994
|
+
def js_round(num)
|
|
995
|
+
`Math.round(#{num})`
|
|
996
|
+
end
|
|
997
|
+
|
|
998
|
+
# Ceiling of number
|
|
999
|
+
# @param num [Number] Number
|
|
1000
|
+
# @return [Integer] Ceiling value
|
|
1001
|
+
def js_ceil(num)
|
|
1002
|
+
`Math.ceil(#{num})`
|
|
1003
|
+
end
|
|
1004
|
+
|
|
1005
|
+
# Format number with fixed decimal places
|
|
1006
|
+
# @param num [Number] Number to format
|
|
1007
|
+
# @param digits [Integer] Number of decimal places
|
|
1008
|
+
# @return [String] Formatted number string
|
|
1009
|
+
def js_to_fixed(num, digits)
|
|
1010
|
+
`#{num}.toFixed(#{digits})`
|
|
1011
|
+
end
|
|
1012
|
+
|
|
1013
|
+
# Generate random integer between 0 and max (exclusive)
|
|
1014
|
+
# @param max [Integer] Maximum value (exclusive)
|
|
1015
|
+
# @return [Integer] Random integer
|
|
1016
|
+
def random_int(max)
|
|
1017
|
+
`Math.floor(Math.random() * #{max})`
|
|
1018
|
+
end
|
|
1019
|
+
|
|
1020
|
+
# Floor a number
|
|
1021
|
+
# @param num [Number] Number to floor
|
|
1022
|
+
# @return [Integer] Floored number
|
|
1023
|
+
def js_floor(num)
|
|
1024
|
+
`Math.floor(#{num})`
|
|
1025
|
+
end
|
|
1026
|
+
|
|
1027
|
+
# ===== Global Object Access =====
|
|
1028
|
+
|
|
1029
|
+
# Check if a global JavaScript object/class exists
|
|
1030
|
+
# @param name [String] Global name (e.g., 'Chart', 'React')
|
|
1031
|
+
# @return [Boolean] true if exists
|
|
1032
|
+
def js_global_exists?(name)
|
|
1033
|
+
`typeof window[#{name}] !== 'undefined'`
|
|
1034
|
+
end
|
|
1035
|
+
|
|
1036
|
+
# Get a global JavaScript object/class
|
|
1037
|
+
# @param name [String] Global name
|
|
1038
|
+
# @return [Native] Global object
|
|
1039
|
+
def js_global(name)
|
|
1040
|
+
`window[#{name}]`
|
|
1041
|
+
end
|
|
1042
|
+
|
|
1043
|
+
# Create new instance of a JavaScript class
|
|
1044
|
+
# @param klass [Native] JavaScript class/constructor
|
|
1045
|
+
# @param args [Array] Constructor arguments
|
|
1046
|
+
# @return [Native] New instance
|
|
1047
|
+
def js_new(klass, *args)
|
|
1048
|
+
if args.empty?
|
|
1049
|
+
`new klass()`
|
|
1050
|
+
else
|
|
1051
|
+
# Convert Ruby objects to native, pass JS objects as-is
|
|
1052
|
+
native_args = args.map { |a| `#{a} != null && typeof #{a}.$to_n === 'function' ? #{a}.$to_n() : #{a}` }
|
|
1053
|
+
# Use Reflect.construct for dynamic argument passing
|
|
1054
|
+
`Reflect.construct(#{klass}, #{native_args})`
|
|
1055
|
+
end
|
|
1056
|
+
end
|
|
1057
|
+
|
|
1058
|
+
# Define a JavaScript function on the controller (this[name] = function)
|
|
1059
|
+
# @param name [Symbol, String] Function name
|
|
1060
|
+
# @yield Block that becomes the function body
|
|
1061
|
+
def js_define_method(name, &block)
|
|
1062
|
+
`this[#{name.to_s}] = #{block}`
|
|
1063
|
+
end
|
|
1064
|
+
|
|
1065
|
+
# Define a JavaScript function on an object (obj[name] = function)
|
|
1066
|
+
# @param obj [Native] JavaScript object
|
|
1067
|
+
# @param name [Symbol, String] Function name
|
|
1068
|
+
# @yield Block that becomes the function body
|
|
1069
|
+
def js_define_method_on(obj, name, &block)
|
|
1070
|
+
`#{obj}[#{name.to_s}] = #{block}`
|
|
1071
|
+
end
|
|
1072
|
+
|
|
1073
|
+
# ===== Array Methods =====
|
|
1074
|
+
|
|
1075
|
+
# Get array length
|
|
1076
|
+
# @param arr [Native] JavaScript array
|
|
1077
|
+
# @return [Integer] Array length
|
|
1078
|
+
def js_length(arr)
|
|
1079
|
+
`#{arr}.length`
|
|
1080
|
+
end
|
|
1081
|
+
|
|
1082
|
+
# Map over array with block
|
|
1083
|
+
# @param arr [Native] JavaScript array
|
|
1084
|
+
# @yield [item] Block to execute for each item
|
|
1085
|
+
# @return [Native] New array with mapped values
|
|
1086
|
+
def js_map(arr, &block)
|
|
1087
|
+
`#{arr}.map(#{block})`
|
|
1088
|
+
end
|
|
1089
|
+
|
|
1090
|
+
# Filter array with block
|
|
1091
|
+
# @param arr [Native] JavaScript array
|
|
1092
|
+
# @yield [item] Block to execute for each item
|
|
1093
|
+
# @return [Native] Filtered array
|
|
1094
|
+
def js_filter(arr, &block)
|
|
1095
|
+
`#{arr}.filter(#{block})`
|
|
1096
|
+
end
|
|
1097
|
+
|
|
1098
|
+
# Reduce array with block
|
|
1099
|
+
# @param arr [Native] JavaScript array
|
|
1100
|
+
# @param initial [Object] Initial value
|
|
1101
|
+
# @yield [acc, item] Block to execute for each item
|
|
1102
|
+
# @return [Object] Reduced value
|
|
1103
|
+
def js_reduce(arr, initial, &block)
|
|
1104
|
+
`#{arr}.reduce(#{block}, #{initial})`
|
|
1105
|
+
end
|
|
1106
|
+
|
|
1107
|
+
# ForEach over array with block
|
|
1108
|
+
# @param arr [Native] JavaScript array
|
|
1109
|
+
# @yield [item, index] Block to execute for each item
|
|
1110
|
+
def js_each(arr, &block)
|
|
1111
|
+
`#{arr}.forEach(#{block})`
|
|
1112
|
+
end
|
|
1113
|
+
|
|
1114
|
+
# Slice array
|
|
1115
|
+
# @param arr [Native] JavaScript array
|
|
1116
|
+
# @param start [Integer] Start index
|
|
1117
|
+
# @param end_idx [Integer, nil] End index (optional)
|
|
1118
|
+
# @return [Native] Sliced array
|
|
1119
|
+
def js_slice(arr, start, end_idx = nil)
|
|
1120
|
+
if end_idx
|
|
1121
|
+
`#{arr}.slice(#{start}, #{end_idx})`
|
|
1122
|
+
else
|
|
1123
|
+
`#{arr}.slice(#{start})`
|
|
1124
|
+
end
|
|
1125
|
+
end
|
|
1126
|
+
|
|
1127
|
+
# ===== Object Methods =====
|
|
1128
|
+
|
|
1129
|
+
# Create empty JavaScript object
|
|
1130
|
+
# @return [Native] Empty JavaScript object
|
|
1131
|
+
def js_object
|
|
1132
|
+
`{}`
|
|
1133
|
+
end
|
|
1134
|
+
|
|
1135
|
+
# Get object keys
|
|
1136
|
+
# @param obj [Native] JavaScript object
|
|
1137
|
+
# @return [Native] Array of keys
|
|
1138
|
+
def js_keys(obj)
|
|
1139
|
+
`Object.keys(#{obj})`
|
|
1140
|
+
end
|
|
1141
|
+
|
|
1142
|
+
# Get object values
|
|
1143
|
+
# @param obj [Native] JavaScript object
|
|
1144
|
+
# @return [Native] Array of values
|
|
1145
|
+
def js_values(obj)
|
|
1146
|
+
`Object.values(#{obj})`
|
|
1147
|
+
end
|
|
1148
|
+
|
|
1149
|
+
# Get object entries
|
|
1150
|
+
# @param obj [Native] JavaScript object
|
|
1151
|
+
# @return [Native] Array of [key, value] pairs
|
|
1152
|
+
def js_entries(obj)
|
|
1153
|
+
`Object.entries(#{obj})`
|
|
1154
|
+
end
|
|
1155
|
+
|
|
1156
|
+
# Create Set from array and get size
|
|
1157
|
+
# @param arr [Native] JavaScript array
|
|
1158
|
+
# @return [Integer] Number of unique elements
|
|
1159
|
+
def js_unique_count(arr)
|
|
1160
|
+
`new Set(#{arr}).size`
|
|
1161
|
+
end
|
|
1162
|
+
|
|
1163
|
+
# ===== Fetch API =====
|
|
1164
|
+
|
|
1165
|
+
# Simple fetch that returns Promise-wrapped response
|
|
1166
|
+
# @param url [String] URL to fetch
|
|
1167
|
+
# @return [Native] Promise
|
|
1168
|
+
def js_fetch(url)
|
|
1169
|
+
`fetch(#{url})`
|
|
1170
|
+
end
|
|
1171
|
+
|
|
1172
|
+
# Fetch JSON from URL with callback
|
|
1173
|
+
# @param url [String] URL to fetch
|
|
1174
|
+
# @yield [data] Block to handle response data
|
|
1175
|
+
def fetch_json(url, &success_block)
|
|
1176
|
+
`
|
|
1177
|
+
fetch(#{url})
|
|
1178
|
+
.then(response => response.json())
|
|
1179
|
+
.then(data => #{success_block}.$call(data))
|
|
1180
|
+
.catch(error => console.error('Fetch error:', error))
|
|
1181
|
+
`
|
|
1182
|
+
end
|
|
1183
|
+
|
|
1184
|
+
# Fetch JSON from URL returning a Promise (for chaining)
|
|
1185
|
+
# @param url [String] URL to fetch
|
|
1186
|
+
# @return [Native] Promise that resolves to JSON data
|
|
1187
|
+
def fetch_json_promise(url)
|
|
1188
|
+
`fetch(#{url}).then(response => response.json())`
|
|
1189
|
+
end
|
|
1190
|
+
|
|
1191
|
+
# Fetch JSON with response validation
|
|
1192
|
+
# @param url [String] URL to fetch
|
|
1193
|
+
# @return [Native] Promise that resolves to JSON data or rejects on error
|
|
1194
|
+
def fetch_json_safe(url)
|
|
1195
|
+
`fetch(#{url}).then(function(response) { if (!response.ok) { throw new Error('Network response was not ok: ' + response.status); } return response.json(); })`
|
|
1196
|
+
end
|
|
1197
|
+
|
|
1198
|
+
# Fetch multiple URLs in parallel and get JSON results
|
|
1199
|
+
# @param urls [Array<String>] URLs to fetch
|
|
1200
|
+
# @return [Native] Promise that resolves to array of JSON results
|
|
1201
|
+
def fetch_all_json(urls)
|
|
1202
|
+
promises = urls.map { |url| fetch_json_promise(url) }
|
|
1203
|
+
`Promise.all(#{promises})`
|
|
1204
|
+
end
|
|
1205
|
+
|
|
1206
|
+
# Fetch JSON with success and error callbacks
|
|
1207
|
+
# @param url [String] URL to fetch
|
|
1208
|
+
# @param on_success [Proc] Success callback receiving data
|
|
1209
|
+
# @param on_error [Proc] Error callback receiving error
|
|
1210
|
+
def fetch_json_with_handlers(url, on_success:, on_error: nil)
|
|
1211
|
+
promise = fetch_json_safe(url)
|
|
1212
|
+
promise = js_then(promise) { |data| on_success.call(data) }
|
|
1213
|
+
if on_error
|
|
1214
|
+
js_catch(promise) { |error| on_error.call(error) }
|
|
1215
|
+
else
|
|
1216
|
+
js_catch(promise) { |error| console_error('Fetch error:', error) }
|
|
1217
|
+
end
|
|
1218
|
+
end
|
|
1219
|
+
|
|
1220
|
+
# ===== Promise Methods =====
|
|
1221
|
+
|
|
1222
|
+
# Create Promise.all from array of promises
|
|
1223
|
+
# @param promises [Array<Native>] Array of promises
|
|
1224
|
+
# @return [Native] Promise that resolves when all complete
|
|
1225
|
+
def promise_all(promises)
|
|
1226
|
+
`Promise.all(#{promises})`
|
|
1227
|
+
end
|
|
1228
|
+
|
|
1229
|
+
# Create Promise.race from array of promises
|
|
1230
|
+
# @param promises [Array<Native>] Array of promises
|
|
1231
|
+
# @return [Native] Promise that resolves when first completes
|
|
1232
|
+
def promise_race(promises)
|
|
1233
|
+
`Promise.race(#{promises})`
|
|
1234
|
+
end
|
|
1235
|
+
|
|
1236
|
+
# Create a resolved Promise with value
|
|
1237
|
+
# @param value [Object] Value to resolve with
|
|
1238
|
+
# @return [Native] Resolved Promise
|
|
1239
|
+
def promise_resolve(value)
|
|
1240
|
+
native_value = value.respond_to?(:to_n) ? value.to_n : value
|
|
1241
|
+
`Promise.resolve(#{native_value})`
|
|
1242
|
+
end
|
|
1243
|
+
|
|
1244
|
+
# Create a rejected Promise with error
|
|
1245
|
+
# @param error [Object] Error to reject with
|
|
1246
|
+
# @return [Native] Rejected Promise
|
|
1247
|
+
def promise_reject(error)
|
|
1248
|
+
`Promise.reject(#{error})`
|
|
1249
|
+
end
|
|
1250
|
+
|
|
1251
|
+
# Add then handler to promise
|
|
1252
|
+
# @param promise [Native] JavaScript Promise
|
|
1253
|
+
# @yield [value] Block to handle resolved value
|
|
1254
|
+
# @return [Native] New Promise
|
|
1255
|
+
def js_then(promise, &block)
|
|
1256
|
+
`#{promise}.then(#{block})`
|
|
1257
|
+
end
|
|
1258
|
+
|
|
1259
|
+
# Add catch handler to promise
|
|
1260
|
+
# @param promise [Native] JavaScript Promise
|
|
1261
|
+
# @yield [error] Block to handle rejection
|
|
1262
|
+
# @return [Native] New Promise
|
|
1263
|
+
def js_catch(promise, &block)
|
|
1264
|
+
`#{promise}.catch(#{block})`
|
|
1265
|
+
end
|
|
1266
|
+
|
|
1267
|
+
# Add finally handler to promise
|
|
1268
|
+
# @param promise [Native] JavaScript Promise
|
|
1269
|
+
# @yield Block to execute regardless of outcome
|
|
1270
|
+
# @return [Native] New Promise
|
|
1271
|
+
def js_finally(promise, &block)
|
|
1272
|
+
`#{promise}.finally(#{block})`
|
|
1273
|
+
end
|
|
1274
|
+
|
|
793
1275
|
private
|
|
794
1276
|
|
|
795
|
-
# Convert snake_case to camelCase
|
|
1277
|
+
# Convert snake_case to camelCase, preserving existing camelCase
|
|
796
1278
|
# @param name [Symbol, String] The name to convert
|
|
797
1279
|
# @param capitalize_first [Boolean] Whether to capitalize first letter
|
|
798
1280
|
# @return [String] camelCase string
|
|
799
1281
|
def camelize(name, capitalize_first = true)
|
|
800
1282
|
str = name.to_s
|
|
1283
|
+
|
|
1284
|
+
# If no underscores, assume already camelCase - just adjust first letter
|
|
1285
|
+
unless str.include?('_')
|
|
1286
|
+
if capitalize_first
|
|
1287
|
+
return str[0].upcase + str[1..-1].to_s
|
|
1288
|
+
else
|
|
1289
|
+
return str[0].downcase + str[1..-1].to_s
|
|
1290
|
+
end
|
|
1291
|
+
end
|
|
1292
|
+
|
|
1293
|
+
# Convert snake_case to camelCase
|
|
801
1294
|
parts = str.split('_')
|
|
802
1295
|
if capitalize_first
|
|
803
1296
|
parts.map(&:capitalize).join
|