@expressive/mvc 1.0.0-beta.32 → 1.0.0-beta.33
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.esm.js +138 -128
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +139 -128
- package/lib/index.js.map +1 -1
- package/package.json +1 -1
- package/types/instructions.d.ts +92 -6
package/lib/index.js
CHANGED
|
@@ -24,7 +24,7 @@ function issues(register) {
|
|
|
24
24
|
return Library;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
const Oops$
|
|
27
|
+
const Oops$9 = issues({
|
|
28
28
|
BadEffectCallback: () => `Callback for effect-callback may only return a function.`
|
|
29
29
|
});
|
|
30
30
|
const { assign, create, defineProperty, entries, getPrototypeOf, getOwnPropertyNames, getOwnPropertyDescriptor, getOwnPropertyDescriptors, getOwnPropertySymbols, keys: keys$1, values } = Object;
|
|
@@ -53,7 +53,7 @@ function createEffect(callback) {
|
|
|
53
53
|
if (unSet instanceof Promise)
|
|
54
54
|
unSet = undefined;
|
|
55
55
|
if (unSet && typeof unSet !== "function")
|
|
56
|
-
throw Oops$
|
|
56
|
+
throw Oops$9.BadEffectCallback();
|
|
57
57
|
};
|
|
58
58
|
}
|
|
59
59
|
function createValueEffect(callback) {
|
|
@@ -69,7 +69,7 @@ function createValueEffect(callback) {
|
|
|
69
69
|
if (typeof out == "function")
|
|
70
70
|
unSet = out;
|
|
71
71
|
else
|
|
72
|
-
throw Oops$
|
|
72
|
+
throw Oops$9.BadEffectCallback();
|
|
73
73
|
};
|
|
74
74
|
}
|
|
75
75
|
function select(source, select) {
|
|
@@ -98,6 +98,13 @@ class Subscriber {
|
|
|
98
98
|
this.active = false;
|
|
99
99
|
this.handle = {};
|
|
100
100
|
this.dependant = new Set();
|
|
101
|
+
this.debug = () => {
|
|
102
|
+
const update = [];
|
|
103
|
+
this.notify = keys => {
|
|
104
|
+
update.splice(0, update.length, ...keys.filter(k => k in this.handle));
|
|
105
|
+
};
|
|
106
|
+
return update;
|
|
107
|
+
};
|
|
101
108
|
this.listen = (key, from) => {
|
|
102
109
|
const handler = this.handle[key];
|
|
103
110
|
if (!handler)
|
|
@@ -107,28 +114,16 @@ class Subscriber {
|
|
|
107
114
|
const notify = this.onUpdate(key, from);
|
|
108
115
|
if (notify)
|
|
109
116
|
from.waiting.add(notify);
|
|
117
|
+
if (this.notify)
|
|
118
|
+
from.waiting.add(this.notify);
|
|
110
119
|
};
|
|
111
120
|
if (!(parent instanceof Controller))
|
|
112
121
|
parent = manage(parent);
|
|
113
|
-
const subject = this.source =
|
|
114
|
-
parent.subject;
|
|
115
|
-
const proxy = this.proxy =
|
|
116
|
-
create(subject);
|
|
117
122
|
this.parent = parent;
|
|
123
|
+
this.source = parent.subject;
|
|
124
|
+
this.proxy = create(parent.subject);
|
|
118
125
|
define(this.proxy, LOCAL, this);
|
|
119
|
-
|
|
120
|
-
get: () => (this.parent.handled.filter(key => key in this.handle))
|
|
121
|
-
});
|
|
122
|
-
if ("update" in subject) {
|
|
123
|
-
define(proxy, "update", (...args) => {
|
|
124
|
-
if (!args.length) {
|
|
125
|
-
const refresh = this.onUpdate("", parent);
|
|
126
|
-
if (refresh)
|
|
127
|
-
refresh([]);
|
|
128
|
-
}
|
|
129
|
-
return subject.update(...args);
|
|
130
|
-
});
|
|
131
|
-
}
|
|
126
|
+
defineLazy(this.proxy, UPDATE, this.debug);
|
|
132
127
|
for (const key in parent.state)
|
|
133
128
|
this.spy(key);
|
|
134
129
|
}
|
|
@@ -162,7 +157,7 @@ class Subscriber {
|
|
|
162
157
|
}
|
|
163
158
|
}
|
|
164
159
|
|
|
165
|
-
const Oops$
|
|
160
|
+
const Oops$8 = issues({
|
|
166
161
|
ComputeFailed: (parent, property, initial) => `An exception was thrown while ${initial ? "initializing" : "refreshing"} [${parent}.${property}].`,
|
|
167
162
|
ComputedEarly: (property) => `Note: Computed values don't run until accessed, except when subscribed to. '${property}' getter may have run earlier than intended.`
|
|
168
163
|
});
|
|
@@ -181,14 +176,14 @@ function prepare(parent, key, source, setter, getter) {
|
|
|
181
176
|
}
|
|
182
177
|
register.set(key, info);
|
|
183
178
|
const current = getter
|
|
184
|
-
? () => getter
|
|
179
|
+
? () => getter(parent, key)
|
|
185
180
|
: () => state[key];
|
|
186
181
|
function compute(initial) {
|
|
187
182
|
try {
|
|
188
183
|
return setter.call(sub.proxy, sub.proxy);
|
|
189
184
|
}
|
|
190
185
|
catch (err) {
|
|
191
|
-
Oops$
|
|
186
|
+
Oops$8.ComputeFailed(subject, key, !!initial).warn();
|
|
192
187
|
throw err;
|
|
193
188
|
}
|
|
194
189
|
}
|
|
@@ -234,7 +229,7 @@ function prepare(parent, key, source, setter, getter) {
|
|
|
234
229
|
}
|
|
235
230
|
catch (e) {
|
|
236
231
|
if (early)
|
|
237
|
-
Oops$
|
|
232
|
+
Oops$8.ComputedEarly(key).warn();
|
|
238
233
|
throw e;
|
|
239
234
|
}
|
|
240
235
|
finally {
|
|
@@ -360,30 +355,16 @@ class Controller {
|
|
|
360
355
|
this.state = {};
|
|
361
356
|
this.frame = new Set();
|
|
362
357
|
this.waiting = new Set();
|
|
363
|
-
this.handled = [];
|
|
364
358
|
this.followers = new Set();
|
|
365
359
|
}
|
|
366
360
|
static setup(onto) {
|
|
367
361
|
const control = new this(onto);
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
defineProperty(onto, STATE, {
|
|
375
|
-
get: () => (Object.assign({}, control.state)),
|
|
376
|
-
configurable: true
|
|
377
|
-
});
|
|
378
|
-
defineProperty(onto, UPDATE, {
|
|
379
|
-
get: () => [...control.handled],
|
|
380
|
-
configurable: true
|
|
381
|
-
});
|
|
382
|
-
control.start();
|
|
383
|
-
if (onto.didCreate)
|
|
384
|
-
onto.didCreate();
|
|
385
|
-
return control;
|
|
386
|
-
}
|
|
362
|
+
defineLazy(onto, CONTROL, () => {
|
|
363
|
+
onto[STATE] = control.state;
|
|
364
|
+
control.start();
|
|
365
|
+
if (onto.didCreate)
|
|
366
|
+
onto.didCreate();
|
|
367
|
+
return control;
|
|
387
368
|
});
|
|
388
369
|
return control;
|
|
389
370
|
}
|
|
@@ -462,14 +443,17 @@ class Controller {
|
|
|
462
443
|
}
|
|
463
444
|
emit() {
|
|
464
445
|
flush(this);
|
|
446
|
+
const keys = Object.freeze([...this.frame]);
|
|
465
447
|
const handle = new Set(this.waiting);
|
|
466
|
-
const handled = this.handled =
|
|
467
|
-
Object.freeze([...this.frame]);
|
|
468
448
|
this.waiting.clear();
|
|
469
449
|
this.frame.clear();
|
|
450
|
+
defineProperty(this.subject, UPDATE, {
|
|
451
|
+
configurable: true,
|
|
452
|
+
value: keys
|
|
453
|
+
});
|
|
470
454
|
handle.forEach(callback => {
|
|
471
455
|
try {
|
|
472
|
-
callback(
|
|
456
|
+
callback(keys);
|
|
473
457
|
}
|
|
474
458
|
catch (e) { }
|
|
475
459
|
});
|
|
@@ -526,6 +510,61 @@ function child(source, name) {
|
|
|
526
510
|
}, name || source.name);
|
|
527
511
|
}
|
|
528
512
|
|
|
513
|
+
const Oops$7 = issues({
|
|
514
|
+
NonOptional: (Parent, key) => `Property ${Parent}.${key} is marked as required.`,
|
|
515
|
+
BadFactory: () => `Set instruction can only accept a factory or undefined.`,
|
|
516
|
+
FactoryFailed: (model, key) => `Generating initial value for ${model}.${key} failed.`
|
|
517
|
+
});
|
|
518
|
+
function lazy(value) {
|
|
519
|
+
return apply(function lazy(key) {
|
|
520
|
+
const source = this.subject;
|
|
521
|
+
source[key] = value;
|
|
522
|
+
defineProperty(this.state, key, {
|
|
523
|
+
get: () => source[key]
|
|
524
|
+
});
|
|
525
|
+
});
|
|
526
|
+
}
|
|
527
|
+
function set(factory, argument) {
|
|
528
|
+
return apply(function set(key) {
|
|
529
|
+
let onSet;
|
|
530
|
+
let onGet;
|
|
531
|
+
const required = argument === true || argument === undefined;
|
|
532
|
+
if (factory === undefined)
|
|
533
|
+
onGet = () => pendingValue(this, key);
|
|
534
|
+
else if (typeof factory !== "function")
|
|
535
|
+
throw Oops$7.BadFactory();
|
|
536
|
+
else {
|
|
537
|
+
onGet = pendingFactory(this, key, factory);
|
|
538
|
+
if (required)
|
|
539
|
+
try {
|
|
540
|
+
onGet();
|
|
541
|
+
}
|
|
542
|
+
catch (err) {
|
|
543
|
+
if (err instanceof Promise)
|
|
544
|
+
;
|
|
545
|
+
else {
|
|
546
|
+
Oops$7.FactoryFailed(this.subject, key).warn();
|
|
547
|
+
throw err;
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
if (typeof argument == "function")
|
|
552
|
+
onSet = createValueEffect(argument);
|
|
553
|
+
else if (required)
|
|
554
|
+
onSet = (value) => {
|
|
555
|
+
if (value === undefined)
|
|
556
|
+
throw Oops$7.NonOptional(this.subject, key);
|
|
557
|
+
};
|
|
558
|
+
return {
|
|
559
|
+
set: this.setter(key, onSet),
|
|
560
|
+
get: onGet
|
|
561
|
+
};
|
|
562
|
+
});
|
|
563
|
+
}
|
|
564
|
+
function on(initial, onUpdate) {
|
|
565
|
+
return set(initial && (() => initial), onUpdate);
|
|
566
|
+
}
|
|
567
|
+
|
|
529
568
|
const Oops$6 = issues({
|
|
530
569
|
CantAttachGlobal: (parent, child) => `Singleton '${parent}' attempted to attach '${child}' but it is not also a singleton.`,
|
|
531
570
|
AmbientRequired: (requested, requester, key) => `Attempted to find an instance of ${requested} in context. It is required for [${requester}.${key}], but one could not be found.`
|
|
@@ -628,10 +667,13 @@ function act(task) {
|
|
|
628
667
|
};
|
|
629
668
|
});
|
|
630
669
|
}
|
|
631
|
-
function from(source, setter,
|
|
670
|
+
function from(source, setter, argument) {
|
|
632
671
|
return apply(function from(key) {
|
|
633
672
|
const { subject } = this;
|
|
634
673
|
let getSource;
|
|
674
|
+
let getter = argument === true
|
|
675
|
+
? pendingValue
|
|
676
|
+
: argument || undefined;
|
|
635
677
|
// Easy mistake, using a peer, will always be unresolved.
|
|
636
678
|
if (typeof source == "symbol")
|
|
637
679
|
throw Oops$5.PeerNotAllowed(subject, key);
|
|
@@ -646,7 +688,7 @@ function from(source, setter, getter) {
|
|
|
646
688
|
// is a peer Model (constructor)
|
|
647
689
|
else if (Model.isTypeof(source))
|
|
648
690
|
getSource = pendingAccess(subject, source, key, true);
|
|
649
|
-
// Regular function is
|
|
691
|
+
// Regular function is too ambiguous so not allowed.
|
|
650
692
|
else
|
|
651
693
|
throw Oops$5.BadComputedSource(subject, key, source);
|
|
652
694
|
prepare(this, key, getSource, setter, getter);
|
|
@@ -656,12 +698,14 @@ function from(source, setter, getter) {
|
|
|
656
698
|
const Oops$4 = issues({
|
|
657
699
|
ValueNotReady: (model, key) => `Value ${model}.${key} value is not yet available.`
|
|
658
700
|
});
|
|
701
|
+
/* deprecated - ignore coverage */
|
|
702
|
+
/* istanbul ignore next */
|
|
659
703
|
function pending(source, compute) {
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
704
|
+
if (source === undefined)
|
|
705
|
+
return set();
|
|
706
|
+
if (typeof source == "function" && !source.prototype)
|
|
707
|
+
return set(source);
|
|
708
|
+
return from(source, compute, true);
|
|
665
709
|
}
|
|
666
710
|
/**
|
|
667
711
|
* Get value, suspend instead if undefined.
|
|
@@ -675,6 +719,40 @@ function pendingValue(via, key) {
|
|
|
675
719
|
throw suspend(via, key);
|
|
676
720
|
return value;
|
|
677
721
|
}
|
|
722
|
+
function pendingFactory(via, key, fn) {
|
|
723
|
+
const { subject, state } = via;
|
|
724
|
+
let waiting;
|
|
725
|
+
let error;
|
|
726
|
+
return () => {
|
|
727
|
+
if (waiting)
|
|
728
|
+
throw waiting;
|
|
729
|
+
if (error)
|
|
730
|
+
throw error;
|
|
731
|
+
if (key in state)
|
|
732
|
+
return state[key];
|
|
733
|
+
let output;
|
|
734
|
+
try {
|
|
735
|
+
output = fn.call(subject, key, subject);
|
|
736
|
+
}
|
|
737
|
+
catch (err) {
|
|
738
|
+
throw error = err;
|
|
739
|
+
}
|
|
740
|
+
if (output instanceof Promise) {
|
|
741
|
+
const issue = Oops$4.ValueNotReady(subject, key);
|
|
742
|
+
output
|
|
743
|
+
.catch(err => error = err)
|
|
744
|
+
.then(out => state[key] = out)
|
|
745
|
+
.finally(() => waiting = undefined);
|
|
746
|
+
throw waiting = Object.assign(output, {
|
|
747
|
+
message: issue.message,
|
|
748
|
+
stack: issue.stack
|
|
749
|
+
});
|
|
750
|
+
}
|
|
751
|
+
else {
|
|
752
|
+
return state[key] = output;
|
|
753
|
+
}
|
|
754
|
+
};
|
|
755
|
+
}
|
|
678
756
|
function suspend(source, key) {
|
|
679
757
|
const error = Oops$4.ValueNotReady(source.subject, key);
|
|
680
758
|
const promise = new Promise(resolve => {
|
|
@@ -694,45 +772,6 @@ function suspend(source, key) {
|
|
|
694
772
|
message: error.message,
|
|
695
773
|
stack: error.stack
|
|
696
774
|
});
|
|
697
|
-
}
|
|
698
|
-
function suspendForComputed(source, compute) {
|
|
699
|
-
function getter(_value, key) {
|
|
700
|
-
return pendingValue(manage(this), key);
|
|
701
|
-
}
|
|
702
|
-
return from(source, compute, getter);
|
|
703
|
-
}
|
|
704
|
-
function suspendForValue() {
|
|
705
|
-
return apply(function pending(key) {
|
|
706
|
-
this.state[key] = undefined;
|
|
707
|
-
return {
|
|
708
|
-
set: this.setter(key),
|
|
709
|
-
get: () => pendingValue(this, key)
|
|
710
|
-
};
|
|
711
|
-
});
|
|
712
|
-
}
|
|
713
|
-
function suspendForAsync(source) {
|
|
714
|
-
return apply(function suspense(key) {
|
|
715
|
-
const subject = this.subject;
|
|
716
|
-
let waiting = true;
|
|
717
|
-
let value;
|
|
718
|
-
let error;
|
|
719
|
-
return () => {
|
|
720
|
-
if (error)
|
|
721
|
-
throw error;
|
|
722
|
-
if (!waiting)
|
|
723
|
-
return value;
|
|
724
|
-
const issue = Oops$4.ValueNotReady(subject, key);
|
|
725
|
-
let suspend = source
|
|
726
|
-
.call(subject, key)
|
|
727
|
-
.catch(err => error = err)
|
|
728
|
-
.then(out => value = out)
|
|
729
|
-
.finally(() => waiting = false);
|
|
730
|
-
throw Object.assign(suspend, {
|
|
731
|
-
message: issue.message,
|
|
732
|
-
stack: issue.stack
|
|
733
|
-
});
|
|
734
|
-
};
|
|
735
|
-
});
|
|
736
775
|
}
|
|
737
776
|
|
|
738
777
|
function use$1(init) {
|
|
@@ -973,9 +1012,7 @@ class Model {
|
|
|
973
1012
|
return proxy;
|
|
974
1013
|
}
|
|
975
1014
|
tag(id) {
|
|
976
|
-
const hook = use$1(refresh =>
|
|
977
|
-
return new Subscriber(this, () => refresh);
|
|
978
|
-
});
|
|
1015
|
+
const hook = use$1(refresh => (new Subscriber(this, () => refresh)));
|
|
979
1016
|
useElementLifecycle(hook, id || 0);
|
|
980
1017
|
return hook.proxy;
|
|
981
1018
|
}
|
|
@@ -1023,12 +1060,10 @@ class Model {
|
|
|
1023
1060
|
invoke();
|
|
1024
1061
|
return this.on(select, invoke, true);
|
|
1025
1062
|
}
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
return sub.commit();
|
|
1031
|
-
}
|
|
1063
|
+
const sub = new Subscriber(control, () => invoke);
|
|
1064
|
+
target = sub.proxy;
|
|
1065
|
+
invoke();
|
|
1066
|
+
return sub.commit();
|
|
1032
1067
|
}
|
|
1033
1068
|
import(from, subset) {
|
|
1034
1069
|
for (const key of keys(manage(this), subset))
|
|
@@ -1224,31 +1259,6 @@ function parent(Expects, required) {
|
|
|
1224
1259
|
});
|
|
1225
1260
|
}
|
|
1226
1261
|
|
|
1227
|
-
function on(initial, cb) {
|
|
1228
|
-
return apply(function on(key) {
|
|
1229
|
-
this.manage(key, initial, cb && createValueEffect(cb));
|
|
1230
|
-
});
|
|
1231
|
-
}
|
|
1232
|
-
function memo(factory, defer) {
|
|
1233
|
-
return apply(function memo(key) {
|
|
1234
|
-
const source = this.subject;
|
|
1235
|
-
const get = () => factory.call(source);
|
|
1236
|
-
if (defer)
|
|
1237
|
-
defineLazy(source, key, get);
|
|
1238
|
-
else
|
|
1239
|
-
define(source, key, get());
|
|
1240
|
-
});
|
|
1241
|
-
}
|
|
1242
|
-
function lazy(value) {
|
|
1243
|
-
return apply(function lazy(key) {
|
|
1244
|
-
const source = this.subject;
|
|
1245
|
-
source[key] = value;
|
|
1246
|
-
defineProperty(this.state, key, {
|
|
1247
|
-
get: () => source[key]
|
|
1248
|
-
});
|
|
1249
|
-
});
|
|
1250
|
-
}
|
|
1251
|
-
|
|
1252
1262
|
const Oops = issues({
|
|
1253
1263
|
GlobalDoesNotExist: (name) => `Tried to access singleton ${name}, but none exist! Did you forget to initialize?\nCall ${name}.create() before attempting to access, or consider using ${name}.use() instead.`,
|
|
1254
1264
|
GlobalExists: (name) => `Shared instance of ${name} already exists! Consider unmounting existing, or use ${name}.reset() to force-delete it.`
|
|
@@ -1300,11 +1310,12 @@ exports.child = child;
|
|
|
1300
1310
|
exports["default"] = Model;
|
|
1301
1311
|
exports.from = from;
|
|
1302
1312
|
exports.lazy = lazy;
|
|
1303
|
-
exports.memo =
|
|
1313
|
+
exports.memo = set;
|
|
1304
1314
|
exports.on = on;
|
|
1305
1315
|
exports.parent = parent;
|
|
1306
1316
|
exports.pending = pending;
|
|
1307
1317
|
exports.ref = ref;
|
|
1318
|
+
exports.set = set;
|
|
1308
1319
|
exports.tap = tap;
|
|
1309
1320
|
exports.use = use;
|
|
1310
1321
|
//# sourceMappingURL=index.js.map
|