@expressive/mvc 1.0.0-beta.44 → 1.0.0-beta.45
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/lib/index.d.ts +27 -37
- package/lib/index.esm.js +268 -205
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +268 -204
- package/lib/index.js.map +1 -1
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -101,6 +101,149 @@ function applyUpdate(subject, keys) {
|
|
|
101
101
|
};
|
|
102
102
|
}
|
|
103
103
|
|
|
104
|
+
const CONTROL = Symbol("CONTROL");
|
|
105
|
+
const WHY = Symbol("UPDATE");
|
|
106
|
+
const LOCAL = Symbol("LOCAL");
|
|
107
|
+
const STATE = Symbol("STATE");
|
|
108
|
+
class Model {
|
|
109
|
+
constructor() {
|
|
110
|
+
define(this, CONTROL, new Controller(this));
|
|
111
|
+
define(this, "get", this);
|
|
112
|
+
define(this, "set", this);
|
|
113
|
+
}
|
|
114
|
+
get [STATE]() {
|
|
115
|
+
return this[CONTROL].state;
|
|
116
|
+
}
|
|
117
|
+
get [WHY]() {
|
|
118
|
+
return UPDATE.get(this);
|
|
119
|
+
}
|
|
120
|
+
on(select, handler, squash, once) {
|
|
121
|
+
return control(this, control => {
|
|
122
|
+
if (typeof select == "function")
|
|
123
|
+
return control.addListener(select);
|
|
124
|
+
const keys = typeof select == "string" ? [select] :
|
|
125
|
+
!select.length ? getOwnPropertyNames(control.state) :
|
|
126
|
+
select;
|
|
127
|
+
ensure(control, keys);
|
|
128
|
+
const callback = squash
|
|
129
|
+
? handler.bind(this)
|
|
130
|
+
: frame => frame
|
|
131
|
+
.filter(k => keys.includes(k))
|
|
132
|
+
.forEach(k => handler.call(this, control.state[k], k));
|
|
133
|
+
const trigger = once
|
|
134
|
+
? frame => { remove(); callback(frame); }
|
|
135
|
+
: callback;
|
|
136
|
+
const remove = control.addListener(key => {
|
|
137
|
+
if (keys.includes(key))
|
|
138
|
+
return trigger;
|
|
139
|
+
});
|
|
140
|
+
return remove;
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
once(select, callback, squash) {
|
|
144
|
+
if (callback)
|
|
145
|
+
return this.on(select, callback, squash, true);
|
|
146
|
+
return new Promise(resolve => {
|
|
147
|
+
this.on(select, resolve, true, true);
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
effect(callback, select) {
|
|
151
|
+
const effect = createEffect(callback);
|
|
152
|
+
return control(this, control => {
|
|
153
|
+
if (!select) {
|
|
154
|
+
const sub = new Subscriber(control, () => invoke);
|
|
155
|
+
const invoke = () => {
|
|
156
|
+
const x = sub.proxy;
|
|
157
|
+
effect.call(x, x);
|
|
158
|
+
};
|
|
159
|
+
invoke();
|
|
160
|
+
return sub.commit();
|
|
161
|
+
}
|
|
162
|
+
const invoke = () => {
|
|
163
|
+
effect.call(this.get, this.get);
|
|
164
|
+
};
|
|
165
|
+
invoke();
|
|
166
|
+
if (!select.length) {
|
|
167
|
+
control.onDestroy.add(invoke);
|
|
168
|
+
return () => {
|
|
169
|
+
control.onDestroy.delete(invoke);
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
return control.addListener(key => {
|
|
173
|
+
if (select.includes(key))
|
|
174
|
+
return invoke;
|
|
175
|
+
});
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
// TODO: account for exotic properties
|
|
179
|
+
import(source, select) {
|
|
180
|
+
const { subject } = control(this);
|
|
181
|
+
if (!select)
|
|
182
|
+
select = getOwnPropertyNames(subject);
|
|
183
|
+
for (const key of select)
|
|
184
|
+
if (key in source)
|
|
185
|
+
this[key] = source[key];
|
|
186
|
+
}
|
|
187
|
+
export(subset) {
|
|
188
|
+
const { state } = control(this);
|
|
189
|
+
const output = {};
|
|
190
|
+
if (!subset)
|
|
191
|
+
subset = getOwnPropertyNames(state);
|
|
192
|
+
for (const key of subset)
|
|
193
|
+
output[key] = state[key];
|
|
194
|
+
return output;
|
|
195
|
+
}
|
|
196
|
+
update(arg, tag) {
|
|
197
|
+
const target = control(this);
|
|
198
|
+
if (typeof arg == "string") {
|
|
199
|
+
target.update(arg);
|
|
200
|
+
if (1 in arguments && arg in this) {
|
|
201
|
+
const method = this[arg];
|
|
202
|
+
if (typeof method == "function")
|
|
203
|
+
if (typeof tag != "boolean")
|
|
204
|
+
method.call(this, tag);
|
|
205
|
+
else if (tag)
|
|
206
|
+
method.call(this);
|
|
207
|
+
}
|
|
208
|
+
arg = undefined;
|
|
209
|
+
}
|
|
210
|
+
return target.requestUpdate(arg);
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Mark this instance for garbage-collection and send `willDestroy` event to all listeners.
|
|
214
|
+
*/
|
|
215
|
+
destroy() {
|
|
216
|
+
control(this).stop();
|
|
217
|
+
}
|
|
218
|
+
toString() {
|
|
219
|
+
return this.constructor.name;
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Creates a new instance of this controller.
|
|
223
|
+
*
|
|
224
|
+
* Beyond `new this(...)`, method will activate managed-state.
|
|
225
|
+
*
|
|
226
|
+
* @param args - arguments sent to constructor
|
|
227
|
+
*/
|
|
228
|
+
static create(...args) {
|
|
229
|
+
const instance = new this(...args);
|
|
230
|
+
control(instance);
|
|
231
|
+
return instance;
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Static equivalent of `x instanceof this`.
|
|
235
|
+
*
|
|
236
|
+
* Will determine if provided class is a subtype of this one.
|
|
237
|
+
*/
|
|
238
|
+
static isTypeof(maybe) {
|
|
239
|
+
return (typeof maybe == "function" &&
|
|
240
|
+
maybe.prototype instanceof this);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
defineLazy(Model, CONTROL, function () {
|
|
244
|
+
return new Controller(this);
|
|
245
|
+
});
|
|
246
|
+
|
|
104
247
|
class Subscriber {
|
|
105
248
|
constructor(target, onUpdate) {
|
|
106
249
|
this.onUpdate = onUpdate;
|
|
@@ -312,6 +455,7 @@ const Oops$9 = issues({
|
|
|
312
455
|
StrictUpdate: () => `Strict update() did not find pending updates.`,
|
|
313
456
|
NoChaining: () => `Then called with undefined; update promise will never catch nor supports chaining.`
|
|
314
457
|
});
|
|
458
|
+
const PENDING = new Map();
|
|
315
459
|
const READY = new WeakSet();
|
|
316
460
|
class Controller {
|
|
317
461
|
constructor(subject) {
|
|
@@ -337,52 +481,28 @@ class Controller {
|
|
|
337
481
|
const { value: entry } = getOwnPropertyDescriptor(subject, key);
|
|
338
482
|
if (typeof entry == "function")
|
|
339
483
|
return;
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
const instruction = Pending.get(entry);
|
|
346
|
-
if (instruction) {
|
|
347
|
-
Pending.delete(entry);
|
|
348
|
-
delete subject[key];
|
|
349
|
-
const desc = instruction.call(this, key, this);
|
|
350
|
-
if (desc === false)
|
|
351
|
-
return;
|
|
352
|
-
if (typeof desc == "object") {
|
|
353
|
-
if ("value" in desc)
|
|
354
|
-
state[key] = desc.value;
|
|
355
|
-
onSet = desc.set;
|
|
356
|
-
onGet = desc.get;
|
|
357
|
-
suspense = desc.suspense;
|
|
358
|
-
enumerable = desc.enumerable;
|
|
359
|
-
}
|
|
484
|
+
if (typeof entry == "symbol") {
|
|
485
|
+
const instruction = PENDING.get(entry);
|
|
486
|
+
if (instruction)
|
|
487
|
+
instruction.call(this, key, this);
|
|
488
|
+
return;
|
|
360
489
|
}
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
if (onSet !== false)
|
|
364
|
-
set = this.ref(key, onSet);
|
|
365
|
-
const get = (local) => {
|
|
366
|
-
if (!(key in state) && suspense)
|
|
367
|
-
throw suspend(this, key);
|
|
368
|
-
const value = state[key];
|
|
369
|
-
if (onGet)
|
|
370
|
-
return local
|
|
371
|
-
? onGet(value, local)
|
|
372
|
-
: onGet(value);
|
|
373
|
-
return value;
|
|
374
|
-
};
|
|
490
|
+
state[key] = entry;
|
|
491
|
+
const set = this.ref(key);
|
|
375
492
|
defineProperty(subject, key, {
|
|
376
|
-
enumerable
|
|
493
|
+
enumerable: false,
|
|
494
|
+
get: () => state[key],
|
|
495
|
+
set
|
|
377
496
|
});
|
|
378
497
|
defineProperty(proxy, key, {
|
|
379
|
-
enumerable
|
|
498
|
+
enumerable: false,
|
|
380
499
|
get() {
|
|
381
500
|
const local = this[LOCAL];
|
|
382
501
|
if (local && !local.watch[key])
|
|
383
502
|
local.watch[key] = true;
|
|
384
|
-
return
|
|
385
|
-
}
|
|
503
|
+
return state[key];
|
|
504
|
+
},
|
|
505
|
+
set
|
|
386
506
|
});
|
|
387
507
|
}
|
|
388
508
|
ref(key, handler) {
|
|
@@ -481,179 +601,55 @@ function control(subject, cb) {
|
|
|
481
601
|
return cb(control);
|
|
482
602
|
}
|
|
483
603
|
|
|
484
|
-
const CONTROL = Symbol("CONTROL");
|
|
485
|
-
const WHY = Symbol("UPDATE");
|
|
486
|
-
const LOCAL = Symbol("LOCAL");
|
|
487
|
-
const STATE = Symbol("STATE");
|
|
488
|
-
class Model {
|
|
489
|
-
constructor() {
|
|
490
|
-
define(this, CONTROL, new Controller(this));
|
|
491
|
-
define(this, "get", this);
|
|
492
|
-
define(this, "set", this);
|
|
493
|
-
}
|
|
494
|
-
get [STATE]() {
|
|
495
|
-
return this[CONTROL].state;
|
|
496
|
-
}
|
|
497
|
-
get [WHY]() {
|
|
498
|
-
return UPDATE.get(this);
|
|
499
|
-
}
|
|
500
|
-
on(select, handler, squash, once) {
|
|
501
|
-
return control(this, control => {
|
|
502
|
-
if (typeof select == "function")
|
|
503
|
-
return control.addListener(select);
|
|
504
|
-
const keys = typeof select == "string" ? [select] :
|
|
505
|
-
!select.length ? getOwnPropertyNames(control.state) :
|
|
506
|
-
select;
|
|
507
|
-
ensure(control, keys);
|
|
508
|
-
const callback = squash
|
|
509
|
-
? handler.bind(this)
|
|
510
|
-
: frame => frame
|
|
511
|
-
.filter(k => keys.includes(k))
|
|
512
|
-
.forEach(k => handler.call(this, control.state[k], k));
|
|
513
|
-
const trigger = once
|
|
514
|
-
? frame => { remove(); callback(frame); }
|
|
515
|
-
: callback;
|
|
516
|
-
const remove = control.addListener(key => {
|
|
517
|
-
if (keys.includes(key))
|
|
518
|
-
return trigger;
|
|
519
|
-
});
|
|
520
|
-
return remove;
|
|
521
|
-
});
|
|
522
|
-
}
|
|
523
|
-
once(select, callback, squash) {
|
|
524
|
-
if (callback)
|
|
525
|
-
return this.on(select, callback, squash, true);
|
|
526
|
-
return new Promise(resolve => {
|
|
527
|
-
this.on(select, resolve, true, true);
|
|
528
|
-
});
|
|
529
|
-
}
|
|
530
|
-
effect(callback, select) {
|
|
531
|
-
const effect = createEffect(callback);
|
|
532
|
-
return control(this, control => {
|
|
533
|
-
if (!select) {
|
|
534
|
-
const sub = new Subscriber(control, () => invoke);
|
|
535
|
-
const invoke = () => {
|
|
536
|
-
const x = sub.proxy;
|
|
537
|
-
effect.call(x, x);
|
|
538
|
-
};
|
|
539
|
-
invoke();
|
|
540
|
-
return sub.commit();
|
|
541
|
-
}
|
|
542
|
-
const invoke = () => {
|
|
543
|
-
effect.call(this.get, this.get);
|
|
544
|
-
};
|
|
545
|
-
invoke();
|
|
546
|
-
if (!select.length) {
|
|
547
|
-
control.onDestroy.add(invoke);
|
|
548
|
-
return () => {
|
|
549
|
-
control.onDestroy.delete(invoke);
|
|
550
|
-
};
|
|
551
|
-
}
|
|
552
|
-
return control.addListener(key => {
|
|
553
|
-
if (select.includes(key))
|
|
554
|
-
return invoke;
|
|
555
|
-
});
|
|
556
|
-
});
|
|
557
|
-
}
|
|
558
|
-
// TODO: account for exotic properties
|
|
559
|
-
import(source, select) {
|
|
560
|
-
const { subject } = control(this);
|
|
561
|
-
if (!select)
|
|
562
|
-
select = getOwnPropertyNames(subject);
|
|
563
|
-
for (const key of select)
|
|
564
|
-
if (key in source)
|
|
565
|
-
this[key] = source[key];
|
|
566
|
-
}
|
|
567
|
-
export(subset) {
|
|
568
|
-
const { state } = control(this);
|
|
569
|
-
const output = {};
|
|
570
|
-
if (!subset)
|
|
571
|
-
subset = getOwnPropertyNames(state);
|
|
572
|
-
for (const key of subset)
|
|
573
|
-
output[key] = state[key];
|
|
574
|
-
return output;
|
|
575
|
-
}
|
|
576
|
-
update(arg, tag) {
|
|
577
|
-
const target = control(this);
|
|
578
|
-
if (typeof arg == "string") {
|
|
579
|
-
target.update(arg);
|
|
580
|
-
if (1 in arguments && arg in this) {
|
|
581
|
-
const method = this[arg];
|
|
582
|
-
if (typeof method == "function")
|
|
583
|
-
if (typeof tag != "boolean")
|
|
584
|
-
method.call(this, tag);
|
|
585
|
-
else if (tag)
|
|
586
|
-
method.call(this);
|
|
587
|
-
}
|
|
588
|
-
arg = undefined;
|
|
589
|
-
}
|
|
590
|
-
return target.requestUpdate(arg);
|
|
591
|
-
}
|
|
592
|
-
/**
|
|
593
|
-
* Mark this instance for garbage-collection and send `willDestroy` event to all listeners.
|
|
594
|
-
*/
|
|
595
|
-
destroy() {
|
|
596
|
-
control(this).stop();
|
|
597
|
-
}
|
|
598
|
-
toString() {
|
|
599
|
-
return this.constructor.name;
|
|
600
|
-
}
|
|
601
|
-
/**
|
|
602
|
-
* Creates a new instance of this controller.
|
|
603
|
-
*
|
|
604
|
-
* Beyond `new this(...)`, method will activate managed-state.
|
|
605
|
-
*
|
|
606
|
-
* @param args - arguments sent to constructor
|
|
607
|
-
*/
|
|
608
|
-
static create(...args) {
|
|
609
|
-
const instance = new this(...args);
|
|
610
|
-
control(instance);
|
|
611
|
-
return instance;
|
|
612
|
-
}
|
|
613
|
-
/**
|
|
614
|
-
* Static equivalent of `x instanceof this`.
|
|
615
|
-
*
|
|
616
|
-
* Will determine if provided class is a subtype of this one.
|
|
617
|
-
*/
|
|
618
|
-
static isTypeof(maybe) {
|
|
619
|
-
return (typeof maybe == "function" &&
|
|
620
|
-
maybe.prototype instanceof this);
|
|
621
|
-
}
|
|
622
|
-
}
|
|
623
|
-
defineLazy(Model, CONTROL, function () {
|
|
624
|
-
return new Controller(this);
|
|
625
|
-
});
|
|
626
|
-
|
|
627
|
-
const Pending = new Map();
|
|
628
604
|
function apply(fn, label) {
|
|
629
605
|
const name = label || fn.name || "pending";
|
|
630
606
|
const placeholder = Symbol(`${name} instruction`);
|
|
631
607
|
function setup(key) {
|
|
608
|
+
const { proxy, state, subject } = this;
|
|
609
|
+
const control = this;
|
|
610
|
+
PENDING.delete(placeholder);
|
|
611
|
+
delete subject[key];
|
|
632
612
|
let output = fn.call(this, key, this);
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
}
|
|
641
|
-
if ("recursive" in output && output.recursive)
|
|
642
|
-
return Object.assign(Object.assign({}, output), { get: recursive(this, key) });
|
|
643
|
-
}
|
|
644
|
-
case "boolean":
|
|
645
|
-
return output;
|
|
613
|
+
if (typeof output == "function")
|
|
614
|
+
output = { get: output };
|
|
615
|
+
if (typeof output != "object")
|
|
616
|
+
return;
|
|
617
|
+
if ("explicit" in output && output.explicit) {
|
|
618
|
+
defineProperty(subject, key, output);
|
|
619
|
+
return false;
|
|
646
620
|
}
|
|
647
|
-
|
|
621
|
+
if ("recursive" in output && output.recursive)
|
|
622
|
+
output = Object.assign(Object.assign({}, output), { get: recursive(this, key) });
|
|
623
|
+
const desc = output;
|
|
624
|
+
if ("value" in desc)
|
|
625
|
+
state[key] = desc.value;
|
|
626
|
+
const { get: onGet, set: onSet, enumerable, suspense } = desc;
|
|
627
|
+
let set = onSet === false
|
|
628
|
+
? undefined
|
|
629
|
+
: this.ref(key, onSet);
|
|
630
|
+
function get() {
|
|
631
|
+
if (!(key in state) && suspense)
|
|
632
|
+
throw suspend(control, key);
|
|
633
|
+
const local = this[LOCAL];
|
|
634
|
+
if (local && !(key in local.watch))
|
|
635
|
+
local.watch[key] = true;
|
|
636
|
+
const value = state[key];
|
|
637
|
+
if (!onGet)
|
|
638
|
+
return value;
|
|
639
|
+
return local
|
|
640
|
+
? onGet(value, local)
|
|
641
|
+
: onGet(value);
|
|
642
|
+
}
|
|
643
|
+
for (const x of [subject, proxy])
|
|
644
|
+
defineProperty(x, key, { enumerable, get, set });
|
|
648
645
|
}
|
|
649
|
-
|
|
646
|
+
PENDING.set(placeholder, setup);
|
|
650
647
|
return placeholder;
|
|
651
648
|
}
|
|
652
649
|
function recursive(source, key) {
|
|
653
|
-
|
|
654
|
-
const subscribe = (parent) => {
|
|
650
|
+
return forSubscriber((parent, context) => {
|
|
655
651
|
let child;
|
|
656
|
-
|
|
652
|
+
function init() {
|
|
657
653
|
if (child) {
|
|
658
654
|
child.release();
|
|
659
655
|
parent.dependant.delete(child);
|
|
@@ -668,15 +664,23 @@ function recursive(source, key) {
|
|
|
668
664
|
parent.dependant.add(child);
|
|
669
665
|
context.set(parent, child.proxy);
|
|
670
666
|
}
|
|
671
|
-
}
|
|
667
|
+
}
|
|
672
668
|
init();
|
|
673
669
|
parent.watch[key] = init;
|
|
674
|
-
};
|
|
670
|
+
});
|
|
671
|
+
}
|
|
672
|
+
function forSubscriber(fn) {
|
|
673
|
+
const context = new WeakMap();
|
|
675
674
|
return (value, local) => {
|
|
676
675
|
if (!local)
|
|
677
676
|
return value;
|
|
678
|
-
if (!context.has(local))
|
|
679
|
-
|
|
677
|
+
if (!context.has(local)) {
|
|
678
|
+
const output = fn(local, context);
|
|
679
|
+
if (output) {
|
|
680
|
+
context.set(local, output);
|
|
681
|
+
return output;
|
|
682
|
+
}
|
|
683
|
+
}
|
|
680
684
|
return context.get(local);
|
|
681
685
|
};
|
|
682
686
|
}
|
|
@@ -710,6 +714,65 @@ function act(task) {
|
|
|
710
714
|
});
|
|
711
715
|
}
|
|
712
716
|
|
|
717
|
+
class Managed extends Array {
|
|
718
|
+
constructor(onUpdate) {
|
|
719
|
+
super();
|
|
720
|
+
this.lastUpdate = [0, 0];
|
|
721
|
+
this.update = (from, to) => {
|
|
722
|
+
this.lastUpdate = [from, to];
|
|
723
|
+
onUpdate();
|
|
724
|
+
};
|
|
725
|
+
}
|
|
726
|
+
push(...items) {
|
|
727
|
+
const length = this.length;
|
|
728
|
+
const end = super.push(...items);
|
|
729
|
+
this.update(length, end);
|
|
730
|
+
return end;
|
|
731
|
+
}
|
|
732
|
+
unshift(...items) {
|
|
733
|
+
const end = super.push(...items);
|
|
734
|
+
this.update(0, end);
|
|
735
|
+
return end;
|
|
736
|
+
}
|
|
737
|
+
splice(start, deleteCount, ...rest) {
|
|
738
|
+
this.update(start, deleteCount !== rest.length ? Infinity : deleteCount);
|
|
739
|
+
return super.splice(start, deleteCount, ...rest);
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
function array() {
|
|
743
|
+
return apply(function array(key) {
|
|
744
|
+
const array = new Managed(() => this.update(key));
|
|
745
|
+
const access = forSubscriber(context => {
|
|
746
|
+
const local = Object.create(array);
|
|
747
|
+
const update = context.onUpdate(key, this);
|
|
748
|
+
let rangeA = 0;
|
|
749
|
+
let rangeB = 0;
|
|
750
|
+
function onUpdate() {
|
|
751
|
+
const [lastA, lastB] = array.lastUpdate;
|
|
752
|
+
if (rangeA <= lastB && rangeB >= lastA)
|
|
753
|
+
return update;
|
|
754
|
+
}
|
|
755
|
+
function listen(eventA, eventB) {
|
|
756
|
+
if (context.active)
|
|
757
|
+
return;
|
|
758
|
+
context.watch[key] = onUpdate;
|
|
759
|
+
rangeA = Math.min(rangeA, eventA);
|
|
760
|
+
rangeB = Math.max(rangeB, eventB);
|
|
761
|
+
}
|
|
762
|
+
local[Symbol.iterator] = () => {
|
|
763
|
+
listen(0, Infinity);
|
|
764
|
+
return array[Symbol.iterator]();
|
|
765
|
+
};
|
|
766
|
+
return local;
|
|
767
|
+
});
|
|
768
|
+
return {
|
|
769
|
+
get: access,
|
|
770
|
+
set: false,
|
|
771
|
+
value: array
|
|
772
|
+
};
|
|
773
|
+
});
|
|
774
|
+
}
|
|
775
|
+
|
|
713
776
|
function ref(arg) {
|
|
714
777
|
return apply(function ref(key) {
|
|
715
778
|
let value = {};
|
|
@@ -1305,6 +1368,7 @@ exports.STATE = STATE;
|
|
|
1305
1368
|
exports.WHY = WHY;
|
|
1306
1369
|
exports.act = act;
|
|
1307
1370
|
exports.apply = apply;
|
|
1371
|
+
exports.array = array;
|
|
1308
1372
|
exports["default"] = MVC;
|
|
1309
1373
|
exports.from = from;
|
|
1310
1374
|
exports.parent = parent;
|