@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.esm.js
CHANGED
|
@@ -20,7 +20,7 @@ function issues(register) {
|
|
|
20
20
|
return Library;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
const Oops$
|
|
23
|
+
const Oops$9 = issues({
|
|
24
24
|
BadEffectCallback: () => `Callback for effect-callback may only return a function.`
|
|
25
25
|
});
|
|
26
26
|
const { assign, create, defineProperty, entries, getPrototypeOf, getOwnPropertyNames, getOwnPropertyDescriptor, getOwnPropertyDescriptors, getOwnPropertySymbols, keys: keys$1, values } = Object;
|
|
@@ -49,7 +49,7 @@ function createEffect(callback) {
|
|
|
49
49
|
if (unSet instanceof Promise)
|
|
50
50
|
unSet = undefined;
|
|
51
51
|
if (unSet && typeof unSet !== "function")
|
|
52
|
-
throw Oops$
|
|
52
|
+
throw Oops$9.BadEffectCallback();
|
|
53
53
|
};
|
|
54
54
|
}
|
|
55
55
|
function createValueEffect(callback) {
|
|
@@ -65,7 +65,7 @@ function createValueEffect(callback) {
|
|
|
65
65
|
if (typeof out == "function")
|
|
66
66
|
unSet = out;
|
|
67
67
|
else
|
|
68
|
-
throw Oops$
|
|
68
|
+
throw Oops$9.BadEffectCallback();
|
|
69
69
|
};
|
|
70
70
|
}
|
|
71
71
|
function select(source, select) {
|
|
@@ -94,6 +94,13 @@ class Subscriber {
|
|
|
94
94
|
this.active = false;
|
|
95
95
|
this.handle = {};
|
|
96
96
|
this.dependant = new Set();
|
|
97
|
+
this.debug = () => {
|
|
98
|
+
const update = [];
|
|
99
|
+
this.notify = keys => {
|
|
100
|
+
update.splice(0, update.length, ...keys.filter(k => k in this.handle));
|
|
101
|
+
};
|
|
102
|
+
return update;
|
|
103
|
+
};
|
|
97
104
|
this.listen = (key, from) => {
|
|
98
105
|
const handler = this.handle[key];
|
|
99
106
|
if (!handler)
|
|
@@ -103,28 +110,16 @@ class Subscriber {
|
|
|
103
110
|
const notify = this.onUpdate(key, from);
|
|
104
111
|
if (notify)
|
|
105
112
|
from.waiting.add(notify);
|
|
113
|
+
if (this.notify)
|
|
114
|
+
from.waiting.add(this.notify);
|
|
106
115
|
};
|
|
107
116
|
if (!(parent instanceof Controller))
|
|
108
117
|
parent = manage(parent);
|
|
109
|
-
const subject = this.source =
|
|
110
|
-
parent.subject;
|
|
111
|
-
const proxy = this.proxy =
|
|
112
|
-
create(subject);
|
|
113
118
|
this.parent = parent;
|
|
119
|
+
this.source = parent.subject;
|
|
120
|
+
this.proxy = create(parent.subject);
|
|
114
121
|
define(this.proxy, LOCAL, this);
|
|
115
|
-
|
|
116
|
-
get: () => (this.parent.handled.filter(key => key in this.handle))
|
|
117
|
-
});
|
|
118
|
-
if ("update" in subject) {
|
|
119
|
-
define(proxy, "update", (...args) => {
|
|
120
|
-
if (!args.length) {
|
|
121
|
-
const refresh = this.onUpdate("", parent);
|
|
122
|
-
if (refresh)
|
|
123
|
-
refresh([]);
|
|
124
|
-
}
|
|
125
|
-
return subject.update(...args);
|
|
126
|
-
});
|
|
127
|
-
}
|
|
122
|
+
defineLazy(this.proxy, UPDATE, this.debug);
|
|
128
123
|
for (const key in parent.state)
|
|
129
124
|
this.spy(key);
|
|
130
125
|
}
|
|
@@ -158,7 +153,7 @@ class Subscriber {
|
|
|
158
153
|
}
|
|
159
154
|
}
|
|
160
155
|
|
|
161
|
-
const Oops$
|
|
156
|
+
const Oops$8 = issues({
|
|
162
157
|
ComputeFailed: (parent, property, initial) => `An exception was thrown while ${initial ? "initializing" : "refreshing"} [${parent}.${property}].`,
|
|
163
158
|
ComputedEarly: (property) => `Note: Computed values don't run until accessed, except when subscribed to. '${property}' getter may have run earlier than intended.`
|
|
164
159
|
});
|
|
@@ -177,14 +172,14 @@ function prepare(parent, key, source, setter, getter) {
|
|
|
177
172
|
}
|
|
178
173
|
register.set(key, info);
|
|
179
174
|
const current = getter
|
|
180
|
-
? () => getter
|
|
175
|
+
? () => getter(parent, key)
|
|
181
176
|
: () => state[key];
|
|
182
177
|
function compute(initial) {
|
|
183
178
|
try {
|
|
184
179
|
return setter.call(sub.proxy, sub.proxy);
|
|
185
180
|
}
|
|
186
181
|
catch (err) {
|
|
187
|
-
Oops$
|
|
182
|
+
Oops$8.ComputeFailed(subject, key, !!initial).warn();
|
|
188
183
|
throw err;
|
|
189
184
|
}
|
|
190
185
|
}
|
|
@@ -230,7 +225,7 @@ function prepare(parent, key, source, setter, getter) {
|
|
|
230
225
|
}
|
|
231
226
|
catch (e) {
|
|
232
227
|
if (early)
|
|
233
|
-
Oops$
|
|
228
|
+
Oops$8.ComputedEarly(key).warn();
|
|
234
229
|
throw e;
|
|
235
230
|
}
|
|
236
231
|
finally {
|
|
@@ -356,30 +351,16 @@ class Controller {
|
|
|
356
351
|
this.state = {};
|
|
357
352
|
this.frame = new Set();
|
|
358
353
|
this.waiting = new Set();
|
|
359
|
-
this.handled = [];
|
|
360
354
|
this.followers = new Set();
|
|
361
355
|
}
|
|
362
356
|
static setup(onto) {
|
|
363
357
|
const control = new this(onto);
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
defineProperty(onto, STATE, {
|
|
371
|
-
get: () => (Object.assign({}, control.state)),
|
|
372
|
-
configurable: true
|
|
373
|
-
});
|
|
374
|
-
defineProperty(onto, UPDATE, {
|
|
375
|
-
get: () => [...control.handled],
|
|
376
|
-
configurable: true
|
|
377
|
-
});
|
|
378
|
-
control.start();
|
|
379
|
-
if (onto.didCreate)
|
|
380
|
-
onto.didCreate();
|
|
381
|
-
return control;
|
|
382
|
-
}
|
|
358
|
+
defineLazy(onto, CONTROL, () => {
|
|
359
|
+
onto[STATE] = control.state;
|
|
360
|
+
control.start();
|
|
361
|
+
if (onto.didCreate)
|
|
362
|
+
onto.didCreate();
|
|
363
|
+
return control;
|
|
383
364
|
});
|
|
384
365
|
return control;
|
|
385
366
|
}
|
|
@@ -458,14 +439,17 @@ class Controller {
|
|
|
458
439
|
}
|
|
459
440
|
emit() {
|
|
460
441
|
flush(this);
|
|
442
|
+
const keys = Object.freeze([...this.frame]);
|
|
461
443
|
const handle = new Set(this.waiting);
|
|
462
|
-
const handled = this.handled =
|
|
463
|
-
Object.freeze([...this.frame]);
|
|
464
444
|
this.waiting.clear();
|
|
465
445
|
this.frame.clear();
|
|
446
|
+
defineProperty(this.subject, UPDATE, {
|
|
447
|
+
configurable: true,
|
|
448
|
+
value: keys
|
|
449
|
+
});
|
|
466
450
|
handle.forEach(callback => {
|
|
467
451
|
try {
|
|
468
|
-
callback(
|
|
452
|
+
callback(keys);
|
|
469
453
|
}
|
|
470
454
|
catch (e) { }
|
|
471
455
|
});
|
|
@@ -522,6 +506,61 @@ function child(source, name) {
|
|
|
522
506
|
}, name || source.name);
|
|
523
507
|
}
|
|
524
508
|
|
|
509
|
+
const Oops$7 = issues({
|
|
510
|
+
NonOptional: (Parent, key) => `Property ${Parent}.${key} is marked as required.`,
|
|
511
|
+
BadFactory: () => `Set instruction can only accept a factory or undefined.`,
|
|
512
|
+
FactoryFailed: (model, key) => `Generating initial value for ${model}.${key} failed.`
|
|
513
|
+
});
|
|
514
|
+
function lazy(value) {
|
|
515
|
+
return apply(function lazy(key) {
|
|
516
|
+
const source = this.subject;
|
|
517
|
+
source[key] = value;
|
|
518
|
+
defineProperty(this.state, key, {
|
|
519
|
+
get: () => source[key]
|
|
520
|
+
});
|
|
521
|
+
});
|
|
522
|
+
}
|
|
523
|
+
function set(factory, argument) {
|
|
524
|
+
return apply(function set(key) {
|
|
525
|
+
let onSet;
|
|
526
|
+
let onGet;
|
|
527
|
+
const required = argument === true || argument === undefined;
|
|
528
|
+
if (factory === undefined)
|
|
529
|
+
onGet = () => pendingValue(this, key);
|
|
530
|
+
else if (typeof factory !== "function")
|
|
531
|
+
throw Oops$7.BadFactory();
|
|
532
|
+
else {
|
|
533
|
+
onGet = pendingFactory(this, key, factory);
|
|
534
|
+
if (required)
|
|
535
|
+
try {
|
|
536
|
+
onGet();
|
|
537
|
+
}
|
|
538
|
+
catch (err) {
|
|
539
|
+
if (err instanceof Promise)
|
|
540
|
+
;
|
|
541
|
+
else {
|
|
542
|
+
Oops$7.FactoryFailed(this.subject, key).warn();
|
|
543
|
+
throw err;
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
if (typeof argument == "function")
|
|
548
|
+
onSet = createValueEffect(argument);
|
|
549
|
+
else if (required)
|
|
550
|
+
onSet = (value) => {
|
|
551
|
+
if (value === undefined)
|
|
552
|
+
throw Oops$7.NonOptional(this.subject, key);
|
|
553
|
+
};
|
|
554
|
+
return {
|
|
555
|
+
set: this.setter(key, onSet),
|
|
556
|
+
get: onGet
|
|
557
|
+
};
|
|
558
|
+
});
|
|
559
|
+
}
|
|
560
|
+
function on(initial, onUpdate) {
|
|
561
|
+
return set(initial && (() => initial), onUpdate);
|
|
562
|
+
}
|
|
563
|
+
|
|
525
564
|
const Oops$6 = issues({
|
|
526
565
|
CantAttachGlobal: (parent, child) => `Singleton '${parent}' attempted to attach '${child}' but it is not also a singleton.`,
|
|
527
566
|
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.`
|
|
@@ -624,10 +663,13 @@ function act(task) {
|
|
|
624
663
|
};
|
|
625
664
|
});
|
|
626
665
|
}
|
|
627
|
-
function from(source, setter,
|
|
666
|
+
function from(source, setter, argument) {
|
|
628
667
|
return apply(function from(key) {
|
|
629
668
|
const { subject } = this;
|
|
630
669
|
let getSource;
|
|
670
|
+
let getter = argument === true
|
|
671
|
+
? pendingValue
|
|
672
|
+
: argument || undefined;
|
|
631
673
|
// Easy mistake, using a peer, will always be unresolved.
|
|
632
674
|
if (typeof source == "symbol")
|
|
633
675
|
throw Oops$5.PeerNotAllowed(subject, key);
|
|
@@ -642,7 +684,7 @@ function from(source, setter, getter) {
|
|
|
642
684
|
// is a peer Model (constructor)
|
|
643
685
|
else if (Model.isTypeof(source))
|
|
644
686
|
getSource = pendingAccess(subject, source, key, true);
|
|
645
|
-
// Regular function is
|
|
687
|
+
// Regular function is too ambiguous so not allowed.
|
|
646
688
|
else
|
|
647
689
|
throw Oops$5.BadComputedSource(subject, key, source);
|
|
648
690
|
prepare(this, key, getSource, setter, getter);
|
|
@@ -652,12 +694,14 @@ function from(source, setter, getter) {
|
|
|
652
694
|
const Oops$4 = issues({
|
|
653
695
|
ValueNotReady: (model, key) => `Value ${model}.${key} value is not yet available.`
|
|
654
696
|
});
|
|
697
|
+
/* deprecated - ignore coverage */
|
|
698
|
+
/* istanbul ignore next */
|
|
655
699
|
function pending(source, compute) {
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
700
|
+
if (source === undefined)
|
|
701
|
+
return set();
|
|
702
|
+
if (typeof source == "function" && !source.prototype)
|
|
703
|
+
return set(source);
|
|
704
|
+
return from(source, compute, true);
|
|
661
705
|
}
|
|
662
706
|
/**
|
|
663
707
|
* Get value, suspend instead if undefined.
|
|
@@ -671,6 +715,40 @@ function pendingValue(via, key) {
|
|
|
671
715
|
throw suspend(via, key);
|
|
672
716
|
return value;
|
|
673
717
|
}
|
|
718
|
+
function pendingFactory(via, key, fn) {
|
|
719
|
+
const { subject, state } = via;
|
|
720
|
+
let waiting;
|
|
721
|
+
let error;
|
|
722
|
+
return () => {
|
|
723
|
+
if (waiting)
|
|
724
|
+
throw waiting;
|
|
725
|
+
if (error)
|
|
726
|
+
throw error;
|
|
727
|
+
if (key in state)
|
|
728
|
+
return state[key];
|
|
729
|
+
let output;
|
|
730
|
+
try {
|
|
731
|
+
output = fn.call(subject, key, subject);
|
|
732
|
+
}
|
|
733
|
+
catch (err) {
|
|
734
|
+
throw error = err;
|
|
735
|
+
}
|
|
736
|
+
if (output instanceof Promise) {
|
|
737
|
+
const issue = Oops$4.ValueNotReady(subject, key);
|
|
738
|
+
output
|
|
739
|
+
.catch(err => error = err)
|
|
740
|
+
.then(out => state[key] = out)
|
|
741
|
+
.finally(() => waiting = undefined);
|
|
742
|
+
throw waiting = Object.assign(output, {
|
|
743
|
+
message: issue.message,
|
|
744
|
+
stack: issue.stack
|
|
745
|
+
});
|
|
746
|
+
}
|
|
747
|
+
else {
|
|
748
|
+
return state[key] = output;
|
|
749
|
+
}
|
|
750
|
+
};
|
|
751
|
+
}
|
|
674
752
|
function suspend(source, key) {
|
|
675
753
|
const error = Oops$4.ValueNotReady(source.subject, key);
|
|
676
754
|
const promise = new Promise(resolve => {
|
|
@@ -690,45 +768,6 @@ function suspend(source, key) {
|
|
|
690
768
|
message: error.message,
|
|
691
769
|
stack: error.stack
|
|
692
770
|
});
|
|
693
|
-
}
|
|
694
|
-
function suspendForComputed(source, compute) {
|
|
695
|
-
function getter(_value, key) {
|
|
696
|
-
return pendingValue(manage(this), key);
|
|
697
|
-
}
|
|
698
|
-
return from(source, compute, getter);
|
|
699
|
-
}
|
|
700
|
-
function suspendForValue() {
|
|
701
|
-
return apply(function pending(key) {
|
|
702
|
-
this.state[key] = undefined;
|
|
703
|
-
return {
|
|
704
|
-
set: this.setter(key),
|
|
705
|
-
get: () => pendingValue(this, key)
|
|
706
|
-
};
|
|
707
|
-
});
|
|
708
|
-
}
|
|
709
|
-
function suspendForAsync(source) {
|
|
710
|
-
return apply(function suspense(key) {
|
|
711
|
-
const subject = this.subject;
|
|
712
|
-
let waiting = true;
|
|
713
|
-
let value;
|
|
714
|
-
let error;
|
|
715
|
-
return () => {
|
|
716
|
-
if (error)
|
|
717
|
-
throw error;
|
|
718
|
-
if (!waiting)
|
|
719
|
-
return value;
|
|
720
|
-
const issue = Oops$4.ValueNotReady(subject, key);
|
|
721
|
-
let suspend = source
|
|
722
|
-
.call(subject, key)
|
|
723
|
-
.catch(err => error = err)
|
|
724
|
-
.then(out => value = out)
|
|
725
|
-
.finally(() => waiting = false);
|
|
726
|
-
throw Object.assign(suspend, {
|
|
727
|
-
message: issue.message,
|
|
728
|
-
stack: issue.stack
|
|
729
|
-
});
|
|
730
|
-
};
|
|
731
|
-
});
|
|
732
771
|
}
|
|
733
772
|
|
|
734
773
|
function use$1(init) {
|
|
@@ -969,9 +1008,7 @@ class Model {
|
|
|
969
1008
|
return proxy;
|
|
970
1009
|
}
|
|
971
1010
|
tag(id) {
|
|
972
|
-
const hook = use$1(refresh =>
|
|
973
|
-
return new Subscriber(this, () => refresh);
|
|
974
|
-
});
|
|
1011
|
+
const hook = use$1(refresh => (new Subscriber(this, () => refresh)));
|
|
975
1012
|
useElementLifecycle(hook, id || 0);
|
|
976
1013
|
return hook.proxy;
|
|
977
1014
|
}
|
|
@@ -1019,12 +1056,10 @@ class Model {
|
|
|
1019
1056
|
invoke();
|
|
1020
1057
|
return this.on(select, invoke, true);
|
|
1021
1058
|
}
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
return sub.commit();
|
|
1027
|
-
}
|
|
1059
|
+
const sub = new Subscriber(control, () => invoke);
|
|
1060
|
+
target = sub.proxy;
|
|
1061
|
+
invoke();
|
|
1062
|
+
return sub.commit();
|
|
1028
1063
|
}
|
|
1029
1064
|
import(from, subset) {
|
|
1030
1065
|
for (const key of keys(manage(this), subset))
|
|
@@ -1220,31 +1255,6 @@ function parent(Expects, required) {
|
|
|
1220
1255
|
});
|
|
1221
1256
|
}
|
|
1222
1257
|
|
|
1223
|
-
function on(initial, cb) {
|
|
1224
|
-
return apply(function on(key) {
|
|
1225
|
-
this.manage(key, initial, cb && createValueEffect(cb));
|
|
1226
|
-
});
|
|
1227
|
-
}
|
|
1228
|
-
function memo(factory, defer) {
|
|
1229
|
-
return apply(function memo(key) {
|
|
1230
|
-
const source = this.subject;
|
|
1231
|
-
const get = () => factory.call(source);
|
|
1232
|
-
if (defer)
|
|
1233
|
-
defineLazy(source, key, get);
|
|
1234
|
-
else
|
|
1235
|
-
define(source, key, get());
|
|
1236
|
-
});
|
|
1237
|
-
}
|
|
1238
|
-
function lazy(value) {
|
|
1239
|
-
return apply(function lazy(key) {
|
|
1240
|
-
const source = this.subject;
|
|
1241
|
-
source[key] = value;
|
|
1242
|
-
defineProperty(this.state, key, {
|
|
1243
|
-
get: () => source[key]
|
|
1244
|
-
});
|
|
1245
|
-
});
|
|
1246
|
-
}
|
|
1247
|
-
|
|
1248
1258
|
const Oops = issues({
|
|
1249
1259
|
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.`,
|
|
1250
1260
|
GlobalExists: (name) => `Shared instance of ${name} already exists! Consider unmounting existing, or use ${name}.reset() to force-delete it.`
|
|
@@ -1286,5 +1296,5 @@ class Singleton extends Model {
|
|
|
1286
1296
|
}
|
|
1287
1297
|
}
|
|
1288
1298
|
|
|
1289
|
-
export { Consumer, Model, Provider, Singleton, act, apply, child, Model as default, from, lazy, memo, on, parent, pending, ref, tap, use };
|
|
1299
|
+
export { Consumer, Model, Provider, Singleton, act, apply, child, Model as default, from, lazy, set as memo, on, parent, pending, ref, set, tap, use };
|
|
1290
1300
|
//# sourceMappingURL=index.esm.js.map
|