@expressive/mvc 0.0.4 → 0.2.0
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 +35 -11
- package/lib/index.esm.js +79 -74
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +79 -74
- package/lib/index.js.map +1 -1
- package/package.json +2 -2
package/lib/index.d.ts
CHANGED
|
@@ -75,6 +75,11 @@ declare namespace Model {
|
|
|
75
75
|
export type Methods<T> = {
|
|
76
76
|
[K in keyof T]: T[K] extends Ref ? never : T[K] extends Function ? K : never;
|
|
77
77
|
}[keyof T];
|
|
78
|
+
export type Refs<T extends Model> = {
|
|
79
|
+
<K extends Field<T>>(key: K, value: T[K]): void;
|
|
80
|
+
} & {
|
|
81
|
+
[P in Field<T>]: (next: any) => void;
|
|
82
|
+
};
|
|
78
83
|
/**
|
|
79
84
|
* Subset of `keyof T` which are not methods or defined by base Model U.
|
|
80
85
|
*
|
|
@@ -107,14 +112,23 @@ interface Model extends Stateful {
|
|
|
107
112
|
* Circular reference to `this` controller.
|
|
108
113
|
*
|
|
109
114
|
* Useful to obtain full reference where one has already destructured.
|
|
115
|
+
*
|
|
116
|
+
* @deprecated will be removed in favor of `is`
|
|
110
117
|
*/
|
|
111
118
|
get: this;
|
|
112
119
|
/**
|
|
113
|
-
|
|
120
|
+
* Circular reference to `this` controller.
|
|
121
|
+
*
|
|
122
|
+
* Useful to obtain full reference where one has already destructured.
|
|
123
|
+
*/
|
|
124
|
+
is: this;
|
|
125
|
+
/**
|
|
126
|
+
* Setter utility
|
|
114
127
|
*
|
|
115
|
-
*
|
|
128
|
+
* Can be used to set (and force-update) values.
|
|
129
|
+
* Shortcut to update values, contains refs for all controlled values.
|
|
116
130
|
*/
|
|
117
|
-
set: this
|
|
131
|
+
set: Model.Refs<this>;
|
|
118
132
|
}
|
|
119
133
|
declare class Model {
|
|
120
134
|
static [CONTROL]: Controller;
|
|
@@ -186,7 +200,7 @@ declare class Controller<T extends Stateful = any> {
|
|
|
186
200
|
constructor(subject: T);
|
|
187
201
|
start(): void;
|
|
188
202
|
stop(): void;
|
|
189
|
-
|
|
203
|
+
manage(key: Model.Field<T>, value: any): void;
|
|
190
204
|
ref(key: Model.Field<T>, handler?: Controller.OnValue<T>): (value: any) => void;
|
|
191
205
|
addListener(listener: Controller.OnEvent<T>): () => void;
|
|
192
206
|
emit(keys: readonly Model.Event<T>[]): void;
|
|
@@ -458,8 +472,10 @@ declare class MVC extends Model {
|
|
|
458
472
|
|
|
459
473
|
declare namespace Consumer {
|
|
460
474
|
type HasProps<E extends Class> = {
|
|
475
|
+
/** @deprecated - use for instead */
|
|
476
|
+
of?: never;
|
|
461
477
|
/** Type of controller to fetch from context. */
|
|
462
|
-
|
|
478
|
+
for: E;
|
|
463
479
|
/**
|
|
464
480
|
* Getter function. Is called on every natural render of this component.
|
|
465
481
|
* Will throw if usable instance cannot be found in context.
|
|
@@ -467,14 +483,18 @@ declare namespace Consumer {
|
|
|
467
483
|
has: (value: InstanceType<E>) => void;
|
|
468
484
|
};
|
|
469
485
|
type GetProps<E extends Class> = {
|
|
486
|
+
/** @deprecated - use for instead */
|
|
487
|
+
of?: never;
|
|
470
488
|
/** Type of controller to fetch from context. */
|
|
471
|
-
|
|
489
|
+
for: E;
|
|
472
490
|
/** Getter function. Is called on every natural render of this component. */
|
|
473
491
|
get: (value: InstanceType<E> | undefined) => void;
|
|
474
492
|
};
|
|
475
493
|
type RenderProps<E extends Class> = {
|
|
494
|
+
/** @deprecated - use for instead */
|
|
495
|
+
of?: never;
|
|
476
496
|
/** Type of controller to fetch from context. */
|
|
477
|
-
|
|
497
|
+
for: E;
|
|
478
498
|
/**
|
|
479
499
|
* Render function, will receive instance of desired controller.
|
|
480
500
|
*
|
|
@@ -507,11 +527,15 @@ declare namespace Provider {
|
|
|
507
527
|
};
|
|
508
528
|
type Existent<E> = E extends Class ? InstanceType<E> : E extends Model ? E : never;
|
|
509
529
|
type NormalProps<E, I = Existent<E>> = {
|
|
510
|
-
|
|
530
|
+
/** @deprecated use for instead. */
|
|
531
|
+
of?: never;
|
|
532
|
+
for: E;
|
|
511
533
|
children: React.ReactNode | ((instance: I) => React.ReactNode);
|
|
512
534
|
} & Model.Compat<I>;
|
|
513
535
|
type MultipleProps<T extends Item> = {
|
|
514
|
-
|
|
536
|
+
/** @deprecated use for instead. */
|
|
537
|
+
of?: never;
|
|
538
|
+
for: Collection<T>;
|
|
515
539
|
children?: React.ReactNode | (() => React.ReactNode);
|
|
516
540
|
} & Model.Compat<Existent<T>>;
|
|
517
541
|
type Props<T extends Item> = MultipleProps<T> | NormalProps<T>;
|
|
@@ -575,7 +599,7 @@ declare function tap<T extends Class>(Type: T, required?: boolean): InstanceOf<T
|
|
|
575
599
|
declare function useFrom<T extends Stateful, R>(source: (() => T) | T, compute: (this: T, from: T) => R, expect: true): Exclude<R, undefined>;
|
|
576
600
|
declare function useFrom<T extends Stateful, R>(source: (() => T) | T, compute: (this: T, from: T) => R, expect?: boolean): R;
|
|
577
601
|
|
|
578
|
-
declare function
|
|
602
|
+
declare function useLocal<T extends typeof Model>(Type: T, arg?: boolean | string): any;
|
|
579
603
|
|
|
580
604
|
declare function useModel<T extends Class, I extends InstanceOf<T>>(source: T, watch: Model.Field<I>[], callback?: (instance: I) => void): I;
|
|
581
605
|
declare function useModel<T extends Class, I extends InstanceOf<T>>(source: T, callback?: (instance: I) => void): I;
|
|
@@ -597,4 +621,4 @@ declare function useTap<T extends Stateful, K extends Model.Field<T>>(source: T
|
|
|
597
621
|
declare function useTap<T extends Stateful, R>(source: T | (() => T) | useTap.Tappable, compute: (this: T, from: T) => R, expect: true): Exclude<R, undefined>;
|
|
598
622
|
declare function useTap<T extends Stateful, R>(source: T | (() => T) | useTap.Tappable, compute: (this: T, from: T) => R, expect?: boolean): R;
|
|
599
623
|
|
|
600
|
-
export { CONTROL, Consumer, Global, LOCAL, MVC as Model, Provider, STATE, Stateful, WHY, act, apply, array, MVC as default, from, parent, ref, set, tap, use, useFrom,
|
|
624
|
+
export { CONTROL, Consumer, Global, LOCAL, MVC as Model, Provider, STATE, Stateful, WHY, act, apply, array, MVC as default, from, parent, ref, set, tap, use, useFrom, useLocal, useModel, useTap };
|
package/lib/index.esm.js
CHANGED
|
@@ -43,10 +43,10 @@ function issues(register) {
|
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
const Oops$c = issues({
|
|
46
|
-
|
|
46
|
+
NotReady: (model, key) => `Value ${model}.${key} value is not yet available.`,
|
|
47
47
|
});
|
|
48
48
|
function suspend(source, key) {
|
|
49
|
-
const error = Oops$c.
|
|
49
|
+
const error = Oops$c.NotReady(source.subject, key);
|
|
50
50
|
const promise = new Promise(resolve => {
|
|
51
51
|
const release = source.addListener(forKey => {
|
|
52
52
|
if (forKey == key)
|
|
@@ -87,7 +87,7 @@ function mayRetry(fn) {
|
|
|
87
87
|
}
|
|
88
88
|
|
|
89
89
|
const Oops$b = issues({
|
|
90
|
-
|
|
90
|
+
BadCallback: () => `Callback for effect-callback may only return a function.`
|
|
91
91
|
});
|
|
92
92
|
const { assign, create, defineProperty, entries, getPrototypeOf, getOwnPropertyNames, getOwnPropertyDescriptor, getOwnPropertySymbols, values } = Object;
|
|
93
93
|
function define(target, key, value) {
|
|
@@ -112,7 +112,7 @@ function createEffect(callback) {
|
|
|
112
112
|
if (unSet instanceof Promise)
|
|
113
113
|
unSet = undefined;
|
|
114
114
|
if (unSet && typeof unSet !== "function")
|
|
115
|
-
throw Oops$b.
|
|
115
|
+
throw Oops$b.BadCallback();
|
|
116
116
|
};
|
|
117
117
|
}
|
|
118
118
|
function createValueEffect(callback) {
|
|
@@ -128,7 +128,7 @@ function createValueEffect(callback) {
|
|
|
128
128
|
if (typeof out == "function")
|
|
129
129
|
unSet = out;
|
|
130
130
|
else
|
|
131
|
-
throw Oops$b.
|
|
131
|
+
throw Oops$b.BadCallback();
|
|
132
132
|
};
|
|
133
133
|
}
|
|
134
134
|
|
|
@@ -150,7 +150,16 @@ class Model {
|
|
|
150
150
|
constructor() {
|
|
151
151
|
define(this, CONTROL, new Controller(this));
|
|
152
152
|
define(this, "get", this);
|
|
153
|
-
define(this, "
|
|
153
|
+
define(this, "is", this);
|
|
154
|
+
defineLazy(this, "set", () => {
|
|
155
|
+
const controller = control(this);
|
|
156
|
+
const assign = (key, value) => {
|
|
157
|
+
controller.update(key, value);
|
|
158
|
+
};
|
|
159
|
+
for (const key of getOwnPropertyNames(controller.proxy))
|
|
160
|
+
define(assign, key, controller.ref(key));
|
|
161
|
+
return assign;
|
|
162
|
+
});
|
|
154
163
|
}
|
|
155
164
|
get [STATE]() {
|
|
156
165
|
return this[CONTROL].state;
|
|
@@ -287,10 +296,7 @@ class Model {
|
|
|
287
296
|
return (typeof maybe == "function" &&
|
|
288
297
|
maybe.prototype instanceof this);
|
|
289
298
|
}
|
|
290
|
-
}
|
|
291
|
-
defineLazy(Model, CONTROL, function () {
|
|
292
|
-
return new Controller(this);
|
|
293
|
-
});
|
|
299
|
+
}
|
|
294
300
|
|
|
295
301
|
class Subscriber {
|
|
296
302
|
constructor(target, onUpdate) {
|
|
@@ -339,10 +345,10 @@ class Subscriber {
|
|
|
339
345
|
}
|
|
340
346
|
|
|
341
347
|
const Oops$a = issues({
|
|
342
|
-
|
|
348
|
+
BadSource: (model, property, got) => `Bad from-instruction provided to ${model}.${property}. Expects an arrow-function or a Model as source. Got ${got}.`,
|
|
343
349
|
PeerNotAllowed: (model, property) => `Attempted to use an instruction result (probably use or tap) as computed source for ${model}.${property}. This is not possible.`,
|
|
344
|
-
|
|
345
|
-
|
|
350
|
+
Failed: (parent, property, initial) => `An exception was thrown while ${initial ? "initializing" : "refreshing"} [${parent}.${property}].`,
|
|
351
|
+
Early: (property) => `Note: Computed values don't run until accessed, except when subscribed to. '${property}' getter may have run earlier than intended.`
|
|
346
352
|
});
|
|
347
353
|
const INIT = new WeakSet();
|
|
348
354
|
const INFO = new WeakMap();
|
|
@@ -369,7 +375,7 @@ function from(source, arg1, arg2) {
|
|
|
369
375
|
}
|
|
370
376
|
// Regular function is too ambiguous so not allowed.
|
|
371
377
|
else
|
|
372
|
-
throw Oops$a.
|
|
378
|
+
throw Oops$a.BadSource(subject, key, source);
|
|
373
379
|
let sub;
|
|
374
380
|
const setter = arg1;
|
|
375
381
|
const info = { key, parent, priority: 1 };
|
|
@@ -384,7 +390,7 @@ function from(source, arg1, arg2) {
|
|
|
384
390
|
return setter.call(sub.proxy, sub.proxy);
|
|
385
391
|
}
|
|
386
392
|
catch (err) {
|
|
387
|
-
Oops$a.
|
|
393
|
+
Oops$a.Failed(subject, key, !!initial).warn();
|
|
388
394
|
throw err;
|
|
389
395
|
}
|
|
390
396
|
}
|
|
@@ -425,7 +431,7 @@ function from(source, arg1, arg2) {
|
|
|
425
431
|
}
|
|
426
432
|
catch (e) {
|
|
427
433
|
if (early)
|
|
428
|
-
Oops$a.
|
|
434
|
+
Oops$a.Early(key).warn();
|
|
429
435
|
throw e;
|
|
430
436
|
}
|
|
431
437
|
finally {
|
|
@@ -492,26 +498,28 @@ class Controller {
|
|
|
492
498
|
this.proxy = Object.create(subject);
|
|
493
499
|
}
|
|
494
500
|
start() {
|
|
495
|
-
|
|
496
|
-
|
|
501
|
+
READY.add(this);
|
|
502
|
+
for (const key in this.subject) {
|
|
503
|
+
const { value: entry } = getOwnPropertyDescriptor(this.subject, key);
|
|
504
|
+
if (typeof entry == "function")
|
|
505
|
+
continue;
|
|
506
|
+
if (typeof entry == "symbol") {
|
|
507
|
+
const instruction = PENDING.get(entry);
|
|
508
|
+
if (instruction)
|
|
509
|
+
instruction.call(this, key, this);
|
|
510
|
+
continue;
|
|
511
|
+
}
|
|
512
|
+
this.manage(key, entry);
|
|
513
|
+
}
|
|
497
514
|
this.emit([]);
|
|
498
515
|
}
|
|
499
516
|
stop() {
|
|
500
517
|
this.followers.clear();
|
|
501
518
|
this.onDestroy.forEach(x => x());
|
|
502
519
|
}
|
|
503
|
-
manage(key) {
|
|
520
|
+
manage(key, value) {
|
|
504
521
|
const { proxy, state, subject } = this;
|
|
505
|
-
|
|
506
|
-
if (typeof entry == "function")
|
|
507
|
-
return;
|
|
508
|
-
if (typeof entry == "symbol") {
|
|
509
|
-
const instruction = PENDING.get(entry);
|
|
510
|
-
if (instruction)
|
|
511
|
-
instruction.call(this, key, this);
|
|
512
|
-
return;
|
|
513
|
-
}
|
|
514
|
-
state[key] = entry;
|
|
522
|
+
state[key] = value;
|
|
515
523
|
const set = this.ref(key);
|
|
516
524
|
defineProperty(subject, key, {
|
|
517
525
|
enumerable: false,
|
|
@@ -603,26 +611,20 @@ class Controller {
|
|
|
603
611
|
}
|
|
604
612
|
function control(subject, cb) {
|
|
605
613
|
let control = subject[CONTROL];
|
|
606
|
-
const ready = READY.has(control);
|
|
607
614
|
if (!control) {
|
|
608
615
|
control = new Controller(subject);
|
|
609
616
|
define(subject, CONTROL, control);
|
|
610
617
|
}
|
|
611
|
-
|
|
612
|
-
if (!ready) {
|
|
613
|
-
READY.add(control);
|
|
614
|
-
control.start();
|
|
615
|
-
}
|
|
616
|
-
return control;
|
|
617
|
-
}
|
|
618
|
+
const ready = READY.has(control);
|
|
618
619
|
if (!ready) {
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
done = cb(control);
|
|
622
|
-
|
|
623
|
-
|
|
620
|
+
if (cb) {
|
|
621
|
+
let done;
|
|
622
|
+
control.requestUpdate(() => done = cb(control));
|
|
623
|
+
return () => done && done();
|
|
624
|
+
}
|
|
625
|
+
control.start();
|
|
624
626
|
}
|
|
625
|
-
return cb(control);
|
|
627
|
+
return cb ? cb(control) : control;
|
|
626
628
|
}
|
|
627
629
|
|
|
628
630
|
function apply(fn, label) {
|
|
@@ -710,14 +712,14 @@ function forSubscriber(fn) {
|
|
|
710
712
|
}
|
|
711
713
|
|
|
712
714
|
const Oops$8 = issues({
|
|
713
|
-
|
|
715
|
+
DuplicatePending: (key) => `Invoked action ${key} but one is already active.`
|
|
714
716
|
});
|
|
715
717
|
function act(task) {
|
|
716
718
|
return apply(function act(key) {
|
|
717
719
|
let pending = false;
|
|
718
720
|
const invoke = (...args) => __awaiter(this, void 0, void 0, function* () {
|
|
719
721
|
if (pending)
|
|
720
|
-
return Promise.reject(Oops$8.
|
|
722
|
+
return Promise.reject(Oops$8.DuplicatePending(key));
|
|
721
723
|
pending = true;
|
|
722
724
|
this.update(key);
|
|
723
725
|
try {
|
|
@@ -823,8 +825,8 @@ function createRef(key, cb) {
|
|
|
823
825
|
const Oops$7 = issues({
|
|
824
826
|
NonOptional: (Parent, key) => `Property ${Parent}.${key} is marked as required.`,
|
|
825
827
|
BadFactory: () => `Set instruction can only accept a factory or undefined.`,
|
|
826
|
-
|
|
827
|
-
|
|
828
|
+
NotReady: (model, key) => `Value ${model}.${key} value is not yet available.`,
|
|
829
|
+
Failed: (model, key) => `Generating initial value for ${model}.${key} failed.`
|
|
828
830
|
});
|
|
829
831
|
function set(factory, argument) {
|
|
830
832
|
return apply(function set(key) {
|
|
@@ -875,7 +877,7 @@ function pendingFactory(parent, key, fn, required) {
|
|
|
875
877
|
const suspend = () => {
|
|
876
878
|
if (required === false)
|
|
877
879
|
return undefined;
|
|
878
|
-
const issue = Oops$7.
|
|
880
|
+
const issue = Oops$7.NotReady(subject, key);
|
|
879
881
|
Object.assign(pending, {
|
|
880
882
|
message: issue.message,
|
|
881
883
|
stack: issue.stack
|
|
@@ -887,7 +889,7 @@ function pendingFactory(parent, key, fn, required) {
|
|
|
887
889
|
init();
|
|
888
890
|
}
|
|
889
891
|
catch (err) {
|
|
890
|
-
Oops$7.
|
|
892
|
+
Oops$7.Failed(subject, key).warn();
|
|
891
893
|
throw err;
|
|
892
894
|
}
|
|
893
895
|
return () => {
|
|
@@ -906,8 +908,8 @@ function pendingFactory(parent, key, fn, required) {
|
|
|
906
908
|
|
|
907
909
|
const Parent = new WeakMap();
|
|
908
910
|
const Oops$6 = issues({
|
|
909
|
-
|
|
910
|
-
|
|
911
|
+
Required: (expects, child) => `New ${child} created standalone but requires parent of type ${expects}. Did you remember to create via use(${child})?`,
|
|
912
|
+
Unexpected: (expects, child, got) => `New ${child} created as child of ${got}, but must be instanceof ${expects}.`,
|
|
911
913
|
});
|
|
912
914
|
function parent(Expects, required) {
|
|
913
915
|
return apply(function parent() {
|
|
@@ -916,10 +918,10 @@ function parent(Expects, required) {
|
|
|
916
918
|
const expected = Expects.name;
|
|
917
919
|
if (!value) {
|
|
918
920
|
if (required !== false)
|
|
919
|
-
throw Oops$6.
|
|
921
|
+
throw Oops$6.Required(expected, child);
|
|
920
922
|
}
|
|
921
923
|
else if (!(value instanceof Expects))
|
|
922
|
-
throw Oops$6.
|
|
924
|
+
throw Oops$6.Unexpected(expected, child, value);
|
|
923
925
|
return { value };
|
|
924
926
|
});
|
|
925
927
|
}
|
|
@@ -1024,19 +1026,19 @@ class Lookup {
|
|
|
1024
1026
|
const LookupContext = React.createContext(new Lookup());
|
|
1025
1027
|
const useLookup = () => React.useContext(LookupContext);
|
|
1026
1028
|
const Oops$4 = issues({
|
|
1027
|
-
|
|
1029
|
+
NotFound: (name) => `Couldn't find ${name} in context; did you forget to use a Provider?`
|
|
1028
1030
|
});
|
|
1029
|
-
function
|
|
1031
|
+
function useLocal(Type, arg) {
|
|
1030
1032
|
const instance = useLookup().get(Type);
|
|
1031
1033
|
if (!instance && arg !== false)
|
|
1032
|
-
throw Oops$4.
|
|
1034
|
+
throw Oops$4.NotFound(Type.name);
|
|
1033
1035
|
return typeof arg == "string" ?
|
|
1034
1036
|
instance[arg] :
|
|
1035
1037
|
instance;
|
|
1036
1038
|
}
|
|
1037
1039
|
|
|
1038
1040
|
const Oops$3 = issues({
|
|
1039
|
-
|
|
1041
|
+
NotAllowed: (parent, child) => `Global '${parent}' attempted to attach '${child}' but it is not also a singleton.`,
|
|
1040
1042
|
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.`
|
|
1041
1043
|
});
|
|
1042
1044
|
const PendingContext = new WeakMap();
|
|
@@ -1050,7 +1052,7 @@ function tap(type, argument) {
|
|
|
1050
1052
|
};
|
|
1051
1053
|
const { subject } = this;
|
|
1052
1054
|
if ("set" in subject.constructor)
|
|
1053
|
-
throw Oops$3.
|
|
1055
|
+
throw Oops$3.NotAllowed(subject, type.name);
|
|
1054
1056
|
getPending(subject).push(context => {
|
|
1055
1057
|
let instance = context.get(type);
|
|
1056
1058
|
if (typeof argument == "function") {
|
|
@@ -1194,7 +1196,7 @@ function useTap(source, path, expect) {
|
|
|
1194
1196
|
if ("get" in source)
|
|
1195
1197
|
return () => source.get();
|
|
1196
1198
|
if ("prototype" in source)
|
|
1197
|
-
return () =>
|
|
1199
|
+
return () => useLocal(source);
|
|
1198
1200
|
else
|
|
1199
1201
|
return source;
|
|
1200
1202
|
}, [])();
|
|
@@ -1229,7 +1231,7 @@ class MVC extends Model {
|
|
|
1229
1231
|
return useModel(this, arg, callback);
|
|
1230
1232
|
}
|
|
1231
1233
|
static get(required) {
|
|
1232
|
-
return
|
|
1234
|
+
return useLocal(this, required);
|
|
1233
1235
|
}
|
|
1234
1236
|
static tap(key, expect) {
|
|
1235
1237
|
return useTap(this, key, expect);
|
|
@@ -1275,25 +1277,28 @@ class MVC extends Model {
|
|
|
1275
1277
|
}
|
|
1276
1278
|
|
|
1277
1279
|
const Oops$2 = issues({
|
|
1278
|
-
|
|
1280
|
+
BadProps: () => `Provider expects either a render function, 'get' or 'has' props.`
|
|
1279
1281
|
});
|
|
1280
1282
|
function Consumer(props) {
|
|
1281
|
-
const { get, has, children,
|
|
1283
|
+
const { get, has, children, for: type } = props;
|
|
1282
1284
|
if (typeof children == "function")
|
|
1283
|
-
return children(useTap(
|
|
1285
|
+
return children(useTap(type));
|
|
1284
1286
|
const callback = has || get;
|
|
1285
1287
|
if (typeof callback == "function")
|
|
1286
|
-
callback(
|
|
1288
|
+
callback(useLocal(type, !!has));
|
|
1287
1289
|
else
|
|
1288
|
-
throw Oops$2.
|
|
1290
|
+
throw Oops$2.BadProps();
|
|
1289
1291
|
return null;
|
|
1290
1292
|
}
|
|
1291
1293
|
|
|
1292
1294
|
const Oops$1 = issues({
|
|
1293
|
-
|
|
1295
|
+
NoType: () => "Provider 'of' prop must be Model, typeof Model or a collection of them.",
|
|
1296
|
+
PropDeprecated: () => "Provider `of` prop is deprecated, use `for` instead."
|
|
1294
1297
|
});
|
|
1295
1298
|
function Provider(props) {
|
|
1296
|
-
|
|
1299
|
+
if ("of" in props)
|
|
1300
|
+
throw Oops$1.PropDeprecated();
|
|
1301
|
+
const context = useNewContext(props.for);
|
|
1297
1302
|
const render = props.children;
|
|
1298
1303
|
useAppliedProps(context, props);
|
|
1299
1304
|
React.useLayoutEffect(() => () => context.pop(), []);
|
|
@@ -1305,7 +1310,7 @@ function useNewContext(inject) {
|
|
|
1305
1310
|
const from = useLookup();
|
|
1306
1311
|
return React.useMemo(() => {
|
|
1307
1312
|
if (!inject)
|
|
1308
|
-
throw Oops$1.
|
|
1313
|
+
throw Oops$1.NoType();
|
|
1309
1314
|
const context = from.push(inject);
|
|
1310
1315
|
for (const instance of context.local)
|
|
1311
1316
|
if (instance)
|
|
@@ -1319,7 +1324,7 @@ function useAppliedProps(within, props) {
|
|
|
1319
1324
|
const targets = within.local;
|
|
1320
1325
|
return function integrate(props) {
|
|
1321
1326
|
for (const [key, value] of entries(props))
|
|
1322
|
-
if (
|
|
1327
|
+
if (["of", "for", "children"].indexOf(key) < 0)
|
|
1323
1328
|
for (const into of targets)
|
|
1324
1329
|
if (into && key in into)
|
|
1325
1330
|
into[key] = value;
|
|
@@ -1340,15 +1345,15 @@ function RenderFunction(props) {
|
|
|
1340
1345
|
}
|
|
1341
1346
|
|
|
1342
1347
|
const Oops = issues({
|
|
1343
|
-
|
|
1344
|
-
|
|
1348
|
+
DoesNotExist: (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.`,
|
|
1349
|
+
AlreadyExists: (name) => `Shared instance of ${name} already exists! Consider unmounting existing, or use ${name}.reset() to force-delete it.`
|
|
1345
1350
|
});
|
|
1346
1351
|
const Active = new WeakMap();
|
|
1347
1352
|
class Global extends MVC {
|
|
1348
1353
|
static create(...args) {
|
|
1349
1354
|
const Type = this;
|
|
1350
1355
|
if (Active.has(Type))
|
|
1351
|
-
throw Oops.
|
|
1356
|
+
throw Oops.AlreadyExists(this.name);
|
|
1352
1357
|
const instance = super.create(...args);
|
|
1353
1358
|
Active.set(Type, instance);
|
|
1354
1359
|
return instance;
|
|
@@ -1366,7 +1371,7 @@ class Global extends MVC {
|
|
|
1366
1371
|
static get(arg) {
|
|
1367
1372
|
const instance = Active.get(this);
|
|
1368
1373
|
if (!instance && arg !== false)
|
|
1369
|
-
throw Oops.
|
|
1374
|
+
throw Oops.DoesNotExist(this.name);
|
|
1370
1375
|
return (typeof arg == "string" ?
|
|
1371
1376
|
instance[arg] :
|
|
1372
1377
|
instance);
|
|
@@ -1383,5 +1388,5 @@ class Global extends MVC {
|
|
|
1383
1388
|
}
|
|
1384
1389
|
}
|
|
1385
1390
|
|
|
1386
|
-
export { CONTROL, Consumer, Global, LOCAL, MVC as Model, Provider, STATE, WHY, act, apply, array, MVC as default, from, parent, ref, set, tap, use$1 as use, useFrom,
|
|
1391
|
+
export { CONTROL, Consumer, Global, LOCAL, MVC as Model, Provider, STATE, WHY, act, apply, array, MVC as default, from, parent, ref, set, tap, use$1 as use, useFrom, useLocal, useModel, useTap };
|
|
1387
1392
|
//# sourceMappingURL=index.esm.js.map
|