@expressive/mvc 1.0.0-beta.43 → 1.0.0-beta.44
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 +5 -3
- package/lib/index.esm.js +131 -126
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +131 -126
- package/lib/index.js.map +1 -1
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -42,9 +42,6 @@ function defineLazy(object, property, init) {
|
|
|
42
42
|
}
|
|
43
43
|
});
|
|
44
44
|
}
|
|
45
|
-
function setAlias(func, displayName) {
|
|
46
|
-
assign(func, { displayName });
|
|
47
|
-
}
|
|
48
45
|
function createEffect(callback) {
|
|
49
46
|
let unSet;
|
|
50
47
|
return function (value) {
|
|
@@ -152,66 +149,7 @@ class Subscriber {
|
|
|
152
149
|
|
|
153
150
|
const Oops$b = issues({
|
|
154
151
|
ValueNotReady: (model, key) => `Value ${model}.${key} value is not yet available.`,
|
|
155
|
-
FactoryFailed: (model, key) => `Generating initial value for ${model}.${key} failed.`
|
|
156
152
|
});
|
|
157
|
-
/**
|
|
158
|
-
* Get value, suspend instead if undefined.
|
|
159
|
-
*
|
|
160
|
-
* Throws suspense promise also interpretable as an error.
|
|
161
|
-
* React could handle it but other contexts probably not.
|
|
162
|
-
*/
|
|
163
|
-
function pendingValue(via, key) {
|
|
164
|
-
const value = via.state[key];
|
|
165
|
-
if (value === undefined)
|
|
166
|
-
throw suspend(via, key);
|
|
167
|
-
return value;
|
|
168
|
-
}
|
|
169
|
-
function pendingFactory(parent, key, fn, immediate) {
|
|
170
|
-
const { subject, state } = parent;
|
|
171
|
-
let pending;
|
|
172
|
-
let error;
|
|
173
|
-
const init = () => {
|
|
174
|
-
const output = suspenseBoundary(() => {
|
|
175
|
-
return fn.call(subject, key, subject);
|
|
176
|
-
});
|
|
177
|
-
if (output instanceof Promise) {
|
|
178
|
-
pending = output
|
|
179
|
-
.catch(err => error = err)
|
|
180
|
-
.then(val => state[key] = val)
|
|
181
|
-
.finally(() => {
|
|
182
|
-
pending = undefined;
|
|
183
|
-
parent.update(key);
|
|
184
|
-
});
|
|
185
|
-
const issue = Oops$b.ValueNotReady(subject, key);
|
|
186
|
-
Object.assign(pending, {
|
|
187
|
-
message: issue.message,
|
|
188
|
-
stack: issue.stack
|
|
189
|
-
});
|
|
190
|
-
}
|
|
191
|
-
return state[key] = output;
|
|
192
|
-
};
|
|
193
|
-
if (immediate)
|
|
194
|
-
try {
|
|
195
|
-
init();
|
|
196
|
-
}
|
|
197
|
-
catch (err) {
|
|
198
|
-
Oops$b.FactoryFailed(subject, key).warn();
|
|
199
|
-
throw err;
|
|
200
|
-
}
|
|
201
|
-
return () => {
|
|
202
|
-
if (pending)
|
|
203
|
-
throw pending;
|
|
204
|
-
if (error)
|
|
205
|
-
throw error;
|
|
206
|
-
if (key in state)
|
|
207
|
-
return state[key];
|
|
208
|
-
let output = init();
|
|
209
|
-
if (pending)
|
|
210
|
-
throw pending;
|
|
211
|
-
else
|
|
212
|
-
return output;
|
|
213
|
-
};
|
|
214
|
-
}
|
|
215
153
|
function suspend(source, key) {
|
|
216
154
|
const error = Oops$b.ValueNotReady(source.subject, key);
|
|
217
155
|
const promise = new Promise(resolve => {
|
|
@@ -248,9 +186,7 @@ function from(source, arg1, arg2) {
|
|
|
248
186
|
const parent = this;
|
|
249
187
|
const { subject, state } = this;
|
|
250
188
|
let getSource;
|
|
251
|
-
let
|
|
252
|
-
if (arg2 === true || arg1 === true)
|
|
253
|
-
getter = pendingValue;
|
|
189
|
+
let required = arg2 === true || arg1 === true;
|
|
254
190
|
if (typeof arg1 == "boolean")
|
|
255
191
|
arg1 = undefined;
|
|
256
192
|
// Easy mistake, using a peer, will always be unresolved.
|
|
@@ -334,9 +270,6 @@ function from(source, arg1, arg2) {
|
|
|
334
270
|
}
|
|
335
271
|
}
|
|
336
272
|
}
|
|
337
|
-
setAlias(update, `try ${key}`);
|
|
338
|
-
setAlias(create, `new ${key}`);
|
|
339
|
-
setAlias(setter, `run ${key}`);
|
|
340
273
|
INIT.add(create);
|
|
341
274
|
INFO.set(update, info);
|
|
342
275
|
defineProperty(state, key, {
|
|
@@ -344,8 +277,12 @@ function from(source, arg1, arg2) {
|
|
|
344
277
|
configurable: true,
|
|
345
278
|
enumerable: true
|
|
346
279
|
});
|
|
347
|
-
|
|
348
|
-
|
|
280
|
+
return () => {
|
|
281
|
+
const value = parent.state[key];
|
|
282
|
+
if (value === undefined && required)
|
|
283
|
+
throw suspend(this, key);
|
|
284
|
+
return value;
|
|
285
|
+
};
|
|
349
286
|
});
|
|
350
287
|
}
|
|
351
288
|
function ensure(on, keys) {
|
|
@@ -372,7 +309,7 @@ function flush(on) {
|
|
|
372
309
|
}
|
|
373
310
|
|
|
374
311
|
const Oops$9 = issues({
|
|
375
|
-
StrictUpdate: (
|
|
312
|
+
StrictUpdate: () => `Strict update() did not find pending updates.`,
|
|
376
313
|
NoChaining: () => `Then called with undefined; update promise will never catch nor supports chaining.`
|
|
377
314
|
});
|
|
378
315
|
const READY = new WeakSet();
|
|
@@ -402,7 +339,9 @@ class Controller {
|
|
|
402
339
|
return;
|
|
403
340
|
let onGet;
|
|
404
341
|
let onSet;
|
|
342
|
+
let set;
|
|
405
343
|
let enumerable;
|
|
344
|
+
let suspense;
|
|
406
345
|
const instruction = Pending.get(entry);
|
|
407
346
|
if (instruction) {
|
|
408
347
|
Pending.delete(entry);
|
|
@@ -415,31 +354,35 @@ class Controller {
|
|
|
415
354
|
state[key] = desc.value;
|
|
416
355
|
onSet = desc.set;
|
|
417
356
|
onGet = desc.get;
|
|
357
|
+
suspense = desc.suspense;
|
|
418
358
|
enumerable = desc.enumerable;
|
|
419
359
|
}
|
|
420
360
|
}
|
|
421
361
|
else
|
|
422
362
|
state[key] = entry;
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
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);
|
|
428
368
|
const value = state[key];
|
|
429
|
-
if (
|
|
430
|
-
local
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
369
|
+
if (onGet)
|
|
370
|
+
return local
|
|
371
|
+
? onGet(value, local)
|
|
372
|
+
: onGet(value);
|
|
373
|
+
return value;
|
|
374
|
+
};
|
|
434
375
|
defineProperty(subject, key, {
|
|
435
|
-
enumerable,
|
|
436
|
-
set,
|
|
437
|
-
get: onGet
|
|
438
|
-
? () => onGet(state[key])
|
|
439
|
-
: () => state[key]
|
|
376
|
+
enumerable, set, get
|
|
440
377
|
});
|
|
441
378
|
defineProperty(proxy, key, {
|
|
442
|
-
enumerable,
|
|
379
|
+
enumerable, set,
|
|
380
|
+
get() {
|
|
381
|
+
const local = this[LOCAL];
|
|
382
|
+
if (local && !local.watch[key])
|
|
383
|
+
local.watch[key] = true;
|
|
384
|
+
return get(local);
|
|
385
|
+
}
|
|
443
386
|
});
|
|
444
387
|
}
|
|
445
388
|
ref(key, handler) {
|
|
@@ -499,12 +442,12 @@ class Controller {
|
|
|
499
442
|
this.waiting.add(arg);
|
|
500
443
|
return;
|
|
501
444
|
}
|
|
502
|
-
if (
|
|
503
|
-
return Promise.reject(Oops$9.StrictUpdate(
|
|
445
|
+
if (arg === true && this.frame.size < 1)
|
|
446
|
+
return Promise.reject(Oops$9.StrictUpdate());
|
|
504
447
|
return {
|
|
505
448
|
then: (callback) => {
|
|
506
449
|
if (callback)
|
|
507
|
-
if (this.frame.size)
|
|
450
|
+
if (this.frame.size || arg !== false)
|
|
508
451
|
this.waiting.add(callback);
|
|
509
452
|
else
|
|
510
453
|
callback(false);
|
|
@@ -687,17 +630,21 @@ function apply(fn, label) {
|
|
|
687
630
|
const placeholder = Symbol(`${name} instruction`);
|
|
688
631
|
function setup(key) {
|
|
689
632
|
let output = fn.call(this, key, this);
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
633
|
+
switch (typeof output) {
|
|
634
|
+
case "function":
|
|
635
|
+
return { get: output };
|
|
636
|
+
case "object": {
|
|
637
|
+
if ("explicit" in output && output.explicit) {
|
|
638
|
+
defineProperty(this.subject, key, output);
|
|
639
|
+
return false;
|
|
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;
|
|
697
646
|
}
|
|
698
|
-
|
|
699
|
-
output = Object.assign(Object.assign({}, output), { get: recursive(this, key) });
|
|
700
|
-
return output;
|
|
647
|
+
return;
|
|
701
648
|
}
|
|
702
649
|
Pending.set(placeholder, setup);
|
|
703
650
|
return placeholder;
|
|
@@ -753,7 +700,6 @@ function act(task) {
|
|
|
753
700
|
});
|
|
754
701
|
};
|
|
755
702
|
this.state[key] = undefined;
|
|
756
|
-
setAlias(invoke, `run ${key}`);
|
|
757
703
|
defineProperty(invoke, "active", {
|
|
758
704
|
get: () => pending
|
|
759
705
|
});
|
|
@@ -788,20 +734,22 @@ function createRef(key, cb) {
|
|
|
788
734
|
|
|
789
735
|
const Oops$7 = issues({
|
|
790
736
|
NonOptional: (Parent, key) => `Property ${Parent}.${key} is marked as required.`,
|
|
791
|
-
BadFactory: () => `Set instruction can only accept a factory or undefined
|
|
737
|
+
BadFactory: () => `Set instruction can only accept a factory or undefined.`,
|
|
738
|
+
ValueNotReady: (model, key) => `Value ${model}.${key} value is not yet available.`,
|
|
739
|
+
FactoryFailed: (model, key) => `Generating initial value for ${model}.${key} failed.`
|
|
792
740
|
});
|
|
793
741
|
function set(factory, argument) {
|
|
794
742
|
return apply(function set(key) {
|
|
795
743
|
let set;
|
|
796
744
|
let get;
|
|
745
|
+
let suspense;
|
|
797
746
|
const required = argument === true || argument === undefined;
|
|
798
747
|
if (factory === undefined)
|
|
799
|
-
|
|
800
|
-
else if (typeof factory
|
|
801
|
-
throw Oops$7.BadFactory();
|
|
802
|
-
else {
|
|
748
|
+
suspense = true;
|
|
749
|
+
else if (typeof factory === "function")
|
|
803
750
|
get = pendingFactory(this, key, factory, required);
|
|
804
|
-
|
|
751
|
+
else
|
|
752
|
+
throw Oops$7.BadFactory();
|
|
805
753
|
if (typeof argument == "function")
|
|
806
754
|
set = createValueEffect(argument);
|
|
807
755
|
else
|
|
@@ -809,8 +757,63 @@ function set(factory, argument) {
|
|
|
809
757
|
if (value === undefined && required)
|
|
810
758
|
throw Oops$7.NonOptional(this.subject, key);
|
|
811
759
|
};
|
|
812
|
-
return {
|
|
760
|
+
return {
|
|
761
|
+
set,
|
|
762
|
+
get,
|
|
763
|
+
suspense
|
|
764
|
+
};
|
|
813
765
|
});
|
|
766
|
+
}
|
|
767
|
+
function pendingFactory(parent, key, fn, required) {
|
|
768
|
+
const { subject, state } = parent;
|
|
769
|
+
let pending;
|
|
770
|
+
let error;
|
|
771
|
+
const init = () => {
|
|
772
|
+
const output = suspenseBoundary(() => {
|
|
773
|
+
return fn.call(subject, key, subject);
|
|
774
|
+
});
|
|
775
|
+
if (output instanceof Promise) {
|
|
776
|
+
pending = output
|
|
777
|
+
.catch(err => error = err)
|
|
778
|
+
.then(val => state[key] = val)
|
|
779
|
+
.finally(() => {
|
|
780
|
+
pending = undefined;
|
|
781
|
+
parent.update(key);
|
|
782
|
+
});
|
|
783
|
+
return;
|
|
784
|
+
}
|
|
785
|
+
return state[key] = output;
|
|
786
|
+
};
|
|
787
|
+
const suspend = () => {
|
|
788
|
+
if (required === false)
|
|
789
|
+
return undefined;
|
|
790
|
+
const issue = Oops$7.ValueNotReady(subject, key);
|
|
791
|
+
Object.assign(pending, {
|
|
792
|
+
message: issue.message,
|
|
793
|
+
stack: issue.stack
|
|
794
|
+
});
|
|
795
|
+
throw pending;
|
|
796
|
+
};
|
|
797
|
+
if (required)
|
|
798
|
+
try {
|
|
799
|
+
init();
|
|
800
|
+
}
|
|
801
|
+
catch (err) {
|
|
802
|
+
Oops$7.FactoryFailed(subject, key).warn();
|
|
803
|
+
throw err;
|
|
804
|
+
}
|
|
805
|
+
return () => {
|
|
806
|
+
if (pending)
|
|
807
|
+
return suspend();
|
|
808
|
+
if (error)
|
|
809
|
+
throw error;
|
|
810
|
+
if (key in state)
|
|
811
|
+
return state[key];
|
|
812
|
+
let output = init();
|
|
813
|
+
return pending
|
|
814
|
+
? suspend()
|
|
815
|
+
: output;
|
|
816
|
+
};
|
|
814
817
|
}
|
|
815
818
|
|
|
816
819
|
const Parent = new WeakMap();
|
|
@@ -953,24 +956,26 @@ const ContextWasUsed = new WeakMap();
|
|
|
953
956
|
function tap(type, argument) {
|
|
954
957
|
return apply(function tap(key) {
|
|
955
958
|
if ("set" in type)
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
959
|
+
return {
|
|
960
|
+
recursive: true,
|
|
961
|
+
value: type.get()
|
|
962
|
+
};
|
|
963
|
+
const { subject } = this;
|
|
964
|
+
if ("set" in subject.constructor)
|
|
965
|
+
throw Oops$3.CantAttachGlobal(subject, type.name);
|
|
966
|
+
getPending(subject).push(context => {
|
|
967
|
+
let instance = context.get(type);
|
|
968
|
+
if (typeof argument == "function") {
|
|
969
|
+
if (argument(instance) === false)
|
|
970
|
+
instance = undefined;
|
|
971
|
+
}
|
|
972
|
+
else if (!instance && argument)
|
|
973
|
+
throw Oops$3.AmbientRequired(type.name, subject, key);
|
|
974
|
+
this.update(key, instance);
|
|
975
|
+
});
|
|
972
976
|
return {
|
|
973
|
-
recursive: true
|
|
977
|
+
recursive: true,
|
|
978
|
+
suspense: true
|
|
974
979
|
};
|
|
975
980
|
});
|
|
976
981
|
}
|
|
@@ -1268,7 +1273,7 @@ class Global extends MVC {
|
|
|
1268
1273
|
static set(updates) {
|
|
1269
1274
|
const instance = Active.get(this) || this.create();
|
|
1270
1275
|
instance.import(updates);
|
|
1271
|
-
return instance.update();
|
|
1276
|
+
return instance.update(false);
|
|
1272
1277
|
}
|
|
1273
1278
|
static get(arg) {
|
|
1274
1279
|
const instance = Active.get(this);
|