mol_tree2 1.0.1395 → 1.0.1397

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/web.mjs CHANGED
@@ -44,6 +44,11 @@ var $;
44
44
  var $;
45
45
  (function ($) {
46
46
  const instances = new WeakSet();
47
+ /**
48
+ * Proxy that delegates all to lazy returned target.
49
+ *
50
+ * $mol_delegate( Array.prototype , ()=> fetch_array() )
51
+ */
47
52
  function $mol_delegate(proto, target) {
48
53
  const proxy = new Proxy(proto, {
49
54
  get: (_, field) => {
@@ -147,7 +152,7 @@ var $;
147
152
  var $;
148
153
  (function ($) {
149
154
  function $mol_fail_hidden(error) {
150
- throw error;
155
+ throw error; /// Use 'Never Pause Here' breakpoint in DevTools or simply blackbox this script
151
156
  }
152
157
  $.$mol_fail_hidden = $mol_fail_hidden;
153
158
  })($ || ($ = {}));
@@ -239,6 +244,9 @@ var $;
239
244
  [Symbol.dispose]() {
240
245
  this.destructor();
241
246
  }
247
+ //[ Symbol.toPrimitive ]( hint: string ) {
248
+ // return hint === 'number' ? this.valueOf() : this.toString()
249
+ //}
242
250
  toString() {
243
251
  return this[Symbol.toStringTag] || this.constructor.name + '<>';
244
252
  }
@@ -250,6 +258,7 @@ var $;
250
258
  "use strict";
251
259
  var $;
252
260
  (function ($) {
261
+ /** Position in any resource. */
253
262
  class $mol_span extends $mol_object2 {
254
263
  uri;
255
264
  source;
@@ -265,13 +274,17 @@ var $;
265
274
  this.length = length;
266
275
  this[Symbol.toStringTag] = this.uri + ('#' + this.row + ':' + this.col + '/' + this.length);
267
276
  }
277
+ /** Span for begin of unknown resource */
268
278
  static unknown = $mol_span.begin('?');
279
+ /** Makes new span for begin of resource. */
269
280
  static begin(uri, source = '') {
270
281
  return new $mol_span(uri, source, 1, 1, 0);
271
282
  }
283
+ /** Makes new span for end of resource. */
272
284
  static end(uri, source) {
273
285
  return new $mol_span(uri, source, 1, source.length + 1, 0);
274
286
  }
287
+ /** Makes new span for entire resource. */
275
288
  static entire(uri, source) {
276
289
  return new $mol_span(uri, source, 1, 1, source.length);
277
290
  }
@@ -286,15 +299,19 @@ var $;
286
299
  length: this.length
287
300
  };
288
301
  }
302
+ /** Makes new error for this span. */
289
303
  error(message, Class = Error) {
290
304
  return new Class(`${message} (${this})`);
291
305
  }
306
+ /** Makes new span for same uri. */
292
307
  span(row, col, length) {
293
308
  return new $mol_span(this.uri, this.source, row, col, length);
294
309
  }
310
+ /** Makes new span after end of this. */
295
311
  after(length = 0) {
296
312
  return new $mol_span(this.uri, this.source, this.row, this.col + this.length, length);
297
313
  }
314
+ /** Makes new span between begin and end. */
298
315
  slice(begin, end = -1) {
299
316
  let len = this.length;
300
317
  if (begin < 0)
@@ -317,6 +334,7 @@ var $;
317
334
  "use strict";
318
335
  var $;
319
336
  (function ($) {
337
+ /** Syntax error with cordinates and source line snippet. */
320
338
  class $mol_error_syntax extends SyntaxError {
321
339
  reason;
322
340
  line;
@@ -335,6 +353,7 @@ var $;
335
353
  "use strict";
336
354
  var $;
337
355
  (function ($) {
356
+ /** Parses tree format from string. */
338
357
  function $mol_tree2_from_string(str, uri = '?') {
339
358
  const span = $mol_span.entire(uri, str);
340
359
  var root = $mol_tree2.list([], span);
@@ -344,6 +363,7 @@ var $;
344
363
  var indent = 0;
345
364
  var line_start = pos;
346
365
  row++;
366
+ // read indent
347
367
  while (str.length > pos && str[pos] == '\t') {
348
368
  indent++;
349
369
  pos++;
@@ -352,8 +372,10 @@ var $;
352
372
  min_indent = indent;
353
373
  }
354
374
  indent -= min_indent;
375
+ // invalid tab size
355
376
  if (indent < 0 || indent >= stack.length) {
356
377
  const sp = span.span(row, 1, pos - line_start);
378
+ // skip error line
357
379
  while (str.length > pos && str[pos] != '\n') {
358
380
  pos++;
359
381
  }
@@ -368,7 +390,9 @@ var $;
368
390
  }
369
391
  stack.length = indent + 1;
370
392
  var parent = stack[indent];
393
+ // parse types
371
394
  while (str.length > pos && str[pos] != '\\' && str[pos] != '\n') {
395
+ // type can not contain space and tab
372
396
  var error_start = pos;
373
397
  while (str.length > pos && (str[pos] == ' ' || str[pos] == '\t')) {
374
398
  pos++;
@@ -380,6 +404,7 @@ var $;
380
404
  const sp = span.span(row, error_start - line_start + 1, pos - error_start);
381
405
  this.$mol_fail(new this.$mol_error_syntax(`Wrong nodes separator`, str.substring(line_start, line_end), sp));
382
406
  }
407
+ // read type
383
408
  var type_start = pos;
384
409
  while (str.length > pos &&
385
410
  str[pos] != '\\' &&
@@ -394,10 +419,12 @@ var $;
394
419
  parent_kids.push(next);
395
420
  parent = next;
396
421
  }
422
+ // read one space if exists
397
423
  if (str.length > pos && str[pos] == ' ') {
398
424
  pos++;
399
425
  }
400
426
  }
427
+ // read data
401
428
  if (str.length > pos && str[pos] == '\\') {
402
429
  var data_start = pos;
403
430
  while (str.length > pos && str[pos] != '\n') {
@@ -408,6 +435,7 @@ var $;
408
435
  parent_kids.push(next);
409
436
  parent = next;
410
437
  }
438
+ // now must be end of text
411
439
  if (str.length === pos && stack.length > 0) {
412
440
  const sp = span.span(row, pos - line_start + 1, 1);
413
441
  this.$mol_fail(new this.$mol_error_syntax(`Unexpected EOF, LF required`, str.substring(line_start, str.length), sp));
@@ -424,6 +452,7 @@ var $;
424
452
  "use strict";
425
453
  var $;
426
454
  (function ($) {
455
+ /** Serializes tree to string in tree format. */
427
456
  function $mol_tree2_to_string(tree) {
428
457
  let output = [];
429
458
  function dump(tree, prefix = '') {
@@ -467,12 +496,25 @@ var $;
467
496
  "use strict";
468
497
  var $;
469
498
  (function ($) {
499
+ /**
500
+ * Abstract Syntax Tree with human readable serialization.
501
+ * Avoid direct instantiation. Use static factories instead.
502
+ * @see https://github.com/nin-jin/tree.d
503
+ */
470
504
  class $mol_tree2 extends Object {
471
505
  type;
472
506
  value;
473
507
  kids;
474
508
  span;
475
- constructor(type, value, kids, span) {
509
+ constructor(
510
+ /** Type of structural node, `value` should be empty */
511
+ type,
512
+ /** Content of data node, `type` should be empty */
513
+ value,
514
+ /** Child nodes */
515
+ kids,
516
+ /** Position in most far source resource */
517
+ span) {
476
518
  super();
477
519
  this.type = type;
478
520
  this.value = value;
@@ -480,12 +522,15 @@ var $;
480
522
  this.span = span;
481
523
  this[Symbol.toStringTag] = type || '\\' + value;
482
524
  }
525
+ /** Makes collection node. */
483
526
  static list(kids, span = $mol_span.unknown) {
484
527
  return new $mol_tree2('', '', kids, span);
485
528
  }
529
+ /** Makes new derived collection node. */
486
530
  list(kids) {
487
531
  return $mol_tree2.list(kids, this.span);
488
532
  }
533
+ /** Makes data node for any string. */
489
534
  static data(value, kids = [], span = $mol_span.unknown) {
490
535
  const chunks = value.split('\n');
491
536
  if (chunks.length > 1) {
@@ -499,21 +544,26 @@ var $;
499
544
  }
500
545
  return new $mol_tree2('', value, kids, span);
501
546
  }
547
+ /** Makes new derived data node. */
502
548
  data(value, kids = []) {
503
549
  return $mol_tree2.data(value, kids, this.span);
504
550
  }
551
+ /** Makes struct node. */
505
552
  static struct(type, kids = [], span = $mol_span.unknown) {
506
553
  if (/[ \n\t\\]/.test(type)) {
507
554
  $$.$mol_fail(span.error(`Wrong type ${JSON.stringify(type)}`));
508
555
  }
509
556
  return new $mol_tree2(type, '', kids, span);
510
557
  }
558
+ /** Makes new derived structural node. */
511
559
  struct(type, kids = []) {
512
560
  return $mol_tree2.struct(type, kids, this.span);
513
561
  }
562
+ /** Makes new derived node with different kids id defined. */
514
563
  clone(kids, span = this.span) {
515
564
  return new $mol_tree2(this.type, this.value, kids, span);
516
565
  }
566
+ /** Returns multiline text content. */
517
567
  text() {
518
568
  var values = [];
519
569
  for (var kid of this.kids) {
@@ -523,15 +573,20 @@ var $;
523
573
  }
524
574
  return this.value + values.join('\n');
525
575
  }
576
+ /** Parses tree format. */
577
+ /** @deprecated Use $mol_tree2_from_string */
526
578
  static fromString(str, uri = 'unknown') {
527
579
  return $$.$mol_tree2_from_string(str, uri);
528
580
  }
581
+ /** Serializes to tree format. */
529
582
  toString() {
530
583
  return $$.$mol_tree2_to_string(this);
531
584
  }
585
+ /** Makes new tree with node overrided by path. */
532
586
  insert(value, ...path) {
533
587
  return this.update($mol_maybe(value), ...path)[0];
534
588
  }
589
+ /** Makes new tree with node overrided by path. */
535
590
  update(value, ...path) {
536
591
  if (path.length === 0)
537
592
  return value;
@@ -564,6 +619,7 @@ var $;
564
619
  return [this.clone(kids)];
565
620
  }
566
621
  }
622
+ /** Query nodes by path. */
567
623
  select(...path) {
568
624
  let next = [this];
569
625
  for (const type of path) {
@@ -590,6 +646,7 @@ var $;
590
646
  }
591
647
  return this.list(next);
592
648
  }
649
+ /** Filter kids by path or value. */
593
650
  filter(path, value) {
594
651
  const sub = this.kids.filter(item => {
595
652
  var found = item.select(...path);
@@ -617,9 +674,11 @@ var $;
617
674
  $mol_fail_hidden(error);
618
675
  }
619
676
  }
677
+ /** Transform tree through context with transformers */
620
678
  hack(belt, context = {}) {
621
679
  return [].concat(...this.kids.map(child => child.hack_self(belt, context)));
622
680
  }
681
+ /** Makes Error with node coordinates. */
623
682
  error(message, Class = Error) {
624
683
  return this.span.error(`${message}\n${this.clone([])}`, Class);
625
684
  }
@@ -916,14 +975,18 @@ var $;
916
975
  ];
917
976
  },
918
977
  '': (input, belt) => {
978
+ // string
919
979
  if (!input.type)
920
980
  return [
921
981
  input.data(JSON.stringify(input.text())),
922
982
  ];
983
+ // variable
923
984
  if (/^[\w$#][\w0-9$]*$/i.test(input.type))
924
985
  return [
925
986
  input.data(input.type),
987
+ // ... input.hack( context ),
926
988
  ];
989
+ // number
927
990
  if ($mol_tree2_js_is_number(input.type))
928
991
  return [
929
992
  input.data(input.type)
@@ -1248,6 +1311,7 @@ var $;
1248
1311
  "use strict";
1249
1312
  var $;
1250
1313
  (function ($) {
1314
+ /** Makes JSON from json.tree. */
1251
1315
  function $mol_tree2_to_json(tree) {
1252
1316
  if (!tree.type) {
1253
1317
  if (tree.kids.every(kid => !kid.type))
package/web.test.js CHANGED
@@ -224,6 +224,12 @@ var $;
224
224
  createDocumentFragment: () => $mol_dom_context.document.createDocumentFragment(),
225
225
  };
226
226
  $.$mol_jsx_frag = '';
227
+ /**
228
+ * JSX adapter that makes DOM tree.
229
+ * Generates global unique ids for every DOM-element by components tree with ids.
230
+ * Ensures all local ids are unique.
231
+ * Can reuse an existing nodes by GUIDs when used inside [`mol_jsx_attach`](https://github.com/hyoo-ru/mam_mol/tree/master/jsx/attach).
232
+ */
227
233
  function $mol_jsx(Elem, props, ...childNodes) {
228
234
  const id = props && props.id || '';
229
235
  const guid = id ? $.$mol_jsx_prefix ? $.$mol_jsx_prefix + '/' + id : id : $.$mol_jsx_prefix;
@@ -334,6 +340,8 @@ var $;
334
340
 
335
341
  ;
336
342
  "use strict";
343
+ /** @jsx $mol_jsx */
344
+ /** @jsxFrag $mol_jsx_frag */
337
345
  var $;
338
346
  (function ($) {
339
347
  $mol_test({
@@ -439,6 +447,7 @@ var $;
439
447
  "use strict";
440
448
  var $;
441
449
  (function ($) {
450
+ /** Generates unique identifier. */
442
451
  function $mol_guid(length = 8, exists = () => false) {
443
452
  for (;;) {
444
453
  let id = Math.random().toString(36).substring(2, length + 2).toUpperCase();
@@ -454,6 +463,7 @@ var $;
454
463
  "use strict";
455
464
  var $;
456
465
  (function ($) {
466
+ /** Lazy computed lists with native Array interface. $mol_range2_array is mutable but all derived ranges are immutable. */
457
467
  function $mol_range2(item = index => index, size = () => Number.POSITIVE_INFINITY) {
458
468
  const source = typeof item === 'function' ? new $mol_range2_array() : item;
459
469
  if (typeof item !== 'function') {
@@ -502,6 +512,7 @@ var $;
502
512
  }
503
513
  $.$mol_range2 = $mol_range2;
504
514
  class $mol_range2_array extends Array {
515
+ // Lazy
505
516
  concat(...tail) {
506
517
  if (tail.length === 0)
507
518
  return this;
@@ -513,6 +524,7 @@ var $;
513
524
  }
514
525
  return $mol_range2(index => index < this.length ? this[index] : tail[0][index - this.length], () => this.length + tail[0].length);
515
526
  }
527
+ // Lazy
516
528
  filter(check, context) {
517
529
  const filtered = [];
518
530
  let cursor = -1;
@@ -525,13 +537,16 @@ var $;
525
537
  return filtered[index];
526
538
  }, () => cursor < this.length ? Number.POSITIVE_INFINITY : filtered.length);
527
539
  }
540
+ // Diligent
528
541
  forEach(proceed, context) {
529
542
  for (let [key, value] of this.entries())
530
543
  proceed.call(context, value, key, this);
531
544
  }
545
+ // Lazy
532
546
  map(proceed, context) {
533
547
  return $mol_range2(index => proceed.call(context, this[index], index, this), () => this.length);
534
548
  }
549
+ // Diligent
535
550
  reduce(merge, result) {
536
551
  let index = 0;
537
552
  if (arguments.length === 1) {
@@ -542,12 +557,15 @@ var $;
542
557
  }
543
558
  return result;
544
559
  }
560
+ // Lazy
545
561
  toReversed() {
546
562
  return $mol_range2(index => this[this.length - 1 - index], () => this.length);
547
563
  }
564
+ // Lazy
548
565
  slice(from = 0, to = this.length) {
549
566
  return $mol_range2(index => this[from + index], () => Math.min(to, this.length) - from);
550
567
  }
568
+ // Lazy
551
569
  some(check, context) {
552
570
  for (let index = 0; index < this.length; ++index) {
553
571
  if (check.call(context, this[index], index, this))
@@ -743,6 +761,10 @@ var $;
743
761
  var $;
744
762
  (function ($) {
745
763
  $.$mol_compare_deep_cache = new WeakMap();
764
+ /**
765
+ * Deeply compares two values. Returns true if equal.
766
+ * Define `Symbol.toPrimitive` to customize.
767
+ */
746
768
  function $mol_compare_deep(left, right) {
747
769
  if (Object.is(left, right))
748
770
  return true;
@@ -880,6 +902,7 @@ var $;
880
902
 
881
903
  ;
882
904
  "use strict";
905
+ /** @jsx $mol_jsx */
883
906
  var $;
884
907
  (function ($) {
885
908
  $mol_test({
@@ -941,6 +964,7 @@ var $;
941
964
  const obj3_copy = { test: 3, obj2: obj2_copy };
942
965
  obj1.obj3 = obj3;
943
966
  obj1_copy.obj3 = obj3_copy;
967
+ // warmup cache
944
968
  $mol_assert_not($mol_compare_deep(obj1, {}));
945
969
  $mol_assert_not($mol_compare_deep(obj2, {}));
946
970
  $mol_assert_not($mol_compare_deep(obj3, {}));
@@ -1010,6 +1034,7 @@ var $;
1010
1034
  "use strict";
1011
1035
  var $;
1012
1036
  (function ($) {
1037
+ // https://docs.google.com/document/d/1FTascZXT9cxfetuPRT2eXPQKXui4nWFivUnS_335T3U/preview#
1013
1038
  $['devtoolsFormatters'] ||= [];
1014
1039
  function $mol_dev_format_register(config) {
1015
1040
  $['devtoolsFormatters'].push(config);
@@ -1061,6 +1086,7 @@ var $;
1061
1086
  return false;
1062
1087
  if (!val)
1063
1088
  return false;
1089
+ // if( Error.isError( val ) ) true
1064
1090
  if (val[$.$mol_dev_format_body])
1065
1091
  return true;
1066
1092
  return false;
@@ -1078,12 +1104,16 @@ var $;
1078
1104
  return $.$mol_dev_format_accent($mol_dev_format_native(val), '💨', $mol_dev_format_native(error), '');
1079
1105
  }
1080
1106
  }
1107
+ // if( Error.isError( val ) ) {
1108
+ // return $mol_dev_format_native( val )
1109
+ // }
1081
1110
  return null;
1082
1111
  },
1083
1112
  });
1084
1113
  function $mol_dev_format_native(obj) {
1085
1114
  if (typeof obj === 'undefined')
1086
1115
  return $.$mol_dev_format_shade('undefined');
1116
+ // if( ![ 'object', 'function', 'symbol' ].includes( typeof obj ) ) return obj
1087
1117
  return [
1088
1118
  'object',
1089
1119
  {
@@ -1141,6 +1171,9 @@ var $;
1141
1171
  'margin-left': '13px'
1142
1172
  });
1143
1173
  class Stack extends Array {
1174
+ // [ Symbol.toPrimitive ]() {
1175
+ // return this.toString()
1176
+ // }
1144
1177
  toString() {
1145
1178
  return this.join('\n');
1146
1179
  }
@@ -1163,6 +1196,7 @@ var $;
1163
1196
  this.method = call.getMethodName() ?? '';
1164
1197
  if (this.method === this.function)
1165
1198
  this.method = '';
1199
+ // const func = c.getFunction()
1166
1200
  this.pos = [call.getEnclosingLineNumber() ?? 0, call.getEnclosingColumnNumber() ?? 0];
1167
1201
  this.eval = call.getEvalOrigin() ?? '';
1168
1202
  this.source = call.getScriptNameOrSourceURL() ?? '';
@@ -1209,18 +1243,34 @@ var $;
1209
1243
  "use strict";
1210
1244
  var $;
1211
1245
  (function ($) {
1246
+ /**
1247
+ * Argument must be Truthy
1248
+ * @deprecated use $mol_assert_equal instead
1249
+ */
1212
1250
  function $mol_assert_ok(value) {
1213
1251
  if (value)
1214
1252
  return;
1215
1253
  $mol_fail(new Error(`${value} ≠ true`));
1216
1254
  }
1217
1255
  $.$mol_assert_ok = $mol_assert_ok;
1256
+ /**
1257
+ * Argument must be Falsy
1258
+ * @deprecated use $mol_assert_equal instead
1259
+ */
1218
1260
  function $mol_assert_not(value) {
1219
1261
  if (!value)
1220
1262
  return;
1221
1263
  $mol_fail(new Error(`${value} ≠ false`));
1222
1264
  }
1223
1265
  $.$mol_assert_not = $mol_assert_not;
1266
+ /**
1267
+ * Handler must throw an error.
1268
+ * @example
1269
+ * $mol_assert_fail( ()=>{ throw new Error( 'Parse error' ) } ) // Passes because throws error
1270
+ * $mol_assert_fail( ()=>{ throw new Error( 'Parse error' ) } , 'Parse error' ) // Passes because throws right message
1271
+ * $mol_assert_fail( ()=>{ throw new Error( 'Parse error' ) } , Error ) // Passes because throws right class
1272
+ * @see https://mol.hyoo.ru/#!section=docs/=9q9dv3_fgxjsf
1273
+ */
1224
1274
  function $mol_assert_fail(handler, ErrorRight) {
1225
1275
  const fail = $.$mol_fail;
1226
1276
  try {
@@ -1243,10 +1293,18 @@ var $;
1243
1293
  $mol_fail(new Error('Not failed', { cause: { expect: ErrorRight } }));
1244
1294
  }
1245
1295
  $.$mol_assert_fail = $mol_assert_fail;
1296
+ /** @deprecated Use $mol_assert_equal */
1246
1297
  function $mol_assert_like(...args) {
1247
1298
  $mol_assert_equal(...args);
1248
1299
  }
1249
1300
  $.$mol_assert_like = $mol_assert_like;
1301
+ /**
1302
+ * All arguments must not be structural equal to each other.
1303
+ * @example
1304
+ * $mol_assert_unique( 1 , 2 , 3 ) // Passes
1305
+ * $mol_assert_unique( 1 , 1 , 2 ) // Fails because 1 === 1
1306
+ * @see https://mol.hyoo.ru/#!section=docs/=9q9dv3_fgxjsf
1307
+ */
1250
1308
  function $mol_assert_unique(...args) {
1251
1309
  for (let i = 0; i < args.length; ++i) {
1252
1310
  for (let j = 0; j < args.length; ++j) {
@@ -1259,6 +1317,13 @@ var $;
1259
1317
  }
1260
1318
  }
1261
1319
  $.$mol_assert_unique = $mol_assert_unique;
1320
+ /**
1321
+ * All arguments must be structural equal each other.
1322
+ * @example
1323
+ * $mol_assert_like( [1] , [1] , [1] ) // Passes
1324
+ * $mol_assert_like( [1] , [1] , [2] ) // Fails because 1 !== 2
1325
+ * @see https://mol.hyoo.ru/#!section=docs/=9q9dv3_fgxjsf
1326
+ */
1262
1327
  function $mol_assert_equal(...args) {
1263
1328
  for (let i = 1; i < args.length; ++i) {
1264
1329
  if ($mol_compare_deep(args[0], args[i]))
@@ -1311,6 +1376,7 @@ var $;
1311
1376
  "use strict";
1312
1377
  var $;
1313
1378
  (function ($) {
1379
+ /** Log begin of collapsed group only when some logged inside, returns func to close group */
1314
1380
  function $mol_log3_area_lazy(event) {
1315
1381
  const self = this.$;
1316
1382
  const stack = self.$mol_log3_stack;
@@ -1831,6 +1897,11 @@ var $;
1831
1897
  "use strict";
1832
1898
  var $;
1833
1899
  (function ($) {
1900
+ /**
1901
+ * Combines list of unary functions/classes to one function.
1902
+ *
1903
+ * const reparse = $mol_data_pipe( JSON.stringify , JSON.parse )
1904
+ **/
1834
1905
  function $mol_data_pipe(...funcs) {
1835
1906
  return $mol_data_setup(function (input) {
1836
1907
  let value = input;
@@ -1847,6 +1918,14 @@ var $;
1847
1918
  var $;
1848
1919
  (function ($) {
1849
1920
  $mol_test({
1921
+ // @todo enable on strict
1922
+ // 'no functions'() {
1923
+ // const stringify = $mol_data_pipe()
1924
+ // type Type = $mol_type_assert<
1925
+ // typeof stringify,
1926
+ // ( input : never )=> never
1927
+ // >
1928
+ // },
1850
1929
  'single function'() {
1851
1930
  const stringify = $mol_data_pipe((input) => input.toString());
1852
1931
  $mol_assert_equal(stringify(5), '5');