smsmslib 1.0.78 → 1.0.79
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.
- package/javascr/util/array.js +36 -0
- package/javascr/util/deep.js +116 -0
- package/javascr/util/deepwalk.js +139 -0
- package/javascr/util/index.js +1 -0
- package/javascr/util/prop.js +60 -8
- package/package.json +2 -2
package/javascr/util/array.js
CHANGED
|
@@ -197,3 +197,39 @@ export function sj_array_is_unique(a_src)
|
|
|
197
197
|
}
|
|
198
198
|
|
|
199
199
|
|
|
200
|
+
/**
|
|
201
|
+
* Normalizes an array subscript (index) to ensure it falls within the valid
|
|
202
|
+
* range of [0, i_len - 1].
|
|
203
|
+
*
|
|
204
|
+
* This function supports circular indexing (wrap-around). For example, if i_len
|
|
205
|
+
* is 5, an index of 5 wraps around to 0, and an index of -1 wraps around to 4.
|
|
206
|
+
*
|
|
207
|
+
* @param {number} i_len [in]
|
|
208
|
+
* The length of the array or array-like object (e.g., string).
|
|
209
|
+
* Must be a positive integer.
|
|
210
|
+
*
|
|
211
|
+
* @param {number} i_sub [in]
|
|
212
|
+
* The subscript (index) to be normalized.
|
|
213
|
+
*
|
|
214
|
+
* @returns {number}
|
|
215
|
+
* The normalized index within the range [0, i_len - 1].
|
|
216
|
+
* Returns -1 if i_len is 0 or negative.
|
|
217
|
+
*/
|
|
218
|
+
export function sj_subscript_norm(i_len, i_sub)
|
|
219
|
+
{
|
|
220
|
+
let i_r = - 1;
|
|
221
|
+
|
|
222
|
+
if (0 < i_len)
|
|
223
|
+
{
|
|
224
|
+
i_r = i_sub % i_len;
|
|
225
|
+
|
|
226
|
+
if (i_r < 0)
|
|
227
|
+
{
|
|
228
|
+
i_r += i_len;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
return i_r;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file
|
|
3
|
+
* Provides utility functions for **deeply nested property access and
|
|
4
|
+
* modification** targeting an object's Own Properties.
|
|
5
|
+
*
|
|
6
|
+
* @module javascr/system/deep
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/** ---------------------------------------------------------------------------
|
|
10
|
+
* Imports.
|
|
11
|
+
* --------------------------------------------------------------------------- */
|
|
12
|
+
|
|
13
|
+
import
|
|
14
|
+
{
|
|
15
|
+
sj_prop_get_own,
|
|
16
|
+
sj_prop_set_own,
|
|
17
|
+
PropRet_t,
|
|
18
|
+
}
|
|
19
|
+
from "prop.js";
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
/** ---------------------------------------------------------------------------
|
|
23
|
+
* Functions.
|
|
24
|
+
* --------------------------------------------------------------------------- */
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Updates the value of a deeply nested **own property** using an
|
|
28
|
+
* array of keys.
|
|
29
|
+
*
|
|
30
|
+
* @param {any} dst [in]
|
|
31
|
+
* The root object or array to traverse.
|
|
32
|
+
*
|
|
33
|
+
* @param {(string|number)[]} a_prop [in]
|
|
34
|
+
* An array of property names or indices representing the path to the target.
|
|
35
|
+
* Must not be empty. Each element must correspond to an existing own property,
|
|
36
|
+
* and the final property must be writable.
|
|
37
|
+
*
|
|
38
|
+
* @param {any} value [in]
|
|
39
|
+
* The new value to assign to the target property.
|
|
40
|
+
*
|
|
41
|
+
* @returns {boolean}
|
|
42
|
+
* true if the traversal was successful and the target property was updated;
|
|
43
|
+
* otherwise, false. Returns false if a_prop is empty or not an array.
|
|
44
|
+
*/
|
|
45
|
+
export function sj_deep_set_own(dst, a_prop, value)
|
|
46
|
+
{
|
|
47
|
+
let dst_ref = dst;
|
|
48
|
+
let b_ok = Array.isArray(a_prop) && (0 < a_prop.length);
|
|
49
|
+
|
|
50
|
+
for (let i_depth = 0; b_ok && (i_depth < a_prop.length); i_depth++)
|
|
51
|
+
{
|
|
52
|
+
const prop = a_prop[i_depth];
|
|
53
|
+
|
|
54
|
+
if (i_depth < (a_prop.length - 1))
|
|
55
|
+
{
|
|
56
|
+
const o_ret = sj_prop_get_own(dst_ref, prop);
|
|
57
|
+
|
|
58
|
+
b_ok = o_ret && o_ret.b_ok;
|
|
59
|
+
dst_ref = o_ret.value;
|
|
60
|
+
}
|
|
61
|
+
else
|
|
62
|
+
{
|
|
63
|
+
b_ok = sj_prop_set_own(dst_ref, prop, value);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return b_ok;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Retrieves a value from a deeply nested property using an array of keys.
|
|
73
|
+
*
|
|
74
|
+
* @param {any} src [in]
|
|
75
|
+
* The object, array, or array-like object to start the traversal.
|
|
76
|
+
*
|
|
77
|
+
* @param {(string|number)[]} a_prop [in]
|
|
78
|
+
* An array of property names or indices representing the path to the target
|
|
79
|
+
* property. If this array is empty, the function returns the `src` itself
|
|
80
|
+
* wrapped in PropRet_t.
|
|
81
|
+
*
|
|
82
|
+
* @returns {object|null}
|
|
83
|
+
* An instance of PropRet_t containing the following properties, or null
|
|
84
|
+
* if the instance creation fails:
|
|
85
|
+
* - b_ok : true if the property value was retrieved successfully;
|
|
86
|
+
* otherwise, false.
|
|
87
|
+
* - value: The retrieved property value if b_ok is true; otherwise, undefined.
|
|
88
|
+
*
|
|
89
|
+
* Example:
|
|
90
|
+
* - If a_prop is empty: returns { b_ok: true, value: src }.
|
|
91
|
+
* - If successful: returns { b_ok: true, value: [found value] }.
|
|
92
|
+
* - If not found or invalid: returns { b_ok: false, value: undefined }.
|
|
93
|
+
*/
|
|
94
|
+
export function sj_deep_get_own(src, a_prop)
|
|
95
|
+
{
|
|
96
|
+
let src_ref = src;
|
|
97
|
+
let b_ok = Array.isArray(a_prop);
|
|
98
|
+
let o_ret = PropRet_t(b_ok, src_ref);
|
|
99
|
+
|
|
100
|
+
b_ok = o_ret && o_ret.b_ok;
|
|
101
|
+
|
|
102
|
+
for (let i_depth = 0; b_ok && (i_depth < a_prop.length); i_depth++)
|
|
103
|
+
{
|
|
104
|
+
o_ret = sj_prop_get_own(src_ref, a_prop[i_depth]);
|
|
105
|
+
b_ok = o_ret && o_ret.b_ok;
|
|
106
|
+
|
|
107
|
+
if (b_ok)
|
|
108
|
+
{
|
|
109
|
+
src_ref = o_ret.value;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return o_ret;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file
|
|
3
|
+
*
|
|
4
|
+
* @module javascr/system/deepwalk
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/** ---------------------------------------------------------------------------
|
|
8
|
+
* Imports.
|
|
9
|
+
* --------------------------------------------------------------------------- */
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
/** ---------------------------------------------------------------------------
|
|
14
|
+
* Functions.
|
|
15
|
+
* --------------------------------------------------------------------------- */
|
|
16
|
+
|
|
17
|
+
export function sj_deep_walk(value, i_depth, f_cb, user)
|
|
18
|
+
{
|
|
19
|
+
let i_ret = go_tree_walk_ret.i_noncb;
|
|
20
|
+
|
|
21
|
+
if (typeof(f_cb) === go_typeof.s_function)
|
|
22
|
+
{
|
|
23
|
+
const o_user = sj_new_lit(() => ({i_depth, f_cb, user}));
|
|
24
|
+
|
|
25
|
+
i_ret = go_tree_walk_ret.i_fatal;
|
|
26
|
+
|
|
27
|
+
if (o_user)
|
|
28
|
+
{
|
|
29
|
+
const o_root = deep_walk_node_t(value);
|
|
30
|
+
|
|
31
|
+
if (o_root)
|
|
32
|
+
{
|
|
33
|
+
i_ret = sj_tree_walk(deep_walk_cb, o_root, o_user);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return i_ret;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
function deep_walk_cb(ao_TreeStack, from_child, o_user)
|
|
44
|
+
{
|
|
45
|
+
let b_continue = true;
|
|
46
|
+
const b_depth = (o_user.i_depth < 1) || (ao_TreeStack.length <= o_user.i_depth);
|
|
47
|
+
const o_TreeStack = ao_TreeStack.at(- 1); /* tail */
|
|
48
|
+
const o_node = o_TreeStack.node;
|
|
49
|
+
|
|
50
|
+
o_TreeStack.child = null;
|
|
51
|
+
|
|
52
|
+
if (b_depth && o_node.as_key && (o_TreeStack.i_child < o_node.as_key.length))
|
|
53
|
+
{
|
|
54
|
+
const s_key = o_node.as_key[o_TreeStack.i_child];
|
|
55
|
+
|
|
56
|
+
o_TreeStack.child = deep_walk_node_t(o_node.value[s_key]);
|
|
57
|
+
b_continue &&= (!!o_TreeStack.child);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (b_continue && (o_TreeStack.i_child === 0))
|
|
61
|
+
{
|
|
62
|
+
b_continue = o_user.f_cb(ao_TreeStack, o_user.i_depth, o_user.user);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return b_continue;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// return path to ao_TreeStack[tail]
|
|
69
|
+
export function sj_deep_path(ao_TreeStack)
|
|
70
|
+
{
|
|
71
|
+
let as_path = sj_array_new(0);
|
|
72
|
+
const b_arr = Array.isArray(ao_TreeStack);
|
|
73
|
+
let b_ok = b_arr && (0 < ao_TreeStack.length) && (!!as_path);
|
|
74
|
+
|
|
75
|
+
for (let i_stk = 0; b_ok && (i_stk < ao_TreeStack.length - 1); i_stk++)
|
|
76
|
+
{
|
|
77
|
+
let i_ret;
|
|
78
|
+
const o_TreeStack = ao_TreeStack[i_stk];
|
|
79
|
+
const o_ret = sj_deep_get_own(o_TreeStack, ["node", "as_key"]);
|
|
80
|
+
|
|
81
|
+
b_ok = false;
|
|
82
|
+
|
|
83
|
+
if ((!!o_ret) && o_ret.b_ok)
|
|
84
|
+
{
|
|
85
|
+
const as_key = o_ret.value;
|
|
86
|
+
|
|
87
|
+
if (as_key && (o_TreeStack.i_child < as_key.length))
|
|
88
|
+
{
|
|
89
|
+
i_ret = sj_array_push(as_path, as_key[o_TreeStack.i_child]);
|
|
90
|
+
b_ok = (0 < i_ret);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (!b_ok)
|
|
96
|
+
{
|
|
97
|
+
as_path = null;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return as_path;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Creates a node object for deep traversal (tree walking).
|
|
106
|
+
*
|
|
107
|
+
* @param {any} value [in]
|
|
108
|
+
* The value to be wrapped in a node.
|
|
109
|
+
*
|
|
110
|
+
* @returns {object|null}
|
|
111
|
+
* A node object containing:
|
|
112
|
+
* - value : The original value.
|
|
113
|
+
* - b_array: True if the value is an array.
|
|
114
|
+
* - as_key : An array of own property keys if the value is an object;
|
|
115
|
+
* otherwise null.
|
|
116
|
+
* Returns null if the node object cannot be created.
|
|
117
|
+
*/
|
|
118
|
+
function deep_walk_node_t(value)
|
|
119
|
+
{
|
|
120
|
+
let o_node = null;
|
|
121
|
+
let as_key = null;
|
|
122
|
+
const b_obj = sj_is_object(value);
|
|
123
|
+
|
|
124
|
+
if (b_obj)
|
|
125
|
+
{
|
|
126
|
+
as_key = sj_keys(value);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if ((!b_obj) || as_key)
|
|
130
|
+
{
|
|
131
|
+
const b_array = Array.isArray(value);
|
|
132
|
+
|
|
133
|
+
o_node = sj_new_lit(() => ({value, b_array, as_key}));
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return o_node;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
|
package/javascr/util/index.js
CHANGED
package/javascr/util/prop.js
CHANGED
|
@@ -254,10 +254,11 @@ export function sj_prop_set_own(o_any, prop, value)
|
|
|
254
254
|
* The property name (non-empty string) or array index (non-negative integer)
|
|
255
255
|
* to retrieve.
|
|
256
256
|
*
|
|
257
|
-
* @returns {object}
|
|
258
|
-
*
|
|
259
|
-
*
|
|
260
|
-
* -
|
|
257
|
+
* @returns {object|null}
|
|
258
|
+
* An instance of PropRet_t containing the following properties, or null
|
|
259
|
+
* if the instance creation fails:
|
|
260
|
+
* - b_ok : true if the property exists as an own property; otherwise, false.
|
|
261
|
+
* - value: The retrieved property value if b_ok is true; otherwise, undefined.
|
|
261
262
|
*/
|
|
262
263
|
export function sj_prop_get_own(o_any, prop)
|
|
263
264
|
{
|
|
@@ -277,8 +278,8 @@ export function sj_prop_get_own(o_any, prop)
|
|
|
277
278
|
}
|
|
278
279
|
}
|
|
279
280
|
|
|
280
|
-
const
|
|
281
|
-
return
|
|
281
|
+
const o_ret = PropRet_t(b_ok, value);
|
|
282
|
+
return o_ret;
|
|
282
283
|
}
|
|
283
284
|
|
|
284
285
|
|
|
@@ -297,8 +298,9 @@ export function sj_prop_get_own(o_any, prop)
|
|
|
297
298
|
* The property name (non-empty string) or array index (non-negative integer)
|
|
298
299
|
* to delete.
|
|
299
300
|
*
|
|
300
|
-
* @returns {object}
|
|
301
|
-
*
|
|
301
|
+
* @returns {object|null}
|
|
302
|
+
* An instance of PropRet_t containing the following properties, or null
|
|
303
|
+
* if the instance creation fails:
|
|
302
304
|
* - b_ok : true if the property existed and was successfully deleted.
|
|
303
305
|
* - value: The value of the property before deletion if b_ok is true;
|
|
304
306
|
* otherwise, undefined.
|
|
@@ -324,8 +326,58 @@ export function sj_prop_delete_own(o_any, prop)
|
|
|
324
326
|
}
|
|
325
327
|
}
|
|
326
328
|
|
|
329
|
+
const o_ret = PropRet_t(b_ok, value);
|
|
330
|
+
return o_ret;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* Creates a result object for property-related operations.
|
|
336
|
+
*
|
|
337
|
+
* @param {boolean} b_ok [in]
|
|
338
|
+
* True if the operation succeeded; otherwise, false.
|
|
339
|
+
*
|
|
340
|
+
* @param {any} value [in]
|
|
341
|
+
* The property value.
|
|
342
|
+
*
|
|
343
|
+
* @returns {object|null}
|
|
344
|
+
* A literal object containing the following properties, or null if the
|
|
345
|
+
* creation fails:
|
|
346
|
+
* - b_ok : Same as the argument.
|
|
347
|
+
* - value: Same as the argument.
|
|
348
|
+
*/
|
|
349
|
+
export function PropRet_t(b_ok, value)
|
|
350
|
+
{
|
|
327
351
|
const s_lit = sj_new_lit(() => ({b_ok, value}));
|
|
352
|
+
|
|
328
353
|
return s_lit;
|
|
329
354
|
}
|
|
330
355
|
|
|
331
356
|
|
|
357
|
+
/**
|
|
358
|
+
* Retrieves an array of a given object's own enumerable property names.
|
|
359
|
+
*
|
|
360
|
+
* @param {any} any [in]
|
|
361
|
+
* The object whose enumerable own properties are to be returned.
|
|
362
|
+
*
|
|
363
|
+
* @returns {string[] | null}
|
|
364
|
+
* string[]: All the enumerable properties of the given object.
|
|
365
|
+
* null : The input is not a valid object, or a runtime error occurred.
|
|
366
|
+
*/
|
|
367
|
+
export function sj_keys(any)
|
|
368
|
+
{
|
|
369
|
+
let as_key = null;
|
|
370
|
+
|
|
371
|
+
try
|
|
372
|
+
{
|
|
373
|
+
as_key = Object.keys(any);
|
|
374
|
+
}
|
|
375
|
+
catch (o_err)
|
|
376
|
+
{
|
|
377
|
+
console.error(`${sj_keys.name}: ${o_err.message}`);
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
return as_key;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "smsmslib",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.79",
|
|
4
4
|
"description": "Reusable functions for me.",
|
|
5
5
|
"files": [
|
|
6
6
|
"javascr/**/*.js",
|
|
@@ -19,6 +19,6 @@
|
|
|
19
19
|
"author": "",
|
|
20
20
|
"license": "ISC",
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"smsmslib": "^1.0.
|
|
22
|
+
"smsmslib": "^1.0.79"
|
|
23
23
|
}
|
|
24
24
|
}
|