@expressive/mvc 0.21.2 → 0.21.3
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 +25 -20
- package/lib/index.esm.js +45 -41
- package/lib/index.js +45 -41
- package/package.json +1 -1
package/lib/index.d.ts
CHANGED
|
@@ -16,6 +16,26 @@ declare function run<S>(action: Async<S>): typeof action & {
|
|
|
16
16
|
active: boolean;
|
|
17
17
|
};
|
|
18
18
|
|
|
19
|
+
declare namespace Context {
|
|
20
|
+
type Inputs = {
|
|
21
|
+
[key: string | number]: Model | Model.New;
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
declare class Context {
|
|
25
|
+
/** Use */
|
|
26
|
+
key: string;
|
|
27
|
+
private table;
|
|
28
|
+
private layer;
|
|
29
|
+
private has;
|
|
30
|
+
get<T extends Model>(Type: Model.Type<T>): T | undefined;
|
|
31
|
+
include(inputs: Context.Inputs): Map<Model, boolean>;
|
|
32
|
+
/** Context must force-reset becasue inputs are no longer safe. */
|
|
33
|
+
private bailout;
|
|
34
|
+
add<T extends Model>(input: T | Model.New<T>, implicit?: boolean): T;
|
|
35
|
+
push(): this;
|
|
36
|
+
pop(): void;
|
|
37
|
+
}
|
|
38
|
+
|
|
19
39
|
type Callback = () => void;
|
|
20
40
|
|
|
21
41
|
declare global {
|
|
@@ -50,18 +70,19 @@ declare namespace Control {
|
|
|
50
70
|
* Returned callback is forwarded.
|
|
51
71
|
*/
|
|
52
72
|
type OnReady<T extends Model> = (control: Control<T>) => Callback | void;
|
|
53
|
-
type
|
|
73
|
+
type RequestRefresh = (update: (tick: number) => number) => void;
|
|
74
|
+
type HasHook = (type: typeof Model, relativeTo: Model, callback: (got: Model | undefined) => void) => void;
|
|
75
|
+
type GetAdapter<T> = (refresh: RequestRefresh, context: Context) => {
|
|
54
76
|
mount: () => (() => void) | void;
|
|
55
77
|
render: () => T;
|
|
56
78
|
} | void;
|
|
57
|
-
type GetHook = <T
|
|
58
|
-
type UseAdapter<T extends Model> = (
|
|
79
|
+
type GetHook = <T>(adapter: GetAdapter<T>) => T | null;
|
|
80
|
+
type UseAdapter<T extends Model> = (refresh: RequestRefresh) => {
|
|
59
81
|
instance: T;
|
|
60
82
|
mount: () => (() => void) | void;
|
|
61
83
|
render: (props: Model.Compat<T>) => T;
|
|
62
84
|
};
|
|
63
85
|
type UseHook = <T extends Model>(adapter: UseAdapter<T>) => (props: Model.Compat<T>) => T;
|
|
64
|
-
type HasHook = (type: typeof Model, relativeTo: Model, callback: (got: Model | undefined) => void) => void;
|
|
65
86
|
}
|
|
66
87
|
declare class Control<T extends Model = any> {
|
|
67
88
|
subject: T;
|
|
@@ -381,20 +402,4 @@ declare function use<T extends Model>(from: () => Promise<T> | T, callback?: (i:
|
|
|
381
402
|
*/
|
|
382
403
|
declare function use<T extends Model>(peer: T, callback?: (i: T) => void): T;
|
|
383
404
|
|
|
384
|
-
declare namespace Context {
|
|
385
|
-
type Inputs = {
|
|
386
|
-
[key: string | number]: Model | Model.New;
|
|
387
|
-
};
|
|
388
|
-
}
|
|
389
|
-
declare class Context {
|
|
390
|
-
private table;
|
|
391
|
-
private layer;
|
|
392
|
-
private has;
|
|
393
|
-
get<T extends Model>(Type: Model.Type<T>): T | undefined;
|
|
394
|
-
include(inputs: Context.Inputs): Map<Model, boolean>;
|
|
395
|
-
add<T extends Model>(input: T | Model.New<T>, implicit?: boolean): T;
|
|
396
|
-
push(): this;
|
|
397
|
-
pop(): void;
|
|
398
|
-
}
|
|
399
|
-
|
|
400
405
|
export { Context, Control, Debug, Model, Model as default, get, ref, run, set, use };
|
package/lib/index.esm.js
CHANGED
|
@@ -198,18 +198,18 @@ const Oops$6 = issues({
|
|
|
198
198
|
NotFound: (name) => `Could not find ${name} in context.`
|
|
199
199
|
});
|
|
200
200
|
function get$1(arg1, arg2) {
|
|
201
|
-
return Control.get(
|
|
201
|
+
return Control.get((dispatch, context) => {
|
|
202
|
+
const refresh = () => dispatch(x => x + 1);
|
|
202
203
|
let onUpdate;
|
|
203
204
|
let value;
|
|
204
205
|
if (typeof arg1 !== "function") {
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
});
|
|
206
|
+
const got = context.get(this);
|
|
207
|
+
if (got)
|
|
208
|
+
value = arg1 === undefined
|
|
209
|
+
? Control.watch(got, k => k ? onUpdate : undefined)
|
|
210
|
+
: got;
|
|
211
|
+
else if (arg1 !== false)
|
|
212
|
+
throw Oops$6.NotFound(this);
|
|
213
213
|
return {
|
|
214
214
|
mount() {
|
|
215
215
|
onUpdate = refresh;
|
|
@@ -223,23 +223,22 @@ function get$1(arg1, arg2) {
|
|
|
223
223
|
let getValue;
|
|
224
224
|
let factory;
|
|
225
225
|
let proxy;
|
|
226
|
-
context(
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
});
|
|
226
|
+
const found = context.get(this);
|
|
227
|
+
if (!found)
|
|
228
|
+
throw Oops$6.NotFound(this);
|
|
229
|
+
proxy = Control.watch(found, () => factory ? null : onUpdate);
|
|
230
|
+
getValue = () => compute.call(proxy, proxy, forceUpdate);
|
|
231
|
+
value = getValue();
|
|
232
|
+
function forceUpdate(action) {
|
|
233
|
+
if (typeof action == "function")
|
|
234
|
+
action = action();
|
|
235
|
+
if (getValue)
|
|
236
|
+
didUpdate(getValue());
|
|
237
|
+
else
|
|
238
|
+
refresh();
|
|
239
|
+
if (action)
|
|
240
|
+
return action.finally(refresh);
|
|
241
|
+
}
|
|
243
242
|
if (value === null) {
|
|
244
243
|
getValue = undefined;
|
|
245
244
|
onUpdate = null;
|
|
@@ -295,11 +294,12 @@ const notEqual = (a, b) => (b !== a && (!Array.isArray(a) ||
|
|
|
295
294
|
a.some((x, i) => x !== b[i])));
|
|
296
295
|
|
|
297
296
|
function use$1(arg1, arg2) {
|
|
298
|
-
const render = Control.use(
|
|
299
|
-
let onUpdate;
|
|
300
|
-
let applyProps = typeof arg1 === "object";
|
|
297
|
+
const render = Control.use(dispatch => {
|
|
301
298
|
const instance = this.new();
|
|
302
299
|
const proxy = Control.watch(instance, () => onUpdate);
|
|
300
|
+
const refresh = () => dispatch(x => x + 1);
|
|
301
|
+
let onUpdate;
|
|
302
|
+
let applyProps = typeof arg1 === "object";
|
|
303
303
|
if (typeof arg1 == "function")
|
|
304
304
|
arg1(instance);
|
|
305
305
|
return {
|
|
@@ -429,7 +429,7 @@ const REGISTER = new WeakMap();
|
|
|
429
429
|
const OBSERVER = new WeakMap();
|
|
430
430
|
const PARENTS = new WeakMap();
|
|
431
431
|
class Control {
|
|
432
|
-
constructor(subject, id =
|
|
432
|
+
constructor(subject, id = uid()) {
|
|
433
433
|
this.subject = subject;
|
|
434
434
|
this.id = id;
|
|
435
435
|
this.frame = new Set();
|
|
@@ -605,7 +605,7 @@ function apply(instruction) {
|
|
|
605
605
|
return placeholder;
|
|
606
606
|
}
|
|
607
607
|
/** Random alphanumberic of length 6; will always start with a letter. */
|
|
608
|
-
function
|
|
608
|
+
function uid() {
|
|
609
609
|
return (Math.random() * 0.722 + 0.278).toString(36).substring(2, 8).toUpperCase();
|
|
610
610
|
}
|
|
611
611
|
|
|
@@ -953,8 +953,7 @@ function use(input, argument) {
|
|
|
953
953
|
}
|
|
954
954
|
|
|
955
955
|
const Oops = issues({
|
|
956
|
-
MultipleExist: (name) => `Did find ${name} in context, but multiple were defined
|
|
957
|
-
NewValue: (name) => `Provider already has already defined '${name}' but got new value. This is not yet supported.`
|
|
956
|
+
MultipleExist: (name) => `Did find ${name} in context, but multiple were defined.`
|
|
958
957
|
});
|
|
959
958
|
class Context {
|
|
960
959
|
constructor() {
|
|
@@ -980,14 +979,13 @@ class Context {
|
|
|
980
979
|
for (const key in inputs) {
|
|
981
980
|
const input = inputs[key];
|
|
982
981
|
const exists = this.layer.get(key);
|
|
983
|
-
if (exists)
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
init.set(instance, true);
|
|
982
|
+
if (!exists) {
|
|
983
|
+
const instance = this.add(input);
|
|
984
|
+
this.layer.set(key, input);
|
|
985
|
+
init.set(instance, true);
|
|
986
|
+
}
|
|
987
|
+
else if (exists !== input)
|
|
988
|
+
return this.bailout(inputs);
|
|
991
989
|
}
|
|
992
990
|
for (const [model] of init) {
|
|
993
991
|
const { state } = control(model, true);
|
|
@@ -1000,6 +998,12 @@ class Context {
|
|
|
1000
998
|
}
|
|
1001
999
|
return init;
|
|
1002
1000
|
}
|
|
1001
|
+
/** Context must force-reset becasue inputs are no longer safe. */
|
|
1002
|
+
bailout(inputs) {
|
|
1003
|
+
this.pop();
|
|
1004
|
+
this.key = uid();
|
|
1005
|
+
return this.include(inputs);
|
|
1006
|
+
}
|
|
1003
1007
|
add(input, implicit) {
|
|
1004
1008
|
let writable = true;
|
|
1005
1009
|
let T;
|
package/lib/index.js
CHANGED
|
@@ -202,18 +202,18 @@ const Oops$6 = issues({
|
|
|
202
202
|
NotFound: (name) => `Could not find ${name} in context.`
|
|
203
203
|
});
|
|
204
204
|
function get$1(arg1, arg2) {
|
|
205
|
-
return Control.get(
|
|
205
|
+
return Control.get((dispatch, context) => {
|
|
206
|
+
const refresh = () => dispatch(x => x + 1);
|
|
206
207
|
let onUpdate;
|
|
207
208
|
let value;
|
|
208
209
|
if (typeof arg1 !== "function") {
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
});
|
|
210
|
+
const got = context.get(this);
|
|
211
|
+
if (got)
|
|
212
|
+
value = arg1 === undefined
|
|
213
|
+
? Control.watch(got, k => k ? onUpdate : undefined)
|
|
214
|
+
: got;
|
|
215
|
+
else if (arg1 !== false)
|
|
216
|
+
throw Oops$6.NotFound(this);
|
|
217
217
|
return {
|
|
218
218
|
mount() {
|
|
219
219
|
onUpdate = refresh;
|
|
@@ -227,23 +227,22 @@ function get$1(arg1, arg2) {
|
|
|
227
227
|
let getValue;
|
|
228
228
|
let factory;
|
|
229
229
|
let proxy;
|
|
230
|
-
context(
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
});
|
|
230
|
+
const found = context.get(this);
|
|
231
|
+
if (!found)
|
|
232
|
+
throw Oops$6.NotFound(this);
|
|
233
|
+
proxy = Control.watch(found, () => factory ? null : onUpdate);
|
|
234
|
+
getValue = () => compute.call(proxy, proxy, forceUpdate);
|
|
235
|
+
value = getValue();
|
|
236
|
+
function forceUpdate(action) {
|
|
237
|
+
if (typeof action == "function")
|
|
238
|
+
action = action();
|
|
239
|
+
if (getValue)
|
|
240
|
+
didUpdate(getValue());
|
|
241
|
+
else
|
|
242
|
+
refresh();
|
|
243
|
+
if (action)
|
|
244
|
+
return action.finally(refresh);
|
|
245
|
+
}
|
|
247
246
|
if (value === null) {
|
|
248
247
|
getValue = undefined;
|
|
249
248
|
onUpdate = null;
|
|
@@ -299,11 +298,12 @@ const notEqual = (a, b) => (b !== a && (!Array.isArray(a) ||
|
|
|
299
298
|
a.some((x, i) => x !== b[i])));
|
|
300
299
|
|
|
301
300
|
function use$1(arg1, arg2) {
|
|
302
|
-
const render = Control.use(
|
|
303
|
-
let onUpdate;
|
|
304
|
-
let applyProps = typeof arg1 === "object";
|
|
301
|
+
const render = Control.use(dispatch => {
|
|
305
302
|
const instance = this.new();
|
|
306
303
|
const proxy = Control.watch(instance, () => onUpdate);
|
|
304
|
+
const refresh = () => dispatch(x => x + 1);
|
|
305
|
+
let onUpdate;
|
|
306
|
+
let applyProps = typeof arg1 === "object";
|
|
307
307
|
if (typeof arg1 == "function")
|
|
308
308
|
arg1(instance);
|
|
309
309
|
return {
|
|
@@ -433,7 +433,7 @@ const REGISTER = new WeakMap();
|
|
|
433
433
|
const OBSERVER = new WeakMap();
|
|
434
434
|
const PARENTS = new WeakMap();
|
|
435
435
|
class Control {
|
|
436
|
-
constructor(subject, id =
|
|
436
|
+
constructor(subject, id = uid()) {
|
|
437
437
|
this.subject = subject;
|
|
438
438
|
this.id = id;
|
|
439
439
|
this.frame = new Set();
|
|
@@ -609,7 +609,7 @@ function apply(instruction) {
|
|
|
609
609
|
return placeholder;
|
|
610
610
|
}
|
|
611
611
|
/** Random alphanumberic of length 6; will always start with a letter. */
|
|
612
|
-
function
|
|
612
|
+
function uid() {
|
|
613
613
|
return (Math.random() * 0.722 + 0.278).toString(36).substring(2, 8).toUpperCase();
|
|
614
614
|
}
|
|
615
615
|
|
|
@@ -957,8 +957,7 @@ function use(input, argument) {
|
|
|
957
957
|
}
|
|
958
958
|
|
|
959
959
|
const Oops = issues({
|
|
960
|
-
MultipleExist: (name) => `Did find ${name} in context, but multiple were defined
|
|
961
|
-
NewValue: (name) => `Provider already has already defined '${name}' but got new value. This is not yet supported.`
|
|
960
|
+
MultipleExist: (name) => `Did find ${name} in context, but multiple were defined.`
|
|
962
961
|
});
|
|
963
962
|
class Context {
|
|
964
963
|
constructor() {
|
|
@@ -984,14 +983,13 @@ class Context {
|
|
|
984
983
|
for (const key in inputs) {
|
|
985
984
|
const input = inputs[key];
|
|
986
985
|
const exists = this.layer.get(key);
|
|
987
|
-
if (exists)
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
init.set(instance, true);
|
|
986
|
+
if (!exists) {
|
|
987
|
+
const instance = this.add(input);
|
|
988
|
+
this.layer.set(key, input);
|
|
989
|
+
init.set(instance, true);
|
|
990
|
+
}
|
|
991
|
+
else if (exists !== input)
|
|
992
|
+
return this.bailout(inputs);
|
|
995
993
|
}
|
|
996
994
|
for (const [model] of init) {
|
|
997
995
|
const { state } = control(model, true);
|
|
@@ -1004,6 +1002,12 @@ class Context {
|
|
|
1004
1002
|
}
|
|
1005
1003
|
return init;
|
|
1006
1004
|
}
|
|
1005
|
+
/** Context must force-reset becasue inputs are no longer safe. */
|
|
1006
|
+
bailout(inputs) {
|
|
1007
|
+
this.pop();
|
|
1008
|
+
this.key = uid();
|
|
1009
|
+
return this.include(inputs);
|
|
1010
|
+
}
|
|
1007
1011
|
add(input, implicit) {
|
|
1008
1012
|
let writable = true;
|
|
1009
1013
|
let T;
|
package/package.json
CHANGED