vasille 2.2.2 → 2.3.2
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 +34 -28
- package/cdn/es2015.js +18 -724
- package/cdn/es5.js +687 -957
- package/flow-typed/vasille.js +14 -59
- package/lib/core/core.js +3 -3
- package/lib/index.js +5 -4
- package/lib/models/array-model.js +6 -9
- package/lib/models/object-model.js +3 -17
- package/lib/node/node.js +6 -3
- package/lib/views/object-view.js +1 -1
- package/lib-node/binding/attribute.js +35 -0
- package/lib-node/binding/binding.js +33 -0
- package/lib-node/binding/class.js +48 -0
- package/lib-node/binding/style.js +27 -0
- package/lib-node/core/core.js +243 -0
- package/lib-node/core/destroyable.js +49 -0
- package/lib-node/core/errors.js +23 -0
- package/lib-node/core/ivalue.js +63 -0
- package/lib-node/functional/options.js +2 -0
- package/lib-node/index.js +54 -0
- package/lib-node/models/array-model.js +218 -0
- package/lib-node/models/listener.js +134 -0
- package/lib-node/models/map-model.js +70 -0
- package/lib-node/models/model.js +2 -0
- package/lib-node/models/object-model.js +82 -0
- package/lib-node/models/set-model.js +66 -0
- package/lib-node/node/app.js +54 -0
- package/lib-node/node/node.js +885 -0
- package/lib-node/node/watch.js +23 -0
- package/lib-node/spec/html.js +2 -0
- package/lib-node/spec/react.js +2 -0
- package/lib-node/spec/svg.js +2 -0
- package/lib-node/value/expression.js +90 -0
- package/lib-node/value/mirror.js +60 -0
- package/lib-node/value/pointer.js +30 -0
- package/lib-node/value/reference.js +55 -0
- package/lib-node/views/array-view.js +21 -0
- package/lib-node/views/base-view.js +43 -0
- package/lib-node/views/map-view.js +18 -0
- package/lib-node/views/object-view.js +20 -0
- package/lib-node/views/repeat-node.js +71 -0
- package/lib-node/views/set-view.js +19 -0
- package/package.json +21 -17
- package/types/core/core.d.ts +4 -4
- package/types/functional/options.d.ts +2 -2
- package/types/index.d.ts +10 -7
- package/types/models/array-model.d.ts +1 -1
- package/types/models/object-model.d.ts +1 -1
- package/types/node/node.d.ts +5 -4
- package/types/node/watch.d.ts +2 -2
- package/types/views/repeat-node.d.ts +2 -2
- package/lib/core/executor.js +0 -154
- package/lib/core/signal.js +0 -50
- package/lib/core/slot.js +0 -47
- package/lib/functional/components.js +0 -17
- package/lib/functional/merge.js +0 -41
- package/lib/functional/models.js +0 -26
- package/lib/functional/reactivity.js +0 -33
- package/lib/functional/stack.js +0 -127
- package/lib/node/interceptor.js +0 -83
- package/lib/v/index.js +0 -23
- package/lib/views/repeater.js +0 -63
- package/types/functional/components.d.ts +0 -4
- package/types/functional/merge.d.ts +0 -1
- package/types/functional/models.d.ts +0 -10
- package/types/functional/reactivity.d.ts +0 -11
- package/types/functional/stack.d.ts +0 -24
- package/types/v/index.d.ts +0 -36
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Reactive = exports.ReactivePrivate = exports.current = void 0;
|
|
4
|
+
const destroyable_js_1 = require("./destroyable.js");
|
|
5
|
+
const errors_1 = require("./errors");
|
|
6
|
+
const expression_1 = require("../value/expression");
|
|
7
|
+
const reference_1 = require("../value/reference");
|
|
8
|
+
const pointer_1 = require("../value/pointer");
|
|
9
|
+
const mirror_1 = require("../value/mirror");
|
|
10
|
+
exports.current = null;
|
|
11
|
+
const currentStack = [];
|
|
12
|
+
function stack(node) {
|
|
13
|
+
currentStack.push(exports.current);
|
|
14
|
+
exports.current = node;
|
|
15
|
+
}
|
|
16
|
+
function unstack() {
|
|
17
|
+
exports.current = currentStack.pop();
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Private stuff of a reactive object
|
|
21
|
+
* @class ReactivePrivate
|
|
22
|
+
* @extends Destroyable
|
|
23
|
+
*/
|
|
24
|
+
class ReactivePrivate extends destroyable_js_1.Destroyable {
|
|
25
|
+
constructor() {
|
|
26
|
+
super();
|
|
27
|
+
/**
|
|
28
|
+
* A list of user-defined values
|
|
29
|
+
* @type {Set}
|
|
30
|
+
*/
|
|
31
|
+
this.watch = new Set;
|
|
32
|
+
/**
|
|
33
|
+
* A list of user-defined bindings
|
|
34
|
+
* @type {Set}
|
|
35
|
+
*/
|
|
36
|
+
this.bindings = new Set;
|
|
37
|
+
/**
|
|
38
|
+
* A list of user defined models
|
|
39
|
+
*/
|
|
40
|
+
this.models = new Set;
|
|
41
|
+
/**
|
|
42
|
+
* Reactivity switch state
|
|
43
|
+
* @type {boolean}
|
|
44
|
+
*/
|
|
45
|
+
this.enabled = true;
|
|
46
|
+
/**
|
|
47
|
+
* The frozen state of object
|
|
48
|
+
* @type {boolean}
|
|
49
|
+
*/
|
|
50
|
+
this.frozen = false;
|
|
51
|
+
this.$seal();
|
|
52
|
+
}
|
|
53
|
+
$destroy() {
|
|
54
|
+
this.watch.forEach(value => value.$destroy());
|
|
55
|
+
this.watch.clear();
|
|
56
|
+
this.bindings.forEach(binding => binding.$destroy());
|
|
57
|
+
this.bindings.clear();
|
|
58
|
+
this.models.forEach(model => model.disableReactivity());
|
|
59
|
+
this.models.clear();
|
|
60
|
+
this.freezeExpr && this.freezeExpr.$destroy();
|
|
61
|
+
this.onDestroy && this.onDestroy();
|
|
62
|
+
super.$destroy();
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
exports.ReactivePrivate = ReactivePrivate;
|
|
66
|
+
/**
|
|
67
|
+
* A reactive object
|
|
68
|
+
* @class Reactive
|
|
69
|
+
* @extends Destroyable
|
|
70
|
+
*/
|
|
71
|
+
class Reactive extends destroyable_js_1.Destroyable {
|
|
72
|
+
constructor(input, $) {
|
|
73
|
+
super();
|
|
74
|
+
this.input = input;
|
|
75
|
+
this.$ = $ || new ReactivePrivate;
|
|
76
|
+
this.$seal();
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Get parent node
|
|
80
|
+
*/
|
|
81
|
+
get parent() {
|
|
82
|
+
return this.$.parent;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Create a reference
|
|
86
|
+
* @param value {*} value to reference
|
|
87
|
+
*/
|
|
88
|
+
ref(value) {
|
|
89
|
+
const $ = this.$;
|
|
90
|
+
const ref = new reference_1.Reference(value);
|
|
91
|
+
$.watch.add(ref);
|
|
92
|
+
return ref;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Create a mirror
|
|
96
|
+
* @param value {IValue} value to mirror
|
|
97
|
+
*/
|
|
98
|
+
mirror(value) {
|
|
99
|
+
const mirror = new mirror_1.Mirror(value, false);
|
|
100
|
+
this.$.watch.add(mirror);
|
|
101
|
+
return mirror;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Create a forward-only mirror
|
|
105
|
+
* @param value {IValue} value to mirror
|
|
106
|
+
*/
|
|
107
|
+
forward(value) {
|
|
108
|
+
const mirror = new mirror_1.Mirror(value, true);
|
|
109
|
+
this.$.watch.add(mirror);
|
|
110
|
+
return mirror;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Creates a pointer
|
|
114
|
+
* @param value {*} default value to point
|
|
115
|
+
* @param forwardOnly {boolean} forward only sync
|
|
116
|
+
*/
|
|
117
|
+
point(value, forwardOnly = false) {
|
|
118
|
+
const $ = this.$;
|
|
119
|
+
const pointer = new pointer_1.Pointer(value, forwardOnly);
|
|
120
|
+
$.watch.add(pointer);
|
|
121
|
+
return pointer;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Register a model
|
|
125
|
+
* @param model
|
|
126
|
+
*/
|
|
127
|
+
register(model) {
|
|
128
|
+
this.$.models.add(model);
|
|
129
|
+
return model;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Creates a watcher
|
|
133
|
+
* @param func {function} function to run on any argument change
|
|
134
|
+
* @param values
|
|
135
|
+
*/
|
|
136
|
+
watch(func, ...values) {
|
|
137
|
+
const $ = this.$;
|
|
138
|
+
$.watch.add(new expression_1.Expression(func, !this.$.frozen, ...values));
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Creates a computed value
|
|
142
|
+
* @param func {function} function to run on any argument change
|
|
143
|
+
* @param values
|
|
144
|
+
* @return {IValue} the created ivalue
|
|
145
|
+
*/
|
|
146
|
+
expr(func, ...values) {
|
|
147
|
+
const res = new expression_1.Expression(func, !this.$.frozen, ...values);
|
|
148
|
+
const $ = this.$;
|
|
149
|
+
$.watch.add(res);
|
|
150
|
+
return res;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Enable reactivity of fields
|
|
154
|
+
*/
|
|
155
|
+
enable() {
|
|
156
|
+
const $ = this.$;
|
|
157
|
+
if (!$.enabled) {
|
|
158
|
+
$.watch.forEach(watcher => {
|
|
159
|
+
watcher.$enable();
|
|
160
|
+
});
|
|
161
|
+
$.models.forEach(model => {
|
|
162
|
+
model.enableReactivity();
|
|
163
|
+
});
|
|
164
|
+
$.enabled = true;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Disable reactivity of fields
|
|
169
|
+
*/
|
|
170
|
+
disable() {
|
|
171
|
+
const $ = this.$;
|
|
172
|
+
if ($.enabled) {
|
|
173
|
+
$.watch.forEach(watcher => {
|
|
174
|
+
watcher.$disable();
|
|
175
|
+
});
|
|
176
|
+
$.models.forEach(model => {
|
|
177
|
+
model.disableReactivity();
|
|
178
|
+
});
|
|
179
|
+
$.enabled = false;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Disable/Enable reactivity of object fields with feedback
|
|
184
|
+
* @param cond {IValue} show condition
|
|
185
|
+
* @param onOff {function} on show feedback
|
|
186
|
+
* @param onOn {function} on hide feedback
|
|
187
|
+
*/
|
|
188
|
+
bindAlive(cond, onOff, onOn) {
|
|
189
|
+
const $ = this.$;
|
|
190
|
+
if ($.freezeExpr) {
|
|
191
|
+
throw (0, errors_1.wrongBinding)("this component already have a freeze state");
|
|
192
|
+
}
|
|
193
|
+
if ($.watch.has(cond)) {
|
|
194
|
+
throw (0, errors_1.wrongBinding)("freeze state must be bound to an external component");
|
|
195
|
+
}
|
|
196
|
+
$.freezeExpr = new expression_1.Expression((cond) => {
|
|
197
|
+
$.frozen = !cond;
|
|
198
|
+
if (cond) {
|
|
199
|
+
onOn === null || onOn === void 0 ? void 0 : onOn();
|
|
200
|
+
this.enable();
|
|
201
|
+
}
|
|
202
|
+
else {
|
|
203
|
+
onOff === null || onOff === void 0 ? void 0 : onOff();
|
|
204
|
+
this.disable();
|
|
205
|
+
}
|
|
206
|
+
}, true, cond);
|
|
207
|
+
return this;
|
|
208
|
+
}
|
|
209
|
+
init() {
|
|
210
|
+
this.applyOptions(this.input);
|
|
211
|
+
return this.compose(this.input);
|
|
212
|
+
}
|
|
213
|
+
applyOptions(input) {
|
|
214
|
+
// empty
|
|
215
|
+
}
|
|
216
|
+
applyOptionsNow() {
|
|
217
|
+
this.applyOptions(this.input);
|
|
218
|
+
}
|
|
219
|
+
compose(input) {
|
|
220
|
+
throw (0, errors_1.notOverwritten)();
|
|
221
|
+
}
|
|
222
|
+
composeNow() {
|
|
223
|
+
this.compose(this.input);
|
|
224
|
+
}
|
|
225
|
+
runFunctional(f, ...args) {
|
|
226
|
+
stack(this);
|
|
227
|
+
// yet another ts bug
|
|
228
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
229
|
+
// @ts-ignore
|
|
230
|
+
const result = f(...args);
|
|
231
|
+
unstack();
|
|
232
|
+
return result;
|
|
233
|
+
}
|
|
234
|
+
runOnDestroy(func) {
|
|
235
|
+
this.$.onDestroy = func;
|
|
236
|
+
}
|
|
237
|
+
$destroy() {
|
|
238
|
+
super.$destroy();
|
|
239
|
+
this.$.$destroy();
|
|
240
|
+
this.$ = null;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
exports.Reactive = Reactive;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Destroyable = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Mark an object which can be destroyed
|
|
6
|
+
* @class Destroyable
|
|
7
|
+
*/
|
|
8
|
+
class Destroyable {
|
|
9
|
+
/**
|
|
10
|
+
* Make object fields non configurable
|
|
11
|
+
* @protected
|
|
12
|
+
*/
|
|
13
|
+
$seal() {
|
|
14
|
+
const $ = this;
|
|
15
|
+
Object.keys($).forEach(i => {
|
|
16
|
+
// eslint-disable-next-line no-prototype-builtins
|
|
17
|
+
if (this.hasOwnProperty(i)) {
|
|
18
|
+
const config = Object.getOwnPropertyDescriptor($, i);
|
|
19
|
+
if (config.configurable) {
|
|
20
|
+
let descriptor;
|
|
21
|
+
if (config.set || config.get) {
|
|
22
|
+
descriptor = {
|
|
23
|
+
configurable: false,
|
|
24
|
+
get: config.get,
|
|
25
|
+
set: config.set,
|
|
26
|
+
enumerable: config.enumerable
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
descriptor = {
|
|
31
|
+
value: $[i],
|
|
32
|
+
configurable: false,
|
|
33
|
+
writable: config.writable,
|
|
34
|
+
enumerable: config.enumerable
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
Object.defineProperty($, i, descriptor);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Garbage collector method
|
|
44
|
+
*/
|
|
45
|
+
$destroy() {
|
|
46
|
+
// nothing here
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
exports.Destroyable = Destroyable;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.wrongBinding = exports.userError = exports.internalError = exports.notOverwritten = void 0;
|
|
4
|
+
const reportIt = "Report it here: https://gitlab.com/vasille-js/vasille-js/-/issues";
|
|
5
|
+
function notOverwritten() {
|
|
6
|
+
console.error("Vasille-SFP: Internal error", "Must be overwritten", reportIt);
|
|
7
|
+
return "not-overwritten";
|
|
8
|
+
}
|
|
9
|
+
exports.notOverwritten = notOverwritten;
|
|
10
|
+
function internalError(msg) {
|
|
11
|
+
console.error("Vasille-SFP: Internal error", msg, reportIt);
|
|
12
|
+
return "internal-error";
|
|
13
|
+
}
|
|
14
|
+
exports.internalError = internalError;
|
|
15
|
+
function userError(msg, err) {
|
|
16
|
+
console.error("Vasille-SFP: User error", msg);
|
|
17
|
+
return err;
|
|
18
|
+
}
|
|
19
|
+
exports.userError = userError;
|
|
20
|
+
function wrongBinding(msg) {
|
|
21
|
+
return userError(msg, "wrong-binding");
|
|
22
|
+
}
|
|
23
|
+
exports.wrongBinding = wrongBinding;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.IValue = exports.Switchable = void 0;
|
|
4
|
+
const destroyable_js_1 = require("./destroyable.js");
|
|
5
|
+
const errors_1 = require("./errors");
|
|
6
|
+
class Switchable extends destroyable_js_1.Destroyable {
|
|
7
|
+
/**
|
|
8
|
+
* Enable update handlers triggering
|
|
9
|
+
*/
|
|
10
|
+
$enable() {
|
|
11
|
+
throw (0, errors_1.notOverwritten)();
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* disable update handlers triggering
|
|
15
|
+
*/
|
|
16
|
+
$disable() {
|
|
17
|
+
throw (0, errors_1.notOverwritten)();
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
exports.Switchable = Switchable;
|
|
21
|
+
/**
|
|
22
|
+
* Interface which describes a value
|
|
23
|
+
* @class IValue
|
|
24
|
+
* @extends Destroyable
|
|
25
|
+
*/
|
|
26
|
+
class IValue extends Switchable {
|
|
27
|
+
/**
|
|
28
|
+
* @param isEnabled {boolean} initial is enabled state
|
|
29
|
+
*/
|
|
30
|
+
constructor(isEnabled) {
|
|
31
|
+
super();
|
|
32
|
+
this.isEnabled = isEnabled;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Get the encapsulated value
|
|
36
|
+
* @return {*} the encapsulated value
|
|
37
|
+
*/
|
|
38
|
+
get $() {
|
|
39
|
+
throw (0, errors_1.notOverwritten)();
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Sets the encapsulated value
|
|
43
|
+
* @param value {*} value to encapsulate
|
|
44
|
+
*/
|
|
45
|
+
set $(value) {
|
|
46
|
+
throw (0, errors_1.notOverwritten)();
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Add a new handler to value change
|
|
50
|
+
* @param handler {function(value : *)} the handler to add
|
|
51
|
+
*/
|
|
52
|
+
$on(handler) {
|
|
53
|
+
throw (0, errors_1.notOverwritten)();
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Removes a handler of value change
|
|
57
|
+
* @param handler {function(value : *)} the handler to remove
|
|
58
|
+
*/
|
|
59
|
+
$off(handler) {
|
|
60
|
+
throw (0, errors_1.notOverwritten)();
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
exports.IValue = IValue;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.current = exports.userError = exports.Watch = exports.Reactive = exports.Binding = exports.Expression = exports.Portal = exports.App = exports.AppNode = exports.Extension = exports.Component = exports.Tag = exports.INode = exports.Fragment = exports.SetView = exports.ObjectView = exports.MapView = exports.ArrayView = exports.Listener = exports.BaseView = exports.SetModel = exports.ObjectModel = exports.MapModel = exports.ArrayModel = exports.Pointer = exports.Mirror = exports.Reference = exports.IValue = exports.Destroyable = void 0;
|
|
4
|
+
const destroyable_1 = require("./core/destroyable");
|
|
5
|
+
Object.defineProperty(exports, "Destroyable", { enumerable: true, get: function () { return destroyable_1.Destroyable; } });
|
|
6
|
+
const core_1 = require("./core/core");
|
|
7
|
+
Object.defineProperty(exports, "current", { enumerable: true, get: function () { return core_1.current; } });
|
|
8
|
+
Object.defineProperty(exports, "Reactive", { enumerable: true, get: function () { return core_1.Reactive; } });
|
|
9
|
+
const ivalue_1 = require("./core/ivalue");
|
|
10
|
+
Object.defineProperty(exports, "IValue", { enumerable: true, get: function () { return ivalue_1.IValue; } });
|
|
11
|
+
const array_model_1 = require("./models/array-model");
|
|
12
|
+
Object.defineProperty(exports, "ArrayModel", { enumerable: true, get: function () { return array_model_1.ArrayModel; } });
|
|
13
|
+
const listener_1 = require("./models/listener");
|
|
14
|
+
Object.defineProperty(exports, "Listener", { enumerable: true, get: function () { return listener_1.Listener; } });
|
|
15
|
+
const map_model_1 = require("./models/map-model");
|
|
16
|
+
Object.defineProperty(exports, "MapModel", { enumerable: true, get: function () { return map_model_1.MapModel; } });
|
|
17
|
+
const object_model_1 = require("./models/object-model");
|
|
18
|
+
Object.defineProperty(exports, "ObjectModel", { enumerable: true, get: function () { return object_model_1.ObjectModel; } });
|
|
19
|
+
const set_model_1 = require("./models/set-model");
|
|
20
|
+
Object.defineProperty(exports, "SetModel", { enumerable: true, get: function () { return set_model_1.SetModel; } });
|
|
21
|
+
const app_1 = require("./node/app");
|
|
22
|
+
Object.defineProperty(exports, "App", { enumerable: true, get: function () { return app_1.App; } });
|
|
23
|
+
Object.defineProperty(exports, "AppNode", { enumerable: true, get: function () { return app_1.AppNode; } });
|
|
24
|
+
Object.defineProperty(exports, "Portal", { enumerable: true, get: function () { return app_1.Portal; } });
|
|
25
|
+
const node_1 = require("./node/node");
|
|
26
|
+
Object.defineProperty(exports, "Component", { enumerable: true, get: function () { return node_1.Component; } });
|
|
27
|
+
Object.defineProperty(exports, "Extension", { enumerable: true, get: function () { return node_1.Extension; } });
|
|
28
|
+
Object.defineProperty(exports, "Fragment", { enumerable: true, get: function () { return node_1.Fragment; } });
|
|
29
|
+
Object.defineProperty(exports, "INode", { enumerable: true, get: function () { return node_1.INode; } });
|
|
30
|
+
Object.defineProperty(exports, "Tag", { enumerable: true, get: function () { return node_1.Tag; } });
|
|
31
|
+
const expression_1 = require("./value/expression");
|
|
32
|
+
Object.defineProperty(exports, "Expression", { enumerable: true, get: function () { return expression_1.Expression; } });
|
|
33
|
+
const mirror_1 = require("./value/mirror");
|
|
34
|
+
Object.defineProperty(exports, "Mirror", { enumerable: true, get: function () { return mirror_1.Mirror; } });
|
|
35
|
+
const pointer_1 = require("./value/pointer");
|
|
36
|
+
Object.defineProperty(exports, "Pointer", { enumerable: true, get: function () { return pointer_1.Pointer; } });
|
|
37
|
+
const reference_1 = require("./value/reference");
|
|
38
|
+
Object.defineProperty(exports, "Reference", { enumerable: true, get: function () { return reference_1.Reference; } });
|
|
39
|
+
const array_view_1 = require("./views/array-view");
|
|
40
|
+
Object.defineProperty(exports, "ArrayView", { enumerable: true, get: function () { return array_view_1.ArrayView; } });
|
|
41
|
+
const base_view_1 = require("./views/base-view");
|
|
42
|
+
Object.defineProperty(exports, "BaseView", { enumerable: true, get: function () { return base_view_1.BaseView; } });
|
|
43
|
+
const map_view_1 = require("./views/map-view");
|
|
44
|
+
Object.defineProperty(exports, "MapView", { enumerable: true, get: function () { return map_view_1.MapView; } });
|
|
45
|
+
const object_view_1 = require("./views/object-view");
|
|
46
|
+
Object.defineProperty(exports, "ObjectView", { enumerable: true, get: function () { return object_view_1.ObjectView; } });
|
|
47
|
+
const set_view_1 = require("./views/set-view");
|
|
48
|
+
Object.defineProperty(exports, "SetView", { enumerable: true, get: function () { return set_view_1.SetView; } });
|
|
49
|
+
const binding_1 = require("./binding/binding");
|
|
50
|
+
Object.defineProperty(exports, "Binding", { enumerable: true, get: function () { return binding_1.Binding; } });
|
|
51
|
+
const errors_1 = require("./core/errors");
|
|
52
|
+
Object.defineProperty(exports, "userError", { enumerable: true, get: function () { return errors_1.userError; } });
|
|
53
|
+
const watch_1 = require("./node/watch");
|
|
54
|
+
Object.defineProperty(exports, "Watch", { enumerable: true, get: function () { return watch_1.Watch; } });
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ArrayModel = void 0;
|
|
4
|
+
const listener_1 = require("./listener");
|
|
5
|
+
/**
|
|
6
|
+
* Model based on Array class
|
|
7
|
+
* @extends Array
|
|
8
|
+
* @implements IModel
|
|
9
|
+
*/
|
|
10
|
+
class ArrayModel extends Array {
|
|
11
|
+
/**
|
|
12
|
+
* @param data {Array} input data
|
|
13
|
+
*/
|
|
14
|
+
constructor(data = []) {
|
|
15
|
+
super();
|
|
16
|
+
Object.defineProperty(this, 'listener', {
|
|
17
|
+
value: new listener_1.Listener,
|
|
18
|
+
writable: false,
|
|
19
|
+
configurable: false
|
|
20
|
+
});
|
|
21
|
+
for (let i = 0; i < data.length; i++) {
|
|
22
|
+
super.push(data[i]);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
/* Array members */
|
|
26
|
+
/**
|
|
27
|
+
* Gets the last item of array
|
|
28
|
+
* @return {*} the last item of array
|
|
29
|
+
*/
|
|
30
|
+
get last() {
|
|
31
|
+
return this.length ? this[this.length - 1] : null;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Calls Array.fill and notify about changes
|
|
35
|
+
* @param value {*} value to fill with
|
|
36
|
+
* @param start {?number} begin index
|
|
37
|
+
* @param end {?number} end index
|
|
38
|
+
*/
|
|
39
|
+
fill(value, start, end) {
|
|
40
|
+
if (!start) {
|
|
41
|
+
start = 0;
|
|
42
|
+
}
|
|
43
|
+
if (!end) {
|
|
44
|
+
end = this.length;
|
|
45
|
+
}
|
|
46
|
+
for (let i = start; i < end; i++) {
|
|
47
|
+
this.listener.emitRemoved(this[i], this[i]);
|
|
48
|
+
this[i] = value;
|
|
49
|
+
this.listener.emitAdded(value, value);
|
|
50
|
+
}
|
|
51
|
+
return this;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Calls Array.pop and notify about changes
|
|
55
|
+
* @return {*} removed value
|
|
56
|
+
*/
|
|
57
|
+
pop() {
|
|
58
|
+
const v = super.pop();
|
|
59
|
+
if (v !== undefined) {
|
|
60
|
+
this.listener.emitRemoved(v, v);
|
|
61
|
+
}
|
|
62
|
+
return v;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Calls Array.push and notify about changes
|
|
66
|
+
* @param items {...*} values to push
|
|
67
|
+
* @return {number} new length of array
|
|
68
|
+
*/
|
|
69
|
+
push(...items) {
|
|
70
|
+
items.forEach(item => {
|
|
71
|
+
this.listener.emitAdded(item, item);
|
|
72
|
+
super.push(item);
|
|
73
|
+
});
|
|
74
|
+
return this.length;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Calls Array.shift and notify about changed
|
|
78
|
+
* @return {*} the shifted value
|
|
79
|
+
*/
|
|
80
|
+
shift() {
|
|
81
|
+
const v = super.shift();
|
|
82
|
+
if (v !== undefined) {
|
|
83
|
+
this.listener.emitRemoved(v, v);
|
|
84
|
+
}
|
|
85
|
+
return v;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Calls Array.splice and notify about changed
|
|
89
|
+
* @param start {number} start index
|
|
90
|
+
* @param deleteCount {?number} delete count
|
|
91
|
+
* @param items {...*}
|
|
92
|
+
* @return {ArrayModel} a pointer to this
|
|
93
|
+
*/
|
|
94
|
+
splice(start, deleteCount, ...items) {
|
|
95
|
+
start = Math.min(start, this.length);
|
|
96
|
+
deleteCount = deleteCount || this.length - start;
|
|
97
|
+
const before = this[start + deleteCount];
|
|
98
|
+
for (let i = 0; i < deleteCount; i++) {
|
|
99
|
+
const index = start + deleteCount - i - 1;
|
|
100
|
+
if (this[index] !== undefined) {
|
|
101
|
+
this.listener.emitRemoved(this[index], this[index]);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
for (let i = 0; i < items.length; i++) {
|
|
105
|
+
this.listener.emitAdded(before, items[i]);
|
|
106
|
+
}
|
|
107
|
+
return new ArrayModel(super.splice(start, deleteCount, ...items));
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Calls Array.unshift and notify about changed
|
|
111
|
+
* @param items {...*} values to insert
|
|
112
|
+
* @return {number} the length after prepend
|
|
113
|
+
*/
|
|
114
|
+
unshift(...items) {
|
|
115
|
+
for (let i = 0; i < items.length; i++) {
|
|
116
|
+
this.listener.emitAdded(this[i], items[i]);
|
|
117
|
+
}
|
|
118
|
+
return super.unshift(...items);
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Inserts a value to the end of array
|
|
122
|
+
* @param v {*} value to insert
|
|
123
|
+
*/
|
|
124
|
+
append(v) {
|
|
125
|
+
this.listener.emitAdded(null, v);
|
|
126
|
+
super.push(v);
|
|
127
|
+
return this;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Clears array
|
|
131
|
+
* @return {this} a pointer to this
|
|
132
|
+
*/
|
|
133
|
+
clear() {
|
|
134
|
+
this.forEach(v => {
|
|
135
|
+
this.listener.emitRemoved(v, v);
|
|
136
|
+
});
|
|
137
|
+
super.splice(0);
|
|
138
|
+
return this;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Inserts a value to position `index`
|
|
142
|
+
* @param index {number} index to insert value
|
|
143
|
+
* @param v {*} value to insert
|
|
144
|
+
* @return {this} a pointer to this
|
|
145
|
+
*/
|
|
146
|
+
insert(index, v) {
|
|
147
|
+
this.listener.emitAdded(this[index], v);
|
|
148
|
+
super.splice(index, 0, v);
|
|
149
|
+
return this;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Inserts a value to the beginning of array
|
|
153
|
+
* @param v {*} value to insert
|
|
154
|
+
* @return {this} a pointer to this
|
|
155
|
+
*/
|
|
156
|
+
prepend(v) {
|
|
157
|
+
this.listener.emitAdded(this[0], v);
|
|
158
|
+
super.unshift(v);
|
|
159
|
+
return this;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Removes a value from an index
|
|
163
|
+
* @param index {number} index of value to remove
|
|
164
|
+
* @return {this} a pointer to this
|
|
165
|
+
*/
|
|
166
|
+
removeAt(index) {
|
|
167
|
+
if (index > 0 && index < this.length) {
|
|
168
|
+
this.listener.emitRemoved(this[index], this[index]);
|
|
169
|
+
super.splice(index, 1);
|
|
170
|
+
}
|
|
171
|
+
return this;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Removes the first value of array
|
|
175
|
+
* @return {this} a pointer to this
|
|
176
|
+
*/
|
|
177
|
+
removeFirst() {
|
|
178
|
+
if (this.length) {
|
|
179
|
+
this.listener.emitRemoved(this[0], this[0]);
|
|
180
|
+
super.shift();
|
|
181
|
+
}
|
|
182
|
+
return this;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Removes the ast value of array
|
|
186
|
+
* @return {this} a pointer to this
|
|
187
|
+
*/
|
|
188
|
+
removeLast() {
|
|
189
|
+
const last = this.last;
|
|
190
|
+
if (last != null) {
|
|
191
|
+
this.listener.emitRemoved(this[this.length - 1], last);
|
|
192
|
+
super.pop();
|
|
193
|
+
}
|
|
194
|
+
return this;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Remove the first occurrence of value
|
|
198
|
+
* @param v {*} value to remove
|
|
199
|
+
* @return {this}
|
|
200
|
+
*/
|
|
201
|
+
removeOne(v) {
|
|
202
|
+
this.removeAt(this.indexOf(v));
|
|
203
|
+
return this;
|
|
204
|
+
}
|
|
205
|
+
replace(at, with_) {
|
|
206
|
+
this.listener.emitAdded(this[at], with_);
|
|
207
|
+
this.listener.emitRemoved(this[at], this[at]);
|
|
208
|
+
this[at] = with_;
|
|
209
|
+
return this;
|
|
210
|
+
}
|
|
211
|
+
enableReactivity() {
|
|
212
|
+
this.listener.enableReactivity();
|
|
213
|
+
}
|
|
214
|
+
disableReactivity() {
|
|
215
|
+
this.listener.disableReactivity();
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
exports.ArrayModel = ArrayModel;
|