verstak 0.22.515 → 0.22.516

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.
@@ -6,4 +6,6 @@ export interface CellRange {
6
6
  }
7
7
  export declare function parseCellRange(text: string, result: CellRange): CellRange;
8
8
  export declare function emitCellRange(value: CellRange): string;
9
+ export declare function emitLetters(n: number): string;
10
+ export declare function emitCellPosition(x: number, y: number): string;
9
11
  export declare function equalCellRanges(a: CellRange, b: CellRange): boolean;
@@ -134,22 +134,7 @@ export function emitCellRange(value) {
134
134
  const p2 = emitCellPosition(value.x2, value.y2);
135
135
  return `${p1}${p2 !== "" ? `:${p2}` : ""}`;
136
136
  }
137
- export function equalCellRanges(a, b) {
138
- return a.x1 === b.x1 && a.y1 === b.y1 && a.x2 === b.x2 && a.y1 === b.y2;
139
- }
140
- function isWhitespace(char) {
141
- return char === 32 || (char >= 9 && char <= 13) || char === 133 || char === 160;
142
- }
143
- function isDigit(input, index) {
144
- return 48 <= input && input <= 57;
145
- }
146
- function isCapitalLetter(ch) {
147
- return 65 <= ch && ch <= 90;
148
- }
149
- function isLowercaseLetter(ch) {
150
- return 97 <= ch && ch <= 122;
151
- }
152
- function emitLetters(n) {
137
+ export function emitLetters(n) {
153
138
  if (n < 0)
154
139
  throw new Error(`emitLetters: argument (${n}) should not be negative or zero`);
155
140
  let result = "";
@@ -160,7 +145,7 @@ function emitLetters(n) {
160
145
  }
161
146
  return result;
162
147
  }
163
- function emitCellPosition(x, y) {
148
+ export function emitCellPosition(x, y) {
164
149
  let result = "";
165
150
  if (x > 0 && y > 0)
166
151
  result = `${emitLetters(x - 1)}${y}`;
@@ -174,3 +159,18 @@ function emitCellPosition(x, y) {
174
159
  result = "";
175
160
  return result;
176
161
  }
162
+ export function equalCellRanges(a, b) {
163
+ return a.x1 === b.x1 && a.y1 === b.y1 && a.x2 === b.x2 && a.y1 === b.y2;
164
+ }
165
+ function isWhitespace(char) {
166
+ return char === 32 || (char >= 9 && char <= 13) || char === 133 || char === 160;
167
+ }
168
+ function isDigit(input, index) {
169
+ return 48 <= input && input <= 57;
170
+ }
171
+ function isCapitalLetter(ch) {
172
+ return 65 <= ch && ch <= 90;
173
+ }
174
+ function isLowercaseLetter(ch) {
175
+ return 97 <= ch && ch <= 122;
176
+ }
@@ -1 +1,2 @@
1
1
  export declare function objectHasMember<T>(obj: any, member: string): obj is T;
2
+ export declare function getCallerInfo(prefix: string): string;
@@ -1,3 +1,35 @@
1
1
  export function objectHasMember(obj, member) {
2
2
  return obj === Object(obj) && !Array.isArray(obj) && member in obj;
3
3
  }
4
+ export function getCallerInfo(prefix) {
5
+ const restore = Error.stackTraceLimit = 20;
6
+ const error = new Error();
7
+ const stack = error.stack || "";
8
+ Error.stackTraceLimit = restore;
9
+ const lines = stack.split("\n");
10
+ let i = lines.findIndex(x => x.indexOf(".claim") >= 0);
11
+ i = i >= 0 ? i + 2 : 5;
12
+ let caller = extractFunctionAndLocation(lines[i]);
13
+ let location = caller;
14
+ if (caller.func === "VerstakDriver.render" || caller.func === "render") {
15
+ i = i - 1;
16
+ caller = extractFunctionAndLocation(lines[i]);
17
+ location = extractFunctionAndLocation(lines[i + 1]);
18
+ }
19
+ else {
20
+ while (!caller.func) {
21
+ i = i - 1;
22
+ caller = extractFunctionAndLocation(lines[i]);
23
+ }
24
+ location = extractFunctionAndLocation(lines[i + 1]);
25
+ }
26
+ const result = `${prefix}:${caller.func}@${location.file}`;
27
+ return result;
28
+ }
29
+ function extractFunctionAndLocation(s) {
30
+ const match = s.match(/(?:\s*at\s+)?(?:(\S+)\s\()?(?:.*?)([^\/\(\):]+)(?:(:|\d)*\)?)$/);
31
+ return {
32
+ func: (match === null || match === void 0 ? void 0 : match[1]) || "",
33
+ file: (match === null || match === void 0 ? void 0 : match[2]) || "",
34
+ };
35
+ }
@@ -21,8 +21,8 @@ export interface BlockVmt<T = unknown, M = unknown, R = void> {
21
21
  finalize?: Render<T, M, R>;
22
22
  }
23
23
  export declare function asBaseFor<T, M, R>(outer: BlockBody<T, M, R> | undefined, base: BlockBody<T, M, R>): BlockVmt<T, M, R>;
24
- export declare function setContext<T extends Object>(type: Type<T>, context: T): void;
25
- export declare function use<T extends Object>(type: Type<T>): T;
24
+ export declare function nestedContext<T extends Object>(type: Type<T>, context: T): void;
25
+ export declare function useContext<T extends Object>(type: Type<T>): T;
26
26
  export declare abstract class VBlock<T = unknown, M = unknown, R = void> {
27
27
  static readonly shortFrameDuration = 16;
28
28
  static readonly longFrameDuration = 300;
@@ -58,13 +58,14 @@ export declare abstract class VBlock<T = unknown, M = unknown, R = void> {
58
58
  static renderNestedTreesThenDo(action: (error: unknown) => void): void;
59
59
  static runForAllBlocks<T>(action: (e: T) => void): void;
60
60
  static claim<T = undefined, M = unknown, R = void>(driver: AbstractDriver<T> | undefined, body: BlockBody<T, M, R>): VBlock<T, M, R>;
61
+ private static generateKey;
61
62
  static getDefaultLoggingOptions(): LoggingOptions | undefined;
62
63
  static setDefaultLoggingOptions(logging?: LoggingOptions): void;
63
64
  }
64
65
  export declare enum LayoutKind {
65
66
  Block = 0,
66
67
  Grid = 1,
67
- Row = 2,
68
+ Line = 2,
68
69
  Group = 3,
69
70
  Text = 4
70
71
  }
@@ -77,7 +78,7 @@ export declare class AbstractDriver<T> {
77
78
  get isAuxiliary(): boolean;
78
79
  get isBlock(): boolean;
79
80
  get isGrid(): boolean;
80
- get isRow(): boolean;
81
+ get isLine(): boolean;
81
82
  constructor(name: string, layout: LayoutKind, createCursor?: () => Cursor);
82
83
  initialize(block: VBlock<T>, native: T): void;
83
84
  finalize(block: VBlock<T>, isLeader: boolean): boolean;
@@ -17,7 +17,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
17
17
  });
18
18
  };
19
19
  import { reactive, nonreactive, Transaction, options, Reentrance, Rx, Collection, ObservableObject, raw } from "reactronic";
20
- import { equalCellRanges } from "./CellRange";
20
+ import { getCallerInfo } from "./Utils";
21
+ import { emitLetters, equalCellRanges } from "./CellRange";
21
22
  import { Cursor, Align } from "./Cursor";
22
23
  export var Priority;
23
24
  (function (Priority) {
@@ -37,10 +38,10 @@ function via(outer, base) {
37
38
  const inherited = base !== null && base !== void 0 ? base : NOP;
38
39
  return outer ? b => outer(b, () => inherited(b)) : inherited;
39
40
  }
40
- export function setContext(type, context) {
41
+ export function nestedContext(type, context) {
41
42
  return VBlockImpl.setContext(type, context);
42
43
  }
43
- export function use(type) {
44
+ export function useContext(type) {
44
45
  return VBlockImpl.use(type);
45
46
  }
46
47
  export class VBlock {
@@ -70,12 +71,12 @@ export class VBlock {
70
71
  if (body instanceof Function)
71
72
  body = { render: body };
72
73
  let key = body.key;
73
- if (driver.isRow) {
74
+ if (driver.isLine) {
74
75
  const last = children.lastClaimedItem();
75
76
  if (((_a = last === null || last === void 0 ? void 0 : last.instance) === null || _a === void 0 ? void 0 : _a.driver) === driver)
76
77
  ex = last;
77
78
  }
78
- ex !== null && ex !== void 0 ? ex : (ex = children.claim(key = key || `${++owner.numerator}!`, undefined, "nested blocks can be declared inside render function only"));
79
+ ex !== null && ex !== void 0 ? ex : (ex = children.claim(key = key || VBlock.generateKey(owner), undefined, "nested blocks can be declared inside render function only"));
79
80
  if (ex) {
80
81
  result = ex.instance;
81
82
  if (result.driver !== driver && driver !== undefined)
@@ -86,7 +87,7 @@ export class VBlock {
86
87
  result.body = body;
87
88
  }
88
89
  else {
89
- result = new VBlockImpl(key || `${++owner.numerator}!`, driver, owner, body);
90
+ result = new VBlockImpl(key || VBlock.generateKey(owner), driver, owner, body);
90
91
  result.item = children.add(result);
91
92
  VBlockImpl.grandCount++;
92
93
  if (body.reacting)
@@ -94,6 +95,16 @@ export class VBlock {
94
95
  }
95
96
  return result;
96
97
  }
98
+ static generateKey(owner) {
99
+ const n = owner.numerator++;
100
+ const lettered = emitLetters(n);
101
+ let result;
102
+ if (Rx.isLogging)
103
+ result = `[${getCallerInfo(lettered)}]`;
104
+ else
105
+ result = `[${lettered}]`;
106
+ return result;
107
+ }
97
108
  static getDefaultLoggingOptions() {
98
109
  return VBlockImpl.logging;
99
110
  }
@@ -109,7 +120,7 @@ export var LayoutKind;
109
120
  (function (LayoutKind) {
110
121
  LayoutKind[LayoutKind["Block"] = 0] = "Block";
111
122
  LayoutKind[LayoutKind["Grid"] = 1] = "Grid";
112
- LayoutKind[LayoutKind["Row"] = 2] = "Row";
123
+ LayoutKind[LayoutKind["Line"] = 2] = "Line";
113
124
  LayoutKind[LayoutKind["Group"] = 3] = "Group";
114
125
  LayoutKind[LayoutKind["Text"] = 4] = "Text";
115
126
  })(LayoutKind || (LayoutKind = {}));
@@ -124,7 +135,7 @@ export class AbstractDriver {
124
135
  get isAuxiliary() { return (this.layout & 2) === 2; }
125
136
  get isBlock() { return this.layout === LayoutKind.Block; }
126
137
  get isGrid() { return this.layout === LayoutKind.Grid; }
127
- get isRow() { return this.layout === LayoutKind.Row; }
138
+ get isLine() { return this.layout === LayoutKind.Line; }
128
139
  initialize(block, native) {
129
140
  var _a, _b;
130
141
  const b = block;
@@ -278,16 +289,16 @@ class VBlockImpl extends VBlock {
278
289
  }
279
290
  get minHeight() { return this.appliedMinHeight; }
280
291
  set minHeight(value) {
281
- if (value !== this.appliedMinWidth) {
282
- this.driver.applyMinWidth(this, value);
283
- this.appliedMinWidth = value;
292
+ if (value !== this.appliedMinHeight) {
293
+ this.driver.applyMinHeight(this, value);
294
+ this.appliedMinHeight = value;
284
295
  }
285
296
  }
286
297
  get maxHeight() { return this.appliedMaxHeight; }
287
298
  set maxHeight(value) {
288
- if (value !== this.appliedMaxWidth) {
289
- this.driver.applyMaxWidth(this, value);
290
- this.appliedMaxWidth = value;
299
+ if (value !== this.appliedMaxHeight) {
300
+ this.driver.applyMaxHeight(this, value);
301
+ this.appliedMaxHeight = value;
291
302
  }
292
303
  }
293
304
  get contentAlignment() { return this.appliedContentAlignment; }
@@ -381,10 +392,7 @@ function runRenderNestedTreesThenDo(error, action) {
381
392
  try {
382
393
  children.endMerge(error);
383
394
  for (const item of children.removedItems(true)) {
384
- const b = item.instance;
385
- if (b.key !== b.body.key)
386
- console.warn(`every conditionally rendered block requires explicit key: ${b.key}, ${b.driver.name}`);
387
- runFinalize(item, true);
395
+ runFinalize(item, true, true);
388
396
  }
389
397
  if (!error) {
390
398
  const ownerIsBlock = owner.driver.isBlock;
@@ -400,7 +408,7 @@ function runRenderNestedTreesThenDo(error, action) {
400
408
  break;
401
409
  const block = item.instance;
402
410
  const driver = block.driver;
403
- const host = driver.isRow ? owner : partHost;
411
+ const host = driver.isLine ? owner : partHost;
404
412
  const p = (_a = block.renderingPriority) !== null && _a !== void 0 ? _a : Priority.SyncP0;
405
413
  redeploy = markToRedeployIfNecessary(redeploy, host, item, children, sequential);
406
414
  if (p === Priority.SyncP0)
@@ -409,7 +417,7 @@ function runRenderNestedTreesThenDo(error, action) {
409
417
  p1 = push(item, p1);
410
418
  else
411
419
  p2 = push(item, p2);
412
- if (ownerIsBlock && driver.isRow)
420
+ if (ownerIsBlock && driver.isLine)
413
421
  partHost = block;
414
422
  }
415
423
  if (!Transaction.isCanceled && (p1 !== undefined || p2 !== undefined))
@@ -523,7 +531,7 @@ function runRender(item) {
523
531
  block.assignedCells = undefined;
524
532
  block.children.beginMerge();
525
533
  result = block.driver.render(block);
526
- if (block.driver.isRow)
534
+ if (block.driver.isLine)
527
535
  block.host.cursor.lineFeed();
528
536
  else if (block.assignedCells === undefined)
529
537
  block.cells = undefined;
@@ -540,10 +548,12 @@ function runRender(item) {
540
548
  });
541
549
  }
542
550
  }
543
- function runFinalize(item, isLeader) {
551
+ function runFinalize(item, isLeader, individual) {
544
552
  var _a;
545
553
  const block = item.instance;
546
554
  if (block.stamp >= 0) {
555
+ if (individual && block.key !== block.body.key && !block.driver.isLine)
556
+ console.log(`WARNING: it is recommended to assign explicit key for conditionally rendered block in order to avoid unexpected side effects: ${block.key}`);
547
557
  block.stamp = ~block.stamp;
548
558
  const childrenAreLeaders = block.driver.finalize(block, isLeader);
549
559
  if ((_a = block.body) === null || _a === void 0 ? void 0 : _a.reacting) {
@@ -559,7 +569,7 @@ function runFinalize(item, isLeader) {
559
569
  });
560
570
  }
561
571
  for (const item of block.children.items())
562
- runFinalize(item, childrenAreLeaders);
572
+ runFinalize(item, childrenAreLeaders, false);
563
573
  VBlockImpl.grandCount--;
564
574
  }
565
575
  }
@@ -4,7 +4,7 @@ export declare function Block<M = unknown, R = void>(body: BlockBody<HTMLElement
4
4
  export declare function PlainText(content: string, body?: BlockBody<HTMLElement, void, void>): VBlock<HTMLElement, void, void>;
5
5
  export declare function HtmlText(content: string, body?: BlockBody<HTMLElement, void, void>): VBlock<HTMLElement, void, void>;
6
6
  export declare function Grid<M = unknown, R = void>(body: BlockBody<HTMLElement, M, R>): VBlock<HTMLElement, M, R>;
7
- export declare function Line<T = void>(body: (block: void) => T): void;
7
+ export declare function line<T = void>(body: (block: void) => T): void;
8
8
  export declare function lineFeed(noCoalescing?: boolean, key?: string): VBlock<HTMLElement>;
9
9
  export declare function Group<M = unknown, R = void>(body: BlockBody<HTMLElement, M, R>): VBlock<HTMLElement, M, R>;
10
10
  export declare class VerstakDriver<T extends HTMLElement> extends HtmlDriver<T> {
@@ -20,13 +20,12 @@ export function HtmlText(content, body) {
20
20
  export function Grid(body) {
21
21
  return VBlock.claim(VerstakTags.grid, body);
22
22
  }
23
- export function Line(body) {
23
+ export function line(body) {
24
24
  lineFeed();
25
25
  body();
26
- lineFeed();
27
26
  }
28
27
  export function lineFeed(noCoalescing, key) {
29
- return VBlock.claim(VerstakTags.row, { key });
28
+ return VBlock.claim(VerstakTags.line, { key });
30
29
  }
31
30
  export function Group(body) {
32
31
  return VBlock.claim(VerstakTags.group, body);
@@ -63,14 +62,14 @@ export class VerstakDriver extends HtmlDriver {
63
62
  block.native.style.maxWidth = `${maxWidth}`;
64
63
  }
65
64
  applyHeightGrowth(block, heightGrowth) {
66
- if (block.driver.isRow) {
65
+ if (block.driver.isLine) {
67
66
  const css = block.native.style;
68
67
  if (heightGrowth > 0)
69
68
  css.flexGrow = `${heightGrowth}`;
70
69
  else
71
70
  css.flexGrow = "";
72
71
  }
73
- else if (block.host.driver.isRow) {
72
+ else if (block.host.driver.isLine) {
74
73
  block.driver.applyFrameAlignment(block, Align.Stretch);
75
74
  block.host.driver.applyHeightGrowth(block.host, heightGrowth);
76
75
  }
@@ -118,8 +117,8 @@ export class VerstakDriver extends HtmlDriver {
118
117
  block.native.removeAttribute("floating");
119
118
  }
120
119
  render(block) {
121
- if (block.driver.layout < LayoutKind.Row)
122
- VBlock.claim(VerstakTags.row, {});
120
+ if (block.driver.layout < LayoutKind.Line)
121
+ lineFeed();
123
122
  return super.render(block);
124
123
  }
125
124
  }
@@ -127,7 +126,7 @@ const VerstakTags = {
127
126
  block: new VerstakDriver("v-block", LayoutKind.Block),
128
127
  text: new VerstakDriver("v-text", LayoutKind.Text),
129
128
  grid: new VerstakDriver("v-grid", LayoutKind.Grid, () => new GridCursor()),
130
- row: new VerstakDriver("v-row", LayoutKind.Row),
129
+ line: new VerstakDriver("v-line", LayoutKind.Line),
131
130
  group: new VerstakDriver("v-group", LayoutKind.Group),
132
131
  };
133
132
  const AlignToCss = ["stretch", "start", "center", "end"];
@@ -3,8 +3,8 @@ import { VBlock, AbstractDriver } from "../core/api";
3
3
  export class BaseHtmlDriver extends AbstractDriver {
4
4
  initialize(block, element) {
5
5
  element = this.createElement(block);
6
- if (Rx.isLogging && this.name)
7
- element.setAttribute("n", block.key);
6
+ if (Rx.isLogging && !block.driver.isLine && this.name)
7
+ element.setAttribute("key", block.key);
8
8
  super.initialize(block, element);
9
9
  }
10
10
  finalize(block, isLeader) {
@@ -23,9 +23,9 @@ export class BaseHtmlDriver extends AbstractDriver {
23
23
  if (e) {
24
24
  const nativeParent = BaseHtmlDriver.findNearestParentHtmlBlock(block).native;
25
25
  if (nativeParent) {
26
- if (sequential) {
26
+ if (sequential && !block.driver.isLine) {
27
27
  const after = BaseHtmlDriver.findPrevSiblingHtmlBlock(block.item);
28
- if (after === undefined) {
28
+ if (after === undefined || after.instance.driver.isLine) {
29
29
  if (nativeParent !== e.parentNode || !e.previousSibling)
30
30
  nativeParent.prepend(e);
31
31
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "verstak",
3
- "version": "0.22.515",
3
+ "version": "0.22.516",
4
4
  "description": "Verstak - Front-End Library",
5
5
  "publisher": "Nezaboodka Software",
6
6
  "license": "Apache-2.0",
@@ -31,7 +31,7 @@
31
31
  },
32
32
  "homepage": "https://github.com/nezaboodka/verstak/blob/master/README.md#readme",
33
33
  "dependencies": {
34
- "reactronic": "^0.22.509"
34
+ "reactronic": "^0.22.510"
35
35
  },
36
36
  "devDependencies": {
37
37
  "@types/node": "18.11.9",