verstak 0.23.107 → 0.23.109

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.
@@ -0,0 +1,877 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
11
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
12
+ return new (P || (P = Promise))(function (resolve, reject) {
13
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
14
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
15
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
16
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
17
+ });
18
+ };
19
+ import { reactive, nonreactive, Transaction, options, Reentrance, Rx, Collection, ObservableObject, raw } from "reactronic";
20
+ import { BlockKind, Priority, Mode, Align } from "./Interfaces";
21
+ import { emitLetters, equalBlockCoords, parseBlockCoords, getCallerInfo } from "./Utils";
22
+ export class Verstak {
23
+ static claim(driver, builder, base) {
24
+ var _a;
25
+ let result;
26
+ if (builder)
27
+ builder.base = base;
28
+ else
29
+ builder = base !== null && base !== void 0 ? base : {};
30
+ let key = builder.key;
31
+ const owner = gCurrent === null || gCurrent === void 0 ? void 0 : gCurrent.instance;
32
+ if (owner) {
33
+ let ex = undefined;
34
+ const children = owner.descriptor.children;
35
+ if (driver.isRow) {
36
+ const last = children.lastClaimedItem();
37
+ if (((_a = last === null || last === void 0 ? void 0 : last.instance) === null || _a === void 0 ? void 0 : _a.descriptor.driver) === driver)
38
+ ex = last;
39
+ }
40
+ ex !== null && ex !== void 0 ? ex : (ex = children.claim(key = key || generateKey(owner), undefined, "nested blocks can be declared inside render function only"));
41
+ if (ex) {
42
+ result = ex.instance;
43
+ const d = result.descriptor;
44
+ if (d.driver !== driver && driver !== undefined)
45
+ throw new Error(`changing block driver is not yet supported: "${result.descriptor.driver.name}" -> "${driver === null || driver === void 0 ? void 0 : driver.name}"`);
46
+ const exTriggers = d.builder.triggers;
47
+ if (triggersAreEqual(builder.triggers, exTriggers))
48
+ builder.triggers = exTriggers;
49
+ d.builder = builder;
50
+ }
51
+ else {
52
+ result = new BlockImpl(key || generateKey(owner), driver, owner, builder);
53
+ result.descriptor.item = children.add(result);
54
+ }
55
+ }
56
+ else {
57
+ result = new BlockImpl(key || "", driver, owner, builder);
58
+ result.descriptor.item = Collection.createItem(result);
59
+ triggerRendering(result.descriptor.item);
60
+ }
61
+ return result;
62
+ }
63
+ static get block() {
64
+ if (gCurrent === undefined)
65
+ throw new Error("current block is undefined");
66
+ return gCurrent.instance;
67
+ }
68
+ static renderNestedTreesThenDo(action) {
69
+ runRenderNestedTreesThenDo(undefined, action);
70
+ }
71
+ static getDefaultLoggingOptions() {
72
+ return BlockImpl.logging;
73
+ }
74
+ static setDefaultLoggingOptions(logging) {
75
+ BlockImpl.logging = logging;
76
+ }
77
+ }
78
+ Verstak.shortFrameDuration = 16;
79
+ Verstak.longFrameDuration = 300;
80
+ Verstak.currentRenderingPriority = Priority.Realtime;
81
+ Verstak.frameDuration = Verstak.longFrameDuration;
82
+ export class BaseDriver {
83
+ constructor(name, isRow, preset) {
84
+ this.name = name;
85
+ this.isRow = isRow;
86
+ this.preset = preset;
87
+ }
88
+ claim(block) {
89
+ const b = block;
90
+ chainedClaim(b, b.descriptor.builder);
91
+ }
92
+ create(block, b) {
93
+ chainedCreate(block, block.descriptor.builder);
94
+ }
95
+ initialize(block) {
96
+ var _a;
97
+ const b = block;
98
+ (_a = this.preset) === null || _a === void 0 ? void 0 : _a.call(this, b);
99
+ chainedInitialize(b, b.descriptor.builder);
100
+ }
101
+ mount(block) {
102
+ }
103
+ render(block) {
104
+ chainedRender(block, block.descriptor.builder);
105
+ }
106
+ finalize(block, isLeader) {
107
+ const b = block;
108
+ chainedFinalize(b, b.descriptor.builder);
109
+ return isLeader;
110
+ }
111
+ applyKind(block, value) { }
112
+ applyCoords(block, value) { }
113
+ applyWidthGrowth(block, value) { }
114
+ applyMinWidth(block, value) { }
115
+ applyMaxWidth(block, value) { }
116
+ applyHeightGrowth(block, value) { }
117
+ applyMinHeight(block, value) { }
118
+ applyMaxHeight(block, value) { }
119
+ applyContentAlignment(block, value) { }
120
+ applyBlockAlignment(block, value) { }
121
+ applyContentWrapping(block, value) { }
122
+ applyOverlayVisible(block, value) { }
123
+ applyStyle(block, secondary, styleName, enabled) { }
124
+ }
125
+ BaseDriver.fragment = new BaseDriver("fragment", false, b => b.kind = BlockKind.Group);
126
+ function generateKey(owner) {
127
+ const n = owner.descriptor.numerator++;
128
+ const lettered = emitLetters(n);
129
+ let result;
130
+ if (Rx.isLogging)
131
+ result = `·${getCallerInfo(lettered)}`;
132
+ else
133
+ result = `·${lettered}`;
134
+ return result;
135
+ }
136
+ function chainedMode(bb) {
137
+ var _a;
138
+ return (_a = bb === null || bb === void 0 ? void 0 : bb.mode) !== null && _a !== void 0 ? _a : ((bb === null || bb === void 0 ? void 0 : bb.base) ? chainedMode(bb === null || bb === void 0 ? void 0 : bb.base) : Mode.Default);
139
+ }
140
+ function chainedClaim(block, bb) {
141
+ const claim = bb.claim;
142
+ const base = bb.base;
143
+ if (claim)
144
+ claim(block, base ? () => chainedClaim(block, base) : NOP);
145
+ else if (base)
146
+ chainedClaim(block, base);
147
+ }
148
+ function chainedCreate(block, bb) {
149
+ const create = bb.create;
150
+ const base = bb.base;
151
+ if (create)
152
+ create(block, base ? () => chainedCreate(block, base) : NOP);
153
+ else if (base)
154
+ chainedCreate(block, base);
155
+ }
156
+ function chainedInitialize(block, bb) {
157
+ const initialize = bb.initialize;
158
+ const base = bb.base;
159
+ if (initialize)
160
+ initialize(block, base ? () => chainedInitialize(block, base) : NOP);
161
+ else if (base)
162
+ chainedInitialize(block, base);
163
+ }
164
+ function chainedRender(block, bb) {
165
+ const render = bb.render;
166
+ const base = bb.base;
167
+ if (render)
168
+ render(block, base ? () => chainedRender(block, base) : NOP);
169
+ else if (base)
170
+ chainedRender(block, base);
171
+ }
172
+ function chainedFinalize(block, bb) {
173
+ const finalize = bb.finalize;
174
+ const base = bb.base;
175
+ if (finalize)
176
+ finalize(block, base ? () => chainedFinalize(block, base) : NOP);
177
+ else if (base)
178
+ chainedFinalize(block, base);
179
+ }
180
+ export class StaticDriver extends BaseDriver {
181
+ constructor(element, name, isRow, preset) {
182
+ super(name, isRow, preset);
183
+ this.element = element;
184
+ }
185
+ create(block, b) {
186
+ b.native = this.element;
187
+ }
188
+ }
189
+ export class CursorCommand {
190
+ }
191
+ export class CursorCommandDriver extends BaseDriver {
192
+ constructor() {
193
+ super("cursor", false, b => b.kind = BlockKind.Cursor);
194
+ }
195
+ create(block, b) {
196
+ b.native = new CursorCommand();
197
+ super.create(block, b);
198
+ }
199
+ }
200
+ export class ContextVariable {
201
+ constructor(defaultValue) {
202
+ this.defaultValue = defaultValue;
203
+ }
204
+ set value(value) {
205
+ BlockImpl.setContextVariableValue(this, value);
206
+ }
207
+ get value() {
208
+ return BlockImpl.useContextVariableValue(this);
209
+ }
210
+ get valueOrUndefined() {
211
+ return BlockImpl.tryUseContextVariable(this);
212
+ }
213
+ }
214
+ class CursorPosition {
215
+ constructor(prev) {
216
+ this.x = prev.x;
217
+ this.y = prev.y;
218
+ this.runningMaxX = prev.runningMaxX;
219
+ this.runningMaxY = prev.runningMaxY;
220
+ this.flags = prev.flags & ~CursorFlags.OwnCursorPosition;
221
+ }
222
+ }
223
+ var CursorFlags;
224
+ (function (CursorFlags) {
225
+ CursorFlags[CursorFlags["None"] = 0] = "None";
226
+ CursorFlags[CursorFlags["OwnCursorPosition"] = 1] = "OwnCursorPosition";
227
+ CursorFlags[CursorFlags["UsesRunningColumnCount"] = 2] = "UsesRunningColumnCount";
228
+ CursorFlags[CursorFlags["UsesRunningRowCount"] = 4] = "UsesRunningRowCount";
229
+ })(CursorFlags || (CursorFlags = {}));
230
+ const UndefinedBlockCoords = Object.freeze({ x1: 0, y1: 0, x2: 0, y2: 0 });
231
+ const InitialCursorPosition = Object.freeze(new CursorPosition({ x: 1, y: 1, runningMaxX: 0, runningMaxY: 0, flags: CursorFlags.None }));
232
+ class BlockCtxImpl extends ObservableObject {
233
+ constructor(variable, value) {
234
+ super();
235
+ this.next = undefined;
236
+ this.variable = variable;
237
+ this.value = value;
238
+ }
239
+ }
240
+ __decorate([
241
+ raw,
242
+ __metadata("design:type", Object)
243
+ ], BlockCtxImpl.prototype, "next", void 0);
244
+ __decorate([
245
+ raw,
246
+ __metadata("design:type", ContextVariable)
247
+ ], BlockCtxImpl.prototype, "variable", void 0);
248
+ class BlockDescriptorImpl {
249
+ constructor(key, driver, builder, self, owner) {
250
+ this.maxColumnCount = 0;
251
+ this.maxRowCount = 0;
252
+ this.key = key;
253
+ this.driver = driver;
254
+ this.builder = builder;
255
+ if (owner) {
256
+ const d = owner.descriptor;
257
+ this.level = d.level + 1;
258
+ this.owner = owner;
259
+ this.outer = d.context ? owner : d.outer;
260
+ }
261
+ else {
262
+ this.level = 1;
263
+ this.owner = owner = self;
264
+ this.outer = self;
265
+ }
266
+ this.host = self;
267
+ this.children = new Collection(getBlockKey, true);
268
+ this.item = undefined;
269
+ this.stamp = 0;
270
+ this.context = undefined;
271
+ this.numerator = 0;
272
+ this.maxColumnCount = 0;
273
+ this.maxRowCount = 0;
274
+ this.cursorPosition = undefined;
275
+ }
276
+ }
277
+ class BlockImpl {
278
+ constructor(key, driver, owner, builder) {
279
+ this.descriptor = new BlockDescriptorImpl(key, driver, builder, this, owner);
280
+ this.native = undefined;
281
+ this.model = undefined;
282
+ this.controller = undefined;
283
+ this._kind = BlockKind.Row;
284
+ this._area = undefined;
285
+ this._coords = UndefinedBlockCoords;
286
+ this._widthGrowth = 0;
287
+ this._minWidth = "";
288
+ this._maxWidth = "";
289
+ this._heightGrowth = 0;
290
+ this._minHeight = "";
291
+ this._maxHeight = "";
292
+ this._contentAlignment = Align.Default;
293
+ this._blockAlignment = Align.Default;
294
+ this._contentWrapping = false;
295
+ this._overlayVisible = undefined;
296
+ this._hasStyles = false;
297
+ this.childrenShuffling = false;
298
+ this.renderingPriority = Priority.Realtime;
299
+ BlockImpl.grandCount++;
300
+ if (this.isOn(Mode.PinpointRefresh))
301
+ BlockImpl.disposableCount++;
302
+ }
303
+ render(_triggers) {
304
+ renderNow(this.descriptor.item);
305
+ }
306
+ prepareForRender() {
307
+ this._area = undefined;
308
+ this._hasStyles = false;
309
+ }
310
+ isOn(mode) {
311
+ return (chainedMode(this.descriptor.builder) & mode) === mode;
312
+ }
313
+ get isInitialRendering() { return this.descriptor.stamp === 2; }
314
+ get isSequential() { return this.descriptor.children.isStrict; }
315
+ set isSequential(value) { this.descriptor.children.isStrict = value; }
316
+ get isAuxiliary() { return this.kind > BlockKind.Note; }
317
+ get isBand() { return this.kind === BlockKind.Band; }
318
+ get isTable() { return this.kind === BlockKind.Table; }
319
+ get isAutoMountingEnabled() { return !this.isOn(Mode.ManualMounting) && this.descriptor.host !== this; }
320
+ get isMoved() { return this.descriptor.owner.descriptor.children.isMoved(this.descriptor.item); }
321
+ get kind() { return this._kind; }
322
+ set kind(value) {
323
+ if (value !== this._kind || this.descriptor.stamp < 2) {
324
+ this.descriptor.driver.applyKind(this, value);
325
+ this._kind = value;
326
+ }
327
+ }
328
+ get area() { return this._area; }
329
+ set area(value) {
330
+ var _a, _b;
331
+ const d = this.descriptor;
332
+ const driver = d.driver;
333
+ if (!driver.isRow) {
334
+ const owner = d.owner.descriptor;
335
+ const cursorPosition = (_b = (_a = d.item.prev) === null || _a === void 0 ? void 0 : _a.instance.descriptor.cursorPosition) !== null && _b !== void 0 ? _b : InitialCursorPosition;
336
+ const newCursorPosition = d.cursorPosition = owner.children.isStrict ? new CursorPosition(cursorPosition) : undefined;
337
+ const isCursorBlock = driver instanceof CursorCommandDriver;
338
+ const coords = getEffectiveBlockCoords(!isCursorBlock, value, owner.maxColumnCount, owner.maxRowCount, cursorPosition, newCursorPosition);
339
+ if (!equalBlockCoords(coords, this._coords)) {
340
+ driver.applyCoords(this, coords);
341
+ this._coords = coords;
342
+ }
343
+ this._area = value !== null && value !== void 0 ? value : {};
344
+ }
345
+ else
346
+ this.rowBreak();
347
+ }
348
+ get widthGrowth() { return this._widthGrowth; }
349
+ set widthGrowth(value) {
350
+ if (value !== this._widthGrowth) {
351
+ this.descriptor.driver.applyWidthGrowth(this, value);
352
+ this._widthGrowth = value;
353
+ }
354
+ }
355
+ get minWidth() { return this._minWidth; }
356
+ set minWidth(value) {
357
+ if (value !== this._minWidth) {
358
+ this.descriptor.driver.applyMinWidth(this, value);
359
+ this._minWidth = value;
360
+ }
361
+ }
362
+ get maxWidth() { return this._maxWidth; }
363
+ set maxWidth(value) {
364
+ if (value !== this._maxWidth) {
365
+ this.descriptor.driver.applyMaxWidth(this, value);
366
+ this._maxWidth = value;
367
+ }
368
+ }
369
+ get heightGrowth() { return this._heightGrowth; }
370
+ set heightGrowth(value) {
371
+ if (value !== this._heightGrowth) {
372
+ this.descriptor.driver.applyHeightGrowth(this, value);
373
+ this._heightGrowth = value;
374
+ }
375
+ }
376
+ get minHeight() { return this._minHeight; }
377
+ set minHeight(value) {
378
+ if (value !== this._minHeight) {
379
+ this.descriptor.driver.applyMinHeight(this, value);
380
+ this._minHeight = value;
381
+ }
382
+ }
383
+ get maxHeight() { return this._maxHeight; }
384
+ set maxHeight(value) {
385
+ if (value !== this._maxHeight) {
386
+ this.descriptor.driver.applyMaxHeight(this, value);
387
+ this._maxHeight = value;
388
+ }
389
+ }
390
+ get contentAlignment() { return this._contentAlignment; }
391
+ set contentAlignment(value) {
392
+ if (value !== this._contentAlignment) {
393
+ this.descriptor.driver.applyContentAlignment(this, value);
394
+ this._contentAlignment = value;
395
+ }
396
+ }
397
+ get blockAlignment() { return this._blockAlignment; }
398
+ set blockAlignment(value) {
399
+ if (value !== this._blockAlignment) {
400
+ this.descriptor.driver.applyBlockAlignment(this, value);
401
+ this._blockAlignment = value;
402
+ }
403
+ }
404
+ get contentWrapping() { return this._contentWrapping; }
405
+ set contentWrapping(value) {
406
+ if (value !== this._contentWrapping) {
407
+ this.descriptor.driver.applyContentWrapping(this, value);
408
+ this._contentWrapping = value;
409
+ }
410
+ }
411
+ get overlayVisible() { return this._overlayVisible; }
412
+ set overlayVisible(value) {
413
+ if (value !== this._overlayVisible) {
414
+ this.descriptor.driver.applyOverlayVisible(this, value);
415
+ this._overlayVisible = value;
416
+ }
417
+ }
418
+ useStyle(styleName, enabled) {
419
+ this.descriptor.driver.applyStyle(this, this._hasStyles, styleName, enabled);
420
+ this._hasStyles = true;
421
+ }
422
+ configureReactronic(options) {
423
+ if (this.descriptor.stamp !== 1 || !this.isOn(Mode.PinpointRefresh))
424
+ throw new Error("reactronic can be configured only for blocks with separate reaction mode and only inside initialize");
425
+ return Rx.getController(this.render).configure(options);
426
+ }
427
+ static get curr() {
428
+ if (!gCurrent)
429
+ throw new Error("current block is undefined");
430
+ return gCurrent;
431
+ }
432
+ static tryUseContextVariable(variable) {
433
+ var _a, _b;
434
+ let b = BlockImpl.curr.instance;
435
+ while (((_a = b.descriptor.context) === null || _a === void 0 ? void 0 : _a.variable) !== variable && b.descriptor.owner !== b)
436
+ b = b.descriptor.outer;
437
+ return (_b = b.descriptor.context) === null || _b === void 0 ? void 0 : _b.value;
438
+ }
439
+ static useContextVariableValue(variable) {
440
+ var _a;
441
+ const result = (_a = BlockImpl.tryUseContextVariable(variable)) !== null && _a !== void 0 ? _a : variable.defaultValue;
442
+ if (!result)
443
+ throw new Error("context doesn't exist");
444
+ return result;
445
+ }
446
+ static setContextVariableValue(variable, value) {
447
+ const b = BlockImpl.curr.instance;
448
+ const d = b.descriptor;
449
+ const owner = d.owner;
450
+ const hostCtx = nonreactive(() => { var _a; return (_a = owner.descriptor.context) === null || _a === void 0 ? void 0 : _a.value; });
451
+ if (value && value !== hostCtx) {
452
+ if (hostCtx)
453
+ d.outer = owner;
454
+ else
455
+ d.outer = owner.descriptor.outer;
456
+ Transaction.run({ separation: true }, () => {
457
+ const ctx = d.context;
458
+ if (ctx) {
459
+ ctx.variable = variable;
460
+ ctx.value = value;
461
+ }
462
+ else
463
+ d.context = new BlockCtxImpl(variable, value);
464
+ });
465
+ }
466
+ else if (hostCtx)
467
+ d.outer = owner;
468
+ else
469
+ d.outer = owner.descriptor.outer;
470
+ }
471
+ rowBreak() {
472
+ var _a, _b;
473
+ const d = this.descriptor;
474
+ const cursorPosition = (_b = (_a = d.item.prev) === null || _a === void 0 ? void 0 : _a.instance.descriptor.cursorPosition) !== null && _b !== void 0 ? _b : InitialCursorPosition;
475
+ const newCursorPosition = this.descriptor.cursorPosition = new CursorPosition(cursorPosition);
476
+ newCursorPosition.x = 1;
477
+ newCursorPosition.y = newCursorPosition.runningMaxY + 1;
478
+ }
479
+ }
480
+ BlockImpl.grandCount = 0;
481
+ BlockImpl.disposableCount = 0;
482
+ BlockImpl.logging = undefined;
483
+ __decorate([
484
+ reactive,
485
+ options({
486
+ reentrance: Reentrance.CancelPrevious,
487
+ triggeringArgs: true,
488
+ noSideEffects: false,
489
+ }),
490
+ __metadata("design:type", Function),
491
+ __metadata("design:paramtypes", [Object]),
492
+ __metadata("design:returntype", void 0)
493
+ ], BlockImpl.prototype, "render", null);
494
+ function getBlockKey(block) {
495
+ const d = block.descriptor;
496
+ return d.stamp >= 0 ? d.key : undefined;
497
+ }
498
+ function getEffectiveBlockCoords(isRegularBlock, area, maxX, maxY, cursorPosition, newCursorPosition) {
499
+ var _a, _b;
500
+ let result;
501
+ if (typeof (area) === "string") {
502
+ result = parseBlockCoords(area, { x1: 0, y1: 0, x2: 0, y2: 0 });
503
+ absolutizeBlockCoords(result, cursorPosition.x, cursorPosition.y, maxX || Infinity, maxY || Infinity, result);
504
+ if (newCursorPosition) {
505
+ newCursorPosition.x = isRegularBlock ? result.x2 + 1 : result.x1;
506
+ newCursorPosition.y = result.y1;
507
+ newCursorPosition.flags = CursorFlags.OwnCursorPosition;
508
+ }
509
+ }
510
+ else if (newCursorPosition) {
511
+ let dx;
512
+ let dy;
513
+ if (area) {
514
+ dx = (_a = area.cellsOverWidth) !== null && _a !== void 0 ? _a : 1;
515
+ dy = (_b = area.cellsOverHeight) !== null && _b !== void 0 ? _b : 1;
516
+ }
517
+ else
518
+ dx = dy = 1;
519
+ const runningX = maxX !== 0 ? maxX : cursorPosition.runningMaxX;
520
+ const runningY = maxY !== 0 ? maxY : cursorPosition.runningMaxY;
521
+ result = { x1: 0, y1: 0, x2: 0, y2: 0 };
522
+ if (dx === 0 && isRegularBlock) {
523
+ dx = runningX || 1;
524
+ newCursorPosition.flags = CursorFlags.UsesRunningColumnCount;
525
+ }
526
+ if (dx >= 0) {
527
+ if (isRegularBlock) {
528
+ result.x1 = cursorPosition.x;
529
+ result.x2 = absolutizePosition(result.x1 + dx - 1, 0, maxX || Infinity);
530
+ newCursorPosition.x = result.x2 + 1;
531
+ }
532
+ else {
533
+ result.x1 = result.x2 = cursorPosition.x + dx;
534
+ newCursorPosition.x = result.x2;
535
+ }
536
+ }
537
+ else {
538
+ if (isRegularBlock) {
539
+ result.x1 = Math.max(cursorPosition.x + dx, 1);
540
+ result.x2 = cursorPosition.x;
541
+ newCursorPosition.x = result.x2 + 1;
542
+ }
543
+ else {
544
+ result.x1 = result.x2 = cursorPosition.x + dx;
545
+ newCursorPosition.x = result.x2;
546
+ }
547
+ }
548
+ if (dy === 0 && isRegularBlock) {
549
+ dy = runningY || 1;
550
+ newCursorPosition.flags |= CursorFlags.UsesRunningRowCount;
551
+ }
552
+ if (dy >= 0) {
553
+ if (isRegularBlock) {
554
+ result.y1 = cursorPosition.y;
555
+ result.y2 = absolutizePosition(result.y1 + dy - 1, 0, maxY || Infinity);
556
+ if (result.y2 > newCursorPosition.runningMaxY)
557
+ newCursorPosition.runningMaxY = result.y2;
558
+ }
559
+ else
560
+ result.y1 = result.y2 = cursorPosition.y + dy;
561
+ }
562
+ else {
563
+ if (isRegularBlock) {
564
+ result.y1 = Math.max(cursorPosition.y + dy, 1);
565
+ result.y2 = cursorPosition.y;
566
+ }
567
+ else
568
+ result.y1 = result.y2 = cursorPosition.y + dy;
569
+ }
570
+ }
571
+ else
572
+ throw new Error("relative layout requires sequential children");
573
+ return result;
574
+ }
575
+ function runRenderNestedTreesThenDo(error, action) {
576
+ var _a;
577
+ const curr = BlockImpl.curr;
578
+ const owner = curr.instance;
579
+ const children = owner.descriptor.children;
580
+ if (children.isMergeInProgress) {
581
+ let promised = undefined;
582
+ try {
583
+ children.endMerge(error);
584
+ for (const item of children.removedItems(true))
585
+ triggerFinalization(item, true, true);
586
+ if (!error) {
587
+ const ownerIsBand = owner.isBand;
588
+ const sequential = children.isStrict;
589
+ let p1 = undefined;
590
+ let p2 = undefined;
591
+ let mounting = false;
592
+ let hostingRow = owner;
593
+ for (const item of children.items()) {
594
+ if (Transaction.isCanceled)
595
+ break;
596
+ const block = item.instance;
597
+ const isRow = block.descriptor.driver.isRow;
598
+ const host = isRow ? owner : hostingRow;
599
+ const p = (_a = block.renderingPriority) !== null && _a !== void 0 ? _a : Priority.Realtime;
600
+ mounting = markToMountIfNecessary(mounting, host, item, children, sequential);
601
+ if (p === Priority.Realtime)
602
+ triggerRendering(item);
603
+ else if (p === Priority.Normal)
604
+ p1 = push(item, p1);
605
+ else
606
+ p2 = push(item, p2);
607
+ if (ownerIsBand && isRow)
608
+ hostingRow = block;
609
+ }
610
+ if (!Transaction.isCanceled && (p1 !== undefined || p2 !== undefined))
611
+ promised = startIncrementalRendering(curr, children, p1, p2).then(() => action(error), e => action(e));
612
+ }
613
+ }
614
+ finally {
615
+ if (!promised)
616
+ action(error);
617
+ }
618
+ }
619
+ }
620
+ function markToMountIfNecessary(mounting, host, item, children, sequential) {
621
+ const b = item.instance;
622
+ const d = b.descriptor;
623
+ if (b.native && !b.isOn(Mode.ManualMounting)) {
624
+ if (mounting || d.host !== host) {
625
+ children.markAsMoved(item);
626
+ mounting = false;
627
+ }
628
+ }
629
+ else if (sequential && children.isMoved(item))
630
+ mounting = true;
631
+ d.host = host;
632
+ return mounting;
633
+ }
634
+ function startIncrementalRendering(owner, allChildren, priority1, priority2) {
635
+ return __awaiter(this, void 0, void 0, function* () {
636
+ const stamp = owner.instance.descriptor.stamp;
637
+ if (priority1)
638
+ yield renderIncrementally(owner, stamp, allChildren, priority1, Priority.Normal);
639
+ if (priority2)
640
+ yield renderIncrementally(owner, stamp, allChildren, priority2, Priority.Background);
641
+ });
642
+ }
643
+ function renderIncrementally(owner, stamp, allChildren, items, priority) {
644
+ return __awaiter(this, void 0, void 0, function* () {
645
+ yield Transaction.requestNextFrame();
646
+ const block = owner.instance;
647
+ if (!Transaction.isCanceled || !Transaction.isFrameOver(1, Verstak.shortFrameDuration / 3)) {
648
+ let outerPriority = Verstak.currentRenderingPriority;
649
+ Verstak.currentRenderingPriority = priority;
650
+ try {
651
+ if (block.childrenShuffling)
652
+ shuffle(items);
653
+ const frameDurationLimit = priority === Priority.Background ? Verstak.shortFrameDuration : Infinity;
654
+ let frameDuration = Math.min(frameDurationLimit, Math.max(Verstak.frameDuration / 4, Verstak.shortFrameDuration));
655
+ for (const child of items) {
656
+ triggerRendering(child);
657
+ if (Transaction.isFrameOver(1, frameDuration)) {
658
+ Verstak.currentRenderingPriority = outerPriority;
659
+ yield Transaction.requestNextFrame(0);
660
+ outerPriority = Verstak.currentRenderingPriority;
661
+ Verstak.currentRenderingPriority = priority;
662
+ frameDuration = Math.min(4 * frameDuration, Math.min(frameDurationLimit, Verstak.frameDuration));
663
+ }
664
+ if (Transaction.isCanceled && Transaction.isFrameOver(1, Verstak.shortFrameDuration / 3))
665
+ break;
666
+ }
667
+ }
668
+ finally {
669
+ Verstak.currentRenderingPriority = outerPriority;
670
+ }
671
+ }
672
+ });
673
+ }
674
+ function triggerRendering(item) {
675
+ const b = item.instance;
676
+ const d = b.descriptor;
677
+ if (d.stamp >= 0) {
678
+ if (b.isOn(Mode.PinpointRefresh)) {
679
+ if (d.stamp === 0) {
680
+ Transaction.outside(() => {
681
+ if (Rx.isLogging)
682
+ Rx.setLoggingHint(b, d.key);
683
+ Rx.getController(b.render).configure({
684
+ order: d.level,
685
+ });
686
+ });
687
+ }
688
+ nonreactive(b.render, d.builder.triggers);
689
+ }
690
+ else
691
+ renderNow(item);
692
+ }
693
+ }
694
+ function mountIfNecessary(block) {
695
+ const d = block.descriptor;
696
+ const driver = d.driver;
697
+ if (d.stamp === 0) {
698
+ d.stamp = 1;
699
+ nonreactive(() => {
700
+ driver.create(block, block);
701
+ driver.initialize(block);
702
+ if (block.isAutoMountingEnabled)
703
+ driver.mount(block);
704
+ });
705
+ }
706
+ else if (block.isMoved && block.isAutoMountingEnabled)
707
+ nonreactive(() => driver.mount(block));
708
+ }
709
+ function renderNow(item) {
710
+ const b = item.instance;
711
+ const d = b.descriptor;
712
+ if (d.stamp >= 0) {
713
+ let result = undefined;
714
+ runInside(item, () => {
715
+ try {
716
+ mountIfNecessary(b);
717
+ d.stamp++;
718
+ d.numerator = 0;
719
+ b.prepareForRender();
720
+ d.children.beginMerge();
721
+ const driver = d.driver;
722
+ result = driver.render(b);
723
+ if (b.area === undefined && d.owner.isTable)
724
+ b.area = undefined;
725
+ if (result instanceof Promise)
726
+ result.then(v => { runRenderNestedTreesThenDo(undefined, NOP); return v; }, e => { console.log(e); runRenderNestedTreesThenDo(e !== null && e !== void 0 ? e : new Error("unknown error"), NOP); });
727
+ else
728
+ runRenderNestedTreesThenDo(undefined, NOP);
729
+ }
730
+ catch (e) {
731
+ runRenderNestedTreesThenDo(e, NOP);
732
+ console.log(`Rendering failed: ${d.key}`);
733
+ console.log(`${e}`);
734
+ }
735
+ });
736
+ }
737
+ }
738
+ function triggerFinalization(item, isLeader, individual) {
739
+ const b = item.instance;
740
+ const d = b.descriptor;
741
+ if (d.stamp >= 0) {
742
+ const driver = d.driver;
743
+ if (individual && d.key !== d.builder.key && !driver.isRow)
744
+ console.log(`WARNING: it is recommended to assign explicit key for conditionally rendered block in order to avoid unexpected side effects: ${d.key}`);
745
+ d.stamp = ~d.stamp;
746
+ const childrenAreLeaders = nonreactive(() => driver.finalize(b, isLeader));
747
+ b.native = null;
748
+ b.controller = null;
749
+ if (b.isOn(Mode.PinpointRefresh)) {
750
+ item.aux = undefined;
751
+ const last = gLastToDispose;
752
+ if (last)
753
+ gLastToDispose = last.aux = item;
754
+ else
755
+ gFirstToDispose = gLastToDispose = item;
756
+ if (gFirstToDispose === item)
757
+ Transaction.run({ separation: "disposal", hint: `runDisposalLoop(initiator=${item.instance.descriptor.key})` }, () => {
758
+ void runDisposalLoop().then(NOP, error => console.log(error));
759
+ });
760
+ }
761
+ for (const item of d.children.items())
762
+ triggerFinalization(item, childrenAreLeaders, false);
763
+ BlockImpl.grandCount--;
764
+ }
765
+ }
766
+ function runDisposalLoop() {
767
+ return __awaiter(this, void 0, void 0, function* () {
768
+ yield Transaction.requestNextFrame();
769
+ let item = gFirstToDispose;
770
+ while (item !== undefined) {
771
+ if (Transaction.isFrameOver(500, 5))
772
+ yield Transaction.requestNextFrame();
773
+ Rx.dispose(item.instance);
774
+ item = item.aux;
775
+ BlockImpl.disposableCount--;
776
+ }
777
+ gFirstToDispose = gLastToDispose = undefined;
778
+ });
779
+ }
780
+ function wrapToRunInside(func) {
781
+ let wrappedToRunInside;
782
+ const current = gCurrent;
783
+ if (current)
784
+ wrappedToRunInside = (...args) => {
785
+ return runInside(current, func, ...args);
786
+ };
787
+ else
788
+ wrappedToRunInside = func;
789
+ return wrappedToRunInside;
790
+ }
791
+ function runInside(item, func, ...args) {
792
+ const outer = gCurrent;
793
+ try {
794
+ gCurrent = item;
795
+ return func(...args);
796
+ }
797
+ finally {
798
+ gCurrent = outer;
799
+ }
800
+ }
801
+ function triggersAreEqual(a1, a2) {
802
+ let result = a1 === a2;
803
+ if (!result) {
804
+ if (Array.isArray(a1)) {
805
+ result = Array.isArray(a2) &&
806
+ a1.length === a2.length &&
807
+ a1.every((t, i) => t === a2[i]);
808
+ }
809
+ else if (a1 === Object(a1) && a2 === Object(a2)) {
810
+ for (const p in a1) {
811
+ result = a1[p] === a2[p];
812
+ if (!result)
813
+ break;
814
+ }
815
+ }
816
+ }
817
+ return result;
818
+ }
819
+ function absolutizeBlockCoords(area, cursorX, cursorY, maxWidth, maxHeight, result) {
820
+ const x1 = absolutizePosition(area.x1, cursorX, maxWidth);
821
+ const x2 = absolutizePosition(area.x2, x1, maxWidth);
822
+ if (x1 <= x2)
823
+ result.x1 = x1, result.x2 = x2;
824
+ else
825
+ result.x1 = x2, result.x2 = x1;
826
+ const y1 = absolutizePosition(area.y1, cursorY, maxHeight);
827
+ const y2 = absolutizePosition(area.y2, y1, maxHeight);
828
+ if (y1 <= y2)
829
+ result.y1 = y1, result.y2 = y2;
830
+ else
831
+ result.y1 = y2, result.y2 = y1;
832
+ return result;
833
+ }
834
+ function absolutizePosition(pos, cursor, max) {
835
+ if (pos === 0)
836
+ pos = cursor;
837
+ else if (pos < 0)
838
+ pos = Math.max(max + pos, 1);
839
+ else
840
+ pos = Math.min(pos, max);
841
+ return pos;
842
+ }
843
+ function push(item, array) {
844
+ if (array == undefined)
845
+ array = new Array();
846
+ array.push(item);
847
+ return array;
848
+ }
849
+ function shuffle(array) {
850
+ const n = array.length - 1;
851
+ let i = n;
852
+ while (i >= 0) {
853
+ const j = Math.floor(Math.random() * n);
854
+ const t = array[i];
855
+ array[i] = array[j];
856
+ array[j] = t;
857
+ i--;
858
+ }
859
+ return array;
860
+ }
861
+ const ORIGINAL_PROMISE_THEN = Promise.prototype.then;
862
+ function reactronicDomHookedThen(resolve, reject) {
863
+ resolve = resolve ? wrapToRunInside(resolve) : defaultResolve;
864
+ reject = reject ? wrapToRunInside(reject) : defaultReject;
865
+ return ORIGINAL_PROMISE_THEN.call(this, resolve, reject);
866
+ }
867
+ function defaultResolve(value) {
868
+ return value;
869
+ }
870
+ function defaultReject(error) {
871
+ throw error;
872
+ }
873
+ Promise.prototype.then = reactronicDomHookedThen;
874
+ const NOP = (...args) => { };
875
+ let gCurrent = undefined;
876
+ let gFirstToDispose = undefined;
877
+ let gLastToDispose = undefined;