@@ -101,6 +101,26 @@ export const JS_HELPERS: Record<string, string> = {
101101 }
102102 }
103103 return current === undefined ? null : current;
104+ }` ,
105+ kSet : `function kSet(data, path, value) {
106+ if (path.length === 0) return value;
107+ const seg = path[0];
108+ const rest = path.slice(1);
109+ const nextDefault = rest.length === 0 ? null : typeof rest[0] === 'number' ? [] : {};
110+ if (typeof seg === 'number') {
111+ if (data !== null && data !== undefined && !Array.isArray(data)) throw new Error('cannot set array index on non-array');
112+ const arr = Array.isArray(data) ? [...data] : [];
113+ while (arr.length <= seg) arr.push(null);
114+ const existing = arr[seg];
115+ arr[seg] = kSet(existing === null || existing === undefined ? nextDefault : existing, rest, value);
116+ return arr;
117+ } else {
118+ if (Array.isArray(data)) throw new Error('cannot set object key on array');
119+ const obj = data !== null && data !== undefined && typeof data === 'object' ? {...data} : {};
120+ const existing = obj[seg];
121+ obj[seg] = kSet(existing === null || existing === undefined ? nextDefault : existing, rest, value);
122+ return obj;
123+ }
104124}` ,
105125 // Type selectors
106126 kInt : `function kInt(v) {
@@ -213,6 +233,26 @@ export const RUBY_HELPER_DEPS: Record<string, string[]> = {
213233} ;
214234
215235export const RUBY_HELPERS : Record < string , string > = {
236+ k_set : `def k_set(d, p, v)
237+ return v if p.empty?
238+ seg = p[0]
239+ rest = p[1..]
240+ next_default = rest.empty? ? nil : (rest[0].is_a?(Integer) ? [] : {})
241+ if seg.is_a?(Integer)
242+ raise 'cannot set array index on non-array' if !d.nil? && !d.is_a?(Array)
243+ arr = d.is_a?(Array) ? d.dup : []
244+ arr[seg] = nil while arr.length <= seg
245+ existing = arr[seg]
246+ arr[seg] = k_set(existing.nil? ? next_default : existing, rest, v)
247+ arr
248+ else
249+ raise 'cannot set object key on array' if d.is_a?(Array)
250+ obj = d.is_a?(Hash) ? d.dup : {}
251+ existing = obj[seg]
252+ obj[seg] = k_set(existing.nil? ? next_default : existing, rest, v)
253+ obj
254+ end
255+ end` ,
216256 p_ok : `def p_ok(v, p) { success: true, path: p, message: '', value: v, cause: [] } end` ,
217257 p_fail : `def p_fail(p, m = nil, c = nil) { success: false, path: p, message: m || '', value: nil, cause: c || [] } end` ,
218258 p_any : `def p_any(v, p) p_ok(v, p) end` ,
0 commit comments