vasille 2.2.2 → 2.3.0

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/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Vasille
1
+ # Vasille Core Library
2
2
 
3
3
  ![Vasille.js logo](https://gitlab.com/vasille-js/vasille-js/-/raw/v2/img/logo.png)
4
4
 
@@ -10,10 +10,10 @@
10
10
  ## Table of content
11
11
 
12
12
  * [Installation](#installation)
13
+ * [How to use Vasille](#how-to-use-vasille)
13
14
  * [How SAFE is Vasille](#how-safe-is-vasille)
14
15
  * [How FAST is Vasille](#how-fast-is-vasille)
15
16
  * [How POWERFUL is Vasille](#how-powerful-is-vasille)
16
- * [How to use Vasille](#how-to-use-vasille)
17
17
  * [Best Practices](#best-practices)
18
18
 
19
19
 
@@ -23,31 +23,28 @@
23
23
 
24
24
  ```
25
25
  npm install vasille --save
26
+ npm install vasille-less --save
27
+ npm install vasille-magic --save
26
28
  ```
27
29
 
28
- ### How to create the first project step by step
30
+ ## How to use Vasille
29
31
 
30
- [Read instruction here](https://gitlab.com/vasille-js/vasille-js/-/blob/v2/pages/GetStarted.md).
32
+ There are several modes to use Vasille.
31
33
 
32
- ### CDN
34
+ ### Documentation for beginners (how to create the first project step by step):
35
+ * [`Vasille Core Library` - the hard way - `low-level`](https://gitlab.com/vasille-js/vasille-js/-/blob/v2/pages/GetStarted.md)
36
+ * [`Vasille Less Library` - perfect for me - `high-level`](https://gitlab.com/vasille-js/vasille-less/-/blob/v2/pages/GetStarted.md)
37
+ * [`Vasille Magic` - perfect for you - `highest-level`](https://gitlab.com/vasille-js/vcc/-/blob/master/pages/GetStarted.md)
33
38
 
34
- ```html
35
- ES2015 version
36
- <script src="https://unpkg.com/vasille"></script>
37
- ES5 Compatible version
38
- <script src="https://unpkg.com/vasille/cdn/es5.js"></script>
39
- ```
39
+ ### Full documentation:
40
+ * [`Vasille Core Library API`- write anything - `low-level`](https://gitlab.com/vasille-js/vasille-js/-/blob/v2/pages/Vasille-Core-Library-API.md)
41
+ * [`Vasille Less Library API`- write less do more - `high-level`](https://gitlab.com/vasille-js/vasille-less/-/blob/v2/pages/Vasille-Less-Library-API.md)
42
+ * [`Vasille Magic API`- compiler writes for you - `highest-level`](https://gitlab.com/vasille-js/vasille-js/-/blob/v2/pages/API.md)
40
43
 
41
44
  ### Getting ready be example
42
- * [JavaScript Example](https://gitlab.com/vasille-js/learning/vasille-js-example)
43
45
  * [TypeScript Example](https://gitlab.com/vasille-js/learning/vasille-ts-example)
44
- * [Flow.js Example](https://gitlab.com/vasille-js/learning/vasille-flow-js-example)
45
-
46
- ### Flow.js typedef
47
- Add the next line to `[libs]` section in your `.flowconfig` file
48
- ```
49
- node_modules/vasille/flow-typed
50
- ```
46
+ * [JavaScript Example (Vasille Magic not supported)](https://gitlab.com/vasille-js/learning/vasille-js-example)
47
+ * [Flow.js Example (Vasille Magic not supported)](https://gitlab.com/vasille-js/learning/vasille-flow-js-example)
51
48
 
52
49
  <hr>
53
50
 
@@ -168,23 +165,32 @@ which will be reflected into a browser DOM and keep up to date it.
168
165
  * `DebugNode` reflects a `Comment` node, useful for debug.
169
166
  * `Watch` recompose children nodes on model value change.
170
167
  * `RepeatNode` creates multiples children nodes using the same code multiple time.
171
- * `Repeater` repeat slot content `n` times.
172
168
  * `BaseView` represent a view in context of MVC (Model-View-Controller).
173
169
  * `ObjectView` repeats slot content for each value of `ObjectModel`.
174
170
  * `MapView` repeats slot content for each `MapModel` value.
175
171
  * `SetView` repeats slot content for each `SetModel` value.
176
172
  * `ArrayView` repeats slot content for each `ArrayModel` value respecting its order.
177
- * `InterceptorNode` is used to send an event/signal from one child to other
178
- without manually creating of interceptors.
179
173
 
180
- ## How to use Vasille
174
+ <hr>
175
+
176
+ ### CDN
181
177
 
182
- There are several modes, and most of it are WIP (Work In Progress):
183
- * [Object-Oriented Programming - Ready](https://gitlab.com/vasille-js/vasille-js/-/blob/v2/pages/OOP-API.md)
184
- * [Procedural Programming - WIP](https://gitlab.com/vasille-js/vasille-js/-/blob/v2/pages/Procedural-API.md)
185
- * [Template Programming - WIP](https://gitlab.com/vasille-js/vasille-js/-/blob/v2/pages/API.md)
178
+ ```html
179
+ ES2015 version
180
+ <script src="https://unpkg.com/vasille"></script>
181
+ ES5 Compatible version
182
+ <script src="https://unpkg.com/vasille/cdn/es5.js"></script>
183
+ ```
184
+
185
+ ### Flow.js typedef
186
+ Add the next lines to `[libs]` section in your `.flowconfig` file
187
+ ```
188
+ node_modules/vasille/flow-typed
189
+ node_modules/vasille-less/flow-typed
190
+ node_modules/vasille-magic/flow-typed
191
+ ```
186
192
 
187
- ## Best Practices
193
+ ## Best Practices applicable to Vasille Core Library
188
194
 
189
195
  * [Reactive Object Practice](https://gitlab.com/vasille-js/vasille-practices/-/blob/main/practices/reactive-object.ts)
190
196
  * [Application](https://gitlab.com/vasille-js/vasille-practices/-/blob/main/practices/application.ts)
package/cdn/es2015.js CHANGED
@@ -195,6 +195,9 @@ class ObjectModel extends Object {
195
195
  this.listener.emitAdded(key, this.container[key]);
196
196
  return this;
197
197
  }
198
+ get values() {
199
+ return this.container;
200
+ }
198
201
  /**
199
202
  * Deletes an object property
200
203
  * @param key {string} property name
@@ -205,23 +208,6 @@ class ObjectModel extends Object {
205
208
  delete this.container[key];
206
209
  }
207
210
  }
208
- proxy() {
209
- // eslint-disable-next-line @typescript-eslint/no-this-alias
210
- const ts = this;
211
- return new Proxy(this.container, {
212
- get(target, p) {
213
- return ts.get(p);
214
- },
215
- set(target, p, value) {
216
- ts.set(p, value);
217
- return true;
218
- },
219
- deleteProperty(target, p) {
220
- ts.delete(p);
221
- return true;
222
- }
223
- });
224
- }
225
211
  enableReactivity() {
226
212
  this.listener.enableReactivity();
227
213
  }
@@ -387,15 +373,6 @@ class ArrayModel extends Array {
387
373
  super.push(data[i]);
388
374
  }
389
375
  }
390
- // proxy
391
- proxy() {
392
- return new Proxy(this, {
393
- set(target, p, value) {
394
- target.splice(parseInt(p), 1, value);
395
- return true;
396
- }
397
- });
398
- }
399
376
  /* Array members */
400
377
  /**
401
378
  * Gets the last item of array
@@ -576,6 +553,12 @@ class ArrayModel extends Array {
576
553
  this.removeAt(this.indexOf(v));
577
554
  return this;
578
555
  }
556
+ replace(at, with_) {
557
+ this.listener.emitAdded(this[at], with_);
558
+ this.listener.emitRemoved(this[at], this[at]);
559
+ this[at] = with_;
560
+ return this;
561
+ }
579
562
  enableReactivity() {
580
563
  this.listener.enableReactivity();
581
564
  }
@@ -1464,7 +1447,7 @@ class Reactive extends Destroyable {
1464
1447
  }
1465
1448
  init() {
1466
1449
  this.applyOptions(this.input);
1467
- this.compose(this.input);
1450
+ return this.compose(this.input);
1468
1451
  }
1469
1452
  applyOptions(input) {
1470
1453
  // empty
@@ -1473,7 +1456,7 @@ class Reactive extends Destroyable {
1473
1456
  this.applyOptions(this.input);
1474
1457
  }
1475
1458
  compose(input) {
1476
- // empty
1459
+ throw notOverwritten();
1477
1460
  }
1478
1461
  composeNow() {
1479
1462
  this.compose(this.input);
@@ -1565,11 +1548,11 @@ class Fragment extends Reactive {
1565
1548
  $.preinit(app, parent);
1566
1549
  }
1567
1550
  init() {
1568
- super.init();
1551
+ const ret = super.init();
1569
1552
  this.ready();
1553
+ return ret;
1570
1554
  }
1571
1555
  compose(input) {
1572
- super.compose(input);
1573
1556
  input.slot && input.slot(this);
1574
1557
  }
1575
1558
  /** To be overloaded: ready event handler */
@@ -1677,7 +1660,7 @@ class Fragment extends Reactive {
1677
1660
  node.preinit($.app, this);
1678
1661
  node.input.slot = callback || node.input.slot;
1679
1662
  this.pushNode(node);
1680
- node.init();
1663
+ return node.init();
1681
1664
  }
1682
1665
  /**
1683
1666
  * Defines an if node
@@ -2172,6 +2155,9 @@ class Extension extends INode {
2172
2155
  throw userError("A extension node can be encapsulated only in a tag/extension/component", "virtual-dom");
2173
2156
  }
2174
2157
  }
2158
+ extend(options) {
2159
+ this.applyOptions(options);
2160
+ }
2175
2161
  $destroy() {
2176
2162
  super.$destroy();
2177
2163
  }
@@ -2847,7 +2833,7 @@ window.Watch = Watch;
2847
2833
  class ObjectView extends BaseView {
2848
2834
  compose(input) {
2849
2835
  super.compose(input);
2850
- const obj = input.model.proxy();
2836
+ const obj = input.model.values;
2851
2837
  for (const key in obj) {
2852
2838
  this.createChild(input, key, obj[key]);
2853
2839
  }
package/cdn/es5.js CHANGED
@@ -400,6 +400,13 @@ var ObjectModel = /** @class */ (function (_super) {
400
400
  this.listener.emitAdded(key, this.container[key]);
401
401
  return this;
402
402
  };
403
+ Object.defineProperty(ObjectModel.prototype, "values", {
404
+ get: function () {
405
+ return this.container;
406
+ },
407
+ enumerable: false,
408
+ configurable: true
409
+ });
403
410
  /**
404
411
  * Deletes an object property
405
412
  * @param key {string} property name
@@ -410,23 +417,6 @@ var ObjectModel = /** @class */ (function (_super) {
410
417
  delete this.container[key];
411
418
  }
412
419
  };
413
- ObjectModel.prototype.proxy = function () {
414
- // eslint-disable-next-line @typescript-eslint/no-this-alias
415
- var ts = this;
416
- return new Proxy(this.container, {
417
- get: function (target, p) {
418
- return ts.get(p);
419
- },
420
- set: function (target, p, value) {
421
- ts.set(p, value);
422
- return true;
423
- },
424
- deleteProperty: function (target, p) {
425
- ts.delete(p);
426
- return true;
427
- }
428
- });
429
- };
430
420
  ObjectModel.prototype.enableReactivity = function () {
431
421
  this.listener.enableReactivity();
432
422
  };
@@ -610,15 +600,6 @@ var ArrayModel = /** @class */ (function (_super) {
610
600
  }
611
601
  return _this;
612
602
  }
613
- // proxy
614
- ArrayModel.prototype.proxy = function () {
615
- return new Proxy(this, {
616
- set: function (target, p, value) {
617
- target.splice(parseInt(p), 1, value);
618
- return true;
619
- }
620
- });
621
- };
622
603
  Object.defineProperty(ArrayModel.prototype, "last", {
623
604
  /* Array members */
624
605
  /**
@@ -817,6 +798,12 @@ var ArrayModel = /** @class */ (function (_super) {
817
798
  this.removeAt(this.indexOf(v));
818
799
  return this;
819
800
  };
801
+ ArrayModel.prototype.replace = function (at, with_) {
802
+ this.listener.emitAdded(this[at], with_);
803
+ this.listener.emitRemoved(this[at], this[at]);
804
+ this[at] = with_;
805
+ return this;
806
+ };
820
807
  ArrayModel.prototype.enableReactivity = function () {
821
808
  this.listener.enableReactivity();
822
809
  };
@@ -1817,7 +1804,7 @@ var Reactive = /** @class */ (function (_super) {
1817
1804
  };
1818
1805
  Reactive.prototype.init = function () {
1819
1806
  this.applyOptions(this.input);
1820
- this.compose(this.input);
1807
+ return this.compose(this.input);
1821
1808
  };
1822
1809
  Reactive.prototype.applyOptions = function (input) {
1823
1810
  // empty
@@ -1826,7 +1813,7 @@ var Reactive = /** @class */ (function (_super) {
1826
1813
  this.applyOptions(this.input);
1827
1814
  };
1828
1815
  Reactive.prototype.compose = function (input) {
1829
- // empty
1816
+ throw notOverwritten();
1830
1817
  };
1831
1818
  Reactive.prototype.composeNow = function () {
1832
1819
  this.compose(this.input);
@@ -1935,11 +1922,11 @@ var Fragment = /** @class */ (function (_super) {
1935
1922
  $.preinit(app, parent);
1936
1923
  };
1937
1924
  Fragment.prototype.init = function () {
1938
- _super.prototype.init.call(this);
1925
+ var ret = _super.prototype.init.call(this);
1939
1926
  this.ready();
1927
+ return ret;
1940
1928
  };
1941
1929
  Fragment.prototype.compose = function (input) {
1942
- _super.prototype.compose.call(this, input);
1943
1930
  input.slot && input.slot(this);
1944
1931
  };
1945
1932
  /** To be overloaded: ready event handler */
@@ -2047,7 +2034,7 @@ var Fragment = /** @class */ (function (_super) {
2047
2034
  node.preinit($.app, this);
2048
2035
  node.input.slot = callback || node.input.slot;
2049
2036
  this.pushNode(node);
2050
- node.init();
2037
+ return node.init();
2051
2038
  };
2052
2039
  /**
2053
2040
  * Defines an if node
@@ -2576,6 +2563,9 @@ var Extension = /** @class */ (function (_super) {
2576
2563
  throw userError("A extension node can be encapsulated only in a tag/extension/component", "virtual-dom");
2577
2564
  }
2578
2565
  };
2566
+ Extension.prototype.extend = function (options) {
2567
+ this.applyOptions(options);
2568
+ };
2579
2569
  Extension.prototype.$destroy = function () {
2580
2570
  _super.prototype.$destroy.call(this);
2581
2571
  };
@@ -3355,7 +3345,7 @@ var ObjectView = /** @class */ (function (_super) {
3355
3345
  }
3356
3346
  ObjectView.prototype.compose = function (input) {
3357
3347
  _super.prototype.compose.call(this, input);
3358
- var obj = input.model.proxy();
3348
+ var obj = input.model.values;
3359
3349
  for (var key in obj) {
3360
3350
  this.createChild(input, key, obj[key]);
3361
3351
  }
@@ -165,7 +165,7 @@ declare class RepeatNodePrivate<IdT> extends INodePrivate {
165
165
  constructor(): void;
166
166
  $destroy(): void;
167
167
  }
168
- declare interface RNO<T, IdT> extends Options {
168
+ declare interface RNO<T, IdT> extends FragmentOptions {
169
169
  slot?: (node: Fragment, value: T, index: IdT) => void;
170
170
  }
171
171
  /**
@@ -268,12 +268,12 @@ declare class ObjectModel<T> extends Object implements ListenableModel<string, T
268
268
  * @return {ObjectModel} a pointer to this
269
269
  */
270
270
  set(key: string, v: T): this;
271
+ get values(): Record<string, T>;
271
272
  /**
272
273
  * Deletes an object property
273
274
  * @param key {string} property name
274
275
  */
275
276
  delete(key: string): void;
276
- proxy(): Record<string, T>;
277
277
  enableReactivity(): void;
278
278
  disableReactivity(): void;
279
279
  }
@@ -325,7 +325,6 @@ declare class ArrayModel<T> extends Array<T> implements ListenableModel<T, T> {
325
325
  * @param data {Array} input data
326
326
  */
327
327
  constructor(data?: Array<T>): void;
328
- proxy(): ArrayModel<T>;
329
328
  /**
330
329
  * Gets the last item of array
331
330
  * @return {*} the last item of array
@@ -413,6 +412,7 @@ declare class ArrayModel<T> extends Array<T> implements ListenableModel<T, T> {
413
412
  * @return {this}
414
413
  */
415
414
  removeOne(v: T): this;
415
+ replace(at: number, with_: T): this;
416
416
  enableReactivity(): void;
417
417
  disableReactivity(): void;
418
418
  }
@@ -550,7 +550,7 @@ declare interface ListenableModel<K, T> extends IModel {
550
550
  }
551
551
 
552
552
 
553
- declare interface WatchOptions<T> extends Options {
553
+ declare interface WatchOptions<T> extends FragmentOptions {
554
554
  model: IValue<T>;
555
555
  slot?: (node: Fragment, value: T) => void;
556
556
  }
@@ -637,7 +637,7 @@ declare class Fragment<T> extends Reactive {
637
637
  * @param data {*} additional data
638
638
  */
639
639
  preinit(app: AppNode, parent: Fragment, data?: any): void;
640
- init(): void;
640
+ init(): T['return'];
641
641
  compose(input: T): void;
642
642
  /** To be overloaded: ready event handler */
643
643
  ready(): void;
@@ -682,7 +682,7 @@ declare class Fragment<T> extends Reactive {
682
682
  * @param node {Fragment} vasille element to insert
683
683
  * @param callback {function($ : *)}
684
684
  */
685
- create<T>(node: T, callback?: T['input']['slot']): void;
685
+ create<T>(node: T, callback?: T['input']['slot']): T['input']['return'];
686
686
  /**
687
687
  * Defines an if node
688
688
  * @param cond {IValue} condition
@@ -880,6 +880,7 @@ declare class Tag<K> extends INode<TagOptionsWithSlot<K>> {
880
880
  */
881
881
  declare class Extension<T> extends INode<T> {
882
882
  preinit(app: AppNode, parent: Fragment): void;
883
+ extend(options: T): void;
883
884
  $destroy(): void;
884
885
  }
885
886
  /**
@@ -1130,13 +1131,13 @@ declare function debug(text: IValue<string>): void;
1130
1131
  declare function predefine<T>(slot: T | null | undefined, predefined: T): T;
1131
1132
 
1132
1133
 
1133
- declare interface Options {
1134
+ declare interface FragmentOptions {
1134
1135
  "v:is"?: Record<string, IValue<any>>;
1135
1136
  return?: any;
1136
1137
  slot?: (node: Fragment, ...args: any[]) => void;
1137
1138
  }
1138
1139
  declare type AttrType<T> = IValue<T | string | null> | T | string | null | undefined;
1139
- declare interface TagOptions<T> extends Options {
1140
+ declare interface TagOptions<T> extends FragmentOptions {
1140
1141
  "v:attr"?: {
1141
1142
  [K : string]:? AttrType<AcceptedTagsSpec[T]['attrs'][K]>;
1142
1143
  } & Record<string, AttrType<number | boolean>>;
@@ -1342,10 +1343,10 @@ declare class Reactive<T> extends Destroyable {
1342
1343
  * @param onOn {function} on hide feedback
1343
1344
  */
1344
1345
  bindAlive(cond: IValue<boolean>, onOff?: () => void, onOn?: () => void): this;
1345
- init(): void;
1346
+ init(): T['return'];
1346
1347
  applyOptions(input: T): void;
1347
1348
  applyOptionsNow(): void;
1348
- compose(input: T): void;
1349
+ compose(input: T): T['return'];
1349
1350
  composeNow(): void;
1350
1351
  runFunctional<F>(f: F, ...args: Parameters<F>): ReturnType<F>;
1351
1352
  runOnDestroy(func: () => void): void;
package/lib/core/core.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Destroyable } from "./destroyable.js";
2
- import { wrongBinding } from "./errors";
2
+ import { notOverwritten, wrongBinding } from "./errors";
3
3
  import { Expression } from "../value/expression";
4
4
  import { Reference } from "../value/reference";
5
5
  import { Pointer } from "../value/pointer";
@@ -204,7 +204,7 @@ export class Reactive extends Destroyable {
204
204
  }
205
205
  init() {
206
206
  this.applyOptions(this.input);
207
- this.compose(this.input);
207
+ return this.compose(this.input);
208
208
  }
209
209
  applyOptions(input) {
210
210
  // empty
@@ -213,7 +213,7 @@ export class Reactive extends Destroyable {
213
213
  this.applyOptions(this.input);
214
214
  }
215
215
  compose(input) {
216
- // empty
216
+ throw notOverwritten();
217
217
  }
218
218
  composeNow() {
219
219
  this.compose(this.input);
package/lib/index.js CHANGED
@@ -6,7 +6,7 @@ import { Listener } from "./models/listener";
6
6
  import { MapModel } from "./models/map-model";
7
7
  import { ObjectModel } from "./models/object-model";
8
8
  import { SetModel } from "./models/set-model";
9
- import { App, AppNode } from "./node/app";
9
+ import { App, AppNode, Portal } from "./node/app";
10
10
  import { Component, Extension, Fragment, INode, Tag } from "./node/node";
11
11
  import { Expression } from "./value/expression";
12
12
  import { Mirror } from "./value/mirror";
@@ -18,5 +18,4 @@ import { MapView } from "./views/map-view";
18
18
  import { ObjectView } from "./views/object-view";
19
19
  import { SetView } from "./views/set-view";
20
20
  import { Binding } from "./binding/binding";
21
- import * as libV from "./v/index";
22
- export { Destroyable, IValue, Reference, Mirror, Pointer, ArrayModel, MapModel, ObjectModel, SetModel, BaseView, Listener, ArrayView, MapView, ObjectView, SetView, Fragment, INode, Tag, Component, Extension, AppNode, App, Expression, Binding, Reactive, libV };
21
+ export { Destroyable, IValue, Reference, Mirror, Pointer, ArrayModel, MapModel, ObjectModel, SetModel, BaseView, Listener, ArrayView, MapView, ObjectView, SetView, Fragment, INode, Tag, Component, Extension, AppNode, App, Portal, Expression, Binding, Reactive };
@@ -19,15 +19,6 @@ export class ArrayModel extends Array {
19
19
  super.push(data[i]);
20
20
  }
21
21
  }
22
- // proxy
23
- proxy() {
24
- return new Proxy(this, {
25
- set(target, p, value) {
26
- target.splice(parseInt(p), 1, value);
27
- return true;
28
- }
29
- });
30
- }
31
22
  /* Array members */
32
23
  /**
33
24
  * Gets the last item of array
@@ -208,6 +199,12 @@ export class ArrayModel extends Array {
208
199
  this.removeAt(this.indexOf(v));
209
200
  return this;
210
201
  }
202
+ replace(at, with_) {
203
+ this.listener.emitAdded(this[at], with_);
204
+ this.listener.emitRemoved(this[at], this[at]);
205
+ this[at] = with_;
206
+ return this;
207
+ }
211
208
  enableReactivity() {
212
209
  this.listener.enableReactivity();
213
210
  }
@@ -56,6 +56,9 @@ export class ObjectModel extends Object {
56
56
  this.listener.emitAdded(key, this.container[key]);
57
57
  return this;
58
58
  }
59
+ get values() {
60
+ return this.container;
61
+ }
59
62
  /**
60
63
  * Deletes an object property
61
64
  * @param key {string} property name
@@ -66,23 +69,6 @@ export class ObjectModel extends Object {
66
69
  delete this.container[key];
67
70
  }
68
71
  }
69
- proxy() {
70
- // eslint-disable-next-line @typescript-eslint/no-this-alias
71
- const ts = this;
72
- return new Proxy(this.container, {
73
- get(target, p) {
74
- return ts.get(p);
75
- },
76
- set(target, p, value) {
77
- ts.set(p, value);
78
- return true;
79
- },
80
- deleteProperty(target, p) {
81
- ts.delete(p);
82
- return true;
83
- }
84
- });
85
- }
86
72
  enableReactivity() {
87
73
  this.listener.enableReactivity();
88
74
  }
package/lib/node/node.js CHANGED
@@ -70,11 +70,11 @@ export class Fragment extends Reactive {
70
70
  $.preinit(app, parent);
71
71
  }
72
72
  init() {
73
- super.init();
73
+ const ret = super.init();
74
74
  this.ready();
75
+ return ret;
75
76
  }
76
77
  compose(input) {
77
- super.compose(input);
78
78
  input.slot && input.slot(this);
79
79
  }
80
80
  /** To be overloaded: ready event handler */
@@ -182,7 +182,7 @@ export class Fragment extends Reactive {
182
182
  node.preinit($.app, this);
183
183
  node.input.slot = callback || node.input.slot;
184
184
  this.pushNode(node);
185
- node.init();
185
+ return node.init();
186
186
  }
187
187
  /**
188
188
  * Defines an if node
@@ -677,6 +677,9 @@ export class Extension extends INode {
677
677
  throw userError("A extension node can be encapsulated only in a tag/extension/component", "virtual-dom");
678
678
  }
679
679
  }
680
+ extend(options) {
681
+ this.applyOptions(options);
682
+ }
680
683
  $destroy() {
681
684
  super.$destroy();
682
685
  }
@@ -7,7 +7,7 @@ import { BaseView } from "./base-view";
7
7
  export class ObjectView extends BaseView {
8
8
  compose(input) {
9
9
  super.compose(input);
10
- const obj = input.model.proxy();
10
+ const obj = input.model.values;
11
11
  for (const key in obj) {
12
12
  this.createChild(input, key, obj[key]);
13
13
  }
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "Vasille - Safe. Fast. Powerful.",
4
4
  "main": "lib/index.js",
5
5
  "types": "types/index.d.ts",
6
- "version": "2.2.2",
6
+ "version": "2.3.0",
7
7
  "exports": {
8
8
  "import": "./lib/index.js",
9
9
  "browser": "./lib/index.js"
@@ -4,7 +4,7 @@ import { Expression, KindOfIValue } from "../value/expression";
4
4
  import { Pointer } from "../value/pointer";
5
5
  import { Mirror } from "../value/mirror";
6
6
  import { IModel } from "../models/model";
7
- import { Options } from "../functional/options";
7
+ import { FragmentOptions } from "../functional/options";
8
8
  export declare let current: Reactive | null;
9
9
  /**
10
10
  * Private stuff of a reactive object
@@ -55,7 +55,7 @@ export declare class ReactivePrivate extends Destroyable {
55
55
  * @class Reactive
56
56
  * @extends Destroyable
57
57
  */
58
- export declare class Reactive<T extends Options = Options> extends Destroyable {
58
+ export declare class Reactive<T extends FragmentOptions = FragmentOptions> extends Destroyable {
59
59
  /**
60
60
  * Private stuff
61
61
  * @protected
@@ -121,10 +121,10 @@ export declare class Reactive<T extends Options = Options> extends Destroyable {
121
121
  * @param onOn {function} on hide feedback
122
122
  */
123
123
  bindAlive(cond: IValue<boolean>, onOff?: () => void, onOn?: () => void): this;
124
- init(): void;
124
+ init(): T['return'];
125
125
  protected applyOptions(input: T): void;
126
126
  protected applyOptionsNow(): void;
127
- protected compose(input: T): void;
127
+ protected compose(input: T): T['return'];
128
128
  protected composeNow(): void;
129
129
  runFunctional<F extends (...args: any) => any>(f: F, ...args: Parameters<F>): ReturnType<F>;
130
130
  runOnDestroy(func: () => void): void;
@@ -1,13 +1,13 @@
1
1
  import type { IValue } from "../core/ivalue";
2
2
  import { AcceptedTagsMap, AcceptedTagsSpec } from "../spec/react";
3
3
  import type { Fragment } from "../node/node";
4
- export interface Options {
4
+ export interface FragmentOptions {
5
5
  "v:is"?: Record<string, IValue<any>>;
6
6
  return?: any;
7
7
  slot?: (node: Fragment, ...args: any[]) => void;
8
8
  }
9
9
  export declare type AttrType<T> = IValue<T | string | null> | T | string | null | undefined;
10
- export interface TagOptions<T extends keyof AcceptedTagsMap> extends Options {
10
+ export interface TagOptions<T extends keyof AcceptedTagsMap> extends FragmentOptions {
11
11
  "v:attr"?: {
12
12
  [K in keyof AcceptedTagsSpec[T]['attrs']]?: AttrType<AcceptedTagsSpec[T]['attrs'][K]>;
13
13
  } & Record<string, AttrType<number | boolean>>;
package/types/index.d.ts CHANGED
@@ -6,7 +6,7 @@ import { Listener } from "./models/listener";
6
6
  import { MapModel } from "./models/map-model";
7
7
  import { ObjectModel } from "./models/object-model";
8
8
  import { SetModel } from "./models/set-model";
9
- import { App, AppNode } from "./node/app";
9
+ import { App, AppNode, AppOptions, Portal } from "./node/app";
10
10
  import { Component, Extension, Fragment, INode, Tag } from "./node/node";
11
11
  import { Expression } from "./value/expression";
12
12
  import { Mirror } from "./value/mirror";
@@ -18,6 +18,5 @@ import { MapView } from "./views/map-view";
18
18
  import { ObjectView } from "./views/object-view";
19
19
  import { SetView } from "./views/set-view";
20
20
  import { Binding } from "./binding/binding";
21
- import { Options, TagOptions } from "./functional/options";
22
- import * as libV from "./v/index";
23
- export { Destroyable, IValue, Reference, Mirror, Pointer, ArrayModel, MapModel, ObjectModel, SetModel, BaseView, Listener, ArrayView, MapView, ObjectView, SetView, Fragment, INode, Tag, Component, Extension, AppNode, App, Expression, Binding, Reactive, Options, TagOptions, libV };
21
+ import { FragmentOptions, TagOptions } from "./functional/options";
22
+ export { Destroyable, IValue, Reference, Mirror, Pointer, ArrayModel, MapModel, ObjectModel, SetModel, BaseView, Listener, ArrayView, MapView, ObjectView, SetView, Fragment, INode, Tag, Component, Extension, AppNode, App, Portal, Expression, Binding, Reactive, FragmentOptions, TagOptions, AppOptions };
@@ -11,7 +11,6 @@ export declare class ArrayModel<T> extends Array<T> implements ListenableModel<T
11
11
  * @param data {Array} input data
12
12
  */
13
13
  constructor(data?: Array<T>);
14
- proxy(): ArrayModel<T>;
15
14
  /**
16
15
  * Gets the last item of array
17
16
  * @return {*} the last item of array
@@ -99,6 +98,7 @@ export declare class ArrayModel<T> extends Array<T> implements ListenableModel<T
99
98
  * @return {this}
100
99
  */
101
100
  removeOne(v: T): this;
101
+ replace(at: number, with_: T): this;
102
102
  enableReactivity(): void;
103
103
  disableReactivity(): void;
104
104
  }
@@ -27,12 +27,12 @@ export declare class ObjectModel<T> extends Object implements ListenableModel<st
27
27
  * @return {ObjectModel} a pointer to this
28
28
  */
29
29
  set(key: string, v: T): this;
30
+ get values(): Record<string, T>;
30
31
  /**
31
32
  * Deletes an object property
32
33
  * @param key {string} property name
33
34
  */
34
35
  delete(key: string): void;
35
- proxy(): Record<string, T>;
36
36
  enableReactivity(): void;
37
37
  disableReactivity(): void;
38
38
  }
@@ -1,7 +1,7 @@
1
1
  import { Reactive, ReactivePrivate } from "../core/core";
2
2
  import { IValue } from "../core/ivalue";
3
3
  import type { AppNode } from "./app";
4
- import { Options, TagOptions } from "../functional/options";
4
+ import { FragmentOptions, TagOptions } from "../functional/options";
5
5
  import { AcceptedTagsMap } from "../spec/react";
6
6
  /**
7
7
  * Represents a Vasille.js node
@@ -45,7 +45,7 @@ export declare class FragmentPrivate extends ReactivePrivate {
45
45
  * This class is symbolic
46
46
  * @extends Reactive
47
47
  */
48
- export declare class Fragment<T extends Options = Options> extends Reactive {
48
+ export declare class Fragment<T extends FragmentOptions = FragmentOptions> extends Reactive {
49
49
  /**
50
50
  * Private part
51
51
  * @protected
@@ -74,7 +74,7 @@ export declare class Fragment<T extends Options = Options> extends Reactive {
74
74
  * @param data {*} additional data
75
75
  */
76
76
  preinit(app: AppNode, parent: Fragment, data?: unknown): void;
77
- init(): void;
77
+ init(): T['return'];
78
78
  protected compose(input: T): void;
79
79
  /** To be overloaded: ready event handler */
80
80
  ready(): void;
@@ -119,7 +119,7 @@ export declare class Fragment<T extends Options = Options> extends Reactive {
119
119
  * @param node {Fragment} vasille element to insert
120
120
  * @param callback {function($ : *)}
121
121
  */
122
- create<T extends Fragment>(node: T, callback?: T['input']['slot']): void;
122
+ create<T extends Fragment>(node: T, callback?: T['input']['slot']): T['input']['return'];
123
123
  /**
124
124
  * Defines an if node
125
125
  * @param cond {IValue} condition
@@ -317,6 +317,7 @@ export declare class Tag<K extends keyof AcceptedTagsMap> extends INode<TagOptio
317
317
  */
318
318
  export declare class Extension<T extends TagOptions<any> = TagOptions<any>> extends INode<T> {
319
319
  preinit(app: AppNode, parent: Fragment): void;
320
+ extend(options: T): void;
320
321
  $destroy(): void;
321
322
  }
322
323
  /**
@@ -1,7 +1,7 @@
1
1
  import { Fragment } from "./node";
2
2
  import { IValue } from "../core/ivalue";
3
- import { Options } from "../functional/options";
4
- interface WatchOptions<T> extends Options {
3
+ import { FragmentOptions } from "../functional/options";
4
+ interface WatchOptions<T> extends FragmentOptions {
5
5
  model: IValue<T>;
6
6
  slot?: (node: Fragment, value: T) => void;
7
7
  }
@@ -1,5 +1,5 @@
1
1
  import { Fragment, INodePrivate } from "../node/node";
2
- import { Options } from "../functional/options";
2
+ import { FragmentOptions } from "../functional/options";
3
3
  /**
4
4
  * Private part of repeat node
5
5
  * @class RepeatNodePrivate
@@ -14,7 +14,7 @@ export declare class RepeatNodePrivate<IdT> extends INodePrivate {
14
14
  constructor();
15
15
  $destroy(): void;
16
16
  }
17
- export interface RNO<T, IdT> extends Options {
17
+ export interface RNO<T, IdT> extends FragmentOptions {
18
18
  slot?: (node: Fragment, value: T, index: IdT) => void;
19
19
  }
20
20
  /**