mol_view_tree2_lib 1.0.196 → 1.0.197
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.d.ts +278 -1
- package/node.d.ts.map +1 -1
- package/node.deps.json +1 -1
- package/node.js +371 -19
- package/node.js.map +1 -1
- package/node.mjs +371 -19
- package/node.test.js +675 -36
- package/node.test.js.map +1 -1
- package/package.json +1 -1
- package/web.d.ts +282 -1
- package/web.d.ts.map +1 -1
- package/web.deps.json +1 -1
- package/web.js +364 -16
- package/web.js.map +1 -1
- package/web.mjs +364 -16
- package/web.test.js +304 -17
- package/web.test.js.map +1 -1
package/node.js
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(
|
|
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
|
}
|
|
@@ -1016,14 +1075,18 @@ var $;
|
|
|
1016
1075
|
];
|
|
1017
1076
|
},
|
|
1018
1077
|
'': (input, belt) => {
|
|
1078
|
+
// string
|
|
1019
1079
|
if (!input.type)
|
|
1020
1080
|
return [
|
|
1021
1081
|
input.data(JSON.stringify(input.text())),
|
|
1022
1082
|
];
|
|
1083
|
+
// variable
|
|
1023
1084
|
if (/^[\w$#][\w0-9$]*$/i.test(input.type))
|
|
1024
1085
|
return [
|
|
1025
1086
|
input.data(input.type),
|
|
1087
|
+
// ... input.hack( context ),
|
|
1026
1088
|
];
|
|
1089
|
+
// number
|
|
1027
1090
|
if ($mol_tree2_js_is_number(input.type))
|
|
1028
1091
|
return [
|
|
1029
1092
|
input.data(input.type)
|
|
@@ -1348,6 +1411,7 @@ var $;
|
|
|
1348
1411
|
"use strict";
|
|
1349
1412
|
var $;
|
|
1350
1413
|
(function ($) {
|
|
1414
|
+
/** Makes JSON from json.tree. */
|
|
1351
1415
|
function $mol_tree2_to_json(tree) {
|
|
1352
1416
|
if (!tree.type) {
|
|
1353
1417
|
if (tree.kids.every(kid => !kid.type))
|
|
@@ -1613,8 +1677,10 @@ var $;
|
|
|
1613
1677
|
var $;
|
|
1614
1678
|
(function ($) {
|
|
1615
1679
|
let x = /x/[Symbol.matchAll];
|
|
1680
|
+
/** Type safe reguar expression builder */
|
|
1616
1681
|
class $mol_regexp extends RegExp {
|
|
1617
1682
|
groups;
|
|
1683
|
+
/** Prefer to use $mol_regexp.from */
|
|
1618
1684
|
constructor(source, flags = 'gsu', groups = []) {
|
|
1619
1685
|
super(source, flags);
|
|
1620
1686
|
this.groups = groups;
|
|
@@ -1634,12 +1700,14 @@ var $;
|
|
|
1634
1700
|
this.lastIndex = index;
|
|
1635
1701
|
}
|
|
1636
1702
|
}
|
|
1703
|
+
/** Parses input and returns found capture groups or null */
|
|
1637
1704
|
[Symbol.match](str) {
|
|
1638
1705
|
const res = [...this[Symbol.matchAll](str)].filter(r => r.groups).map(r => r[0]);
|
|
1639
1706
|
if (!res.length)
|
|
1640
1707
|
return null;
|
|
1641
1708
|
return res;
|
|
1642
1709
|
}
|
|
1710
|
+
/** Splits string by regexp edges */
|
|
1643
1711
|
[Symbol.split](str) {
|
|
1644
1712
|
const res = [];
|
|
1645
1713
|
let token_last = null;
|
|
@@ -1694,12 +1762,14 @@ var $;
|
|
|
1694
1762
|
get native() {
|
|
1695
1763
|
return new RegExp(this.source, this.flags);
|
|
1696
1764
|
}
|
|
1765
|
+
/** Makes regexp that greedy repeats this pattern with delimiter */
|
|
1697
1766
|
static separated(chunk, sep) {
|
|
1698
1767
|
return $mol_regexp.from([
|
|
1699
1768
|
$mol_regexp.repeat_greedy([[chunk], sep], 0),
|
|
1700
1769
|
chunk,
|
|
1701
1770
|
]);
|
|
1702
1771
|
}
|
|
1772
|
+
/** Makes regexp that non-greedy repeats this pattern from min to max count */
|
|
1703
1773
|
static repeat(source, min = 0, max = Number.POSITIVE_INFINITY) {
|
|
1704
1774
|
const regexp = $mol_regexp.from(source);
|
|
1705
1775
|
const upper = Number.isFinite(max) ? max : '';
|
|
@@ -1715,6 +1785,7 @@ var $;
|
|
|
1715
1785
|
};
|
|
1716
1786
|
return regexp2;
|
|
1717
1787
|
}
|
|
1788
|
+
/** Makes regexp that greedy repeats this pattern from min to max count */
|
|
1718
1789
|
static repeat_greedy(source, min = 0, max = Number.POSITIVE_INFINITY) {
|
|
1719
1790
|
const regexp = $mol_regexp.from(source);
|
|
1720
1791
|
const upper = Number.isFinite(max) ? max : '';
|
|
@@ -1730,6 +1801,7 @@ var $;
|
|
|
1730
1801
|
};
|
|
1731
1802
|
return regexp2;
|
|
1732
1803
|
}
|
|
1804
|
+
/** Makes regexp that match any of options */
|
|
1733
1805
|
static vary(sources, flags = 'gsu') {
|
|
1734
1806
|
const groups = [];
|
|
1735
1807
|
const chunks = sources.map(source => {
|
|
@@ -1739,17 +1811,21 @@ var $;
|
|
|
1739
1811
|
});
|
|
1740
1812
|
return new $mol_regexp(`(?:${chunks.join('|')})`, flags, groups);
|
|
1741
1813
|
}
|
|
1814
|
+
/** Makes regexp that allow absent of this pattern */
|
|
1742
1815
|
static optional(source) {
|
|
1743
1816
|
return $mol_regexp.repeat_greedy(source, 0, 1);
|
|
1744
1817
|
}
|
|
1818
|
+
/** Makes regexp that look ahead for pattern */
|
|
1745
1819
|
static force_after(source) {
|
|
1746
1820
|
const regexp = $mol_regexp.from(source);
|
|
1747
1821
|
return new $mol_regexp(`(?=${regexp.source})`, regexp.flags, regexp.groups);
|
|
1748
1822
|
}
|
|
1823
|
+
/** Makes regexp that look ahead for pattern */
|
|
1749
1824
|
static forbid_after(source) {
|
|
1750
1825
|
const regexp = $mol_regexp.from(source);
|
|
1751
1826
|
return new $mol_regexp(`(?!${regexp.source})`, regexp.flags, regexp.groups);
|
|
1752
1827
|
}
|
|
1828
|
+
/** Converts some js values to regexp */
|
|
1753
1829
|
static from(source, { ignoreCase, multiline } = {
|
|
1754
1830
|
ignoreCase: false,
|
|
1755
1831
|
multiline: false,
|
|
@@ -1850,9 +1926,11 @@ var $;
|
|
|
1850
1926
|
return regexp;
|
|
1851
1927
|
}
|
|
1852
1928
|
}
|
|
1929
|
+
/** Makes regexp which includes only unicode category */
|
|
1853
1930
|
static unicode_only(...category) {
|
|
1854
1931
|
return new $mol_regexp(`\\p{${category.join('=')}}`);
|
|
1855
1932
|
}
|
|
1933
|
+
/** Makes regexp which excludes unicode category */
|
|
1856
1934
|
static unicode_except(...category) {
|
|
1857
1935
|
return new $mol_regexp(`\\P{${category.join('=')}}`);
|
|
1858
1936
|
}
|
|
@@ -1976,13 +2054,23 @@ var $;
|
|
|
1976
2054
|
var $;
|
|
1977
2055
|
(function ($) {
|
|
1978
2056
|
const err = $mol_view_tree2_error_str;
|
|
2057
|
+
const is_writable = (input) => input.type.includes('?');
|
|
1979
2058
|
function $mol_view_tree2_class_props(klass) {
|
|
1980
2059
|
let props = this.$mol_view_tree2_class_super(klass);
|
|
2060
|
+
// ! syntax to * and ?val syntax to ?
|
|
1981
2061
|
props = props.clone(props.hack({
|
|
1982
2062
|
'': (node, belt) => {
|
|
1983
|
-
const
|
|
2063
|
+
const next = node.type.indexOf('?');
|
|
2064
|
+
const id = node.type.indexOf('!');
|
|
2065
|
+
let normal = node.type;
|
|
2066
|
+
const ch = node.type[id + 1];
|
|
2067
|
+
if (id !== -1 && ch?.toUpperCase() !== ch?.toLowerCase())
|
|
2068
|
+
normal = `${normal.substring(0, id)}*${next === -1 ? '' : '?'}`;
|
|
2069
|
+
else if (next !== -1)
|
|
2070
|
+
normal = normal.substring(0, next + 1);
|
|
1984
2071
|
if (node.type === normal)
|
|
1985
2072
|
return [node.clone(node.hack(belt))];
|
|
2073
|
+
console.warn(`Syntax ${node.type} is deprecated. Use ${normal} instead`);
|
|
1986
2074
|
return [node.struct(normal, node.hack(belt))];
|
|
1987
2075
|
}
|
|
1988
2076
|
}));
|
|
@@ -2019,12 +2107,26 @@ var $;
|
|
|
2019
2107
|
this.$mol_fail(err `Need a child ${operator.span}`);
|
|
2020
2108
|
if (!context.factory)
|
|
2021
2109
|
this.$mol_fail(err `Need a parent ${left.span}`);
|
|
2110
|
+
if (is_writable(left) !== is_writable(right))
|
|
2111
|
+
this.$mol_fail(err `Left and right operands are not compatible at ${operator.span}`);
|
|
2022
2112
|
add_inner(right.clone([
|
|
2023
2113
|
right.struct('=', [
|
|
2024
2114
|
context.factory.struct(context.factory.type.replace(/\*.*/, '*'), [left.clone([])]),
|
|
2025
2115
|
]),
|
|
2026
2116
|
]));
|
|
2027
2117
|
}
|
|
2118
|
+
else if (operator?.type === "<=>") {
|
|
2119
|
+
const right = operator.kids[0];
|
|
2120
|
+
if (!right)
|
|
2121
|
+
this.$mol_fail(err `Need a child ${operator.span}`);
|
|
2122
|
+
if (!is_writable(left))
|
|
2123
|
+
this.$mol_fail(err `Expected writable at ${left.span}`);
|
|
2124
|
+
if (!is_writable(right))
|
|
2125
|
+
this.$mol_fail(err `Expected writable at ${right.span}`);
|
|
2126
|
+
}
|
|
2127
|
+
else if (operator?.type === "<=" && is_writable(left)) {
|
|
2128
|
+
this.$mol_fail(err `Expected readonly at ${left.span}`);
|
|
2129
|
+
}
|
|
2028
2130
|
if (right)
|
|
2029
2131
|
context = { factory: right.clone([]) };
|
|
2030
2132
|
else if (operator && !context.factory && $mol_view_tree2_class_match(operator)) {
|
|
@@ -2164,6 +2266,7 @@ var $;
|
|
|
2164
2266
|
const left_parts = this.$mol_view_tree2_prop_parts(left);
|
|
2165
2267
|
const right_parts = this.$mol_view_tree2_prop_parts(right);
|
|
2166
2268
|
let conflict;
|
|
2269
|
+
// if (left_parts.next && right_parts.next) conflict = 'next'
|
|
2167
2270
|
if (left_parts.key && right_parts.key)
|
|
2168
2271
|
conflict = 'key';
|
|
2169
2272
|
if (conflict) {
|
|
@@ -2288,7 +2391,7 @@ var $;
|
|
|
2288
2391
|
}, context);
|
|
2289
2392
|
return prop.struct('indent', [
|
|
2290
2393
|
prop.struct('line', [
|
|
2291
|
-
channel_signature.call(this, prop, ...val),
|
|
2394
|
+
channel_signature.call(this, prop, ...val), // Parameter, not Return
|
|
2292
2395
|
prop.data(': '),
|
|
2293
2396
|
...val,
|
|
2294
2397
|
])
|
|
@@ -2329,6 +2432,7 @@ var $;
|
|
|
2329
2432
|
"use strict";
|
|
2330
2433
|
var $;
|
|
2331
2434
|
(function ($) {
|
|
2435
|
+
/** Generates unique identifier. */
|
|
2332
2436
|
function $mol_guid(length = 8, exists = () => false) {
|
|
2333
2437
|
for (;;) {
|
|
2334
2438
|
let id = Math.random().toString(36).substring(2, length + 2).toUpperCase();
|
|
@@ -2344,11 +2448,16 @@ var $;
|
|
|
2344
2448
|
"use strict";
|
|
2345
2449
|
var $;
|
|
2346
2450
|
(function ($) {
|
|
2451
|
+
/** Special status statuses. */
|
|
2347
2452
|
let $mol_wire_cursor;
|
|
2348
2453
|
(function ($mol_wire_cursor) {
|
|
2454
|
+
/** Update required. */
|
|
2349
2455
|
$mol_wire_cursor[$mol_wire_cursor["stale"] = -1] = "stale";
|
|
2456
|
+
/** Some of (transitive) pub update required. */
|
|
2350
2457
|
$mol_wire_cursor[$mol_wire_cursor["doubt"] = -2] = "doubt";
|
|
2458
|
+
/** Actual state but may be dropped. */
|
|
2351
2459
|
$mol_wire_cursor[$mol_wire_cursor["fresh"] = -3] = "fresh";
|
|
2460
|
+
/** State will never be changed. */
|
|
2352
2461
|
$mol_wire_cursor[$mol_wire_cursor["final"] = -4] = "final";
|
|
2353
2462
|
})($mol_wire_cursor = $.$mol_wire_cursor || ($.$mol_wire_cursor = {}));
|
|
2354
2463
|
})($ || ($ = {}));
|
|
@@ -2357,6 +2466,9 @@ var $;
|
|
|
2357
2466
|
"use strict";
|
|
2358
2467
|
var $;
|
|
2359
2468
|
(function ($) {
|
|
2469
|
+
/**
|
|
2470
|
+
* Collects subscribers in compact array. 28B
|
|
2471
|
+
*/
|
|
2360
2472
|
class $mol_wire_pub extends Object {
|
|
2361
2473
|
constructor(id = `$mol_wire_pub:${$mol_guid()}`) {
|
|
2362
2474
|
super();
|
|
@@ -2364,10 +2476,17 @@ var $;
|
|
|
2364
2476
|
}
|
|
2365
2477
|
[Symbol.toStringTag];
|
|
2366
2478
|
data = [];
|
|
2479
|
+
// Derived objects should be Arrays.
|
|
2367
2480
|
static get [Symbol.species]() {
|
|
2368
2481
|
return Array;
|
|
2369
2482
|
}
|
|
2370
|
-
|
|
2483
|
+
/**
|
|
2484
|
+
* Index of first subscriber.
|
|
2485
|
+
*/
|
|
2486
|
+
sub_from = 0; // 4B
|
|
2487
|
+
/**
|
|
2488
|
+
* All current subscribers.
|
|
2489
|
+
*/
|
|
2371
2490
|
get sub_list() {
|
|
2372
2491
|
const res = [];
|
|
2373
2492
|
for (let i = this.sub_from; i < this.data.length; i += 2) {
|
|
@@ -2375,14 +2494,23 @@ var $;
|
|
|
2375
2494
|
}
|
|
2376
2495
|
return res;
|
|
2377
2496
|
}
|
|
2497
|
+
/**
|
|
2498
|
+
* Has any subscribers or not.
|
|
2499
|
+
*/
|
|
2378
2500
|
get sub_empty() {
|
|
2379
2501
|
return this.sub_from === this.data.length;
|
|
2380
2502
|
}
|
|
2503
|
+
/**
|
|
2504
|
+
* Subscribe subscriber to this publisher events and return position of subscriber that required to unsubscribe.
|
|
2505
|
+
*/
|
|
2381
2506
|
sub_on(sub, pub_pos) {
|
|
2382
2507
|
const pos = this.data.length;
|
|
2383
2508
|
this.data.push(sub, pub_pos);
|
|
2384
2509
|
return pos;
|
|
2385
2510
|
}
|
|
2511
|
+
/**
|
|
2512
|
+
* Unsubscribe subscriber from this publisher events by subscriber position provided by `on(pub)`.
|
|
2513
|
+
*/
|
|
2386
2514
|
sub_off(sub_pos) {
|
|
2387
2515
|
if (!(sub_pos < this.data.length)) {
|
|
2388
2516
|
$mol_fail(new Error(`Wrong pos ${sub_pos}`));
|
|
@@ -2395,21 +2523,39 @@ var $;
|
|
|
2395
2523
|
if (end === this.sub_from)
|
|
2396
2524
|
this.reap();
|
|
2397
2525
|
}
|
|
2526
|
+
/**
|
|
2527
|
+
* Called when last sub was unsubscribed.
|
|
2528
|
+
**/
|
|
2398
2529
|
reap() { }
|
|
2530
|
+
/**
|
|
2531
|
+
* Autowire this publisher with current subscriber.
|
|
2532
|
+
**/
|
|
2399
2533
|
promote() {
|
|
2400
2534
|
$mol_wire_auto()?.track_next(this);
|
|
2401
2535
|
}
|
|
2536
|
+
/**
|
|
2537
|
+
* Enforce actualization. Should not throw errors.
|
|
2538
|
+
*/
|
|
2402
2539
|
fresh() { }
|
|
2540
|
+
/**
|
|
2541
|
+
* Allow to put data to caches in the subtree.
|
|
2542
|
+
*/
|
|
2403
2543
|
complete() { }
|
|
2404
2544
|
get incompleted() {
|
|
2405
2545
|
return false;
|
|
2406
2546
|
}
|
|
2547
|
+
/**
|
|
2548
|
+
* Notify subscribers about self changes.
|
|
2549
|
+
*/
|
|
2407
2550
|
emit(quant = $mol_wire_cursor.stale) {
|
|
2408
2551
|
for (let i = this.sub_from; i < this.data.length; i += 2) {
|
|
2409
2552
|
;
|
|
2410
2553
|
this.data[i].absorb(quant, this.data[i + 1]);
|
|
2411
2554
|
}
|
|
2412
2555
|
}
|
|
2556
|
+
/**
|
|
2557
|
+
* Moves peer from one position to another. Doesn't clear data at old position!
|
|
2558
|
+
*/
|
|
2413
2559
|
peer_move(from_pos, to_pos) {
|
|
2414
2560
|
const peer = this.data[from_pos];
|
|
2415
2561
|
const self_pos = this.data[from_pos + 1];
|
|
@@ -2417,6 +2563,9 @@ var $;
|
|
|
2417
2563
|
this.data[to_pos + 1] = self_pos;
|
|
2418
2564
|
peer.peer_repos(self_pos, to_pos);
|
|
2419
2565
|
}
|
|
2566
|
+
/**
|
|
2567
|
+
* Updates self position in the peer.
|
|
2568
|
+
*/
|
|
2420
2569
|
peer_repos(peer_pos, self_pos) {
|
|
2421
2570
|
this.data[peer_pos + 1] = self_pos;
|
|
2422
2571
|
}
|
|
@@ -2432,10 +2581,16 @@ var $;
|
|
|
2432
2581
|
var $;
|
|
2433
2582
|
(function ($) {
|
|
2434
2583
|
$.$mol_wire_auto_sub = null;
|
|
2584
|
+
/**
|
|
2585
|
+
* When fulfilled, all publishers are promoted to this subscriber on access to its.
|
|
2586
|
+
*/
|
|
2435
2587
|
function $mol_wire_auto(next = $.$mol_wire_auto_sub) {
|
|
2436
2588
|
return $.$mol_wire_auto_sub = next;
|
|
2437
2589
|
}
|
|
2438
2590
|
$.$mol_wire_auto = $mol_wire_auto;
|
|
2591
|
+
/**
|
|
2592
|
+
* Affection queue. Used to prevent accidental stack overflow on emit.
|
|
2593
|
+
*/
|
|
2439
2594
|
$.$mol_wire_affected = [];
|
|
2440
2595
|
})($ || ($ = {}));
|
|
2441
2596
|
|
|
@@ -2443,6 +2598,7 @@ var $;
|
|
|
2443
2598
|
"use strict";
|
|
2444
2599
|
var $;
|
|
2445
2600
|
(function ($) {
|
|
2601
|
+
// https://docs.google.com/document/d/1FTascZXT9cxfetuPRT2eXPQKXui4nWFivUnS_335T3U/preview#
|
|
2446
2602
|
$['devtoolsFormatters'] ||= [];
|
|
2447
2603
|
function $mol_dev_format_register(config) {
|
|
2448
2604
|
$['devtoolsFormatters'].push(config);
|
|
@@ -2494,6 +2650,7 @@ var $;
|
|
|
2494
2650
|
return false;
|
|
2495
2651
|
if (!val)
|
|
2496
2652
|
return false;
|
|
2653
|
+
// if( Error.isError( val ) ) true
|
|
2497
2654
|
if (val[$.$mol_dev_format_body])
|
|
2498
2655
|
return true;
|
|
2499
2656
|
return false;
|
|
@@ -2511,12 +2668,16 @@ var $;
|
|
|
2511
2668
|
return $.$mol_dev_format_accent($mol_dev_format_native(val), '💨', $mol_dev_format_native(error), '');
|
|
2512
2669
|
}
|
|
2513
2670
|
}
|
|
2671
|
+
// if( Error.isError( val ) ) {
|
|
2672
|
+
// return $mol_dev_format_native( val )
|
|
2673
|
+
// }
|
|
2514
2674
|
return null;
|
|
2515
2675
|
},
|
|
2516
2676
|
});
|
|
2517
2677
|
function $mol_dev_format_native(obj) {
|
|
2518
2678
|
if (typeof obj === 'undefined')
|
|
2519
2679
|
return $.$mol_dev_format_shade('undefined');
|
|
2680
|
+
// if( ![ 'object', 'function', 'symbol' ].includes( typeof obj ) ) return obj
|
|
2520
2681
|
return [
|
|
2521
2682
|
'object',
|
|
2522
2683
|
{
|
|
@@ -2574,6 +2735,9 @@ var $;
|
|
|
2574
2735
|
'margin-left': '13px'
|
|
2575
2736
|
});
|
|
2576
2737
|
class Stack extends Array {
|
|
2738
|
+
// [ Symbol.toPrimitive ]() {
|
|
2739
|
+
// return this.toString()
|
|
2740
|
+
// }
|
|
2577
2741
|
toString() {
|
|
2578
2742
|
return this.join('\n');
|
|
2579
2743
|
}
|
|
@@ -2596,6 +2760,7 @@ var $;
|
|
|
2596
2760
|
this.method = call.getMethodName() ?? '';
|
|
2597
2761
|
if (this.method === this.function)
|
|
2598
2762
|
this.method = '';
|
|
2763
|
+
// const func = c.getFunction()
|
|
2599
2764
|
this.pos = [call.getEnclosingLineNumber() ?? 0, call.getEnclosingColumnNumber() ?? 0];
|
|
2600
2765
|
this.eval = call.getEvalOrigin() ?? '';
|
|
2601
2766
|
this.source = call.getScriptNameOrSourceURL() ?? '';
|
|
@@ -2642,9 +2807,16 @@ var $;
|
|
|
2642
2807
|
"use strict";
|
|
2643
2808
|
var $;
|
|
2644
2809
|
(function ($) {
|
|
2810
|
+
/**
|
|
2811
|
+
* Publisher that can auto collect other publishers. 32B
|
|
2812
|
+
*
|
|
2813
|
+
* P1 P2 P3 P4 S1 S2 S3
|
|
2814
|
+
* ^ ^
|
|
2815
|
+
* pubs_from subs_from
|
|
2816
|
+
*/
|
|
2645
2817
|
class $mol_wire_pub_sub extends $mol_wire_pub {
|
|
2646
|
-
pub_from = 0;
|
|
2647
|
-
cursor = $mol_wire_cursor.stale;
|
|
2818
|
+
pub_from = 0; // 4B
|
|
2819
|
+
cursor = $mol_wire_cursor.stale; // 4B
|
|
2648
2820
|
get temp() {
|
|
2649
2821
|
return false;
|
|
2650
2822
|
}
|
|
@@ -2762,10 +2934,27 @@ var $;
|
|
|
2762
2934
|
return;
|
|
2763
2935
|
this.cursor = quant;
|
|
2764
2936
|
this.emit($mol_wire_cursor.doubt);
|
|
2937
|
+
// if( pos >= 0 && pos < this.sub_from - 2 ) {
|
|
2938
|
+
// const pub = this.data[ pos ] as $mol_wire_pub
|
|
2939
|
+
// if( pub instanceof $mol_wire_task ) return
|
|
2940
|
+
// for(
|
|
2941
|
+
// let cursor = this.pub_from;
|
|
2942
|
+
// cursor < this.sub_from;
|
|
2943
|
+
// cursor += 2
|
|
2944
|
+
// ) {
|
|
2945
|
+
// const pub = this.data[ cursor ] as $mol_wire_pub
|
|
2946
|
+
// if( pub instanceof $mol_wire_task ) {
|
|
2947
|
+
// pub.destructor()
|
|
2948
|
+
// }
|
|
2949
|
+
// }
|
|
2950
|
+
// }
|
|
2765
2951
|
}
|
|
2766
2952
|
[$mol_dev_format_head]() {
|
|
2767
2953
|
return $mol_dev_format_native(this);
|
|
2768
2954
|
}
|
|
2955
|
+
/**
|
|
2956
|
+
* Is subscribed to any publisher or not.
|
|
2957
|
+
*/
|
|
2769
2958
|
get pub_empty() {
|
|
2770
2959
|
return this.sub_from === this.pub_from;
|
|
2771
2960
|
}
|
|
@@ -2821,6 +3010,13 @@ var $;
|
|
|
2821
3010
|
var $;
|
|
2822
3011
|
(function ($) {
|
|
2823
3012
|
const wrappers = new WeakMap();
|
|
3013
|
+
/**
|
|
3014
|
+
* Suspendable task with support both sync/async api.
|
|
3015
|
+
*
|
|
3016
|
+
* A1 A2 A3 A4 P1 P2 P3 P4 S1 S2 S3
|
|
3017
|
+
* ^ ^ ^
|
|
3018
|
+
* args_from pubs_from subs_from
|
|
3019
|
+
**/
|
|
2824
3020
|
class $mol_wire_fiber extends $mol_wire_pub_sub {
|
|
2825
3021
|
task;
|
|
2826
3022
|
host;
|
|
@@ -2841,6 +3037,7 @@ var $;
|
|
|
2841
3037
|
});
|
|
2842
3038
|
}
|
|
2843
3039
|
static sync() {
|
|
3040
|
+
// Sync whole fiber graph
|
|
2844
3041
|
while (this.planning.size) {
|
|
2845
3042
|
for (const fiber of this.planning) {
|
|
2846
3043
|
this.planning.delete(fiber);
|
|
@@ -2851,6 +3048,7 @@ var $;
|
|
|
2851
3048
|
fiber.fresh();
|
|
2852
3049
|
}
|
|
2853
3050
|
}
|
|
3051
|
+
// Collect garbage
|
|
2854
3052
|
while (this.reaping.size) {
|
|
2855
3053
|
const fibers = this.reaping;
|
|
2856
3054
|
this.reaping = new Set;
|
|
@@ -3002,6 +3200,10 @@ var $;
|
|
|
3002
3200
|
this.cursor = $mol_wire_cursor.stale;
|
|
3003
3201
|
this.fresh();
|
|
3004
3202
|
}
|
|
3203
|
+
/**
|
|
3204
|
+
* Synchronous execution. Throws Promise when waits async task (SuspenseAPI provider).
|
|
3205
|
+
* Should be called inside SuspenseAPI consumer (ie fiber).
|
|
3206
|
+
*/
|
|
3005
3207
|
sync() {
|
|
3006
3208
|
if (!$mol_wire_fiber.warm) {
|
|
3007
3209
|
return this.result();
|
|
@@ -3016,6 +3218,10 @@ var $;
|
|
|
3016
3218
|
}
|
|
3017
3219
|
return this.cache;
|
|
3018
3220
|
}
|
|
3221
|
+
/**
|
|
3222
|
+
* Asynchronous execution.
|
|
3223
|
+
* It's SuspenseAPI consumer. So SuspenseAPI providers can be called inside.
|
|
3224
|
+
*/
|
|
3019
3225
|
async async_raw() {
|
|
3020
3226
|
while (true) {
|
|
3021
3227
|
this.fresh();
|
|
@@ -3028,6 +3234,7 @@ var $;
|
|
|
3028
3234
|
if (!$mol_promise_like(this.cache))
|
|
3029
3235
|
return this.cache;
|
|
3030
3236
|
if (this.cursor === $mol_wire_cursor.final) {
|
|
3237
|
+
// never ends on destructed fiber
|
|
3031
3238
|
await new Promise(() => { });
|
|
3032
3239
|
}
|
|
3033
3240
|
}
|
|
@@ -3075,6 +3282,7 @@ var $;
|
|
|
3075
3282
|
var $;
|
|
3076
3283
|
(function ($) {
|
|
3077
3284
|
const TypedArray = Object.getPrototypeOf(Uint8Array);
|
|
3285
|
+
/** Returns string key for any value. */
|
|
3078
3286
|
function $mol_key(value) {
|
|
3079
3287
|
primitives: {
|
|
3080
3288
|
if (typeof value === 'bigint')
|
|
@@ -3082,9 +3290,9 @@ var $;
|
|
|
3082
3290
|
if (typeof value === 'symbol')
|
|
3083
3291
|
return `Symbol(${value.description})`;
|
|
3084
3292
|
if (!value)
|
|
3085
|
-
return JSON.stringify(value);
|
|
3293
|
+
return JSON.stringify(value); // 0, null, ""
|
|
3086
3294
|
if (typeof value !== 'object' && typeof value !== 'function')
|
|
3087
|
-
return JSON.stringify(value);
|
|
3295
|
+
return JSON.stringify(value); // boolean, number, string
|
|
3088
3296
|
}
|
|
3089
3297
|
caching: {
|
|
3090
3298
|
let key = $mol_key_store.get(value);
|
|
@@ -3162,6 +3370,10 @@ var $;
|
|
|
3162
3370
|
var $;
|
|
3163
3371
|
(function ($) {
|
|
3164
3372
|
$.$mol_compare_deep_cache = new WeakMap();
|
|
3373
|
+
/**
|
|
3374
|
+
* Deeply compares two values. Returns true if equal.
|
|
3375
|
+
* Define `Symbol.toPrimitive` to customize.
|
|
3376
|
+
*/
|
|
3165
3377
|
function $mol_compare_deep(left, right) {
|
|
3166
3378
|
if (Object.is(left, right))
|
|
3167
3379
|
return true;
|
|
@@ -3301,6 +3513,7 @@ var $;
|
|
|
3301
3513
|
"use strict";
|
|
3302
3514
|
var $;
|
|
3303
3515
|
(function ($) {
|
|
3516
|
+
/** Log begin of collapsed group only when some logged inside, returns func to close group */
|
|
3304
3517
|
function $mol_log3_area_lazy(event) {
|
|
3305
3518
|
const self = this.$;
|
|
3306
3519
|
const stack = self.$mol_log3_stack;
|
|
@@ -3325,6 +3538,7 @@ var $;
|
|
|
3325
3538
|
"use strict";
|
|
3326
3539
|
var $;
|
|
3327
3540
|
(function ($) {
|
|
3541
|
+
/** Module for working with terminal. Text coloring when output in terminal */
|
|
3328
3542
|
class $mol_term_color {
|
|
3329
3543
|
static reset = this.ansi(0, 0);
|
|
3330
3544
|
static bold = this.ansi(1, 22);
|
|
@@ -3396,6 +3610,7 @@ var $;
|
|
|
3396
3610
|
"use strict";
|
|
3397
3611
|
var $;
|
|
3398
3612
|
(function ($) {
|
|
3613
|
+
/** One-shot fiber */
|
|
3399
3614
|
class $mol_wire_task extends $mol_wire_fiber {
|
|
3400
3615
|
static getter(task) {
|
|
3401
3616
|
return function $mol_wire_task_get(host, args) {
|
|
@@ -3421,6 +3636,7 @@ var $;
|
|
|
3421
3636
|
}
|
|
3422
3637
|
const key = (host?.[Symbol.toStringTag] ?? host) + ('.' + task.name + '<#>');
|
|
3423
3638
|
const next = new $mol_wire_task(key, task, host, args);
|
|
3639
|
+
// Disabled because non-idempotency is required for try-catch
|
|
3424
3640
|
if (existen?.temp) {
|
|
3425
3641
|
$$.$mol_log3_warn({
|
|
3426
3642
|
place: '$mol_wire_task',
|
|
@@ -3453,7 +3669,7 @@ var $;
|
|
|
3453
3669
|
try {
|
|
3454
3670
|
next[Symbol.toStringTag] = this[Symbol.toStringTag];
|
|
3455
3671
|
}
|
|
3456
|
-
catch {
|
|
3672
|
+
catch { // Promises throw in strict mode
|
|
3457
3673
|
Object.defineProperty(next, Symbol.toStringTag, { value: this[Symbol.toStringTag] });
|
|
3458
3674
|
}
|
|
3459
3675
|
}
|
|
@@ -3478,6 +3694,9 @@ var $;
|
|
|
3478
3694
|
"use strict";
|
|
3479
3695
|
var $;
|
|
3480
3696
|
(function ($) {
|
|
3697
|
+
/**
|
|
3698
|
+
* Decorates method to fiber to ensure it is executed only once inside other fiber.
|
|
3699
|
+
*/
|
|
3481
3700
|
function $mol_wire_method(host, field, descr) {
|
|
3482
3701
|
if (!descr)
|
|
3483
3702
|
descr = Reflect.getOwnPropertyDescriptor(host, field);
|
|
@@ -3559,6 +3778,7 @@ var $;
|
|
|
3559
3778
|
"use strict";
|
|
3560
3779
|
var $;
|
|
3561
3780
|
(function ($) {
|
|
3781
|
+
/** Long-living fiber. */
|
|
3562
3782
|
class $mol_wire_atom extends $mol_wire_fiber {
|
|
3563
3783
|
static solo(host, task) {
|
|
3564
3784
|
const field = task.name + '()';
|
|
@@ -3609,7 +3829,11 @@ var $;
|
|
|
3609
3829
|
}
|
|
3610
3830
|
$mol_wire_atom.watching.add(this);
|
|
3611
3831
|
}
|
|
3832
|
+
/**
|
|
3833
|
+
* Update atom value through another temp fiber.
|
|
3834
|
+
*/
|
|
3612
3835
|
resync(args) {
|
|
3836
|
+
// enforce pulling tasks abort
|
|
3613
3837
|
for (let cursor = this.pub_from; cursor < this.sub_from; cursor += 2) {
|
|
3614
3838
|
const pub = this.data[cursor];
|
|
3615
3839
|
if (pub && pub instanceof $mol_wire_task) {
|
|
@@ -3670,7 +3894,7 @@ var $;
|
|
|
3670
3894
|
try {
|
|
3671
3895
|
next[Symbol.toStringTag] = this[Symbol.toStringTag];
|
|
3672
3896
|
}
|
|
3673
|
-
catch {
|
|
3897
|
+
catch { // Promises throw in strict mode
|
|
3674
3898
|
Object.defineProperty(next, Symbol.toStringTag, { value: this[Symbol.toStringTag] });
|
|
3675
3899
|
}
|
|
3676
3900
|
}
|
|
@@ -3698,6 +3922,7 @@ var $;
|
|
|
3698
3922
|
"use strict";
|
|
3699
3923
|
var $;
|
|
3700
3924
|
(function ($) {
|
|
3925
|
+
/** Decorates solo object channel to [mol_wire_atom](../atom/atom.ts). */
|
|
3701
3926
|
function $mol_wire_solo(host, field, descr) {
|
|
3702
3927
|
if (!descr)
|
|
3703
3928
|
descr = Reflect.getOwnPropertyDescriptor(host, field);
|
|
@@ -3736,6 +3961,7 @@ var $;
|
|
|
3736
3961
|
"use strict";
|
|
3737
3962
|
var $;
|
|
3738
3963
|
(function ($) {
|
|
3964
|
+
/** Reactive memoizing multiplexed property decorator. */
|
|
3739
3965
|
function $mol_wire_plex(host, field, descr) {
|
|
3740
3966
|
if (!descr)
|
|
3741
3967
|
descr = Reflect.getOwnPropertyDescriptor(host, field);
|
|
@@ -3774,7 +4000,25 @@ var $;
|
|
|
3774
4000
|
"use strict";
|
|
3775
4001
|
var $;
|
|
3776
4002
|
(function ($) {
|
|
4003
|
+
/**
|
|
4004
|
+
* Reactive memoizing solo property decorator from [mol_wire](../wire/README.md)
|
|
4005
|
+
* @example
|
|
4006
|
+
* '@' $mol_mem
|
|
4007
|
+
* name(next?: string) {
|
|
4008
|
+
* return next ?? 'default'
|
|
4009
|
+
* }
|
|
4010
|
+
* @see https://mol.hyoo.ru/#!section=docs/=qxmh6t_sinbmb
|
|
4011
|
+
*/
|
|
3777
4012
|
$.$mol_mem = $mol_wire_solo;
|
|
4013
|
+
/**
|
|
4014
|
+
* Reactive memoizing multiplexed property decorator [mol_wire](../wire/README.md)
|
|
4015
|
+
* @example
|
|
4016
|
+
* '@' $mol_mem_key
|
|
4017
|
+
* name(id: number, next?: string) {
|
|
4018
|
+
* return next ?? 'default'
|
|
4019
|
+
* }
|
|
4020
|
+
* @see https://mol.hyoo.ru/#!section=docs/=qxmh6t_sinbmb
|
|
4021
|
+
*/
|
|
3778
4022
|
$.$mol_mem_key = $mol_wire_plex;
|
|
3779
4023
|
})($ || ($ = {}));
|
|
3780
4024
|
|
|
@@ -3791,7 +4035,7 @@ var $;
|
|
|
3791
4035
|
"use strict";
|
|
3792
4036
|
var $;
|
|
3793
4037
|
(function ($) {
|
|
3794
|
-
const mod = require('module');
|
|
4038
|
+
const mod = require /****/('module');
|
|
3795
4039
|
const internals = mod.builtinModules;
|
|
3796
4040
|
function $node_internal_check(name) {
|
|
3797
4041
|
if (name.startsWith('node:'))
|
|
@@ -3805,8 +4049,8 @@ var $;
|
|
|
3805
4049
|
"use strict";
|
|
3806
4050
|
var $;
|
|
3807
4051
|
(function ($) {
|
|
3808
|
-
const path = require('path');
|
|
3809
|
-
const mod = require('module');
|
|
4052
|
+
const path = require /****/('path');
|
|
4053
|
+
const mod = require /****/('module');
|
|
3810
4054
|
const localRequire = mod.createRequire(path.join(process.cwd(), 'package.json'));
|
|
3811
4055
|
function $node_autoinstall(name) {
|
|
3812
4056
|
try {
|
|
@@ -3881,6 +4125,7 @@ var $;
|
|
|
3881
4125
|
])
|
|
3882
4126
|
].map(frame_normalize).join('\n')
|
|
3883
4127
|
});
|
|
4128
|
+
// в nodejs, что б не дублировалось cause в консоли
|
|
3884
4129
|
Object.defineProperty(this, 'cause', {
|
|
3885
4130
|
get: () => cause
|
|
3886
4131
|
});
|
|
@@ -3949,6 +4194,10 @@ var $;
|
|
|
3949
4194
|
props[field] = get_val;
|
|
3950
4195
|
return get_val;
|
|
3951
4196
|
}
|
|
4197
|
+
/**
|
|
4198
|
+
* Convert asynchronous (promise-based) API to synchronous by wrapping function and method calls in a fiber.
|
|
4199
|
+
* @see https://mol.hyoo.ru/#!section=docs/=1fcpsq_1wh0h2
|
|
4200
|
+
*/
|
|
3952
4201
|
function $mol_wire_sync(obj) {
|
|
3953
4202
|
return new Proxy(obj, {
|
|
3954
4203
|
get(obj, field) {
|
|
@@ -4110,6 +4359,9 @@ var $;
|
|
|
4110
4359
|
"use strict";
|
|
4111
4360
|
var $;
|
|
4112
4361
|
(function ($) {
|
|
4362
|
+
/**
|
|
4363
|
+
* Disable reaping of current subscriber
|
|
4364
|
+
*/
|
|
4113
4365
|
function $mol_wire_solid() {
|
|
4114
4366
|
let current = $mol_wire_auto();
|
|
4115
4367
|
if (current.temp)
|
|
@@ -4135,6 +4387,7 @@ var $;
|
|
|
4135
4387
|
"use strict";
|
|
4136
4388
|
var $;
|
|
4137
4389
|
(function ($) {
|
|
4390
|
+
/** Run code without state changes */
|
|
4138
4391
|
function $mol_wire_probe(task, def) {
|
|
4139
4392
|
const warm = $mol_wire_fiber.warm;
|
|
4140
4393
|
try {
|
|
@@ -4293,6 +4546,11 @@ var $;
|
|
|
4293
4546
|
"use strict";
|
|
4294
4547
|
var $;
|
|
4295
4548
|
(function ($) {
|
|
4549
|
+
/**
|
|
4550
|
+
* Returns closure that returns constant value.
|
|
4551
|
+
* @example
|
|
4552
|
+
* const rnd = $mol_const( Math.random() )
|
|
4553
|
+
*/
|
|
4296
4554
|
function $mol_const(value) {
|
|
4297
4555
|
const getter = (() => value);
|
|
4298
4556
|
getter['()'] = value;
|
|
@@ -4307,6 +4565,10 @@ var $;
|
|
|
4307
4565
|
"use strict";
|
|
4308
4566
|
var $;
|
|
4309
4567
|
(function ($) {
|
|
4568
|
+
/**
|
|
4569
|
+
* Decorates method to fiber to ensure it is executed only once inside other fiber from [mol_wire](../wire/README.md)
|
|
4570
|
+
* @see https://mol.hyoo.ru/#!section=docs/=1fcpsq_1wh0h2
|
|
4571
|
+
*/
|
|
4310
4572
|
$.$mol_action = $mol_wire_method;
|
|
4311
4573
|
})($ || ($ = {}));
|
|
4312
4574
|
|
|
@@ -4314,6 +4576,7 @@ var $;
|
|
|
4314
4576
|
"use strict";
|
|
4315
4577
|
var $;
|
|
4316
4578
|
(function ($) {
|
|
4579
|
+
/** Convert a pseudo-synchronous (Suspense API) API to an explicit asynchronous one (for integrating with external systems). */
|
|
4317
4580
|
function $mol_wire_async(obj) {
|
|
4318
4581
|
let fiber;
|
|
4319
4582
|
const temp = $mol_wire_task.getter(obj);
|
|
@@ -4413,7 +4676,8 @@ var $;
|
|
|
4413
4676
|
"use strict";
|
|
4414
4677
|
var $;
|
|
4415
4678
|
(function ($) {
|
|
4416
|
-
let buf = new Uint8Array(2 ** 12);
|
|
4679
|
+
let buf = new Uint8Array(2 ** 12); // 4KB Mem Page
|
|
4680
|
+
/** Temporary buffer. Recursive usage isn't supported. */
|
|
4417
4681
|
function $mol_charset_buffer(size) {
|
|
4418
4682
|
if (buf.byteLength < size)
|
|
4419
4683
|
buf = new Uint8Array(size);
|
|
@@ -4435,19 +4699,19 @@ var $;
|
|
|
4435
4699
|
let pos = from;
|
|
4436
4700
|
for (let i = 0; i < str.length; i++) {
|
|
4437
4701
|
let code = str.charCodeAt(i);
|
|
4438
|
-
if (code < 0x80) {
|
|
4702
|
+
if (code < 0x80) { // ASCII - 1 octet
|
|
4439
4703
|
buf[pos++] = code;
|
|
4440
4704
|
}
|
|
4441
|
-
else if (code < 0x800) {
|
|
4705
|
+
else if (code < 0x800) { // 2 octet
|
|
4442
4706
|
buf[pos++] = 0xc0 | (code >> 6);
|
|
4443
4707
|
buf[pos++] = 0x80 | (code & 0x3f);
|
|
4444
4708
|
}
|
|
4445
|
-
else if (code < 0xd800 || code >= 0xe000) {
|
|
4709
|
+
else if (code < 0xd800 || code >= 0xe000) { // 3 octet
|
|
4446
4710
|
buf[pos++] = 0xe0 | (code >> 12);
|
|
4447
4711
|
buf[pos++] = 0x80 | ((code >> 6) & 0x3f);
|
|
4448
4712
|
buf[pos++] = 0x80 | (code & 0x3f);
|
|
4449
4713
|
}
|
|
4450
|
-
else {
|
|
4714
|
+
else { // surrogate pair
|
|
4451
4715
|
const point = ((code - 0xd800) << 10) + str.charCodeAt(++i) + 0x2400;
|
|
4452
4716
|
buf[pos++] = 0xf0 | (point >> 18);
|
|
4453
4717
|
buf[pos++] = 0x80 | ((point >> 12) & 0x3f);
|
|
@@ -4511,12 +4775,16 @@ var $;
|
|
|
4511
4775
|
(function ($) {
|
|
4512
4776
|
let file_modes;
|
|
4513
4777
|
(function (file_modes) {
|
|
4778
|
+
/** create if it doesn't already exist */
|
|
4514
4779
|
file_modes[file_modes["create"] = $node.fs.constants.O_CREAT] = "create";
|
|
4780
|
+
/** truncate to zero size if it already exists */
|
|
4515
4781
|
file_modes[file_modes["exists_truncate"] = $node.fs.constants.O_TRUNC] = "exists_truncate";
|
|
4782
|
+
/** throw exception if it already exists */
|
|
4516
4783
|
file_modes[file_modes["exists_fail"] = $node.fs.constants.O_EXCL] = "exists_fail";
|
|
4517
4784
|
file_modes[file_modes["read_only"] = $node.fs.constants.O_RDONLY] = "read_only";
|
|
4518
4785
|
file_modes[file_modes["write_only"] = $node.fs.constants.O_WRONLY] = "write_only";
|
|
4519
4786
|
file_modes[file_modes["read_write"] = $node.fs.constants.O_RDWR] = "read_write";
|
|
4787
|
+
/** data will be appended to the end */
|
|
4520
4788
|
file_modes[file_modes["append"] = $node.fs.constants.O_APPEND] = "append";
|
|
4521
4789
|
})(file_modes || (file_modes = {}));
|
|
4522
4790
|
function mode_mask(modes) {
|
|
@@ -4581,12 +4849,24 @@ var $;
|
|
|
4581
4849
|
root() {
|
|
4582
4850
|
const path = this.path();
|
|
4583
4851
|
const base = this.constructor.base;
|
|
4852
|
+
// Если путь выше или равен base или если parent такойже как и this - считаем это корнем
|
|
4584
4853
|
return base.startsWith(path) || this == this.parent();
|
|
4585
4854
|
}
|
|
4586
4855
|
stat(next, virt) {
|
|
4587
4856
|
const path = this.path();
|
|
4588
4857
|
const parent = this.parent();
|
|
4858
|
+
// Отслеживать проверку наличия родительской папки не стоит до корня диска
|
|
4859
|
+
// Лучше ограничить mam-ом
|
|
4589
4860
|
if (!this.root()) {
|
|
4861
|
+
/*
|
|
4862
|
+
Если parent папка удалилась, надо ресетнуть все объекты в ней на любой глубине.
|
|
4863
|
+
Например, rm -rf с последующим git pull: parent папка может удалиться, потом создасться,
|
|
4864
|
+
а текущая папка успеет только удалиться до момента выполнения stat.
|
|
4865
|
+
Поэтому parent.exists() не запустит перевычисления, нужна именно parent.version()
|
|
4866
|
+
|
|
4867
|
+
Однако, parent.version() меняется не только при удалении, будет ложное срабатывание
|
|
4868
|
+
С этим придется мириться, красивого решения пока нет.
|
|
4869
|
+
*/
|
|
4590
4870
|
parent.version();
|
|
4591
4871
|
}
|
|
4592
4872
|
parent.watcher();
|
|
@@ -4600,9 +4880,19 @@ var $;
|
|
|
4600
4880
|
if (/([\/\\]\.|___$)/.test(path))
|
|
4601
4881
|
return;
|
|
4602
4882
|
const file = this.relative(path.at(-1) === '/' ? path.slice(0, -1) : path);
|
|
4883
|
+
// console.log(type, path)
|
|
4884
|
+
// add (change): добавился файл - у parent надо обновить список sub, если он был заюзан
|
|
4885
|
+
// change, unlink (rename): обновился или удалился файл - ресетим
|
|
4886
|
+
// addDir (change), добавилась папка, у parent обновляем список директорий в sub
|
|
4887
|
+
// дочерние ресетим
|
|
4888
|
+
// unlinkDir (rename), удалилась папка, ресетим ее
|
|
4889
|
+
// stat у всех дочерних обновится сам, т.к. связан с parent.version()
|
|
4603
4890
|
this.changed.add(file);
|
|
4604
4891
|
if (!this.watching)
|
|
4605
4892
|
return;
|
|
4893
|
+
// throttle, пока события поступают не сбрасываем.
|
|
4894
|
+
// аналог awaitWriteFinish из chokidar
|
|
4895
|
+
// интервалы между change-сообщениями модифицируемого файла должны быть меньше watch_debounce
|
|
4606
4896
|
this.frame?.destructor();
|
|
4607
4897
|
this.frame = new this.$.$mol_after_timeout(this.watch_debounce(), () => {
|
|
4608
4898
|
if (!this.watching)
|
|
@@ -4611,8 +4901,16 @@ var $;
|
|
|
4611
4901
|
$mol_wire_async(this).flush();
|
|
4612
4902
|
});
|
|
4613
4903
|
}
|
|
4904
|
+
/**
|
|
4905
|
+
* Должно быть больше, чем время между событиями от вотчера при записи внешним процессом.
|
|
4906
|
+
* Иначе запуск ресетов паралельно с изменением может привести к неконсистентности.
|
|
4907
|
+
*/
|
|
4614
4908
|
static watch_debounce() { return 500; }
|
|
4615
4909
|
static flush() {
|
|
4910
|
+
// Пока flush работает, вотчер сюда не заходит, но может добавлять новые изменения
|
|
4911
|
+
// на каждом перезапуске они применятся
|
|
4912
|
+
// Пока run выполняется, изменения накапливаются, в конце run вызывается flush
|
|
4913
|
+
// Пока применяются изменения, run должен ожидать конца flush
|
|
4616
4914
|
for (const file of this.changed) {
|
|
4617
4915
|
const parent = file.parent();
|
|
4618
4916
|
try {
|
|
@@ -4627,16 +4925,32 @@ var $;
|
|
|
4627
4925
|
}
|
|
4628
4926
|
this.changed.clear();
|
|
4629
4927
|
this.watching = true;
|
|
4928
|
+
// this.watch_wd?.destructor()
|
|
4929
|
+
// this.watch_wd = null
|
|
4630
4930
|
}
|
|
4631
4931
|
static watching = true;
|
|
4632
4932
|
static lock = new $mol_lock;
|
|
4633
4933
|
static watch_off(path) {
|
|
4634
4934
|
this.watching = false;
|
|
4935
|
+
// run должен ожидать конца flush
|
|
4635
4936
|
this.flush();
|
|
4636
4937
|
this.watching = false;
|
|
4938
|
+
/*
|
|
4939
|
+
watch запаздывает и событие может прилететь через 3 сек после окончания сайд эффекта
|
|
4940
|
+
поэтому добавляем папку, которую меняет side_effect
|
|
4941
|
+
Когда дойдет до выполнения flush, он ресетнет ее
|
|
4942
|
+
|
|
4943
|
+
Иначе будут лишние срабатывания
|
|
4944
|
+
Например, удалили hyoo/board, watch ресетит и exists начинает отдавать false, срабатывает git clone
|
|
4945
|
+
Сразу после него событие addDir еще не успело прийти,
|
|
4946
|
+
на следующем перезапуске вызывается git pull, т.к.
|
|
4947
|
+
с точки зрения реактивной системы hyoo/board еще не существует.
|
|
4948
|
+
*/
|
|
4637
4949
|
this.changed.add(this.absolute(path));
|
|
4638
4950
|
}
|
|
4951
|
+
// protected static watch_wd = null as null | $mol_after_timeout
|
|
4639
4952
|
static unwatched(side_effect, affected_dir) {
|
|
4953
|
+
// ждем, пока выполнится предыдущий unwatched
|
|
4640
4954
|
const unlock = this.lock.grab();
|
|
4641
4955
|
this.watch_off(affected_dir);
|
|
4642
4956
|
try {
|
|
@@ -4659,6 +4973,7 @@ var $;
|
|
|
4659
4973
|
modified() { return this.stat()?.mtime ?? null; }
|
|
4660
4974
|
version() {
|
|
4661
4975
|
const next = this.stat()?.mtime.getTime().toString(36).toUpperCase() ?? '';
|
|
4976
|
+
// console.log('version', next, this.path())
|
|
4662
4977
|
return next;
|
|
4663
4978
|
}
|
|
4664
4979
|
info(path) { return null; }
|
|
@@ -4676,15 +4991,19 @@ var $;
|
|
|
4676
4991
|
writable(opts) {
|
|
4677
4992
|
return new WritableStream;
|
|
4678
4993
|
}
|
|
4994
|
+
// open( ... modes: readonly $mol_file_mode[] ) { return 0 }
|
|
4679
4995
|
buffer(next) {
|
|
4996
|
+
// Если версия пустая - возвращаем пустой буфер
|
|
4680
4997
|
let readed = new Uint8Array();
|
|
4681
4998
|
if (next === undefined) {
|
|
4999
|
+
// Если меняется версия файла, буфер надо перечитать
|
|
4682
5000
|
if (this.version())
|
|
4683
5001
|
readed = this.read();
|
|
4684
5002
|
}
|
|
4685
5003
|
const prev = $mol_mem_cached(() => this.buffer());
|
|
4686
5004
|
const changed = prev === undefined || !$mol_compare_array(prev, next ?? readed);
|
|
4687
5005
|
if (prev !== undefined && changed) {
|
|
5006
|
+
// Логируем, если повторно читаем/пишем и буфер поменялся
|
|
4688
5007
|
this.$.$mol_log3_rise({
|
|
4689
5008
|
place: `$mol_file_node.buffer()`,
|
|
4690
5009
|
message: 'Changed',
|
|
@@ -4693,6 +5012,11 @@ var $;
|
|
|
4693
5012
|
}
|
|
4694
5013
|
if (next === undefined)
|
|
4695
5014
|
return changed ? readed : prev;
|
|
5015
|
+
// Если буфер при записи не поменялся и файл не удаляли перед этим - не записываем новую версию.
|
|
5016
|
+
// Если записывать, это приведет к смене mtime и вотчер снова триггернется, даже если содержимое файла не поменялось.
|
|
5017
|
+
// В этом алгоритме есть изъян.
|
|
5018
|
+
// Если файл записали, потом отключили вотчер, кто-то из вне его поменял, потом включили вотчер, снова записали тот же буфер,
|
|
5019
|
+
// то буфер не запишется на диск, т.к. кэш не консистентен с диском.
|
|
4696
5020
|
if (!changed && this.exists())
|
|
4697
5021
|
return prev;
|
|
4698
5022
|
this.parent().exists(true);
|
|
@@ -4728,13 +5052,21 @@ var $;
|
|
|
4728
5052
|
}
|
|
4729
5053
|
return null;
|
|
4730
5054
|
}
|
|
5055
|
+
// static watch_root = ''
|
|
5056
|
+
// static watcher_warned = false
|
|
4731
5057
|
watcher() {
|
|
5058
|
+
// const constructor = this.constructor as typeof $mol_file_base
|
|
5059
|
+
// if (! constructor.watcher_warned) {
|
|
5060
|
+
// console.warn(`${constructor}.watcher() not implemented`)
|
|
5061
|
+
// constructor.watcher_warned = true
|
|
5062
|
+
// }
|
|
4732
5063
|
return {
|
|
4733
5064
|
destructor() { }
|
|
4734
5065
|
};
|
|
4735
5066
|
}
|
|
4736
5067
|
exists(next) {
|
|
4737
5068
|
const exists = Boolean(this.stat());
|
|
5069
|
+
// console.log('exists current', exists, 'next', next, this.path())
|
|
4738
5070
|
if (next === undefined)
|
|
4739
5071
|
return exists;
|
|
4740
5072
|
if (next === exists)
|
|
@@ -4760,6 +5092,10 @@ var $;
|
|
|
4760
5092
|
return match ? match[1].substring(1) : '';
|
|
4761
5093
|
}
|
|
4762
5094
|
text(next, virt) {
|
|
5095
|
+
// Если записываем text, и вотчер ресетнул записанный файл,
|
|
5096
|
+
// то надо снова его обновить, вызвать логику, которая делала пуш в text.
|
|
5097
|
+
// Например файл удалили, потом снова создали, версия поменялась - перезаписываем
|
|
5098
|
+
// Если использовать version, то вновь созданный файл, через вотчер запустит свое пересоздание
|
|
4763
5099
|
if (next !== undefined)
|
|
4764
5100
|
this.exists();
|
|
4765
5101
|
return this.text_int(next, virt);
|
|
@@ -4784,6 +5120,7 @@ var $;
|
|
|
4784
5120
|
if (this.type() !== 'dir')
|
|
4785
5121
|
return [];
|
|
4786
5122
|
this.version();
|
|
5123
|
+
// Если дочерний file удалился, список надо обновить
|
|
4787
5124
|
return this.kids().filter(file => file.exists());
|
|
4788
5125
|
}
|
|
4789
5126
|
resolve(path) {
|
|
@@ -4928,10 +5265,15 @@ var $;
|
|
|
4928
5265
|
watcher(reset) {
|
|
4929
5266
|
const path = this.path();
|
|
4930
5267
|
const root = this.root();
|
|
5268
|
+
// Если папки/файла нет, watch упадет с ошибкой
|
|
5269
|
+
// exists обратится к parent.version и parent.watcher
|
|
5270
|
+
// Поэтому у root-папки и выше не надо вызывать exists, иначе поднимется выше base до корня диска
|
|
5271
|
+
// exists вызывать надо, что б пересоздавать вотчер при появлении папки или файла
|
|
4931
5272
|
if (!root && !this.exists())
|
|
4932
5273
|
return super.watcher();
|
|
4933
5274
|
let watcher;
|
|
4934
5275
|
try {
|
|
5276
|
+
// Между exists и watch файл может удалиться, в любом случае надо обрабатывать ENOENT
|
|
4935
5277
|
watcher = $node.fs.watch(path);
|
|
4936
5278
|
}
|
|
4937
5279
|
catch (error) {
|
|
@@ -4941,6 +5283,8 @@ var $;
|
|
|
4941
5283
|
if (root || error.code !== 'ENOENT') {
|
|
4942
5284
|
this.$.$mol_fail_log(error);
|
|
4943
5285
|
}
|
|
5286
|
+
// Если файла нет - вотчер не создается, создастся потом, когда exists поменяется на true.
|
|
5287
|
+
// Если создание упало с другой ошибкой - не ломаем работу mol_file, деградируем до не реактивной fs.
|
|
4944
5288
|
return super.watcher();
|
|
4945
5289
|
}
|
|
4946
5290
|
watcher.on('change', (type, name) => {
|
|
@@ -4952,6 +5296,7 @@ var $;
|
|
|
4952
5296
|
watcher.on('error', e => this.$.$mol_fail_log(e));
|
|
4953
5297
|
let destructed = false;
|
|
4954
5298
|
watcher.on('close', () => {
|
|
5299
|
+
// Если в процессе работы вотчер сам закрылся, надо его переоткрыть
|
|
4955
5300
|
if (!destructed)
|
|
4956
5301
|
setTimeout(() => $mol_wire_async(this).watcher(null), 500);
|
|
4957
5302
|
});
|
|
@@ -5133,6 +5478,10 @@ var $;
|
|
|
5133
5478
|
"use strict";
|
|
5134
5479
|
var $;
|
|
5135
5480
|
(function ($) {
|
|
5481
|
+
/**
|
|
5482
|
+
* Localisation in $mol framework
|
|
5483
|
+
* @see https://mol.hyoo.ru/#!section=docs/=s5aqnb_odub8l
|
|
5484
|
+
*/
|
|
5136
5485
|
class $mol_locale extends $mol_object {
|
|
5137
5486
|
static lang_default() {
|
|
5138
5487
|
return 'en';
|
|
@@ -5282,12 +5631,14 @@ var $;
|
|
|
5282
5631
|
'=>': bind => [],
|
|
5283
5632
|
'^': (ref, belt, context) => [
|
|
5284
5633
|
ref.struct('...', [
|
|
5634
|
+
// prop ^ foo
|
|
5285
5635
|
ref.kids[0]?.type
|
|
5286
5636
|
? ref.struct('()', [
|
|
5287
5637
|
ref.struct('this'),
|
|
5288
5638
|
ref.struct('[]', [ref.data(name_of.call(this, ref.kids[0]))]),
|
|
5289
5639
|
args_of.call(this, ref.kids[0])
|
|
5290
5640
|
])
|
|
5641
|
+
// Having $having foo / ^
|
|
5291
5642
|
: context.chain
|
|
5292
5643
|
? ref.struct('()', [
|
|
5293
5644
|
ref.struct('this'),
|
|
@@ -5299,6 +5650,7 @@ var $;
|
|
|
5299
5650
|
ref.struct('(,)', [ref.struct('obj')]),
|
|
5300
5651
|
...context.chain.slice(1).map(field => ref.struct('[]', [ref.data(field)]))
|
|
5301
5652
|
])
|
|
5653
|
+
// prop ^
|
|
5302
5654
|
: ref.struct('()', [
|
|
5303
5655
|
ref.struct('super'),
|
|
5304
5656
|
ref.struct('[]', [ref.data(name)]),
|