mol_schema 0.0.12 → 0.0.13

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/node.test.js CHANGED
@@ -68,9 +68,11 @@ var $;
68
68
  static [$mol_key_handle]() {
69
69
  return this.toString();
70
70
  }
71
+ /** Short user-readable identity. */
71
72
  static toString() {
72
73
  return $$.$mol_func_name(this);
73
74
  }
75
+ /** Type-guard that checks value by schema. */
74
76
  static check(val) {
75
77
  try {
76
78
  this.guard(val);
@@ -80,9 +82,11 @@ var $;
80
82
  return false;
81
83
  }
82
84
  }
85
+ /** Strict parse. Fails of wrong values. */
83
86
  static guard(value) {
84
87
  return value;
85
88
  }
89
+ /** Relaxed cast. Normalizes wrong values. */
86
90
  static cast(value) {
87
91
  try {
88
92
  return this.guard(value);
@@ -91,6 +95,7 @@ var $;
91
95
  return this.default;
92
96
  }
93
97
  }
98
+ /** Default value which conforms schema. */
94
99
  static default = undefined;
95
100
  }
96
101
  $.$mol_schema_any = $mol_schema_any;
@@ -143,6 +148,7 @@ var $;
143
148
  "use strict";
144
149
  var $;
145
150
  (function ($) {
151
+ /** Generates unique identifier. */
146
152
  function $mol_guid(length = 8, exists = () => false) {
147
153
  for (;;) {
148
154
  let id = Math.random().toString(36).substring(2, length + 2).toUpperCase();
@@ -159,6 +165,7 @@ var $;
159
165
  var $;
160
166
  (function ($) {
161
167
  const TypedArray = Object.getPrototypeOf(Uint8Array);
168
+ /** Returns string key for any value. */
162
169
  function $mol_key(value) {
163
170
  primitives: {
164
171
  if (typeof value === 'bigint')
@@ -166,9 +173,9 @@ var $;
166
173
  if (typeof value === 'symbol')
167
174
  return `Symbol(${value.description})`;
168
175
  if (!value)
169
- return JSON.stringify(value);
176
+ return JSON.stringify(value); // 0, null, ""
170
177
  if (typeof value !== 'object' && typeof value !== 'function')
171
- return JSON.stringify(value);
178
+ return JSON.stringify(value); // boolean, number, string
172
179
  }
173
180
  caching: {
174
181
  let key = $mol_key_store.get(value);
@@ -612,7 +619,7 @@ var $;
612
619
  var $;
613
620
  (function ($) {
614
621
  function $mol_fail_hidden(error) {
615
- throw error;
622
+ throw error; /// Use 'Never Pause Here' breakpoint in DevTools or simply blackbox this script
616
623
  }
617
624
  $.$mol_fail_hidden = $mol_fail_hidden;
618
625
  })($ || ($ = {}));
@@ -727,7 +734,7 @@ var $;
727
734
  "use strict";
728
735
  var $;
729
736
  (function ($) {
730
- const mod = require('module');
737
+ const mod = require /****/('module');
731
738
  const internals = mod.builtinModules;
732
739
  function $node_internal_check(name) {
733
740
  if (name.startsWith('node:'))
@@ -741,8 +748,8 @@ var $;
741
748
  "use strict";
742
749
  var $;
743
750
  (function ($) {
744
- const path = require('path');
745
- const mod = require('module');
751
+ const path = require /****/('path');
752
+ const mod = require /****/('module');
746
753
  const localRequire = mod.createRequire(path.join(process.cwd(), 'package.json'));
747
754
  function $node_autoinstall(name) {
748
755
  try {
@@ -831,6 +838,7 @@ var $;
831
838
  ])
832
839
  ].map(frame_normalize).join('\n')
833
840
  });
841
+ // в nodejs, что б не дублировалось cause в консоли
834
842
  Object.defineProperty(this, 'cause', {
835
843
  get: () => cause
836
844
  });
@@ -1013,6 +1021,9 @@ var $;
1013
1021
  [Symbol.dispose]() {
1014
1022
  this.destructor();
1015
1023
  }
1024
+ //[ Symbol.toPrimitive ]( hint: string ) {
1025
+ // return hint === 'number' ? this.valueOf() : this.toString()
1026
+ //}
1016
1027
  toString() {
1017
1028
  return this[Symbol.toStringTag] || this.constructor.name + '<>';
1018
1029
  }
@@ -1089,11 +1100,16 @@ var $;
1089
1100
  "use strict";
1090
1101
  var $;
1091
1102
  (function ($) {
1103
+ /** Special status statuses. */
1092
1104
  let $mol_wire_cursor;
1093
1105
  (function ($mol_wire_cursor) {
1106
+ /** Update required. */
1094
1107
  $mol_wire_cursor[$mol_wire_cursor["stale"] = -1] = "stale";
1108
+ /** Some of (transitive) pub update required. */
1095
1109
  $mol_wire_cursor[$mol_wire_cursor["doubt"] = -2] = "doubt";
1110
+ /** Actual state but may be dropped. */
1096
1111
  $mol_wire_cursor[$mol_wire_cursor["fresh"] = -3] = "fresh";
1112
+ /** State will never be changed. */
1097
1113
  $mol_wire_cursor[$mol_wire_cursor["final"] = -4] = "final";
1098
1114
  })($mol_wire_cursor = $.$mol_wire_cursor || ($.$mol_wire_cursor = {}));
1099
1115
  })($ || ($ = {}));
@@ -1102,6 +1118,9 @@ var $;
1102
1118
  "use strict";
1103
1119
  var $;
1104
1120
  (function ($) {
1121
+ /**
1122
+ * Collects subscribers in compact array. 28B
1123
+ */
1105
1124
  class $mol_wire_pub extends Object {
1106
1125
  constructor(id = `$mol_wire_pub:${$mol_guid()}`) {
1107
1126
  super();
@@ -1109,10 +1128,17 @@ var $;
1109
1128
  }
1110
1129
  [Symbol.toStringTag];
1111
1130
  data = [];
1131
+ // Derived objects should be Arrays.
1112
1132
  static get [Symbol.species]() {
1113
1133
  return Array;
1114
1134
  }
1115
- sub_from = 0;
1135
+ /**
1136
+ * Index of first subscriber.
1137
+ */
1138
+ sub_from = 0; // 4B
1139
+ /**
1140
+ * All current subscribers.
1141
+ */
1116
1142
  get sub_list() {
1117
1143
  const res = [];
1118
1144
  for (let i = this.sub_from; i < this.data.length; i += 2) {
@@ -1120,14 +1146,23 @@ var $;
1120
1146
  }
1121
1147
  return res;
1122
1148
  }
1149
+ /**
1150
+ * Has any subscribers or not.
1151
+ */
1123
1152
  get sub_empty() {
1124
1153
  return this.sub_from === this.data.length;
1125
1154
  }
1155
+ /**
1156
+ * Subscribe subscriber to this publisher events and return position of subscriber that required to unsubscribe.
1157
+ */
1126
1158
  sub_on(sub, pub_pos) {
1127
1159
  const pos = this.data.length;
1128
1160
  this.data.push(sub, pub_pos);
1129
1161
  return pos;
1130
1162
  }
1163
+ /**
1164
+ * Unsubscribe subscriber from this publisher events by subscriber position provided by `on(pub)`.
1165
+ */
1131
1166
  sub_off(sub_pos) {
1132
1167
  if (!(sub_pos < this.data.length)) {
1133
1168
  $mol_fail(new Error(`Wrong pos ${sub_pos}`));
@@ -1140,21 +1175,39 @@ var $;
1140
1175
  if (end === this.sub_from)
1141
1176
  this.reap();
1142
1177
  }
1178
+ /**
1179
+ * Called when last sub was unsubscribed.
1180
+ **/
1143
1181
  reap() { }
1182
+ /**
1183
+ * Autowire this publisher with current subscriber.
1184
+ **/
1144
1185
  promote() {
1145
1186
  $mol_wire_auto()?.track_next(this);
1146
1187
  }
1188
+ /**
1189
+ * Enforce actualization. Should not throw errors.
1190
+ */
1147
1191
  fresh() { }
1192
+ /**
1193
+ * Allow to put data to caches in the subtree.
1194
+ */
1148
1195
  complete() { }
1149
1196
  get incompleted() {
1150
1197
  return false;
1151
1198
  }
1199
+ /**
1200
+ * Notify subscribers about self changes.
1201
+ */
1152
1202
  emit(quant = $mol_wire_cursor.stale) {
1153
1203
  for (let i = this.sub_from; i < this.data.length; i += 2) {
1154
1204
  ;
1155
1205
  this.data[i].absorb(quant, this.data[i + 1]);
1156
1206
  }
1157
1207
  }
1208
+ /**
1209
+ * Moves peer from one position to another. Doesn't clear data at old position!
1210
+ */
1158
1211
  peer_move(from_pos, to_pos) {
1159
1212
  const peer = this.data[from_pos];
1160
1213
  const self_pos = this.data[from_pos + 1];
@@ -1162,6 +1215,9 @@ var $;
1162
1215
  this.data[to_pos + 1] = self_pos;
1163
1216
  peer.peer_repos(self_pos, to_pos);
1164
1217
  }
1218
+ /**
1219
+ * Updates self position in the peer.
1220
+ */
1165
1221
  peer_repos(peer_pos, self_pos) {
1166
1222
  this.data[peer_pos + 1] = self_pos;
1167
1223
  }
@@ -1177,10 +1233,16 @@ var $;
1177
1233
  var $;
1178
1234
  (function ($) {
1179
1235
  $.$mol_wire_auto_sub = null;
1236
+ /**
1237
+ * When fulfilled, all publishers are promoted to this subscriber on access to its.
1238
+ */
1180
1239
  function $mol_wire_auto(next = $.$mol_wire_auto_sub) {
1181
1240
  return $.$mol_wire_auto_sub = next;
1182
1241
  }
1183
1242
  $.$mol_wire_auto = $mol_wire_auto;
1243
+ /**
1244
+ * Affection queue. Used to prevent accidental stack overflow on emit.
1245
+ */
1184
1246
  $.$mol_wire_affected = [];
1185
1247
  })($ || ($ = {}));
1186
1248
 
@@ -1188,6 +1250,7 @@ var $;
1188
1250
  "use strict";
1189
1251
  var $;
1190
1252
  (function ($) {
1253
+ // https://docs.google.com/document/d/1FTascZXT9cxfetuPRT2eXPQKXui4nWFivUnS_335T3U/preview#
1191
1254
  $['devtoolsFormatters'] ||= [];
1192
1255
  function $mol_dev_format_register(config) {
1193
1256
  $['devtoolsFormatters'].push(config);
@@ -1239,6 +1302,7 @@ var $;
1239
1302
  return false;
1240
1303
  if (!val)
1241
1304
  return false;
1305
+ // if( Error.isError( val ) ) true
1242
1306
  if (val[$.$mol_dev_format_body])
1243
1307
  return true;
1244
1308
  return false;
@@ -1256,12 +1320,16 @@ var $;
1256
1320
  return $.$mol_dev_format_accent($mol_dev_format_native(val), '💨', $mol_dev_format_native(error), '');
1257
1321
  }
1258
1322
  }
1323
+ // if( Error.isError( val ) ) {
1324
+ // return $mol_dev_format_native( val )
1325
+ // }
1259
1326
  return null;
1260
1327
  },
1261
1328
  });
1262
1329
  function $mol_dev_format_native(obj) {
1263
1330
  if (typeof obj === 'undefined')
1264
1331
  return $.$mol_dev_format_shade('undefined');
1332
+ // if( ![ 'object', 'function', 'symbol' ].includes( typeof obj ) ) return obj
1265
1333
  return [
1266
1334
  'object',
1267
1335
  {
@@ -1319,6 +1387,9 @@ var $;
1319
1387
  'margin-left': '13px'
1320
1388
  });
1321
1389
  class Stack extends Array {
1390
+ // [ Symbol.toPrimitive ]() {
1391
+ // return this.toString()
1392
+ // }
1322
1393
  toString() {
1323
1394
  return this.join('\n');
1324
1395
  }
@@ -1341,6 +1412,7 @@ var $;
1341
1412
  this.method = call.getMethodName() ?? '';
1342
1413
  if (this.method === this.function)
1343
1414
  this.method = '';
1415
+ // const func = c.getFunction()
1344
1416
  this.pos = [call.getEnclosingLineNumber() ?? 0, call.getEnclosingColumnNumber() ?? 0];
1345
1417
  this.eval = call.getEvalOrigin() ?? '';
1346
1418
  this.source = call.getScriptNameOrSourceURL() ?? '';
@@ -1387,9 +1459,16 @@ var $;
1387
1459
  "use strict";
1388
1460
  var $;
1389
1461
  (function ($) {
1462
+ /**
1463
+ * Publisher that can auto collect other publishers. 32B
1464
+ *
1465
+ * P1 P2 P3 P4 S1 S2 S3
1466
+ * ^ ^
1467
+ * pubs_from subs_from
1468
+ */
1390
1469
  class $mol_wire_pub_sub extends $mol_wire_pub {
1391
- pub_from = 0;
1392
- cursor = $mol_wire_cursor.stale;
1470
+ pub_from = 0; // 4B
1471
+ cursor = $mol_wire_cursor.stale; // 4B
1393
1472
  get temp() {
1394
1473
  return false;
1395
1474
  }
@@ -1507,10 +1586,27 @@ var $;
1507
1586
  return;
1508
1587
  this.cursor = quant;
1509
1588
  this.emit($mol_wire_cursor.doubt);
1589
+ // if( pos >= 0 && pos < this.sub_from - 2 ) {
1590
+ // const pub = this.data[ pos ] as $mol_wire_pub
1591
+ // if( pub instanceof $mol_wire_task ) return
1592
+ // for(
1593
+ // let cursor = this.pub_from;
1594
+ // cursor < this.sub_from;
1595
+ // cursor += 2
1596
+ // ) {
1597
+ // const pub = this.data[ cursor ] as $mol_wire_pub
1598
+ // if( pub instanceof $mol_wire_task ) {
1599
+ // pub.destructor()
1600
+ // }
1601
+ // }
1602
+ // }
1510
1603
  }
1511
1604
  [$mol_dev_format_head]() {
1512
1605
  return $mol_dev_format_native(this);
1513
1606
  }
1607
+ /**
1608
+ * Is subscribed to any publisher or not.
1609
+ */
1514
1610
  get pub_empty() {
1515
1611
  return this.sub_from === this.pub_from;
1516
1612
  }
@@ -1580,6 +1676,7 @@ var $;
1580
1676
  "use strict";
1581
1677
  var $;
1582
1678
  (function ($) {
1679
+ /// @todo right orderinng
1583
1680
  $.$mol_after_mock_queue = [];
1584
1681
  function $mol_after_mock_warp() {
1585
1682
  const queue = $.$mol_after_mock_queue.splice(0);
@@ -1656,6 +1753,13 @@ var $;
1656
1753
  var $;
1657
1754
  (function ($) {
1658
1755
  const wrappers = new WeakMap();
1756
+ /**
1757
+ * Suspendable task with support both sync/async api.
1758
+ *
1759
+ * A1 A2 A3 A4 P1 P2 P3 P4 S1 S2 S3
1760
+ * ^ ^ ^
1761
+ * args_from pubs_from subs_from
1762
+ **/
1659
1763
  class $mol_wire_fiber extends $mol_wire_pub_sub {
1660
1764
  task;
1661
1765
  host;
@@ -1676,6 +1780,7 @@ var $;
1676
1780
  });
1677
1781
  }
1678
1782
  static sync() {
1783
+ // Sync whole fiber graph
1679
1784
  while (this.planning.size) {
1680
1785
  for (const fiber of this.planning) {
1681
1786
  this.planning.delete(fiber);
@@ -1686,6 +1791,7 @@ var $;
1686
1791
  fiber.fresh();
1687
1792
  }
1688
1793
  }
1794
+ // Collect garbage
1689
1795
  while (this.reaping.size) {
1690
1796
  const fibers = this.reaping;
1691
1797
  this.reaping = new Set;
@@ -1837,6 +1943,10 @@ var $;
1837
1943
  this.cursor = $mol_wire_cursor.stale;
1838
1944
  this.fresh();
1839
1945
  }
1946
+ /**
1947
+ * Synchronous execution. Throws Promise when waits async task (SuspenseAPI provider).
1948
+ * Should be called inside SuspenseAPI consumer (ie fiber).
1949
+ */
1840
1950
  sync() {
1841
1951
  if (!$mol_wire_fiber.warm) {
1842
1952
  return this.result();
@@ -1851,6 +1961,10 @@ var $;
1851
1961
  }
1852
1962
  return this.cache;
1853
1963
  }
1964
+ /**
1965
+ * Asynchronous execution.
1966
+ * It's SuspenseAPI consumer. So SuspenseAPI providers can be called inside.
1967
+ */
1854
1968
  async async_raw() {
1855
1969
  while (true) {
1856
1970
  this.fresh();
@@ -1863,6 +1977,7 @@ var $;
1863
1977
  if (!$mol_promise_like(this.cache))
1864
1978
  return this.cache;
1865
1979
  if (this.cursor === $mol_wire_cursor.final) {
1980
+ // never ends on destructed fiber
1866
1981
  await new Promise(() => { });
1867
1982
  }
1868
1983
  }
@@ -1991,6 +2106,7 @@ var $;
1991
2106
  "use strict";
1992
2107
  var $;
1993
2108
  (function ($) {
2109
+ /** Log begin of collapsed group only when some logged inside, returns func to close group */
1994
2110
  function $mol_log3_area_lazy(event) {
1995
2111
  const self = this.$;
1996
2112
  const stack = self.$mol_log3_stack;
@@ -2015,6 +2131,7 @@ var $;
2015
2131
  "use strict";
2016
2132
  var $;
2017
2133
  (function ($) {
2134
+ /** Module for working with terminal. Text coloring when output in terminal */
2018
2135
  class $mol_term_color {
2019
2136
  static reset = this.ansi(0, 0);
2020
2137
  static bold = this.ansi(1, 22);
@@ -2100,6 +2217,7 @@ var $;
2100
2217
  "use strict";
2101
2218
  var $;
2102
2219
  (function ($) {
2220
+ /** One-shot fiber */
2103
2221
  class $mol_wire_task extends $mol_wire_fiber {
2104
2222
  static getter(task) {
2105
2223
  return function $mol_wire_task_get(host, args) {
@@ -2125,6 +2243,7 @@ var $;
2125
2243
  }
2126
2244
  const key = (host?.[Symbol.toStringTag] ?? host) + ('.' + task.name + '<#>');
2127
2245
  const next = new $mol_wire_task(key, task, host, args);
2246
+ // Disabled because non-idempotency is required for try-catch
2128
2247
  if (existen?.temp) {
2129
2248
  $$.$mol_log3_warn({
2130
2249
  place: '$mol_wire_task',
@@ -2157,7 +2276,7 @@ var $;
2157
2276
  try {
2158
2277
  next[Symbol.toStringTag] = this[Symbol.toStringTag];
2159
2278
  }
2160
- catch {
2279
+ catch { // Promises throw in strict mode
2161
2280
  Object.defineProperty(next, Symbol.toStringTag, { value: this[Symbol.toStringTag] });
2162
2281
  }
2163
2282
  }
@@ -2182,6 +2301,9 @@ var $;
2182
2301
  "use strict";
2183
2302
  var $;
2184
2303
  (function ($) {
2304
+ /**
2305
+ * Decorates method to fiber to ensure it is executed only once inside other fiber.
2306
+ */
2185
2307
  function $mol_wire_method(host, field, descr) {
2186
2308
  if (!descr)
2187
2309
  descr = Reflect.getOwnPropertyDescriptor(host, field);
@@ -2208,6 +2330,7 @@ var $;
2208
2330
  "use strict";
2209
2331
  var $;
2210
2332
  (function ($) {
2333
+ /** Convert a pseudo-synchronous (Suspense API) API to an explicit asynchronous one (for integrating with external systems). */
2211
2334
  function $mol_wire_async(obj) {
2212
2335
  let fiber;
2213
2336
  const temp = $mol_wire_task.getter(obj);
@@ -2319,6 +2442,10 @@ var $;
2319
2442
  props[field] = get_val;
2320
2443
  return get_val;
2321
2444
  }
2445
+ /**
2446
+ * Convert asynchronous (promise-based) API to synchronous by wrapping function and method calls in a fiber.
2447
+ * @see https://mol.hyoo.ru/#!section=docs/=1fcpsq_1wh0h2
2448
+ */
2322
2449
  function $mol_wire_sync(obj) {
2323
2450
  return new Proxy(obj, {
2324
2451
  get(obj, field) {
@@ -2820,6 +2947,12 @@ var $;
2820
2947
  createDocumentFragment: () => $mol_dom_context.document.createDocumentFragment(),
2821
2948
  };
2822
2949
  $.$mol_jsx_frag = '';
2950
+ /**
2951
+ * JSX adapter that makes DOM tree.
2952
+ * Generates global unique ids for every DOM-element by components tree with ids.
2953
+ * Ensures all local ids are unique.
2954
+ * Can reuse an existing nodes by GUIDs when used inside [`mol_jsx_attach`](https://github.com/hyoo-ru/mam_mol/tree/master/jsx/attach).
2955
+ */
2823
2956
  function $mol_jsx(Elem, props, ...childNodes) {
2824
2957
  const id = props && props.id || '';
2825
2958
  const guid = id ? $.$mol_jsx_prefix ? $.$mol_jsx_prefix + '/' + id : id : $.$mol_jsx_prefix;
@@ -2930,6 +3063,8 @@ var $;
2930
3063
 
2931
3064
  ;
2932
3065
  "use strict";
3066
+ /** @jsx $mol_jsx */
3067
+ /** @jsxFrag $mol_jsx_frag */
2933
3068
  var $;
2934
3069
  (function ($) {
2935
3070
  $mol_test({
@@ -3035,6 +3170,7 @@ var $;
3035
3170
  "use strict";
3036
3171
  var $;
3037
3172
  (function ($) {
3173
+ /** Lazy computed lists with native Array interface. $mol_range2_array is mutable but all derived ranges are immutable. */
3038
3174
  function $mol_range2(item = index => index, size = () => Number.POSITIVE_INFINITY) {
3039
3175
  const source = typeof item === 'function' ? new $mol_range2_array() : item;
3040
3176
  if (typeof item !== 'function') {
@@ -3083,6 +3219,7 @@ var $;
3083
3219
  }
3084
3220
  $.$mol_range2 = $mol_range2;
3085
3221
  class $mol_range2_array extends Array {
3222
+ // Lazy
3086
3223
  concat(...tail) {
3087
3224
  if (tail.length === 0)
3088
3225
  return this;
@@ -3094,6 +3231,7 @@ var $;
3094
3231
  }
3095
3232
  return $mol_range2(index => index < this.length ? this[index] : tail[0][index - this.length], () => this.length + tail[0].length);
3096
3233
  }
3234
+ // Lazy
3097
3235
  filter(check, context) {
3098
3236
  const filtered = [];
3099
3237
  let cursor = -1;
@@ -3106,13 +3244,16 @@ var $;
3106
3244
  return filtered[index];
3107
3245
  }, () => cursor < this.length ? Number.POSITIVE_INFINITY : filtered.length);
3108
3246
  }
3247
+ // Diligent
3109
3248
  forEach(proceed, context) {
3110
3249
  for (let [key, value] of this.entries())
3111
3250
  proceed.call(context, value, key, this);
3112
3251
  }
3252
+ // Lazy
3113
3253
  map(proceed, context) {
3114
3254
  return $mol_range2(index => proceed.call(context, this[index], index, this), () => this.length);
3115
3255
  }
3256
+ // Diligent
3116
3257
  reduce(merge, result) {
3117
3258
  let index = 0;
3118
3259
  if (arguments.length === 1) {
@@ -3123,12 +3264,15 @@ var $;
3123
3264
  }
3124
3265
  return result;
3125
3266
  }
3267
+ // Lazy
3126
3268
  toReversed() {
3127
3269
  return $mol_range2(index => this[this.length - 1 - index], () => this.length);
3128
3270
  }
3271
+ // Lazy
3129
3272
  slice(from = 0, to = this.length) {
3130
3273
  return $mol_range2(index => this[from + index], () => Math.min(to, this.length) - from);
3131
3274
  }
3275
+ // Lazy
3132
3276
  some(check, context) {
3133
3277
  for (let index = 0; index < this.length; ++index) {
3134
3278
  if (check.call(context, this[index], index, this))
@@ -3324,6 +3468,10 @@ var $;
3324
3468
  var $;
3325
3469
  (function ($) {
3326
3470
  $.$mol_compare_deep_cache = new WeakMap();
3471
+ /**
3472
+ * Deeply compares two values. Returns true if equal.
3473
+ * Define `Symbol.toPrimitive` to customize.
3474
+ */
3327
3475
  function $mol_compare_deep(left, right) {
3328
3476
  if (Object.is(left, right))
3329
3477
  return true;
@@ -3461,6 +3609,7 @@ var $;
3461
3609
 
3462
3610
  ;
3463
3611
  "use strict";
3612
+ /** @jsx $mol_jsx */
3464
3613
  var $;
3465
3614
  (function ($) {
3466
3615
  $mol_test({
@@ -3522,6 +3671,7 @@ var $;
3522
3671
  const obj3_copy = { test: 3, obj2: obj2_copy };
3523
3672
  obj1.obj3 = obj3;
3524
3673
  obj1_copy.obj3 = obj3_copy;
3674
+ // warmup cache
3525
3675
  $mol_assert_not($mol_compare_deep(obj1, {}));
3526
3676
  $mol_assert_not($mol_compare_deep(obj2, {}));
3527
3677
  $mol_assert_not($mol_compare_deep(obj3, {}));
@@ -3591,18 +3741,34 @@ var $;
3591
3741
  "use strict";
3592
3742
  var $;
3593
3743
  (function ($) {
3744
+ /**
3745
+ * Argument must be Truthy
3746
+ * @deprecated use $mol_assert_equal instead
3747
+ */
3594
3748
  function $mol_assert_ok(value) {
3595
3749
  if (value)
3596
3750
  return;
3597
3751
  $mol_fail(new Error(`${value} ≠ true`));
3598
3752
  }
3599
3753
  $.$mol_assert_ok = $mol_assert_ok;
3754
+ /**
3755
+ * Argument must be Falsy
3756
+ * @deprecated use $mol_assert_equal instead
3757
+ */
3600
3758
  function $mol_assert_not(value) {
3601
3759
  if (!value)
3602
3760
  return;
3603
3761
  $mol_fail(new Error(`${value} ≠ false`));
3604
3762
  }
3605
3763
  $.$mol_assert_not = $mol_assert_not;
3764
+ /**
3765
+ * Handler must throw an error.
3766
+ * @example
3767
+ * $mol_assert_fail( ()=>{ throw new Error( 'Parse error' ) } ) // Passes because throws error
3768
+ * $mol_assert_fail( ()=>{ throw new Error( 'Parse error' ) } , 'Parse error' ) // Passes because throws right message
3769
+ * $mol_assert_fail( ()=>{ throw new Error( 'Parse error' ) } , Error ) // Passes because throws right class
3770
+ * @see https://mol.hyoo.ru/#!section=docs/=9q9dv3_fgxjsf
3771
+ */
3606
3772
  function $mol_assert_fail(handler, ErrorRight) {
3607
3773
  const fail = $.$mol_fail;
3608
3774
  try {
@@ -3625,10 +3791,18 @@ var $;
3625
3791
  $mol_fail(new Error('Not failed', { cause: { expect: ErrorRight } }));
3626
3792
  }
3627
3793
  $.$mol_assert_fail = $mol_assert_fail;
3794
+ /** @deprecated Use $mol_assert_equal */
3628
3795
  function $mol_assert_like(...args) {
3629
3796
  $mol_assert_equal(...args);
3630
3797
  }
3631
3798
  $.$mol_assert_like = $mol_assert_like;
3799
+ /**
3800
+ * All arguments must not be structural equal to each other.
3801
+ * @example
3802
+ * $mol_assert_unique( 1 , 2 , 3 ) // Passes
3803
+ * $mol_assert_unique( 1 , 1 , 2 ) // Fails because 1 === 1
3804
+ * @see https://mol.hyoo.ru/#!section=docs/=9q9dv3_fgxjsf
3805
+ */
3632
3806
  function $mol_assert_unique(...args) {
3633
3807
  for (let i = 0; i < args.length; ++i) {
3634
3808
  for (let j = 0; j < args.length; ++j) {
@@ -3641,6 +3815,13 @@ var $;
3641
3815
  }
3642
3816
  }
3643
3817
  $.$mol_assert_unique = $mol_assert_unique;
3818
+ /**
3819
+ * All arguments must be structural equal each other.
3820
+ * @example
3821
+ * $mol_assert_like( [1] , [1] , [1] ) // Passes
3822
+ * $mol_assert_like( [1] , [1] , [2] ) // Fails because 1 !== 2
3823
+ * @see https://mol.hyoo.ru/#!section=docs/=9q9dv3_fgxjsf
3824
+ */
3644
3825
  function $mol_assert_equal(...args) {
3645
3826
  for (let i = 1; i < args.length; ++i) {
3646
3827
  if ($mol_compare_deep(args[0], args[i]))
@@ -3691,6 +3872,7 @@ var $;
3691
3872
 
3692
3873
  ;
3693
3874
  "use strict";
3875
+ /** @jsx $mol_jsx */
3694
3876
  var $;
3695
3877
  (function ($) {
3696
3878
  $mol_test({
@@ -4116,6 +4298,11 @@ var $;
4116
4298
  var $;
4117
4299
  (function ($) {
4118
4300
  const instances = new WeakSet();
4301
+ /**
4302
+ * Proxy that delegates all to lazy returned target.
4303
+ *
4304
+ * $mol_delegate( Array.prototype , ()=> fetch_array() )
4305
+ */
4119
4306
  function $mol_delegate(proto, target) {
4120
4307
  const proxy = new Proxy(proto, {
4121
4308
  get: (_, field) => {
@@ -4215,6 +4402,7 @@ var $;
4215
4402
  "use strict";
4216
4403
  var $;
4217
4404
  (function ($) {
4405
+ /** Position in any resource. */
4218
4406
  class $mol_span extends $mol_object2 {
4219
4407
  uri;
4220
4408
  source;
@@ -4230,13 +4418,17 @@ var $;
4230
4418
  this.length = length;
4231
4419
  this[Symbol.toStringTag] = this.uri + ('#' + this.row + ':' + this.col + '/' + this.length);
4232
4420
  }
4421
+ /** Span for begin of unknown resource */
4233
4422
  static unknown = $mol_span.begin('?');
4423
+ /** Makes new span for begin of resource. */
4234
4424
  static begin(uri, source = '') {
4235
4425
  return new $mol_span(uri, source, 1, 1, 0);
4236
4426
  }
4427
+ /** Makes new span for end of resource. */
4237
4428
  static end(uri, source) {
4238
4429
  return new $mol_span(uri, source, 1, source.length + 1, 0);
4239
4430
  }
4431
+ /** Makes new span for entire resource. */
4240
4432
  static entire(uri, source) {
4241
4433
  return new $mol_span(uri, source, 1, 1, source.length);
4242
4434
  }
@@ -4251,15 +4443,19 @@ var $;
4251
4443
  length: this.length
4252
4444
  };
4253
4445
  }
4446
+ /** Makes new error for this span. */
4254
4447
  error(message, Class = Error) {
4255
4448
  return new Class(`${message} (${this})`);
4256
4449
  }
4450
+ /** Makes new span for same uri. */
4257
4451
  span(row, col, length) {
4258
4452
  return new $mol_span(this.uri, this.source, row, col, length);
4259
4453
  }
4454
+ /** Makes new span after end of this. */
4260
4455
  after(length = 0) {
4261
4456
  return new $mol_span(this.uri, this.source, this.row, this.col + this.length, length);
4262
4457
  }
4458
+ /** Makes new span between begin and end. */
4263
4459
  slice(begin, end = -1) {
4264
4460
  let len = this.length;
4265
4461
  if (begin < 0)
@@ -4334,6 +4530,7 @@ var $;
4334
4530
  "use strict";
4335
4531
  var $;
4336
4532
  (function ($) {
4533
+ /** Serializes tree to string in tree format. */
4337
4534
  function $mol_tree2_to_string(tree) {
4338
4535
  let output = [];
4339
4536
  function dump(tree, prefix = '') {
@@ -4393,12 +4590,25 @@ var $;
4393
4590
  "use strict";
4394
4591
  var $;
4395
4592
  (function ($) {
4593
+ /**
4594
+ * Abstract Syntax Tree with human readable serialization.
4595
+ * Avoid direct instantiation. Use static factories instead.
4596
+ * @see https://github.com/nin-jin/tree.d
4597
+ */
4396
4598
  class $mol_tree2 extends Object {
4397
4599
  type;
4398
4600
  value;
4399
4601
  kids;
4400
4602
  span;
4401
- constructor(type, value, kids, span) {
4603
+ constructor(
4604
+ /** Type of structural node, `value` should be empty */
4605
+ type,
4606
+ /** Content of data node, `type` should be empty */
4607
+ value,
4608
+ /** Child nodes */
4609
+ kids,
4610
+ /** Position in most far source resource */
4611
+ span) {
4402
4612
  super();
4403
4613
  this.type = type;
4404
4614
  this.value = value;
@@ -4406,12 +4616,15 @@ var $;
4406
4616
  this.span = span;
4407
4617
  this[Symbol.toStringTag] = type || '\\' + value;
4408
4618
  }
4619
+ /** Makes collection node. */
4409
4620
  static list(kids, span = $mol_span.unknown) {
4410
4621
  return new $mol_tree2('', '', kids, span);
4411
4622
  }
4623
+ /** Makes new derived collection node. */
4412
4624
  list(kids) {
4413
4625
  return $mol_tree2.list(kids, this.span);
4414
4626
  }
4627
+ /** Makes data node for any string. */
4415
4628
  static data(value, kids = [], span = $mol_span.unknown) {
4416
4629
  const chunks = value.split('\n');
4417
4630
  if (chunks.length > 1) {
@@ -4425,21 +4638,26 @@ var $;
4425
4638
  }
4426
4639
  return new $mol_tree2('', value, kids, span);
4427
4640
  }
4641
+ /** Makes new derived data node. */
4428
4642
  data(value, kids = []) {
4429
4643
  return $mol_tree2.data(value, kids, this.span);
4430
4644
  }
4645
+ /** Makes struct node. */
4431
4646
  static struct(type, kids = [], span = $mol_span.unknown) {
4432
4647
  if (/[ \n\t\\]/.test(type)) {
4433
4648
  $$.$mol_fail(span.error(`Wrong type ${JSON.stringify(type)}`));
4434
4649
  }
4435
4650
  return new $mol_tree2(type, '', kids, span);
4436
4651
  }
4652
+ /** Makes new derived structural node. */
4437
4653
  struct(type, kids = []) {
4438
4654
  return $mol_tree2.struct(type, kids, this.span);
4439
4655
  }
4656
+ /** Makes new derived node with different kids id defined. */
4440
4657
  clone(kids, span = this.span) {
4441
4658
  return new $mol_tree2(this.type, this.value, kids, span);
4442
4659
  }
4660
+ /** Returns multiline text content. */
4443
4661
  text() {
4444
4662
  var values = [];
4445
4663
  for (var kid of this.kids) {
@@ -4449,15 +4667,20 @@ var $;
4449
4667
  }
4450
4668
  return this.value + values.join('\n');
4451
4669
  }
4670
+ /** Parses tree format. */
4671
+ /** @deprecated Use $mol_tree2_from_string */
4452
4672
  static fromString(str, uri = 'unknown') {
4453
4673
  return $$.$mol_tree2_from_string(str, uri);
4454
4674
  }
4675
+ /** Serializes to tree format. */
4455
4676
  toString() {
4456
4677
  return $$.$mol_tree2_to_string(this);
4457
4678
  }
4679
+ /** Makes new tree with node overrided by path. */
4458
4680
  insert(value, ...path) {
4459
4681
  return this.update($mol_maybe(value), ...path)[0];
4460
4682
  }
4683
+ /** Makes new tree with node overrided by path. */
4461
4684
  update(value, ...path) {
4462
4685
  if (path.length === 0)
4463
4686
  return value;
@@ -4490,6 +4713,7 @@ var $;
4490
4713
  return [this.clone(kids)];
4491
4714
  }
4492
4715
  }
4716
+ /** Query nodes by path. */
4493
4717
  select(...path) {
4494
4718
  let next = [this];
4495
4719
  for (const type of path) {
@@ -4516,6 +4740,7 @@ var $;
4516
4740
  }
4517
4741
  return this.list(next);
4518
4742
  }
4743
+ /** Filter kids by path or value. */
4519
4744
  filter(path, value) {
4520
4745
  const sub = this.kids.filter(item => {
4521
4746
  var found = item.select(...path);
@@ -4543,9 +4768,11 @@ var $;
4543
4768
  $mol_fail_hidden(error);
4544
4769
  }
4545
4770
  }
4771
+ /** Transform tree through context with transformers */
4546
4772
  hack(belt, context = {}) {
4547
4773
  return [].concat(...this.kids.map(child => child.hack_self(belt, context)));
4548
4774
  }
4775
+ /** Makes Error with node coordinates. */
4549
4776
  error(message, Class = Error) {
4550
4777
  return this.span.error(`${message}\n${this.clone([])}`, Class);
4551
4778
  }
@@ -4701,6 +4928,7 @@ var $;
4701
4928
  "use strict";
4702
4929
  var $;
4703
4930
  (function ($) {
4931
+ /** Syntax error with cordinates and source line snippet. */
4704
4932
  class $mol_error_syntax extends SyntaxError {
4705
4933
  reason;
4706
4934
  line;
@@ -4719,6 +4947,7 @@ var $;
4719
4947
  "use strict";
4720
4948
  var $;
4721
4949
  (function ($) {
4950
+ /** Parses tree format from string. */
4722
4951
  function $mol_tree2_from_string(str, uri = '?') {
4723
4952
  const span = $mol_span.entire(uri, str);
4724
4953
  var root = $mol_tree2.list([], span);
@@ -4728,6 +4957,7 @@ var $;
4728
4957
  var indent = 0;
4729
4958
  var line_start = pos;
4730
4959
  row++;
4960
+ // read indent
4731
4961
  while (str.length > pos && str[pos] == '\t') {
4732
4962
  indent++;
4733
4963
  pos++;
@@ -4736,8 +4966,10 @@ var $;
4736
4966
  min_indent = indent;
4737
4967
  }
4738
4968
  indent -= min_indent;
4969
+ // invalid tab size
4739
4970
  if (indent < 0 || indent >= stack.length) {
4740
4971
  const sp = span.span(row, 1, pos - line_start);
4972
+ // skip error line
4741
4973
  while (str.length > pos && str[pos] != '\n') {
4742
4974
  pos++;
4743
4975
  }
@@ -4752,7 +4984,9 @@ var $;
4752
4984
  }
4753
4985
  stack.length = indent + 1;
4754
4986
  var parent = stack[indent];
4987
+ // parse types
4755
4988
  while (str.length > pos && str[pos] != '\\' && str[pos] != '\n') {
4989
+ // type can not contain space and tab
4756
4990
  var error_start = pos;
4757
4991
  while (str.length > pos && (str[pos] == ' ' || str[pos] == '\t')) {
4758
4992
  pos++;
@@ -4764,6 +4998,7 @@ var $;
4764
4998
  const sp = span.span(row, error_start - line_start + 1, pos - error_start);
4765
4999
  this.$mol_fail(new this.$mol_error_syntax(`Wrong nodes separator`, str.substring(line_start, line_end), sp));
4766
5000
  }
5001
+ // read type
4767
5002
  var type_start = pos;
4768
5003
  while (str.length > pos &&
4769
5004
  str[pos] != '\\' &&
@@ -4778,10 +5013,12 @@ var $;
4778
5013
  parent_kids.push(next);
4779
5014
  parent = next;
4780
5015
  }
5016
+ // read one space if exists
4781
5017
  if (str.length > pos && str[pos] == ' ') {
4782
5018
  pos++;
4783
5019
  }
4784
5020
  }
5021
+ // read data
4785
5022
  if (str.length > pos && str[pos] == '\\') {
4786
5023
  var data_start = pos;
4787
5024
  while (str.length > pos && str[pos] != '\n') {
@@ -4792,6 +5029,7 @@ var $;
4792
5029
  parent_kids.push(next);
4793
5030
  parent = next;
4794
5031
  }
5032
+ // now must be end of text
4795
5033
  if (str.length === pos && stack.length > 0) {
4796
5034
  const sp = span.span(row, pos - line_start + 1, 1);
4797
5035
  this.$mol_fail(new this.$mol_error_syntax(`Unexpected EOF, LF required`, str.substring(line_start, str.length), sp));
@@ -4984,6 +5222,12 @@ var $;
4984
5222
  'return result without errors'() {
4985
5223
  $mol_assert_equal($mol_try(() => false), false);
4986
5224
  },
5225
+ //'return error if thrown'() {
5226
+ //
5227
+ // const error = new Error( '$mol_try test error' )
5228
+ // $mol_assert_equal( $mol_try( ()=> { throw error } ) , error )
5229
+ //
5230
+ //} ,
4987
5231
  });
4988
5232
  })($ || ($ = {}));
4989
5233