JSON and type helpers¶
The C side builds every payload with jansson. The JS side gives the same function names on top of plain objects and arrays, so a gclass reads the same in both languages.
Source code: src/helpers.js
Copy and compare¶
json_deep_copy(obj)¶
Gives a deep copy of one value, with structuredClone().
duplicate_objects(obj)¶
Gives a new object in which every value is a deep copy.
json_is_identical(a, b)¶
Tells if two JSON values hold the same data. It compares the content, and not the reference.
Update an object¶
The three update functions are not recursive. They change the destination in place, and they go one level deep.
json_object_update(dst, src)¶
Adds the new keys of src and writes over the keys that dst holds already.
json_object_update_existing(dst, src)¶
Writes only the keys that dst holds already. It adds nothing.
json_object_update_missing(dst, src)¶
Adds only the keys that dst does not hold. It writes over nothing.
Read and write¶
json_object_get(o, k)¶
Gives the value of a key.
json_object_set(o, k, v)¶
Writes a key.
json_object_set_new(o, k, v)¶
Writes a key. In JavaScript it is the same as
json_object_set().
json_object_del(o, k)¶
Deletes a key.
json_array_append(a, v)¶
Puts a value at the end of an array.
json_array_append_new(a, v)¶
Puts a value at the end of an array. In JavaScript it is the same as
json_array_append().
json_array_remove(a, idx)¶
Takes the element at an index out of an array.
json_array_extend(destination, source)¶
Puts every element of source at the end of destination, and gives
destination back. An empty source changes nothing.
Size¶
json_object_size(a)¶
Gives the quantity of keys of an object. It gives 0 for every other type.
json_array_size(a)¶
Gives the length of an array. It gives 0 for every other type.
json_size(a)¶
Gives the size of any JSON value: the quantity of keys of an object, the length
of an array, 1 for a string that is not empty, and 0 for everything else.
empty_json(a)¶
Tells if there is nothing usable in the value: null or undefined, an empty
object or array, an empty string, or any scalar. It is json_size(a) === 0.
This is the twin of empty_json() in the C runtime, and there it is not a
convenience: an attribute declared DTP_JSON with a null default holds
json_null(), a valid pointer, so if(!jn) is dead code. In JavaScript
if(!x) does work, which is why a port between the two runtimes gets this
wrong in both directions. Write the same question in both.
The other question, “absent or explicitly null”, is is_null() here.
JavaScript has no second null to tell apart.
Type predicates¶
Each one gives a boolean.
is_object(v)¶
Tells if the value is an object. An array is not an object here, and null is
not an object.
is_array(v)¶
Tells if the value is an array.
is_string(v)¶
Tells if the value is a string.
is_number(v)¶
Tells if the value is a number. NaN and Infinity are not numbers here.
is_boolean(v)¶
Tells if the value is a boolean.
is_null(v)¶
Tells if the value is null or undefined.
is_date(v)¶
Tells if the value is a Date.
is_function(v)¶
Tells if the value is a function.
is_gobj(v)¶
Tells if the value is a gobj.
is_pure_number(v)¶
Tells if a string holds a number. It accepts an integer, a real number, the
scientific form such as "1.2e3", and a sign.
empty_string(s)¶
Tells if a value is an empty string. A value that is not a string is empty too.
parseBoolean(v)¶
Changes a string into a boolean. It accepts true, on and 1 as true. It
ignores the spaces around the value, and it ignores the case.
A json as a table: the flat form¶
One row per leaf: the id is the path of the item and the value is its value. It is the form to store, to compare and to diff, and it is the only one a person reads when two configurations disagree.
{"a": {"b": 1}, "c": [10, 20]} -> {"a`b": 1, "c`[0]": 10, "c`[1]": 20}The grammar is identical to the C one, and it has to stay that way: a flat
json is written by one side and read by the other. Ids are joined by the
back-tick; a back-tick inside a key is doubled, so no key is forbidden; an
array index is [N]; a key that starts with [ doubles the bracket; and
an empty container is a leaf, because {} and [] have no leaves of their
own. The C side is documented in
kwid.h.
json2flat(jn)¶
Gives the flat form of a json: an object whose keys are the paths of the leaves and whose values are the leaves.
flat2json(flat)¶
Rebuilds the nested json of a flat object. It refuses instead of guessing when an id is a leaf and a container at once: the answer would depend on the order the ids are read in.
flat_key_join(segments)¶
Builds a flat id from its segments, escaping each one. A segment is a string for a key and a number for an array index.
flat_key_split(key)¶
The inverse: the segments of a flat id. An index comes back as a number and
a key as a string — they are two types and not two spellings, which is what
keeps the key "[0]" apart from the index 0.
flat_diff(flat1, flat2)¶
What changed between two flat objects: {added, removed, changed}.
flat_apply(flat, diff)¶
Applies to a flat object what flat_diff() reported. It works on the flat
form on purpose: there an id addresses one value, so applying is setting and
deleting, with nothing to walk and nothing to guess.