mam 1.11.921 → 1.11.923

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.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
  }
@@ -270,6 +278,7 @@ var $;
270
278
  "use strict";
271
279
  var $;
272
280
  (function ($) {
281
+ /** Generates unique identifier. */
273
282
  function $mol_guid(length = 8, exists = () => false) {
274
283
  for (;;) {
275
284
  let id = Math.random().toString(36).substring(2, length + 2).toUpperCase();
@@ -285,11 +294,16 @@ var $;
285
294
  "use strict";
286
295
  var $;
287
296
  (function ($) {
297
+ /** Special status statuses. */
288
298
  let $mol_wire_cursor;
289
299
  (function ($mol_wire_cursor) {
300
+ /** Update required. */
290
301
  $mol_wire_cursor[$mol_wire_cursor["stale"] = -1] = "stale";
302
+ /** Some of (transitive) pub update required. */
291
303
  $mol_wire_cursor[$mol_wire_cursor["doubt"] = -2] = "doubt";
304
+ /** Actual state but may be dropped. */
292
305
  $mol_wire_cursor[$mol_wire_cursor["fresh"] = -3] = "fresh";
306
+ /** State will never be changed. */
293
307
  $mol_wire_cursor[$mol_wire_cursor["final"] = -4] = "final";
294
308
  })($mol_wire_cursor = $.$mol_wire_cursor || ($.$mol_wire_cursor = {}));
295
309
  })($ || ($ = {}));
@@ -298,6 +312,9 @@ var $;
298
312
  "use strict";
299
313
  var $;
300
314
  (function ($) {
315
+ /**
316
+ * Collects subscribers in compact array. 28B
317
+ */
301
318
  class $mol_wire_pub extends Object {
302
319
  constructor(id = `$mol_wire_pub:${$mol_guid()}`) {
303
320
  super();
@@ -305,10 +322,17 @@ var $;
305
322
  }
306
323
  [Symbol.toStringTag];
307
324
  data = [];
325
+ // Derived objects should be Arrays.
308
326
  static get [Symbol.species]() {
309
327
  return Array;
310
328
  }
311
- sub_from = 0;
329
+ /**
330
+ * Index of first subscriber.
331
+ */
332
+ sub_from = 0; // 4B
333
+ /**
334
+ * All current subscribers.
335
+ */
312
336
  get sub_list() {
313
337
  const res = [];
314
338
  for (let i = this.sub_from; i < this.data.length; i += 2) {
@@ -316,14 +340,23 @@ var $;
316
340
  }
317
341
  return res;
318
342
  }
343
+ /**
344
+ * Has any subscribers or not.
345
+ */
319
346
  get sub_empty() {
320
347
  return this.sub_from === this.data.length;
321
348
  }
349
+ /**
350
+ * Subscribe subscriber to this publisher events and return position of subscriber that required to unsubscribe.
351
+ */
322
352
  sub_on(sub, pub_pos) {
323
353
  const pos = this.data.length;
324
354
  this.data.push(sub, pub_pos);
325
355
  return pos;
326
356
  }
357
+ /**
358
+ * Unsubscribe subscriber from this publisher events by subscriber position provided by `on(pub)`.
359
+ */
327
360
  sub_off(sub_pos) {
328
361
  if (!(sub_pos < this.data.length)) {
329
362
  $mol_fail(new Error(`Wrong pos ${sub_pos}`));
@@ -336,21 +369,39 @@ var $;
336
369
  if (end === this.sub_from)
337
370
  this.reap();
338
371
  }
372
+ /**
373
+ * Called when last sub was unsubscribed.
374
+ **/
339
375
  reap() { }
376
+ /**
377
+ * Autowire this publisher with current subscriber.
378
+ **/
340
379
  promote() {
341
380
  $mol_wire_auto()?.track_next(this);
342
381
  }
382
+ /**
383
+ * Enforce actualization. Should not throw errors.
384
+ */
343
385
  fresh() { }
386
+ /**
387
+ * Allow to put data to caches in the subtree.
388
+ */
344
389
  complete() { }
345
390
  get incompleted() {
346
391
  return false;
347
392
  }
393
+ /**
394
+ * Notify subscribers about self changes.
395
+ */
348
396
  emit(quant = $mol_wire_cursor.stale) {
349
397
  for (let i = this.sub_from; i < this.data.length; i += 2) {
350
398
  ;
351
399
  this.data[i].absorb(quant, this.data[i + 1]);
352
400
  }
353
401
  }
402
+ /**
403
+ * Moves peer from one position to another. Doesn't clear data at old position!
404
+ */
354
405
  peer_move(from_pos, to_pos) {
355
406
  const peer = this.data[from_pos];
356
407
  const self_pos = this.data[from_pos + 1];
@@ -358,6 +409,9 @@ var $;
358
409
  this.data[to_pos + 1] = self_pos;
359
410
  peer.peer_repos(self_pos, to_pos);
360
411
  }
412
+ /**
413
+ * Updates self position in the peer.
414
+ */
361
415
  peer_repos(peer_pos, self_pos) {
362
416
  this.data[peer_pos + 1] = self_pos;
363
417
  }
@@ -373,10 +427,16 @@ var $;
373
427
  var $;
374
428
  (function ($) {
375
429
  $.$mol_wire_auto_sub = null;
430
+ /**
431
+ * When fulfilled, all publishers are promoted to this subscriber on access to its.
432
+ */
376
433
  function $mol_wire_auto(next = $.$mol_wire_auto_sub) {
377
434
  return $.$mol_wire_auto_sub = next;
378
435
  }
379
436
  $.$mol_wire_auto = $mol_wire_auto;
437
+ /**
438
+ * Affection queue. Used to prevent accidental stack overflow on emit.
439
+ */
380
440
  $.$mol_wire_affected = [];
381
441
  })($ || ($ = {}));
382
442
 
@@ -384,6 +444,7 @@ var $;
384
444
  "use strict";
385
445
  var $;
386
446
  (function ($) {
447
+ // https://docs.google.com/document/d/1FTascZXT9cxfetuPRT2eXPQKXui4nWFivUnS_335T3U/preview#
387
448
  $['devtoolsFormatters'] ||= [];
388
449
  function $mol_dev_format_register(config) {
389
450
  $['devtoolsFormatters'].push(config);
@@ -435,6 +496,7 @@ var $;
435
496
  return false;
436
497
  if (!val)
437
498
  return false;
499
+ // if( Error.isError( val ) ) true
438
500
  if (val[$.$mol_dev_format_body])
439
501
  return true;
440
502
  return false;
@@ -452,12 +514,16 @@ var $;
452
514
  return $.$mol_dev_format_accent($mol_dev_format_native(val), '💨', $mol_dev_format_native(error), '');
453
515
  }
454
516
  }
517
+ // if( Error.isError( val ) ) {
518
+ // return $mol_dev_format_native( val )
519
+ // }
455
520
  return null;
456
521
  },
457
522
  });
458
523
  function $mol_dev_format_native(obj) {
459
524
  if (typeof obj === 'undefined')
460
525
  return $.$mol_dev_format_shade('undefined');
526
+ // if( ![ 'object', 'function', 'symbol' ].includes( typeof obj ) ) return obj
461
527
  return [
462
528
  'object',
463
529
  {
@@ -515,6 +581,9 @@ var $;
515
581
  'margin-left': '13px'
516
582
  });
517
583
  class Stack extends Array {
584
+ // [ Symbol.toPrimitive ]() {
585
+ // return this.toString()
586
+ // }
518
587
  toString() {
519
588
  return this.join('\n');
520
589
  }
@@ -537,6 +606,7 @@ var $;
537
606
  this.method = call.getMethodName() ?? '';
538
607
  if (this.method === this.function)
539
608
  this.method = '';
609
+ // const func = c.getFunction()
540
610
  this.pos = [call.getEnclosingLineNumber() ?? 0, call.getEnclosingColumnNumber() ?? 0];
541
611
  this.eval = call.getEvalOrigin() ?? '';
542
612
  this.source = call.getScriptNameOrSourceURL() ?? '';
@@ -583,9 +653,16 @@ var $;
583
653
  "use strict";
584
654
  var $;
585
655
  (function ($) {
656
+ /**
657
+ * Publisher that can auto collect other publishers. 32B
658
+ *
659
+ * P1 P2 P3 P4 S1 S2 S3
660
+ * ^ ^
661
+ * pubs_from subs_from
662
+ */
586
663
  class $mol_wire_pub_sub extends $mol_wire_pub {
587
- pub_from = 0;
588
- cursor = $mol_wire_cursor.stale;
664
+ pub_from = 0; // 4B
665
+ cursor = $mol_wire_cursor.stale; // 4B
589
666
  get temp() {
590
667
  return false;
591
668
  }
@@ -703,10 +780,27 @@ var $;
703
780
  return;
704
781
  this.cursor = quant;
705
782
  this.emit($mol_wire_cursor.doubt);
783
+ // if( pos >= 0 && pos < this.sub_from - 2 ) {
784
+ // const pub = this.data[ pos ] as $mol_wire_pub
785
+ // if( pub instanceof $mol_wire_task ) return
786
+ // for(
787
+ // let cursor = this.pub_from;
788
+ // cursor < this.sub_from;
789
+ // cursor += 2
790
+ // ) {
791
+ // const pub = this.data[ cursor ] as $mol_wire_pub
792
+ // if( pub instanceof $mol_wire_task ) {
793
+ // pub.destructor()
794
+ // }
795
+ // }
796
+ // }
706
797
  }
707
798
  [$mol_dev_format_head]() {
708
799
  return $mol_dev_format_native(this);
709
800
  }
801
+ /**
802
+ * Is subscribed to any publisher or not.
803
+ */
710
804
  get pub_empty() {
711
805
  return this.sub_from === this.pub_from;
712
806
  }
@@ -762,6 +856,13 @@ var $;
762
856
  var $;
763
857
  (function ($) {
764
858
  const wrappers = new WeakMap();
859
+ /**
860
+ * Suspendable task with support both sync/async api.
861
+ *
862
+ * A1 A2 A3 A4 P1 P2 P3 P4 S1 S2 S3
863
+ * ^ ^ ^
864
+ * args_from pubs_from subs_from
865
+ **/
765
866
  class $mol_wire_fiber extends $mol_wire_pub_sub {
766
867
  task;
767
868
  host;
@@ -782,6 +883,7 @@ var $;
782
883
  });
783
884
  }
784
885
  static sync() {
886
+ // Sync whole fiber graph
785
887
  while (this.planning.size) {
786
888
  for (const fiber of this.planning) {
787
889
  this.planning.delete(fiber);
@@ -792,6 +894,7 @@ var $;
792
894
  fiber.fresh();
793
895
  }
794
896
  }
897
+ // Collect garbage
795
898
  while (this.reaping.size) {
796
899
  const fibers = this.reaping;
797
900
  this.reaping = new Set;
@@ -943,6 +1046,10 @@ var $;
943
1046
  this.cursor = $mol_wire_cursor.stale;
944
1047
  this.fresh();
945
1048
  }
1049
+ /**
1050
+ * Synchronous execution. Throws Promise when waits async task (SuspenseAPI provider).
1051
+ * Should be called inside SuspenseAPI consumer (ie fiber).
1052
+ */
946
1053
  sync() {
947
1054
  if (!$mol_wire_fiber.warm) {
948
1055
  return this.result();
@@ -957,6 +1064,10 @@ var $;
957
1064
  }
958
1065
  return this.cache;
959
1066
  }
1067
+ /**
1068
+ * Asynchronous execution.
1069
+ * It's SuspenseAPI consumer. So SuspenseAPI providers can be called inside.
1070
+ */
960
1071
  async async_raw() {
961
1072
  while (true) {
962
1073
  this.fresh();
@@ -969,6 +1080,7 @@ var $;
969
1080
  if (!$mol_promise_like(this.cache))
970
1081
  return this.cache;
971
1082
  if (this.cursor === $mol_wire_cursor.final) {
1083
+ // never ends on destructed fiber
972
1084
  await new Promise(() => { });
973
1085
  }
974
1086
  }
@@ -1016,6 +1128,10 @@ var $;
1016
1128
  var $;
1017
1129
  (function ($) {
1018
1130
  $.$mol_compare_deep_cache = new WeakMap();
1131
+ /**
1132
+ * Deeply compares two values. Returns true if equal.
1133
+ * Define `Symbol.toPrimitive` to customize.
1134
+ */
1019
1135
  function $mol_compare_deep(left, right) {
1020
1136
  if (Object.is(left, right))
1021
1137
  return true;
@@ -1155,6 +1271,7 @@ var $;
1155
1271
  "use strict";
1156
1272
  var $;
1157
1273
  (function ($) {
1274
+ /** Log begin of collapsed group only when some logged inside, returns func to close group */
1158
1275
  function $mol_log3_area_lazy(event) {
1159
1276
  const self = this.$;
1160
1277
  const stack = self.$mol_log3_stack;
@@ -1179,6 +1296,7 @@ var $;
1179
1296
  "use strict";
1180
1297
  var $;
1181
1298
  (function ($) {
1299
+ /** Position in any resource. */
1182
1300
  class $mol_span extends $mol_object2 {
1183
1301
  uri;
1184
1302
  source;
@@ -1194,13 +1312,17 @@ var $;
1194
1312
  this.length = length;
1195
1313
  this[Symbol.toStringTag] = this.uri + ('#' + this.row + ':' + this.col + '/' + this.length);
1196
1314
  }
1315
+ /** Span for begin of unknown resource */
1197
1316
  static unknown = $mol_span.begin('?');
1317
+ /** Makes new span for begin of resource. */
1198
1318
  static begin(uri, source = '') {
1199
1319
  return new $mol_span(uri, source, 1, 1, 0);
1200
1320
  }
1321
+ /** Makes new span for end of resource. */
1201
1322
  static end(uri, source) {
1202
1323
  return new $mol_span(uri, source, 1, source.length + 1, 0);
1203
1324
  }
1325
+ /** Makes new span for entire resource. */
1204
1326
  static entire(uri, source) {
1205
1327
  return new $mol_span(uri, source, 1, 1, source.length);
1206
1328
  }
@@ -1215,15 +1337,19 @@ var $;
1215
1337
  length: this.length
1216
1338
  };
1217
1339
  }
1340
+ /** Makes new error for this span. */
1218
1341
  error(message, Class = Error) {
1219
1342
  return new Class(`${message} (${this})`);
1220
1343
  }
1344
+ /** Makes new span for same uri. */
1221
1345
  span(row, col, length) {
1222
1346
  return new $mol_span(this.uri, this.source, row, col, length);
1223
1347
  }
1348
+ /** Makes new span after end of this. */
1224
1349
  after(length = 0) {
1225
1350
  return new $mol_span(this.uri, this.source, this.row, this.col + this.length, length);
1226
1351
  }
1352
+ /** Makes new span between begin and end. */
1227
1353
  slice(begin, end = -1) {
1228
1354
  let len = this.length;
1229
1355
  if (begin < 0)
@@ -1246,6 +1372,7 @@ var $;
1246
1372
  "use strict";
1247
1373
  var $;
1248
1374
  (function ($) {
1375
+ /** Serializes tree to string in tree format. */
1249
1376
  function $mol_tree2_to_string(tree) {
1250
1377
  let output = [];
1251
1378
  function dump(tree, prefix = '') {
@@ -1289,12 +1416,25 @@ var $;
1289
1416
  "use strict";
1290
1417
  var $;
1291
1418
  (function ($) {
1419
+ /**
1420
+ * Abstract Syntax Tree with human readable serialization.
1421
+ * Avoid direct instantiation. Use static factories instead.
1422
+ * @see https://github.com/nin-jin/tree.d
1423
+ */
1292
1424
  class $mol_tree2 extends Object {
1293
1425
  type;
1294
1426
  value;
1295
1427
  kids;
1296
1428
  span;
1297
- constructor(type, value, kids, span) {
1429
+ constructor(
1430
+ /** Type of structural node, `value` should be empty */
1431
+ type,
1432
+ /** Content of data node, `type` should be empty */
1433
+ value,
1434
+ /** Child nodes */
1435
+ kids,
1436
+ /** Position in most far source resource */
1437
+ span) {
1298
1438
  super();
1299
1439
  this.type = type;
1300
1440
  this.value = value;
@@ -1302,12 +1442,15 @@ var $;
1302
1442
  this.span = span;
1303
1443
  this[Symbol.toStringTag] = type || '\\' + value;
1304
1444
  }
1445
+ /** Makes collection node. */
1305
1446
  static list(kids, span = $mol_span.unknown) {
1306
1447
  return new $mol_tree2('', '', kids, span);
1307
1448
  }
1449
+ /** Makes new derived collection node. */
1308
1450
  list(kids) {
1309
1451
  return $mol_tree2.list(kids, this.span);
1310
1452
  }
1453
+ /** Makes data node for any string. */
1311
1454
  static data(value, kids = [], span = $mol_span.unknown) {
1312
1455
  const chunks = value.split('\n');
1313
1456
  if (chunks.length > 1) {
@@ -1321,21 +1464,26 @@ var $;
1321
1464
  }
1322
1465
  return new $mol_tree2('', value, kids, span);
1323
1466
  }
1467
+ /** Makes new derived data node. */
1324
1468
  data(value, kids = []) {
1325
1469
  return $mol_tree2.data(value, kids, this.span);
1326
1470
  }
1471
+ /** Makes struct node. */
1327
1472
  static struct(type, kids = [], span = $mol_span.unknown) {
1328
1473
  if (/[ \n\t\\]/.test(type)) {
1329
1474
  $$.$mol_fail(span.error(`Wrong type ${JSON.stringify(type)}`));
1330
1475
  }
1331
1476
  return new $mol_tree2(type, '', kids, span);
1332
1477
  }
1478
+ /** Makes new derived structural node. */
1333
1479
  struct(type, kids = []) {
1334
1480
  return $mol_tree2.struct(type, kids, this.span);
1335
1481
  }
1482
+ /** Makes new derived node with different kids id defined. */
1336
1483
  clone(kids, span = this.span) {
1337
1484
  return new $mol_tree2(this.type, this.value, kids, span);
1338
1485
  }
1486
+ /** Returns multiline text content. */
1339
1487
  text() {
1340
1488
  var values = [];
1341
1489
  for (var kid of this.kids) {
@@ -1345,15 +1493,20 @@ var $;
1345
1493
  }
1346
1494
  return this.value + values.join('\n');
1347
1495
  }
1496
+ /** Parses tree format. */
1497
+ /** @deprecated Use $mol_tree2_from_string */
1348
1498
  static fromString(str, uri = 'unknown') {
1349
1499
  return $$.$mol_tree2_from_string(str, uri);
1350
1500
  }
1501
+ /** Serializes to tree format. */
1351
1502
  toString() {
1352
1503
  return $$.$mol_tree2_to_string(this);
1353
1504
  }
1505
+ /** Makes new tree with node overrided by path. */
1354
1506
  insert(value, ...path) {
1355
1507
  return this.update($mol_maybe(value), ...path)[0];
1356
1508
  }
1509
+ /** Makes new tree with node overrided by path. */
1357
1510
  update(value, ...path) {
1358
1511
  if (path.length === 0)
1359
1512
  return value;
@@ -1386,6 +1539,7 @@ var $;
1386
1539
  return [this.clone(kids)];
1387
1540
  }
1388
1541
  }
1542
+ /** Query nodes by path. */
1389
1543
  select(...path) {
1390
1544
  let next = [this];
1391
1545
  for (const type of path) {
@@ -1412,6 +1566,7 @@ var $;
1412
1566
  }
1413
1567
  return this.list(next);
1414
1568
  }
1569
+ /** Filter kids by path or value. */
1415
1570
  filter(path, value) {
1416
1571
  const sub = this.kids.filter(item => {
1417
1572
  var found = item.select(...path);
@@ -1439,9 +1594,11 @@ var $;
1439
1594
  $mol_fail_hidden(error);
1440
1595
  }
1441
1596
  }
1597
+ /** Transform tree through context with transformers */
1442
1598
  hack(belt, context = {}) {
1443
1599
  return [].concat(...this.kids.map(child => child.hack_self(belt, context)));
1444
1600
  }
1601
+ /** Makes Error with node coordinates. */
1445
1602
  error(message, Class = Error) {
1446
1603
  return this.span.error(`${message}\n${this.clone([])}`, Class);
1447
1604
  }
@@ -1459,6 +1616,7 @@ var $;
1459
1616
  "use strict";
1460
1617
  var $;
1461
1618
  (function ($) {
1619
+ /** Syntax error with cordinates and source line snippet. */
1462
1620
  class $mol_error_syntax extends SyntaxError {
1463
1621
  reason;
1464
1622
  line;
@@ -1477,6 +1635,7 @@ var $;
1477
1635
  "use strict";
1478
1636
  var $;
1479
1637
  (function ($) {
1638
+ /** Parses tree format from string. */
1480
1639
  function $mol_tree2_from_string(str, uri = '?') {
1481
1640
  const span = $mol_span.entire(uri, str);
1482
1641
  var root = $mol_tree2.list([], span);
@@ -1486,6 +1645,7 @@ var $;
1486
1645
  var indent = 0;
1487
1646
  var line_start = pos;
1488
1647
  row++;
1648
+ // read indent
1489
1649
  while (str.length > pos && str[pos] == '\t') {
1490
1650
  indent++;
1491
1651
  pos++;
@@ -1494,8 +1654,10 @@ var $;
1494
1654
  min_indent = indent;
1495
1655
  }
1496
1656
  indent -= min_indent;
1657
+ // invalid tab size
1497
1658
  if (indent < 0 || indent >= stack.length) {
1498
1659
  const sp = span.span(row, 1, pos - line_start);
1660
+ // skip error line
1499
1661
  while (str.length > pos && str[pos] != '\n') {
1500
1662
  pos++;
1501
1663
  }
@@ -1510,7 +1672,9 @@ var $;
1510
1672
  }
1511
1673
  stack.length = indent + 1;
1512
1674
  var parent = stack[indent];
1675
+ // parse types
1513
1676
  while (str.length > pos && str[pos] != '\\' && str[pos] != '\n') {
1677
+ // type can not contain space and tab
1514
1678
  var error_start = pos;
1515
1679
  while (str.length > pos && (str[pos] == ' ' || str[pos] == '\t')) {
1516
1680
  pos++;
@@ -1522,6 +1686,7 @@ var $;
1522
1686
  const sp = span.span(row, error_start - line_start + 1, pos - error_start);
1523
1687
  this.$mol_fail(new this.$mol_error_syntax(`Wrong nodes separator`, str.substring(line_start, line_end), sp));
1524
1688
  }
1689
+ // read type
1525
1690
  var type_start = pos;
1526
1691
  while (str.length > pos &&
1527
1692
  str[pos] != '\\' &&
@@ -1536,10 +1701,12 @@ var $;
1536
1701
  parent_kids.push(next);
1537
1702
  parent = next;
1538
1703
  }
1704
+ // read one space if exists
1539
1705
  if (str.length > pos && str[pos] == ' ') {
1540
1706
  pos++;
1541
1707
  }
1542
1708
  }
1709
+ // read data
1543
1710
  if (str.length > pos && str[pos] == '\\') {
1544
1711
  var data_start = pos;
1545
1712
  while (str.length > pos && str[pos] != '\n') {
@@ -1550,6 +1717,7 @@ var $;
1550
1717
  parent_kids.push(next);
1551
1718
  parent = next;
1552
1719
  }
1720
+ // now must be end of text
1553
1721
  if (str.length === pos && stack.length > 0) {
1554
1722
  const sp = span.span(row, pos - line_start + 1, 1);
1555
1723
  this.$mol_fail(new this.$mol_error_syntax(`Unexpected EOF, LF required`, str.substring(line_start, str.length), sp));
@@ -1642,6 +1810,7 @@ var $;
1642
1810
  "use strict";
1643
1811
  var $;
1644
1812
  (function ($) {
1813
+ /** Module for working with terminal. Text coloring when output in terminal */
1645
1814
  class $mol_term_color {
1646
1815
  static reset = this.ansi(0, 0);
1647
1816
  static bold = this.ansi(1, 22);
@@ -1713,6 +1882,7 @@ var $;
1713
1882
  "use strict";
1714
1883
  var $;
1715
1884
  (function ($) {
1885
+ /** One-shot fiber */
1716
1886
  class $mol_wire_task extends $mol_wire_fiber {
1717
1887
  static getter(task) {
1718
1888
  return function $mol_wire_task_get(host, args) {
@@ -1738,6 +1908,7 @@ var $;
1738
1908
  }
1739
1909
  const key = (host?.[Symbol.toStringTag] ?? host) + ('.' + task.name + '<#>');
1740
1910
  const next = new $mol_wire_task(key, task, host, args);
1911
+ // Disabled because non-idempotency is required for try-catch
1741
1912
  if (existen?.temp) {
1742
1913
  $$.$mol_log3_warn({
1743
1914
  place: '$mol_wire_task',
@@ -1770,7 +1941,7 @@ var $;
1770
1941
  try {
1771
1942
  next[Symbol.toStringTag] = this[Symbol.toStringTag];
1772
1943
  }
1773
- catch {
1944
+ catch { // Promises throw in strict mode
1774
1945
  Object.defineProperty(next, Symbol.toStringTag, { value: this[Symbol.toStringTag] });
1775
1946
  }
1776
1947
  }
@@ -1795,6 +1966,7 @@ var $;
1795
1966
  "use strict";
1796
1967
  var $;
1797
1968
  (function ($) {
1969
+ /** Convert a pseudo-synchronous (Suspense API) API to an explicit asynchronous one (for integrating with external systems). */
1798
1970
  function $mol_wire_async(obj) {
1799
1971
  let fiber;
1800
1972
  const temp = $mol_wire_task.getter(obj);
@@ -1875,6 +2047,7 @@ var $;
1875
2047
  var $;
1876
2048
  (function ($) {
1877
2049
  const TypedArray = Object.getPrototypeOf(Uint8Array);
2050
+ /** Returns string key for any value. */
1878
2051
  function $mol_key(value) {
1879
2052
  primitives: {
1880
2053
  if (typeof value === 'bigint')
@@ -1882,9 +2055,9 @@ var $;
1882
2055
  if (typeof value === 'symbol')
1883
2056
  return `Symbol(${value.description})`;
1884
2057
  if (!value)
1885
- return JSON.stringify(value);
2058
+ return JSON.stringify(value); // 0, null, ""
1886
2059
  if (typeof value !== 'object' && typeof value !== 'function')
1887
- return JSON.stringify(value);
2060
+ return JSON.stringify(value); // boolean, number, string
1888
2061
  }
1889
2062
  caching: {
1890
2063
  let key = $mol_key_store.get(value);
@@ -1961,6 +2134,9 @@ var $;
1961
2134
  "use strict";
1962
2135
  var $;
1963
2136
  (function ($) {
2137
+ /**
2138
+ * Decorates method to fiber to ensure it is executed only once inside other fiber.
2139
+ */
1964
2140
  function $mol_wire_method(host, field, descr) {
1965
2141
  if (!descr)
1966
2142
  descr = Reflect.getOwnPropertyDescriptor(host, field);
@@ -1993,6 +2169,7 @@ var $;
1993
2169
  "use strict";
1994
2170
  var $;
1995
2171
  (function ($) {
2172
+ /** Long-living fiber. */
1996
2173
  class $mol_wire_atom extends $mol_wire_fiber {
1997
2174
  static solo(host, task) {
1998
2175
  const field = task.name + '()';
@@ -2043,7 +2220,11 @@ var $;
2043
2220
  }
2044
2221
  $mol_wire_atom.watching.add(this);
2045
2222
  }
2223
+ /**
2224
+ * Update atom value through another temp fiber.
2225
+ */
2046
2226
  resync(args) {
2227
+ // enforce pulling tasks abort
2047
2228
  for (let cursor = this.pub_from; cursor < this.sub_from; cursor += 2) {
2048
2229
  const pub = this.data[cursor];
2049
2230
  if (pub && pub instanceof $mol_wire_task) {
@@ -2104,7 +2285,7 @@ var $;
2104
2285
  try {
2105
2286
  next[Symbol.toStringTag] = this[Symbol.toStringTag];
2106
2287
  }
2107
- catch {
2288
+ catch { // Promises throw in strict mode
2108
2289
  Object.defineProperty(next, Symbol.toStringTag, { value: this[Symbol.toStringTag] });
2109
2290
  }
2110
2291
  }
@@ -2132,6 +2313,7 @@ var $;
2132
2313
  "use strict";
2133
2314
  var $;
2134
2315
  (function ($) {
2316
+ /** Decorates solo object channel to [mol_wire_atom](../atom/atom.ts). */
2135
2317
  function $mol_wire_solo(host, field, descr) {
2136
2318
  if (!descr)
2137
2319
  descr = Reflect.getOwnPropertyDescriptor(host, field);
@@ -2170,6 +2352,7 @@ var $;
2170
2352
  "use strict";
2171
2353
  var $;
2172
2354
  (function ($) {
2355
+ /** Reactive memoizing multiplexed property decorator. */
2173
2356
  function $mol_wire_plex(host, field, descr) {
2174
2357
  if (!descr)
2175
2358
  descr = Reflect.getOwnPropertyDescriptor(host, field);
@@ -2208,7 +2391,25 @@ var $;
2208
2391
  "use strict";
2209
2392
  var $;
2210
2393
  (function ($) {
2394
+ /**
2395
+ * Reactive memoizing solo property decorator from [mol_wire](../wire/README.md)
2396
+ * @example
2397
+ * '@' $mol_mem
2398
+ * name(next?: string) {
2399
+ * return next ?? 'default'
2400
+ * }
2401
+ * @see https://mol.hyoo.ru/#!section=docs/=qxmh6t_sinbmb
2402
+ */
2211
2403
  $.$mol_mem = $mol_wire_solo;
2404
+ /**
2405
+ * Reactive memoizing multiplexed property decorator [mol_wire](../wire/README.md)
2406
+ * @example
2407
+ * '@' $mol_mem_key
2408
+ * name(id: number, next?: string) {
2409
+ * return next ?? 'default'
2410
+ * }
2411
+ * @see https://mol.hyoo.ru/#!section=docs/=qxmh6t_sinbmb
2412
+ */
2212
2413
  $.$mol_mem_key = $mol_wire_plex;
2213
2414
  })($ || ($ = {}));
2214
2415
 
@@ -2244,6 +2445,10 @@ var $;
2244
2445
  props[field] = get_val;
2245
2446
  return get_val;
2246
2447
  }
2448
+ /**
2449
+ * Convert asynchronous (promise-based) API to synchronous by wrapping function and method calls in a fiber.
2450
+ * @see https://mol.hyoo.ru/#!section=docs/=1fcpsq_1wh0h2
2451
+ */
2247
2452
  function $mol_wire_sync(obj) {
2248
2453
  return new Proxy(obj, {
2249
2454
  get(obj, field) {
@@ -2368,7 +2573,7 @@ var $;
2368
2573
  "use strict";
2369
2574
  var $;
2370
2575
  (function ($) {
2371
- const mod = require('module');
2576
+ const mod = require /****/('module');
2372
2577
  const internals = mod.builtinModules;
2373
2578
  function $node_internal_check(name) {
2374
2579
  if (name.startsWith('node:'))
@@ -2382,8 +2587,8 @@ var $;
2382
2587
  "use strict";
2383
2588
  var $;
2384
2589
  (function ($) {
2385
- const path = require('path');
2386
- const mod = require('module');
2590
+ const path = require /****/('path');
2591
+ const mod = require /****/('module');
2387
2592
  const localRequire = mod.createRequire(path.join(process.cwd(), 'package.json'));
2388
2593
  function $node_autoinstall(name) {
2389
2594
  try {
@@ -2430,6 +2635,7 @@ require = (req => Object.assign(function require(name) {
2430
2635
  "use strict";
2431
2636
  var $;
2432
2637
  (function ($) {
2638
+ /** Run code without state changes */
2433
2639
  function $mol_wire_probe(task, def) {
2434
2640
  const warm = $mol_wire_fiber.warm;
2435
2641
  try {
@@ -2478,6 +2684,7 @@ var $;
2478
2684
  ])
2479
2685
  ].map(frame_normalize).join('\n')
2480
2686
  });
2687
+ // в nodejs, что б не дублировалось cause в консоли
2481
2688
  Object.defineProperty(this, 'cause', {
2482
2689
  get: () => cause
2483
2690
  });
@@ -2681,7 +2888,7 @@ var $;
2681
2888
  const err = new Error('Worker exited', { cause: { code } });
2682
2889
  if (!inited)
2683
2890
  return fail(err);
2684
- this.error([err]);
2891
+ this.error([err]); // Need to reset callers fail callbacks
2685
2892
  this.restarts(null);
2686
2893
  });
2687
2894
  worker.on('message', e => {
@@ -2741,6 +2948,10 @@ var $;
2741
2948
  "use strict";
2742
2949
  var $;
2743
2950
  (function ($) {
2951
+ /**
2952
+ * Decorates method to fiber to ensure it is executed only once inside other fiber from [mol_wire](../wire/README.md)
2953
+ * @see https://mol.hyoo.ru/#!section=docs/=1fcpsq_1wh0h2
2954
+ */
2744
2955
  $.$mol_action = $mol_wire_method;
2745
2956
  })($ || ($ = {}));
2746
2957
 
@@ -2827,6 +3038,7 @@ var $;
2827
3038
  $mol_error_fence(() => this.remote().changes(changes), e => ($mol_fail_log(e), null));
2828
3039
  }
2829
3040
  changes_schedule() {
3041
+ // ts watcher calls it in host syncronously
2830
3042
  if (this.changes_tick === undefined)
2831
3043
  return;
2832
3044
  if (this.changes_tick !== null)
@@ -2856,11 +3068,12 @@ var $;
2856
3068
  }
2857
3069
  this.run();
2858
3070
  }
3071
+ // Do not place async logic here, to prevent recheck calls race
2859
3072
  recheck() {
2860
3073
  this.changes_tick?.destructor();
2861
- this.changes_tick = undefined;
2862
- this.watching(true);
2863
- this.host();
3074
+ this.changes_tick = undefined; // disable watch sending
3075
+ this.watching(true); // enable host pull in start
3076
+ this.host(); // wait host started
2864
3077
  this.recheck_internal();
2865
3078
  return this.changes_cut();
2866
3079
  }
@@ -2877,6 +3090,7 @@ var $;
2877
3090
  }, {
2878
3091
  ...$node.typescript.sys,
2879
3092
  watchDirectory: (path, cb) => {
3093
+ // console.log('watchDirectory', path )
2880
3094
  this.watchers.set(path, cb);
2881
3095
  return { close() { } };
2882
3096
  },
@@ -2887,6 +3101,7 @@ var $;
2887
3101
  this.run = cb;
2888
3102
  },
2889
3103
  watchFile: (path, cb) => {
3104
+ // console.log('watchFile', path )
2890
3105
  this.watchers.set(path, cb);
2891
3106
  return { close() { } };
2892
3107
  },
@@ -2907,7 +3122,9 @@ var $;
2907
3122
  message: typeof text === 'string' ? text : text.messageText,
2908
3123
  });
2909
3124
  }
2910
- }, () => { }, [], {
3125
+ }, () => { }, //watch reports
3126
+ [], // project refs
3127
+ {
2911
3128
  synchronousWatchDirectory: true,
2912
3129
  watchFile: 5,
2913
3130
  watchDirectory: 0,
@@ -3008,6 +3225,11 @@ var $;
3008
3225
  "use strict";
3009
3226
  var $;
3010
3227
  (function ($) {
3228
+ /**
3229
+ * Returns closure that returns constant value.
3230
+ * @example
3231
+ * const rnd = $mol_const( Math.random() )
3232
+ */
3011
3233
  function $mol_const(value) {
3012
3234
  const getter = (() => value);
3013
3235
  getter['()'] = value;
@@ -3098,7 +3320,8 @@ var $;
3098
3320
  "use strict";
3099
3321
  var $;
3100
3322
  (function ($) {
3101
- let buf = new Uint8Array(2 ** 12);
3323
+ let buf = new Uint8Array(2 ** 12); // 4KB Mem Page
3324
+ /** Temporary buffer. Recursive usage isn't supported. */
3102
3325
  function $mol_charset_buffer(size) {
3103
3326
  if (buf.byteLength < size)
3104
3327
  buf = new Uint8Array(size);
@@ -3120,19 +3343,19 @@ var $;
3120
3343
  let pos = from;
3121
3344
  for (let i = 0; i < str.length; i++) {
3122
3345
  let code = str.charCodeAt(i);
3123
- if (code < 0x80) {
3346
+ if (code < 0x80) { // ASCII - 1 octet
3124
3347
  buf[pos++] = code;
3125
3348
  }
3126
- else if (code < 0x800) {
3349
+ else if (code < 0x800) { // 2 octet
3127
3350
  buf[pos++] = 0xc0 | (code >> 6);
3128
3351
  buf[pos++] = 0x80 | (code & 0x3f);
3129
3352
  }
3130
- else if (code < 0xd800 || code >= 0xe000) {
3353
+ else if (code < 0xd800 || code >= 0xe000) { // 3 octet
3131
3354
  buf[pos++] = 0xe0 | (code >> 12);
3132
3355
  buf[pos++] = 0x80 | ((code >> 6) & 0x3f);
3133
3356
  buf[pos++] = 0x80 | (code & 0x3f);
3134
3357
  }
3135
- else {
3358
+ else { // surrogate pair
3136
3359
  const point = ((code - 0xd800) << 10) + str.charCodeAt(++i) + 0x2400;
3137
3360
  buf[pos++] = 0xf0 | (point >> 18);
3138
3361
  buf[pos++] = 0x80 | ((point >> 12) & 0x3f);
@@ -3194,6 +3417,9 @@ var $;
3194
3417
  "use strict";
3195
3418
  var $;
3196
3419
  (function ($) {
3420
+ /**
3421
+ * Disable reaping of current subscriber
3422
+ */
3197
3423
  function $mol_wire_solid() {
3198
3424
  let current = $mol_wire_auto();
3199
3425
  if (current.temp)
@@ -3214,12 +3440,16 @@ var $;
3214
3440
  (function ($) {
3215
3441
  let file_modes;
3216
3442
  (function (file_modes) {
3443
+ /** create if it doesn't already exist */
3217
3444
  file_modes[file_modes["create"] = $node.fs.constants.O_CREAT] = "create";
3445
+ /** truncate to zero size if it already exists */
3218
3446
  file_modes[file_modes["exists_truncate"] = $node.fs.constants.O_TRUNC] = "exists_truncate";
3447
+ /** throw exception if it already exists */
3219
3448
  file_modes[file_modes["exists_fail"] = $node.fs.constants.O_EXCL] = "exists_fail";
3220
3449
  file_modes[file_modes["read_only"] = $node.fs.constants.O_RDONLY] = "read_only";
3221
3450
  file_modes[file_modes["write_only"] = $node.fs.constants.O_WRONLY] = "write_only";
3222
3451
  file_modes[file_modes["read_write"] = $node.fs.constants.O_RDWR] = "read_write";
3452
+ /** data will be appended to the end */
3223
3453
  file_modes[file_modes["append"] = $node.fs.constants.O_APPEND] = "append";
3224
3454
  })(file_modes || (file_modes = {}));
3225
3455
  function mode_mask(modes) {
@@ -3284,12 +3514,24 @@ var $;
3284
3514
  root() {
3285
3515
  const path = this.path();
3286
3516
  const base = this.constructor.base;
3517
+ // Если путь выше или равен base или если parent такойже как и this - считаем это корнем
3287
3518
  return base.startsWith(path) || this == this.parent();
3288
3519
  }
3289
3520
  stat(next, virt) {
3290
3521
  const path = this.path();
3291
3522
  const parent = this.parent();
3523
+ // Отслеживать проверку наличия родительской папки не стоит до корня диска
3524
+ // Лучше ограничить mam-ом
3292
3525
  if (!this.root()) {
3526
+ /*
3527
+ Если parent папка удалилась, надо ресетнуть все объекты в ней на любой глубине.
3528
+ Например, rm -rf с последующим git pull: parent папка может удалиться, потом создасться,
3529
+ а текущая папка успеет только удалиться до момента выполнения stat.
3530
+ Поэтому parent.exists() не запустит перевычисления, нужна именно parent.version()
3531
+
3532
+ Однако, parent.version() меняется не только при удалении, будет ложное срабатывание
3533
+ С этим придется мириться, красивого решения пока нет.
3534
+ */
3293
3535
  parent.version();
3294
3536
  }
3295
3537
  parent.watcher();
@@ -3303,9 +3545,19 @@ var $;
3303
3545
  if (/([\/\\]\.|___$)/.test(path))
3304
3546
  return;
3305
3547
  const file = this.relative(path.at(-1) === '/' ? path.slice(0, -1) : path);
3548
+ // console.log(type, path)
3549
+ // add (change): добавился файл - у parent надо обновить список sub, если он был заюзан
3550
+ // change, unlink (rename): обновился или удалился файл - ресетим
3551
+ // addDir (change), добавилась папка, у parent обновляем список директорий в sub
3552
+ // дочерние ресетим
3553
+ // unlinkDir (rename), удалилась папка, ресетим ее
3554
+ // stat у всех дочерних обновится сам, т.к. связан с parent.version()
3306
3555
  this.changed.add(file);
3307
3556
  if (!this.watching)
3308
3557
  return;
3558
+ // throttle, пока события поступают не сбрасываем.
3559
+ // аналог awaitWriteFinish из chokidar
3560
+ // интервалы между change-сообщениями модифицируемого файла должны быть меньше watch_debounce
3309
3561
  this.frame?.destructor();
3310
3562
  this.frame = new this.$.$mol_after_timeout(this.watch_debounce(), () => {
3311
3563
  if (!this.watching)
@@ -3314,8 +3566,16 @@ var $;
3314
3566
  $mol_wire_async(this).flush();
3315
3567
  });
3316
3568
  }
3569
+ /**
3570
+ * Должно быть больше, чем время между событиями от вотчера при записи внешним процессом.
3571
+ * Иначе запуск ресетов паралельно с изменением может привести к неконсистентности.
3572
+ */
3317
3573
  static watch_debounce() { return 500; }
3318
3574
  static flush() {
3575
+ // Пока flush работает, вотчер сюда не заходит, но может добавлять новые изменения
3576
+ // на каждом перезапуске они применятся
3577
+ // Пока run выполняется, изменения накапливаются, в конце run вызывается flush
3578
+ // Пока применяются изменения, run должен ожидать конца flush
3319
3579
  for (const file of this.changed) {
3320
3580
  const parent = file.parent();
3321
3581
  try {
@@ -3330,16 +3590,32 @@ var $;
3330
3590
  }
3331
3591
  this.changed.clear();
3332
3592
  this.watching = true;
3593
+ // this.watch_wd?.destructor()
3594
+ // this.watch_wd = null
3333
3595
  }
3334
3596
  static watching = true;
3335
3597
  static lock = new $mol_lock;
3336
3598
  static watch_off(path) {
3337
3599
  this.watching = false;
3600
+ // run должен ожидать конца flush
3338
3601
  this.flush();
3339
3602
  this.watching = false;
3603
+ /*
3604
+ watch запаздывает и событие может прилететь через 3 сек после окончания сайд эффекта
3605
+ поэтому добавляем папку, которую меняет side_effect
3606
+ Когда дойдет до выполнения flush, он ресетнет ее
3607
+
3608
+ Иначе будут лишние срабатывания
3609
+ Например, удалили hyoo/board, watch ресетит и exists начинает отдавать false, срабатывает git clone
3610
+ Сразу после него событие addDir еще не успело прийти,
3611
+ на следующем перезапуске вызывается git pull, т.к.
3612
+ с точки зрения реактивной системы hyoo/board еще не существует.
3613
+ */
3340
3614
  this.changed.add(this.absolute(path));
3341
3615
  }
3616
+ // protected static watch_wd = null as null | $mol_after_timeout
3342
3617
  static unwatched(side_effect, affected_dir) {
3618
+ // ждем, пока выполнится предыдущий unwatched
3343
3619
  const unlock = this.lock.grab();
3344
3620
  this.watch_off(affected_dir);
3345
3621
  try {
@@ -3362,6 +3638,7 @@ var $;
3362
3638
  modified() { return this.stat()?.mtime ?? null; }
3363
3639
  version() {
3364
3640
  const next = this.stat()?.mtime.getTime().toString(36).toUpperCase() ?? '';
3641
+ // console.log('version', next, this.path())
3365
3642
  return next;
3366
3643
  }
3367
3644
  info(path) { return null; }
@@ -3379,15 +3656,19 @@ var $;
3379
3656
  writable(opts) {
3380
3657
  return new WritableStream;
3381
3658
  }
3659
+ // open( ... modes: readonly $mol_file_mode[] ) { return 0 }
3382
3660
  buffer(next) {
3661
+ // Если версия пустая - возвращаем пустой буфер
3383
3662
  let readed = new Uint8Array();
3384
3663
  if (next === undefined) {
3664
+ // Если меняется версия файла, буфер надо перечитать
3385
3665
  if (this.version())
3386
3666
  readed = this.read();
3387
3667
  }
3388
3668
  const prev = $mol_mem_cached(() => this.buffer());
3389
3669
  const changed = prev === undefined || !$mol_compare_array(prev, next ?? readed);
3390
3670
  if (prev !== undefined && changed) {
3671
+ // Логируем, если повторно читаем/пишем и буфер поменялся
3391
3672
  this.$.$mol_log3_rise({
3392
3673
  place: `$mol_file_node.buffer()`,
3393
3674
  message: 'Changed',
@@ -3396,6 +3677,11 @@ var $;
3396
3677
  }
3397
3678
  if (next === undefined)
3398
3679
  return changed ? readed : prev;
3680
+ // Если буфер при записи не поменялся и файл не удаляли перед этим - не записываем новую версию.
3681
+ // Если записывать, это приведет к смене mtime и вотчер снова триггернется, даже если содержимое файла не поменялось.
3682
+ // В этом алгоритме есть изъян.
3683
+ // Если файл записали, потом отключили вотчер, кто-то из вне его поменял, потом включили вотчер, снова записали тот же буфер,
3684
+ // то буфер не запишется на диск, т.к. кэш не консистентен с диском.
3399
3685
  if (!changed && this.exists())
3400
3686
  return prev;
3401
3687
  this.parent().exists(true);
@@ -3431,13 +3717,21 @@ var $;
3431
3717
  }
3432
3718
  return null;
3433
3719
  }
3720
+ // static watch_root = ''
3721
+ // static watcher_warned = false
3434
3722
  watcher() {
3723
+ // const constructor = this.constructor as typeof $mol_file_base
3724
+ // if (! constructor.watcher_warned) {
3725
+ // console.warn(`${constructor}.watcher() not implemented`)
3726
+ // constructor.watcher_warned = true
3727
+ // }
3435
3728
  return {
3436
3729
  destructor() { }
3437
3730
  };
3438
3731
  }
3439
3732
  exists(next) {
3440
3733
  const exists = Boolean(this.stat());
3734
+ // console.log('exists current', exists, 'next', next, this.path())
3441
3735
  if (next === undefined)
3442
3736
  return exists;
3443
3737
  if (next === exists)
@@ -3463,6 +3757,10 @@ var $;
3463
3757
  return match ? match[1].substring(1) : '';
3464
3758
  }
3465
3759
  text(next, virt) {
3760
+ // Если записываем text, и вотчер ресетнул записанный файл,
3761
+ // то надо снова его обновить, вызвать логику, которая делала пуш в text.
3762
+ // Например файл удалили, потом снова создали, версия поменялась - перезаписываем
3763
+ // Если использовать version, то вновь созданный файл, через вотчер запустит свое пересоздание
3466
3764
  if (next !== undefined)
3467
3765
  this.exists();
3468
3766
  return this.text_int(next, virt);
@@ -3487,6 +3785,7 @@ var $;
3487
3785
  if (this.type() !== 'dir')
3488
3786
  return [];
3489
3787
  this.version();
3788
+ // Если дочерний file удалился, список надо обновить
3490
3789
  return this.kids().filter(file => file.exists());
3491
3790
  }
3492
3791
  resolve(path) {
@@ -3631,10 +3930,15 @@ var $;
3631
3930
  watcher(reset) {
3632
3931
  const path = this.path();
3633
3932
  const root = this.root();
3933
+ // Если папки/файла нет, watch упадет с ошибкой
3934
+ // exists обратится к parent.version и parent.watcher
3935
+ // Поэтому у root-папки и выше не надо вызывать exists, иначе поднимется выше base до корня диска
3936
+ // exists вызывать надо, что б пересоздавать вотчер при появлении папки или файла
3634
3937
  if (!root && !this.exists())
3635
3938
  return super.watcher();
3636
3939
  let watcher;
3637
3940
  try {
3941
+ // Между exists и watch файл может удалиться, в любом случае надо обрабатывать ENOENT
3638
3942
  watcher = $node.fs.watch(path);
3639
3943
  }
3640
3944
  catch (error) {
@@ -3644,6 +3948,8 @@ var $;
3644
3948
  if (root || error.code !== 'ENOENT') {
3645
3949
  this.$.$mol_fail_log(error);
3646
3950
  }
3951
+ // Если файла нет - вотчер не создается, создастся потом, когда exists поменяется на true.
3952
+ // Если создание упало с другой ошибкой - не ломаем работу mol_file, деградируем до не реактивной fs.
3647
3953
  return super.watcher();
3648
3954
  }
3649
3955
  watcher.on('change', (type, name) => {
@@ -3655,6 +3961,7 @@ var $;
3655
3961
  watcher.on('error', e => this.$.$mol_fail_log(e));
3656
3962
  let destructed = false;
3657
3963
  watcher.on('close', () => {
3964
+ // Если в процессе работы вотчер сам закрылся, надо его переоткрыть
3658
3965
  if (!destructed)
3659
3966
  setTimeout(() => $mol_wire_async(this).watcher(null), 500);
3660
3967
  });
@@ -4010,14 +4317,18 @@ var $;
4010
4317
  ];
4011
4318
  },
4012
4319
  '': (input, belt) => {
4320
+ // string
4013
4321
  if (!input.type)
4014
4322
  return [
4015
4323
  input.data(JSON.stringify(input.text())),
4016
4324
  ];
4325
+ // variable
4017
4326
  if (/^[\w$#][\w0-9$]*$/i.test(input.type))
4018
4327
  return [
4019
4328
  input.data(input.type),
4329
+ // ... input.hack( context ),
4020
4330
  ];
4331
+ // number
4021
4332
  if ($mol_tree2_js_is_number(input.type))
4022
4333
  return [
4023
4334
  input.data(input.type)
@@ -4149,8 +4460,10 @@ var $;
4149
4460
  var $;
4150
4461
  (function ($) {
4151
4462
  let x = /x/[Symbol.matchAll];
4463
+ /** Type safe reguar expression builder */
4152
4464
  class $mol_regexp extends RegExp {
4153
4465
  groups;
4466
+ /** Prefer to use $mol_regexp.from */
4154
4467
  constructor(source, flags = 'gsu', groups = []) {
4155
4468
  super(source, flags);
4156
4469
  this.groups = groups;
@@ -4170,12 +4483,14 @@ var $;
4170
4483
  this.lastIndex = index;
4171
4484
  }
4172
4485
  }
4486
+ /** Parses input and returns found capture groups or null */
4173
4487
  [Symbol.match](str) {
4174
4488
  const res = [...this[Symbol.matchAll](str)].filter(r => r.groups).map(r => r[0]);
4175
4489
  if (!res.length)
4176
4490
  return null;
4177
4491
  return res;
4178
4492
  }
4493
+ /** Splits string by regexp edges */
4179
4494
  [Symbol.split](str) {
4180
4495
  const res = [];
4181
4496
  let token_last = null;
@@ -4230,12 +4545,14 @@ var $;
4230
4545
  get native() {
4231
4546
  return new RegExp(this.source, this.flags);
4232
4547
  }
4548
+ /** Makes regexp that greedy repeats this pattern with delimiter */
4233
4549
  static separated(chunk, sep) {
4234
4550
  return $mol_regexp.from([
4235
4551
  $mol_regexp.repeat_greedy([[chunk], sep], 0),
4236
4552
  chunk,
4237
4553
  ]);
4238
4554
  }
4555
+ /** Makes regexp that non-greedy repeats this pattern from min to max count */
4239
4556
  static repeat(source, min = 0, max = Number.POSITIVE_INFINITY) {
4240
4557
  const regexp = $mol_regexp.from(source);
4241
4558
  const upper = Number.isFinite(max) ? max : '';
@@ -4251,6 +4568,7 @@ var $;
4251
4568
  };
4252
4569
  return regexp2;
4253
4570
  }
4571
+ /** Makes regexp that greedy repeats this pattern from min to max count */
4254
4572
  static repeat_greedy(source, min = 0, max = Number.POSITIVE_INFINITY) {
4255
4573
  const regexp = $mol_regexp.from(source);
4256
4574
  const upper = Number.isFinite(max) ? max : '';
@@ -4266,6 +4584,7 @@ var $;
4266
4584
  };
4267
4585
  return regexp2;
4268
4586
  }
4587
+ /** Makes regexp that match any of options */
4269
4588
  static vary(sources, flags = 'gsu') {
4270
4589
  const groups = [];
4271
4590
  const chunks = sources.map(source => {
@@ -4275,17 +4594,21 @@ var $;
4275
4594
  });
4276
4595
  return new $mol_regexp(`(?:${chunks.join('|')})`, flags, groups);
4277
4596
  }
4597
+ /** Makes regexp that allow absent of this pattern */
4278
4598
  static optional(source) {
4279
4599
  return $mol_regexp.repeat_greedy(source, 0, 1);
4280
4600
  }
4601
+ /** Makes regexp that look ahead for pattern */
4281
4602
  static force_after(source) {
4282
4603
  const regexp = $mol_regexp.from(source);
4283
4604
  return new $mol_regexp(`(?=${regexp.source})`, regexp.flags, regexp.groups);
4284
4605
  }
4606
+ /** Makes regexp that look ahead for pattern */
4285
4607
  static forbid_after(source) {
4286
4608
  const regexp = $mol_regexp.from(source);
4287
4609
  return new $mol_regexp(`(?!${regexp.source})`, regexp.flags, regexp.groups);
4288
4610
  }
4611
+ /** Converts some js values to regexp */
4289
4612
  static from(source, { ignoreCase, multiline } = {
4290
4613
  ignoreCase: false,
4291
4614
  multiline: false,
@@ -4386,9 +4709,11 @@ var $;
4386
4709
  return regexp;
4387
4710
  }
4388
4711
  }
4712
+ /** Makes regexp which includes only unicode category */
4389
4713
  static unicode_only(...category) {
4390
4714
  return new $mol_regexp(`\\p{${category.join('=')}}`);
4391
4715
  }
4716
+ /** Makes regexp which excludes unicode category */
4392
4717
  static unicode_except(...category) {
4393
4718
  return new $mol_regexp(`\\P{${category.join('=')}}`);
4394
4719
  }
@@ -4509,13 +4834,23 @@ var $;
4509
4834
  var $;
4510
4835
  (function ($) {
4511
4836
  const err = $mol_view_tree2_error_str;
4837
+ const is_writable = (input) => input.type.includes('?');
4512
4838
  function $mol_view_tree2_class_props(klass) {
4513
4839
  let props = this.$mol_view_tree2_class_super(klass);
4840
+ // ! syntax to * and ?val syntax to ?
4514
4841
  props = props.clone(props.hack({
4515
4842
  '': (node, belt) => {
4516
- const normal = node.type.replace(/!\w+/, '*');
4843
+ const next = node.type.indexOf('?');
4844
+ const id = node.type.indexOf('!');
4845
+ let normal = node.type;
4846
+ const ch = node.type[id + 1];
4847
+ if (id !== -1 && ch?.toUpperCase() !== ch?.toLowerCase())
4848
+ normal = `${normal.substring(0, id)}*${next === -1 ? '' : '?'}`;
4849
+ else if (next !== -1)
4850
+ normal = normal.substring(0, next + 1);
4517
4851
  if (node.type === normal)
4518
4852
  return [node.clone(node.hack(belt))];
4853
+ console.warn(`Syntax ${node.type} is deprecated. Use ${normal} instead`);
4519
4854
  return [node.struct(normal, node.hack(belt))];
4520
4855
  }
4521
4856
  }));
@@ -4552,12 +4887,26 @@ var $;
4552
4887
  this.$mol_fail(err `Need a child ${operator.span}`);
4553
4888
  if (!context.factory)
4554
4889
  this.$mol_fail(err `Need a parent ${left.span}`);
4890
+ if (is_writable(left) !== is_writable(right))
4891
+ this.$mol_fail(err `Left and right operands are not compatible at ${operator.span}`);
4555
4892
  add_inner(right.clone([
4556
4893
  right.struct('=', [
4557
4894
  context.factory.struct(context.factory.type.replace(/\*.*/, '*'), [left.clone([])]),
4558
4895
  ]),
4559
4896
  ]));
4560
4897
  }
4898
+ else if (operator?.type === "<=>") {
4899
+ const right = operator.kids[0];
4900
+ if (!right)
4901
+ this.$mol_fail(err `Need a child ${operator.span}`);
4902
+ if (!is_writable(left))
4903
+ this.$mol_fail(err `Expected writable at ${left.span}`);
4904
+ if (!is_writable(right))
4905
+ this.$mol_fail(err `Expected writable at ${right.span}`);
4906
+ }
4907
+ else if (operator?.type === "<=" && is_writable(left)) {
4908
+ this.$mol_fail(err `Expected readonly at ${left.span}`);
4909
+ }
4561
4910
  if (right)
4562
4911
  context = { factory: right.clone([]) };
4563
4912
  else if (operator && !context.factory && $mol_view_tree2_class_match(operator)) {
@@ -4758,6 +5107,10 @@ var $;
4758
5107
  "use strict";
4759
5108
  var $;
4760
5109
  (function ($) {
5110
+ /**
5111
+ * Localisation in $mol framework
5112
+ * @see https://mol.hyoo.ru/#!section=docs/=s5aqnb_odub8l
5113
+ */
4761
5114
  class $mol_locale extends $mol_object {
4762
5115
  static lang_default() {
4763
5116
  return 'en';
@@ -4917,12 +5270,14 @@ var $;
4917
5270
  '=>': bind => [],
4918
5271
  '^': (ref, belt, context) => [
4919
5272
  ref.struct('...', [
5273
+ // prop ^ foo
4920
5274
  ref.kids[0]?.type
4921
5275
  ? ref.struct('()', [
4922
5276
  ref.struct('this'),
4923
5277
  ref.struct('[]', [ref.data(name_of.call(this, ref.kids[0]))]),
4924
5278
  args_of.call(this, ref.kids[0])
4925
5279
  ])
5280
+ // Having $having foo / ^
4926
5281
  : context.chain
4927
5282
  ? ref.struct('()', [
4928
5283
  ref.struct('this'),
@@ -4934,6 +5289,7 @@ var $;
4934
5289
  ref.struct('(,)', [ref.struct('obj')]),
4935
5290
  ...context.chain.slice(1).map(field => ref.struct('[]', [ref.data(field)]))
4936
5291
  ])
5292
+ // prop ^
4937
5293
  : ref.struct('()', [
4938
5294
  ref.struct('super'),
4939
5295
  ref.struct('[]', [ref.data(name)]),
@@ -5215,6 +5571,7 @@ var $;
5215
5571
  const left_parts = this.$mol_view_tree2_prop_parts(left);
5216
5572
  const right_parts = this.$mol_view_tree2_prop_parts(right);
5217
5573
  let conflict;
5574
+ // if (left_parts.next && right_parts.next) conflict = 'next'
5218
5575
  if (left_parts.key && right_parts.key)
5219
5576
  conflict = 'key';
5220
5577
  if (conflict) {
@@ -5339,7 +5696,7 @@ var $;
5339
5696
  }, context);
5340
5697
  return prop.struct('indent', [
5341
5698
  prop.struct('line', [
5342
- channel_signature.call(this, prop, ...val),
5699
+ channel_signature.call(this, prop, ...val), // Parameter, not Return
5343
5700
  prop.data(': '),
5344
5701
  ...val,
5345
5702
  ])
@@ -5565,18 +5922,33 @@ var $;
5565
5922
  "use strict";
5566
5923
  var $;
5567
5924
  (function ($) {
5925
+ /**
5926
+ * # Generic Graph model
5927
+ * - Supports any type of Nodes and Edges.
5928
+ * - All links are ordered, but this may be ignored.
5929
+ * - Multigraph supported using arrays of Edges.
5930
+ * - Hypergraph supported by reusing same Edge on set of links.
5931
+ * - Ubergraph supported using Edges as Nodes to.
5932
+ **/
5568
5933
  class $mol_graph {
5934
+ /** All registered Nodes */
5569
5935
  nodes = new Set();
5936
+ /** Edges for Nodes pairs (from-to-edge) */
5570
5937
  edges_out = new Map();
5938
+ /** Edges for Nodes pairs (to-from-edge) */
5571
5939
  edges_in = new Map();
5940
+ // LINKING NODES
5941
+ /** Full connect two Nodes */
5572
5942
  link(from, to, edge) {
5573
5943
  this.link_out(from, to, edge);
5574
5944
  this.link_in(to, from, edge);
5575
5945
  }
5946
+ /** Full disconnect two Nodes */
5576
5947
  unlink(from, to) {
5577
5948
  this.edges_in.get(to)?.delete(from);
5578
5949
  this.edges_out.get(from)?.delete(to);
5579
5950
  }
5951
+ /** Forward connect two Nodes */
5580
5952
  link_out(from, to, edge) {
5581
5953
  let pair = this.edges_out.get(from);
5582
5954
  if (!pair) {
@@ -5587,6 +5959,7 @@ var $;
5587
5959
  pair.set(to, edge);
5588
5960
  this.nodes.add(to);
5589
5961
  }
5962
+ /** Backward connect two Nodes */
5590
5963
  link_in(to, from, edge) {
5591
5964
  let pair = this.edges_in.get(to);
5592
5965
  if (!pair) {
@@ -5597,15 +5970,21 @@ var $;
5597
5970
  pair.set(from, edge);
5598
5971
  this.nodes.add(to);
5599
5972
  }
5973
+ // GETTING EDGES
5974
+ /** Return any Edge for two Nodes or null */
5600
5975
  edge(from, to) {
5601
5976
  return this.edge_out(from, to) ?? this.edge_in(to, from);
5602
5977
  }
5978
+ /** Return output Edge for two Nodes or null */
5603
5979
  edge_out(from, to) {
5604
5980
  return this.edges_out.get(from)?.get(to) ?? null;
5605
5981
  }
5982
+ /** Return input Edge for two Nodes or null */
5606
5983
  edge_in(to, from) {
5607
5984
  return this.edges_in.get(to)?.get(from) ?? null;
5608
5985
  }
5986
+ // MUTATIONS
5987
+ /** Cut cycles at lowest priority of Edges */
5609
5988
  acyclic(get_weight) {
5610
5989
  const checked = [];
5611
5990
  for (const start of this.nodes) {
@@ -5650,6 +6029,8 @@ var $;
5650
6029
  visit(start);
5651
6030
  }
5652
6031
  }
6032
+ // NODES SELECTION
6033
+ /** Topoligical ordered set of all Nodes for acyclic graph */
5653
6034
  get sorted() {
5654
6035
  const sorted = new Set();
5655
6036
  const visit = (node) => {
@@ -5667,6 +6048,7 @@ var $;
5667
6048
  }
5668
6049
  return sorted;
5669
6050
  }
6051
+ /** All Nodes which don't have input Edges */
5670
6052
  get roots() {
5671
6053
  const roots = [];
5672
6054
  for (const node of this.nodes) {
@@ -5676,6 +6058,13 @@ var $;
5676
6058
  }
5677
6059
  return roots;
5678
6060
  }
6061
+ // DEPTH STATS
6062
+ /**
6063
+ * Nodes depth statistics for acyclic graph
6064
+ * @example
6065
+ * graph.depth_stat( Math.min )
6066
+ * graph.depth_stat( Math.max )
6067
+ **/
5679
6068
  nodes_depth(select) {
5680
6069
  const stat = new Map();
5681
6070
  const visit = (node, depth = 0) => {
@@ -5690,6 +6079,12 @@ var $;
5690
6079
  visit(root);
5691
6080
  return stat;
5692
6081
  }
6082
+ /**
6083
+ * Depth's Nodes statistics for acyclic graph
6084
+ * @example
6085
+ * graph.depth_nodes( Math.min )
6086
+ * graph.depth_nodes( Math.max )
6087
+ **/
5693
6088
  depth_nodes(select) {
5694
6089
  const groups = [];
5695
6090
  for (const [node, depth] of this.nodes_depth(select).entries()) {
@@ -5898,6 +6293,7 @@ var $;
5898
6293
  return new $mol_graph();
5899
6294
  }
5900
6295
  path_added(path) { return this.added.has(path); }
6296
+ // @ $mol_mem_key
5901
6297
  add_module(path) {
5902
6298
  this.added.add(path);
5903
6299
  const mod = this.$.$mol_file.absolute(path);
@@ -5920,6 +6316,7 @@ var $;
5920
6316
  }
5921
6317
  return root.resolve('node_modules').resolve('./' + target);
5922
6318
  }
6319
+ // @ $mol_mem_key
5923
6320
  check_dep([path, target]) {
5924
6321
  const root = this.root();
5925
6322
  const deps = this.dependencies(path);
@@ -5941,6 +6338,7 @@ var $;
5941
6338
  if (index.exists())
5942
6339
  dep = index;
5943
6340
  }
6341
+ //if( dep.type() === 'file' ) dep = dep.parent()
5944
6342
  if (mod === dep)
5945
6343
  return null;
5946
6344
  const from = mod.relate(root);
@@ -6015,6 +6413,7 @@ var $;
6015
6413
  version: this.version,
6016
6414
  sources: this.sources,
6017
6415
  names: this.names,
6416
+ // sourceRoot: this.sourceRoot || undefined,
6018
6417
  mappings: sourcemap_codec.encode(this.segment_lines),
6019
6418
  file: this.file,
6020
6419
  sourcesContent: this.sourceContent,
@@ -6084,7 +6483,7 @@ var $;
6084
6483
  for (let line of lines) {
6085
6484
  const mergedLine = [];
6086
6485
  for (let segment of line) {
6087
- const mergedSegment = [segment[0]];
6486
+ const mergedSegment = [segment[0]]; // generatedColumn
6088
6487
  if (segment.length >= 2) {
6089
6488
  const sourceIndex = segment[1];
6090
6489
  const source = bundleSourceRoot + sourceRoot + raw.sources[sourceIndex];
@@ -6099,9 +6498,9 @@ var $;
6099
6498
  mergedSegment.push(mergedSourceIndex);
6100
6499
  }
6101
6500
  if (segment.length >= 3)
6102
- mergedSegment.push(segment[2]);
6501
+ mergedSegment.push(segment[2]); // originalLine
6103
6502
  if (segment.length >= 4)
6104
- mergedSegment.push(segment[3]);
6503
+ mergedSegment.push(segment[3]); // originalColumn
6105
6504
  if (segment.length >= 5) {
6106
6505
  const nameIndex = segment[4];
6107
6506
  const name = raw.names?.[nameIndex];
@@ -6299,10 +6698,14 @@ var $;
6299
6698
  return true;
6300
6699
  }
6301
6700
  this.update_safe(path);
6701
+ // mod.reset()
6702
+ // for ( const sub of mod.sub() ) sub.reset()
6302
6703
  return true;
6303
6704
  }
6304
6705
  if (this.repo(path)) {
6305
6706
  this.$.$mol_file.unwatched(() => this.init(path), path);
6707
+ // mod.reset()
6708
+ // for ( const sub of mod.sub() ) sub.reset()
6306
6709
  return true;
6307
6710
  }
6308
6711
  return false;
@@ -6379,10 +6782,21 @@ var $;
6379
6782
  command: 'git rev-parse --abbrev-ref --symbolic-full-name HEAD', dir,
6380
6783
  });
6381
6784
  const current_branch = out.stdout.toString().trim();
6785
+ // когда не на ветке - не надо пулить, например сборка во время git bisect
6382
6786
  if (!current_branch)
6383
6787
  return false;
6384
6788
  const command = ['git', 'pull'];
6385
6789
  if (!this.interactive() && this.deepen_supported()) {
6790
+ /**
6791
+ depth и deepen не годятся для локальной разработки, поэтому оставляем ограничение глубины пула только для CI
6792
+
6793
+ --depth=1 в сочетании с сабмодулями обрезает историю, кроме первого коммита
6794
+
6795
+ --deepen=1 если не сделать unset GIT_DIR
6796
+ в git-конфиге сабмодуля выставляет bare=true, после этого все команды падают с сообщением
6797
+ warning: core.bare and core.worktree do not make sense
6798
+ fatal: unable to set up work tree using invalid config
6799
+ */
6386
6800
  command.push('--deepen=1');
6387
6801
  }
6388
6802
  const timeout = this.pull_timeout();
@@ -6455,6 +6869,8 @@ var $;
6455
6869
  return res.stdout.toString().match(/HEAD branch: (.*?)\n/)?.[1] ?? 'master';
6456
6870
  }
6457
6871
  init_existing(dir) {
6872
+ // Например, если вручную склонить ревизию папки в глубине (например, hyoo/mol) перед запуском билда,
6873
+ // то hyoo надо проинициалзировать в соответствии с meta.ree
6458
6874
  const repo = this.repo_ensured(dir);
6459
6875
  const { url, branch } = repo;
6460
6876
  this.$.$mol_run.spawn({ command: ['git', 'init'], dir });
@@ -6510,12 +6926,12 @@ var $;
6510
6926
  if ([node, node_modules].includes(parent)
6511
6927
  && mod.name() !== 'node'
6512
6928
  && !mod.name().startsWith('@')) {
6513
- this.$.$node_autoinstall(mod.name());
6929
+ this.$.$node_autoinstall(mod.name()); // force autoinstall through npm
6514
6930
  return true;
6515
6931
  }
6516
6932
  if ([node, node_modules].includes(parent.parent())
6517
6933
  && parent.name().startsWith('@')) {
6518
- this.$.$node_autoinstall(`${parent.name()}/${mod.name()}`);
6934
+ this.$.$node_autoinstall(`${parent.name()}/${mod.name()}`); // force autoinstall through npm
6519
6935
  return true;
6520
6936
  }
6521
6937
  return false;
@@ -6709,6 +7125,7 @@ var $;
6709
7125
  continue;
6710
7126
  if (exclude && RegExp('[.=](' + exclude.join('|') + ')[.]', 'i').test(name))
6711
7127
  continue;
7128
+ // if (! child.exists()) return false
6712
7129
  const child_path = child.path();
6713
7130
  let files = [];
6714
7131
  if (/(meta\.tree)$/.test(name)) {
@@ -6725,8 +7142,29 @@ var $;
6725
7142
  }
6726
7143
  mods.push(...files, child);
6727
7144
  }
7145
+ //mods.sort( ( a , b )=> a.name().length - b.name().length )
6728
7146
  return mods;
6729
7147
  }
7148
+ // @ $mol_mem_key
7149
+ // modsRecursive( [ path , exclude ] : [ path : string , exclude? : readonly string[] ] ) : $mol_file[] {
7150
+ // var mod = $mol_file.absolute( path )
7151
+ // switch( mod.type() ) {
7152
+ // case 'file' :
7153
+ // return [ mod ]
7154
+ // case 'dir' :
7155
+ // var mods = [ mod ]
7156
+ // for( var m of this.mods( [ path , exclude ] ) ) {
7157
+ // if( m.type() !== 'dir' ) continue
7158
+ // for( var dep of this.modsRecursive( { path : m.path() , exclude } ) ) {
7159
+ // if( mods.indexOf( dep ) !== -1 ) continue
7160
+ // mods.push( dep )
7161
+ // }
7162
+ // }
7163
+ // return mods
7164
+ // default :
7165
+ // throw new Error( `Unsupported type "${mod.type()}" of "${mod.relate()}"` )
7166
+ // }
7167
+ // }
6730
7168
  sources([path, exclude]) {
6731
7169
  const mod = $mol_file.absolute(path);
6732
7170
  if (!mod.exists())
@@ -6835,6 +7273,7 @@ var $;
6835
7273
  }, {
6836
7274
  ...$node.typescript.sys,
6837
7275
  watchDirectory: (path, cb) => {
7276
+ // console.log('watchDirectory', path )
6838
7277
  watchers.set(path, cb);
6839
7278
  return { close() { } };
6840
7279
  },
@@ -6845,6 +7284,7 @@ var $;
6845
7284
  run = cb;
6846
7285
  },
6847
7286
  watchFile: (path, cb) => {
7287
+ // console.log('watchFile', path )
6848
7288
  watchers.set(path, cb);
6849
7289
  return { close() { } };
6850
7290
  },
@@ -6864,7 +7304,9 @@ var $;
6864
7304
  message: typeof text === 'string' ? text : text.messageText,
6865
7305
  });
6866
7306
  }
6867
- }, () => { }, [], {
7307
+ }, () => { }, //watch reports
7308
+ [], // project refs
7309
+ {
6868
7310
  synchronousWatchDirectory: true,
6869
7311
  watchFile: 5,
6870
7312
  watchDirectory: 0,
@@ -6875,6 +7317,7 @@ var $;
6875
7317
  recheck: () => {
6876
7318
  for (const path of paths) {
6877
7319
  const version = $node.fs.statSync(path).mtime.valueOf();
7320
+ // this.js_error( path, null )
6878
7321
  if (versions[path] && versions[path] !== version) {
6879
7322
  const watcher = watchers.get(path);
6880
7323
  if (watcher)
@@ -6907,6 +7350,7 @@ var $;
6907
7350
  map.sources = [src.relate()];
6908
7351
  return {
6909
7352
  text: this.$.$mol_sourcemap_strip(res.outputText),
7353
+ // .replace( /^\/\/#\ssourceMappingURL=[^\n]*/mg , '//' + src.relate() )+'\n',
6910
7354
  map: map,
6911
7355
  };
6912
7356
  }
@@ -7225,12 +7669,12 @@ var $;
7225
7669
  const errors = [];
7226
7670
  const paths = this.tsPaths({ path, exclude: exclude_ext, bundle });
7227
7671
  for (const path of paths) {
7228
- this.js_content(path);
7672
+ this.js_content(path); // recheck on file change
7229
7673
  const error = this.js_error(path);
7230
7674
  if (!error)
7231
7675
  continue;
7232
7676
  errors.push(new Error(error));
7233
- this.js_error(path, null);
7677
+ this.js_error(path, null); // ts will refill it on change
7234
7678
  }
7235
7679
  this.logBundle(target, Date.now() - start);
7236
7680
  if (errors.length) {
@@ -7489,7 +7933,7 @@ var $;
7489
7933
  if ($node_internal_check(dep))
7490
7934
  continue;
7491
7935
  if (dep === 'internal')
7492
- continue;
7936
+ continue; // @TODO: Prevent `internal` deps from `node:internal`.
7493
7937
  json.dependencies[dep] ??= `*`;
7494
7938
  }
7495
7939
  json.keywords = [...this.graph([path, exclude]).nodes]
@@ -7604,9 +8048,23 @@ var $;
7604
8048
  return [];
7605
8049
  const start = this.now();
7606
8050
  var pack = $mol_file.absolute(path);
7607
- var sources = [];
8051
+ var sources = []; // this.sourcesCSS( [ path , exclude ] )
7608
8052
  var target = pack.resolve(`-/${bundle}.css`);
7609
8053
  var targetMap = pack.resolve(`-/${bundle}.css.map`);
8054
+ // var root : any = null //$node['postcss'].root({})
8055
+ // sources.forEach(
8056
+ // src => {
8057
+ // var root2 = $node['postcss'].parse( src.content() , { from : src.path() } )
8058
+ // root = root ? root.append( root2 ) : root2
8059
+ // }
8060
+ // )
8061
+ // var processor = $node['postcss']([
8062
+ // $node[ 'postcss-custom-properties' ]({
8063
+ // preserve : true ,
8064
+ // }) ,
8065
+ // $node[ 'postcss-color-function' ]() ,
8066
+ // ])
8067
+ // var result = processor.process( root , { to : target.relate() , map : { inline : false } } )
7610
8068
  const result = {
7611
8069
  css: '/* CSS compiles into js bundle now! */',
7612
8070
  map: '/* CSS compiles into js bundle now! */',
@@ -7889,8 +8347,8 @@ var $;
7889
8347
  $mol_build.dependors['js'] = source => {
7890
8348
  var depends = {};
7891
8349
  var lines = String(source.text())
7892
- .replace(/\/\*[^]*?\*\//g, '')
7893
- .replace(/\/\/.*$/gm, '')
8350
+ .replace(/\/\*[^]*?\*\//g, '') // drop block comments
8351
+ .replace(/\/\/.*$/gm, '') // drop inline comments
7894
8352
  .split('\n');
7895
8353
  lines.forEach(function (line) {
7896
8354
  var indent = /^([\s\t]*)/.exec(line);
@@ -7910,8 +8368,8 @@ var $;
7910
8368
  $mol_build.dependors['ts'] = $mol_build.dependors['tsx'] = $mol_build.dependors['jam.js'] = $mol_build.dependors['tree.js'] = source => {
7911
8369
  var depends = {};
7912
8370
  var lines = String(source.text())
7913
- .replace(/\/\*(?!\*)[\s\S]*?\*\//g, '')
7914
- .replace(/\/\/.*$/gm, '')
8371
+ .replace(/\/\*(?!\*)[\s\S]*?\*\//g, '') // drop block comments except doc-comments
8372
+ .replace(/\/\/.*$/gm, '') // drop inline comments
7915
8373
  .split('\n');
7916
8374
  lines.forEach(function (line) {
7917
8375
  var indent = /^([\s\t]*)/.exec(line);
@@ -7957,8 +8415,8 @@ var $;
7957
8415
  '/mol/style/attach': 0,
7958
8416
  };
7959
8417
  var lines = String(source.text())
7960
- .replace(/\/\*[^]*?\*\//g, '')
7961
- .replace(/\/\/.*$/gm, '')
8418
+ .replace(/\/\*[^]*?\*\//g, '') // drop block comments
8419
+ .replace(/\/\/.*$/gm, '') // drop inline comments
7962
8420
  .split('\n');
7963
8421
  lines.forEach(function (line) {
7964
8422
  var indent = /^([\s\t]*)/.exec(line);
@@ -7975,8 +8433,8 @@ var $;
7975
8433
  '/mol/3d/glsl': 0,
7976
8434
  };
7977
8435
  var lines = String(source.text())
7978
- .replace(/\/\*[^]*?\*\//g, '')
7979
- .replace(/\/\/.*$/gm, '')
8436
+ .replace(/\/\*[^]*?\*\//g, '') // drop block comments
8437
+ .replace(/\/\/.*$/gm, '') // drop inline comments
7980
8438
  .split('\n');
7981
8439
  lines.forEach(function (line) {
7982
8440
  var indent = /^([\s\t]*)/.exec(line);
@@ -8024,6 +8482,8 @@ var $;
8024
8482
  const results = Object.create(null);
8025
8483
  for (const name of Object.keys(nets)) {
8026
8484
  for (const net of nets[name]) {
8485
+ // Skip over non-IPv4 and internal (i.e. 127.0.0.1) addresses
8486
+ // 'IPv4' is in Node <= 17, from 18 it's a number 4 or 6
8027
8487
  const familyV4Value = typeof net.family === 'string' ? 'IPv4' : 4;
8028
8488
  if (net.family === familyV4Value && !net.internal) {
8029
8489
  if (!results[name]) {
@@ -8051,6 +8511,16 @@ var $;
8051
8511
  socket() {
8052
8512
  const socket = new $node.ws.WebSocketServer({
8053
8513
  server: this.http(),
8514
+ // perMessageDeflate: {
8515
+ // zlibDeflateOptions: {
8516
+ // chunkSize: 1024,
8517
+ // memLevel: 7,
8518
+ // level: 3
8519
+ // },
8520
+ // zlibInflateOptions: {
8521
+ // chunkSize: 10 * 1024
8522
+ // },
8523
+ // }
8054
8524
  });
8055
8525
  socket.on('connection', line => {
8056
8526
  this.connections.add(line);
@@ -8134,6 +8604,7 @@ var $;
8134
8604
  class $mol_build_server extends $mol_server {
8135
8605
  static trace = false;
8136
8606
  sync_middleware(mdl) {
8607
+ // const wrapped = $mol_wire_async(mdl)
8137
8608
  return $mol_func_name_from(async (req, res, next) => {
8138
8609
  const wrapped = $mol_wire_async(mdl);
8139
8610
  try {
@@ -8160,6 +8631,13 @@ var $;
8160
8631
  expressGenerator() { return this.sync_middleware(this.handleRequest.bind(this)); }
8161
8632
  handleRequest(req, res) {
8162
8633
  try {
8634
+ // if( req.query._escaped_fragment_ ) {
8635
+ // const fragment = decodeURIComponent( String( req.query._escaped_fragment_ ) )
8636
+ // const url = req.protocol + '://' + req.get( 'host' ) + req.path + '#!' + fragment
8637
+ // const html = $mol_browser.html( url )
8638
+ // res.send( html ).end()
8639
+ // return
8640
+ // }
8163
8641
  if (!this.generate(req.url))
8164
8642
  return false;
8165
8643
  res.set('Cache-Control', 'no-cache, public');
@@ -8187,6 +8665,15 @@ var $;
8187
8665
  }
8188
8666
  generate(url) {
8189
8667
  $mol_wire_solid();
8668
+ /*
8669
+ Если использовать динамически подгружаемые через $mol_script модули
8670
+ То урл тут может быть вида /demo/app/-/node_modules/stockfish/-/stockfish.js
8671
+ В path должна попасть часть до первого /-/
8672
+ Динамически подгружаться могут обособленные, редко используемые скрипты.
8673
+ Например шахматы, встроенные в основное приложение.
8674
+ У которых здоровый двиг stockfish.js динамически загружается в воркер
8675
+ только при открытии шахмат.
8676
+ */
8190
8677
  const matched = url.match(/^(.*?)\/-\/((?:(?:\w+(?:.\w+)+)(?:\/-\/)?)+)$/);
8191
8678
  if (!matched)
8192
8679
  return null;
@@ -8213,6 +8700,7 @@ var $;
8213
8700
  const root = this.$.$mol_file.absolute(this.rootPublic());
8214
8701
  const dir = root.resolve(req.path);
8215
8702
  const path = dir.path();
8703
+ // Handle .well-known paths (browser/dev tools standard paths)
8216
8704
  if (req.path === '/.well-known/appspecific/com.chrome.devtools.json') {
8217
8705
  const root = this.build().root().path();
8218
8706
  const config = {
@@ -8232,7 +8720,10 @@ var $;
8232
8720
  res.end(JSON.stringify(config, null, 2));
8233
8721
  return true;
8234
8722
  }
8723
+ // ensure загружает сорцы, делает git pull, это не стоит делать на build-папках
8724
+ // Поэтому регулярка выше отсеивает build-папки
8235
8725
  this.ensure(path);
8726
+ // a/b/?c#d, a/b/-/
8236
8727
  const match = req.url.match(/(\/|.*[^\-]\/)([\?#].*)?$/);
8237
8728
  if (!match)
8238
8729
  return;
@@ -8331,11 +8822,16 @@ var $;
8331
8822
  for (const [line, path] of this.lines()) {
8332
8823
  this.notify([line, path]);
8333
8824
  }
8825
+ // this.bundles_keep()
8334
8826
  return socket;
8335
8827
  }
8336
8828
  bundles_count(reset) {
8337
8829
  return 1 + ($mol_wire_probe(() => this.bundles_count()) ?? 0);
8338
8830
  }
8831
+ /**
8832
+ * Держать в памяти собранные бандлы плохо, т.к. gc их может долго не утилизировать и node сожрет память и упадет.
8833
+ * Логичнее удалять отложенно, после того как reload-сокет отписался от пути и повторно не подписался.
8834
+ */
8339
8835
  bundles_keep() {
8340
8836
  const build = this.build();
8341
8837
  this.bundles_count();
@@ -8380,6 +8876,12 @@ var $;
8380
8876
  const build = this.build();
8381
8877
  try {
8382
8878
  const sources = build.sourcesAll([path, ['node']]);
8879
+ /**
8880
+ Бывает надо какой-то внешней программой в watch-режиме компилить js-ки или wasm
8881
+ и класть как артефакт в - (например, игровой движок на unity)
8882
+ При изменении этих файлов, надо перезапускать страницу.
8883
+ Если их класть не в -, а рядом с сорцами, то билдер mol будет пытаться их анализировать и упадет.
8884
+ */
8383
8885
  const resources = build.bundleFiles([path, ['node']]);
8384
8886
  for (const src of [...sources, ...resources])
8385
8887
  src.version();
@@ -8397,6 +8899,7 @@ var $;
8397
8899
  }
8398
8900
  notify([line, path]) {
8399
8901
  this.bundle_changed_at(path);
8902
+ // ignore initial
8400
8903
  if (!$mol_mem_cached(() => this.notify([line, path])))
8401
8904
  return true;
8402
8905
  this.$.$mol_log3_rise({
@@ -8484,6 +8987,11 @@ var $;
8484
8987
  })
8485
8988
  .on('SIGINT', () => process.exit(0))
8486
8989
  .on('close', () => process.exit(0));
8990
+ // this.$.$mol_log3_done({
8991
+ // place: this,
8992
+ // message: 'Watch dog started',
8993
+ // hint,
8994
+ // })
8487
8995
  return terminal;
8488
8996
  }
8489
8997
  }