mol_wire_dom 0.0.1721 → 0.0.1723

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/web.js CHANGED
@@ -32,6 +32,7 @@ $.$$ = $
32
32
  "use strict";
33
33
  var $;
34
34
  (function ($) {
35
+ /** Generates unique identifier. */
35
36
  function $mol_guid(length = 8, exists = () => false) {
36
37
  for (;;) {
37
38
  let id = Math.random().toString(36).substring(2, length + 2).toUpperCase();
@@ -57,11 +58,16 @@ var $;
57
58
  "use strict";
58
59
  var $;
59
60
  (function ($) {
61
+ /** Special status statuses. */
60
62
  let $mol_wire_cursor;
61
63
  (function ($mol_wire_cursor) {
64
+ /** Update required. */
62
65
  $mol_wire_cursor[$mol_wire_cursor["stale"] = -1] = "stale";
66
+ /** Some of (transitive) pub update required. */
63
67
  $mol_wire_cursor[$mol_wire_cursor["doubt"] = -2] = "doubt";
68
+ /** Actual state but may be dropped. */
64
69
  $mol_wire_cursor[$mol_wire_cursor["fresh"] = -3] = "fresh";
70
+ /** State will never be changed. */
65
71
  $mol_wire_cursor[$mol_wire_cursor["final"] = -4] = "final";
66
72
  })($mol_wire_cursor = $.$mol_wire_cursor || ($.$mol_wire_cursor = {}));
67
73
  })($ || ($ = {}));
@@ -70,6 +76,9 @@ var $;
70
76
  "use strict";
71
77
  var $;
72
78
  (function ($) {
79
+ /**
80
+ * Collects subscribers in compact array. 28B
81
+ */
73
82
  class $mol_wire_pub extends Object {
74
83
  constructor(id = `$mol_wire_pub:${$mol_guid()}`) {
75
84
  super();
@@ -77,10 +86,17 @@ var $;
77
86
  }
78
87
  [Symbol.toStringTag];
79
88
  data = [];
89
+ // Derived objects should be Arrays.
80
90
  static get [Symbol.species]() {
81
91
  return Array;
82
92
  }
83
- sub_from = 0;
93
+ /**
94
+ * Index of first subscriber.
95
+ */
96
+ sub_from = 0; // 4B
97
+ /**
98
+ * All current subscribers.
99
+ */
84
100
  get sub_list() {
85
101
  const res = [];
86
102
  for (let i = this.sub_from; i < this.data.length; i += 2) {
@@ -88,14 +104,23 @@ var $;
88
104
  }
89
105
  return res;
90
106
  }
107
+ /**
108
+ * Has any subscribers or not.
109
+ */
91
110
  get sub_empty() {
92
111
  return this.sub_from === this.data.length;
93
112
  }
113
+ /**
114
+ * Subscribe subscriber to this publisher events and return position of subscriber that required to unsubscribe.
115
+ */
94
116
  sub_on(sub, pub_pos) {
95
117
  const pos = this.data.length;
96
118
  this.data.push(sub, pub_pos);
97
119
  return pos;
98
120
  }
121
+ /**
122
+ * Unsubscribe subscriber from this publisher events by subscriber position provided by `on(pub)`.
123
+ */
99
124
  sub_off(sub_pos) {
100
125
  if (!(sub_pos < this.data.length)) {
101
126
  $mol_fail(new Error(`Wrong pos ${sub_pos}`));
@@ -108,21 +133,39 @@ var $;
108
133
  if (end === this.sub_from)
109
134
  this.reap();
110
135
  }
136
+ /**
137
+ * Called when last sub was unsubscribed.
138
+ **/
111
139
  reap() { }
140
+ /**
141
+ * Autowire this publisher with current subscriber.
142
+ **/
112
143
  promote() {
113
144
  $mol_wire_auto()?.track_next(this);
114
145
  }
146
+ /**
147
+ * Enforce actualization. Should not throw errors.
148
+ */
115
149
  fresh() { }
150
+ /**
151
+ * Allow to put data to caches in the subtree.
152
+ */
116
153
  complete() { }
117
154
  get incompleted() {
118
155
  return false;
119
156
  }
157
+ /**
158
+ * Notify subscribers about self changes.
159
+ */
120
160
  emit(quant = $mol_wire_cursor.stale) {
121
161
  for (let i = this.sub_from; i < this.data.length; i += 2) {
122
162
  ;
123
163
  this.data[i].absorb(quant, this.data[i + 1]);
124
164
  }
125
165
  }
166
+ /**
167
+ * Moves peer from one position to another. Doesn't clear data at old position!
168
+ */
126
169
  peer_move(from_pos, to_pos) {
127
170
  const peer = this.data[from_pos];
128
171
  const self_pos = this.data[from_pos + 1];
@@ -130,6 +173,9 @@ var $;
130
173
  this.data[to_pos + 1] = self_pos;
131
174
  peer.peer_repos(self_pos, to_pos);
132
175
  }
176
+ /**
177
+ * Updates self position in the peer.
178
+ */
133
179
  peer_repos(peer_pos, self_pos) {
134
180
  this.data[peer_pos + 1] = self_pos;
135
181
  }
@@ -145,10 +191,16 @@ var $;
145
191
  var $;
146
192
  (function ($) {
147
193
  $.$mol_wire_auto_sub = null;
194
+ /**
195
+ * When fulfilled, all publishers are promoted to this subscriber on access to its.
196
+ */
148
197
  function $mol_wire_auto(next = $.$mol_wire_auto_sub) {
149
198
  return $.$mol_wire_auto_sub = next;
150
199
  }
151
200
  $.$mol_wire_auto = $mol_wire_auto;
201
+ /**
202
+ * Affection queue. Used to prevent accidental stack overflow on emit.
203
+ */
152
204
  $.$mol_wire_affected = [];
153
205
  })($ || ($ = {}));
154
206
 
@@ -157,7 +209,7 @@ var $;
157
209
  var $;
158
210
  (function ($) {
159
211
  function $mol_fail_hidden(error) {
160
- throw error;
212
+ throw error; /// Use 'Never Pause Here' breakpoint in DevTools or simply blackbox this script
161
213
  }
162
214
  $.$mol_fail_hidden = $mol_fail_hidden;
163
215
  })($ || ($ = {}));
@@ -166,6 +218,7 @@ var $;
166
218
  "use strict";
167
219
  var $;
168
220
  (function ($) {
221
+ // https://docs.google.com/document/d/1FTascZXT9cxfetuPRT2eXPQKXui4nWFivUnS_335T3U/preview#
169
222
  $['devtoolsFormatters'] ||= [];
170
223
  function $mol_dev_format_register(config) {
171
224
  $['devtoolsFormatters'].push(config);
@@ -217,6 +270,7 @@ var $;
217
270
  return false;
218
271
  if (!val)
219
272
  return false;
273
+ // if( Error.isError( val ) ) true
220
274
  if (val[$.$mol_dev_format_body])
221
275
  return true;
222
276
  return false;
@@ -234,12 +288,16 @@ var $;
234
288
  return $.$mol_dev_format_accent($mol_dev_format_native(val), '💨', $mol_dev_format_native(error), '');
235
289
  }
236
290
  }
291
+ // if( Error.isError( val ) ) {
292
+ // return $mol_dev_format_native( val )
293
+ // }
237
294
  return null;
238
295
  },
239
296
  });
240
297
  function $mol_dev_format_native(obj) {
241
298
  if (typeof obj === 'undefined')
242
299
  return $.$mol_dev_format_shade('undefined');
300
+ // if( ![ 'object', 'function', 'symbol' ].includes( typeof obj ) ) return obj
243
301
  return [
244
302
  'object',
245
303
  {
@@ -297,6 +355,9 @@ var $;
297
355
  'margin-left': '13px'
298
356
  });
299
357
  class Stack extends Array {
358
+ // [ Symbol.toPrimitive ]() {
359
+ // return this.toString()
360
+ // }
300
361
  toString() {
301
362
  return this.join('\n');
302
363
  }
@@ -319,6 +380,7 @@ var $;
319
380
  this.method = call.getMethodName() ?? '';
320
381
  if (this.method === this.function)
321
382
  this.method = '';
383
+ // const func = c.getFunction()
322
384
  this.pos = [call.getEnclosingLineNumber() ?? 0, call.getEnclosingColumnNumber() ?? 0];
323
385
  this.eval = call.getEvalOrigin() ?? '';
324
386
  this.source = call.getScriptNameOrSourceURL() ?? '';
@@ -365,9 +427,16 @@ var $;
365
427
  "use strict";
366
428
  var $;
367
429
  (function ($) {
430
+ /**
431
+ * Publisher that can auto collect other publishers. 32B
432
+ *
433
+ * P1 P2 P3 P4 S1 S2 S3
434
+ * ^ ^
435
+ * pubs_from subs_from
436
+ */
368
437
  class $mol_wire_pub_sub extends $mol_wire_pub {
369
- pub_from = 0;
370
- cursor = $mol_wire_cursor.stale;
438
+ pub_from = 0; // 4B
439
+ cursor = $mol_wire_cursor.stale; // 4B
371
440
  get temp() {
372
441
  return false;
373
442
  }
@@ -485,10 +554,27 @@ var $;
485
554
  return;
486
555
  this.cursor = quant;
487
556
  this.emit($mol_wire_cursor.doubt);
557
+ // if( pos >= 0 && pos < this.sub_from - 2 ) {
558
+ // const pub = this.data[ pos ] as $mol_wire_pub
559
+ // if( pub instanceof $mol_wire_task ) return
560
+ // for(
561
+ // let cursor = this.pub_from;
562
+ // cursor < this.sub_from;
563
+ // cursor += 2
564
+ // ) {
565
+ // const pub = this.data[ cursor ] as $mol_wire_pub
566
+ // if( pub instanceof $mol_wire_task ) {
567
+ // pub.destructor()
568
+ // }
569
+ // }
570
+ // }
488
571
  }
489
572
  [$mol_dev_format_head]() {
490
573
  return $mol_dev_format_native(this);
491
574
  }
575
+ /**
576
+ * Is subscribed to any publisher or not.
577
+ */
492
578
  get pub_empty() {
493
579
  return this.sub_from === this.pub_from;
494
580
  }
@@ -512,6 +598,11 @@ var $;
512
598
  var $;
513
599
  (function ($) {
514
600
  const instances = new WeakSet();
601
+ /**
602
+ * Proxy that delegates all to lazy returned target.
603
+ *
604
+ * $mol_delegate( Array.prototype , ()=> fetch_array() )
605
+ */
515
606
  function $mol_delegate(proto, target) {
516
607
  const proxy = new Proxy(proto, {
517
608
  get: (_, field) => {
@@ -687,6 +778,9 @@ var $;
687
778
  [Symbol.dispose]() {
688
779
  this.destructor();
689
780
  }
781
+ //[ Symbol.toPrimitive ]( hint: string ) {
782
+ // return hint === 'number' ? this.valueOf() : this.toString()
783
+ //}
690
784
  toString() {
691
785
  return this[Symbol.toStringTag] || this.constructor.name + '<>';
692
786
  }
@@ -742,6 +836,13 @@ var $;
742
836
  var $;
743
837
  (function ($) {
744
838
  const wrappers = new WeakMap();
839
+ /**
840
+ * Suspendable task with support both sync/async api.
841
+ *
842
+ * A1 A2 A3 A4 P1 P2 P3 P4 S1 S2 S3
843
+ * ^ ^ ^
844
+ * args_from pubs_from subs_from
845
+ **/
745
846
  class $mol_wire_fiber extends $mol_wire_pub_sub {
746
847
  task;
747
848
  host;
@@ -762,6 +863,7 @@ var $;
762
863
  });
763
864
  }
764
865
  static sync() {
866
+ // Sync whole fiber graph
765
867
  while (this.planning.size) {
766
868
  for (const fiber of this.planning) {
767
869
  this.planning.delete(fiber);
@@ -772,6 +874,7 @@ var $;
772
874
  fiber.fresh();
773
875
  }
774
876
  }
877
+ // Collect garbage
775
878
  while (this.reaping.size) {
776
879
  const fibers = this.reaping;
777
880
  this.reaping = new Set;
@@ -923,6 +1026,10 @@ var $;
923
1026
  this.cursor = $mol_wire_cursor.stale;
924
1027
  this.fresh();
925
1028
  }
1029
+ /**
1030
+ * Synchronous execution. Throws Promise when waits async task (SuspenseAPI provider).
1031
+ * Should be called inside SuspenseAPI consumer (ie fiber).
1032
+ */
926
1033
  sync() {
927
1034
  if (!$mol_wire_fiber.warm) {
928
1035
  return this.result();
@@ -937,6 +1044,10 @@ var $;
937
1044
  }
938
1045
  return this.cache;
939
1046
  }
1047
+ /**
1048
+ * Asynchronous execution.
1049
+ * It's SuspenseAPI consumer. So SuspenseAPI providers can be called inside.
1050
+ */
940
1051
  async async_raw() {
941
1052
  while (true) {
942
1053
  this.fresh();
@@ -949,6 +1060,7 @@ var $;
949
1060
  if (!$mol_promise_like(this.cache))
950
1061
  return this.cache;
951
1062
  if (this.cursor === $mol_wire_cursor.final) {
1063
+ // never ends on destructed fiber
952
1064
  await new Promise(() => { });
953
1065
  }
954
1066
  }
@@ -996,6 +1108,7 @@ var $;
996
1108
  var $;
997
1109
  (function ($) {
998
1110
  const TypedArray = Object.getPrototypeOf(Uint8Array);
1111
+ /** Returns string key for any value. */
999
1112
  function $mol_key(value) {
1000
1113
  primitives: {
1001
1114
  if (typeof value === 'bigint')
@@ -1003,9 +1116,9 @@ var $;
1003
1116
  if (typeof value === 'symbol')
1004
1117
  return `Symbol(${value.description})`;
1005
1118
  if (!value)
1006
- return JSON.stringify(value);
1119
+ return JSON.stringify(value); // 0, null, ""
1007
1120
  if (typeof value !== 'object' && typeof value !== 'function')
1008
- return JSON.stringify(value);
1121
+ return JSON.stringify(value); // boolean, number, string
1009
1122
  }
1010
1123
  caching: {
1011
1124
  let key = $mol_key_store.get(value);
@@ -1089,6 +1202,10 @@ var $;
1089
1202
  var $;
1090
1203
  (function ($) {
1091
1204
  $.$mol_compare_deep_cache = new WeakMap();
1205
+ /**
1206
+ * Deeply compares two values. Returns true if equal.
1207
+ * Define `Symbol.toPrimitive` to customize.
1208
+ */
1092
1209
  function $mol_compare_deep(left, right) {
1093
1210
  if (Object.is(left, right))
1094
1211
  return true;
@@ -1228,6 +1345,7 @@ var $;
1228
1345
  "use strict";
1229
1346
  var $;
1230
1347
  (function ($) {
1348
+ /** Log begin of collapsed group only when some logged inside, returns func to close group */
1231
1349
  function $mol_log3_area_lazy(event) {
1232
1350
  const self = this.$;
1233
1351
  const stack = self.$mol_log3_stack;
@@ -1284,6 +1402,7 @@ var $;
1284
1402
  "use strict";
1285
1403
  var $;
1286
1404
  (function ($) {
1405
+ /** One-shot fiber */
1287
1406
  class $mol_wire_task extends $mol_wire_fiber {
1288
1407
  static getter(task) {
1289
1408
  return function $mol_wire_task_get(host, args) {
@@ -1309,6 +1428,7 @@ var $;
1309
1428
  }
1310
1429
  const key = (host?.[Symbol.toStringTag] ?? host) + ('.' + task.name + '<#>');
1311
1430
  const next = new $mol_wire_task(key, task, host, args);
1431
+ // Disabled because non-idempotency is required for try-catch
1312
1432
  if (existen?.temp) {
1313
1433
  $$.$mol_log3_warn({
1314
1434
  place: '$mol_wire_task',
@@ -1341,7 +1461,7 @@ var $;
1341
1461
  try {
1342
1462
  next[Symbol.toStringTag] = this[Symbol.toStringTag];
1343
1463
  }
1344
- catch {
1464
+ catch { // Promises throw in strict mode
1345
1465
  Object.defineProperty(next, Symbol.toStringTag, { value: this[Symbol.toStringTag] });
1346
1466
  }
1347
1467
  }
@@ -1366,6 +1486,9 @@ var $;
1366
1486
  "use strict";
1367
1487
  var $;
1368
1488
  (function ($) {
1489
+ /**
1490
+ * Decorates method to fiber to ensure it is executed only once inside other fiber.
1491
+ */
1369
1492
  function $mol_wire_method(host, field, descr) {
1370
1493
  if (!descr)
1371
1494
  descr = Reflect.getOwnPropertyDescriptor(host, field);
@@ -1435,6 +1558,7 @@ var $;
1435
1558
  let error;
1436
1559
  let result;
1437
1560
  let handler;
1561
+ /// Debugger will stop at exceptions but exception will be returned normally
1438
1562
  function $mol_try_web(handler2) {
1439
1563
  handler = handler2;
1440
1564
  error = undefined;
@@ -1475,6 +1599,7 @@ var $;
1475
1599
  "use strict";
1476
1600
  var $;
1477
1601
  (function ($) {
1602
+ /** Long-living fiber. */
1478
1603
  class $mol_wire_atom extends $mol_wire_fiber {
1479
1604
  static solo(host, task) {
1480
1605
  const field = task.name + '()';
@@ -1525,7 +1650,11 @@ var $;
1525
1650
  }
1526
1651
  $mol_wire_atom.watching.add(this);
1527
1652
  }
1653
+ /**
1654
+ * Update atom value through another temp fiber.
1655
+ */
1528
1656
  resync(args) {
1657
+ // enforce pulling tasks abort
1529
1658
  for (let cursor = this.pub_from; cursor < this.sub_from; cursor += 2) {
1530
1659
  const pub = this.data[cursor];
1531
1660
  if (pub && pub instanceof $mol_wire_task) {
@@ -1586,7 +1715,7 @@ var $;
1586
1715
  try {
1587
1716
  next[Symbol.toStringTag] = this[Symbol.toStringTag];
1588
1717
  }
1589
- catch {
1718
+ catch { // Promises throw in strict mode
1590
1719
  Object.defineProperty(next, Symbol.toStringTag, { value: this[Symbol.toStringTag] });
1591
1720
  }
1592
1721
  }
@@ -1822,6 +1951,7 @@ var $;
1822
1951
  ;
1823
1952
  $mol_wire_dom(this)[field] = getter;
1824
1953
  }
1954
+ /** Polyfill makes DOM reactive. */
1825
1955
  function $mol_wire_dom(el) {
1826
1956
  if (el.__defineGetter__ === redefine)
1827
1957
  return el;