@expressive/mvc 0.47.0 → 0.49.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/dist/index.d.ts +17 -5
- package/dist/index.js +168 -169
- package/dist/index.mjs +167 -169
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ declare namespace Model {
|
|
|
8
8
|
*/
|
|
9
9
|
type Callback<T extends Model = Model> = (this: T, thisArg: T) => MaybeAsync<(() => void) | Assign<T> | void>;
|
|
10
10
|
/** Model constructor argument */
|
|
11
|
-
type Argument<T extends Model = Model> =
|
|
11
|
+
type Argument<T extends Model = Model> = Assign<T> | Callback<T> | string | void;
|
|
12
12
|
/** Model constructor arguments */
|
|
13
13
|
type Args<T extends Model = any> = Argument<T>[];
|
|
14
14
|
/** Subset of `keyof T` which are not methods or defined by base Model U. **/
|
|
@@ -198,7 +198,6 @@ declare class Model {
|
|
|
198
198
|
* Register a callback to run when any instance of this Model is updated.
|
|
199
199
|
*/
|
|
200
200
|
static on<T extends Model>(this: Model.Type<T>, listener: Model.OnEvent<T>): () => boolean;
|
|
201
|
-
static at<T extends Model>(this: Model.Type<T>, from: Model, cb: (got: T | undefined) => void): void;
|
|
202
201
|
}
|
|
203
202
|
|
|
204
203
|
declare namespace get {
|
|
@@ -355,11 +354,24 @@ declare function has<T extends Model>(type: Model.Type<T>, one: true): T;
|
|
|
355
354
|
declare function has<T extends Model>(type: Model.Type<T>, required: boolean): T | undefined;
|
|
356
355
|
declare function has<T extends Model>(type: Model.Type<T>, arg?: has.Callback<T>): Set<T>;
|
|
357
356
|
|
|
357
|
+
type Effect<T extends {}> = (this: T, argument: T) => ((update: boolean | null) => void) | Promise<void> | null | void;
|
|
358
|
+
/**
|
|
359
|
+
* Create a side-effect which will update whenever values accessed change.
|
|
360
|
+
* Callback is called immediately and if ever values are stale.
|
|
361
|
+
*
|
|
362
|
+
* @param target - Instance of Model to observe.
|
|
363
|
+
* @param callback - Function to invoke when values change.
|
|
364
|
+
* @param requireValues - If `true` will throw if accessing a value which is `undefined`.
|
|
365
|
+
*/
|
|
366
|
+
declare function effect<T extends {}>(target: T, callback: Effect<Required<T>>, requireValues: true): () => void;
|
|
367
|
+
declare function effect<T extends {}>(target: T, callback: Effect<T>, requireValues?: boolean): () => void;
|
|
368
|
+
|
|
358
369
|
declare namespace Context {
|
|
359
|
-
type Input =
|
|
370
|
+
type Input = Record<string | number, Model | Model.Type<Model>>;
|
|
360
371
|
}
|
|
361
372
|
declare class Context {
|
|
362
|
-
static
|
|
373
|
+
static get<T extends Model>(on: Model, callback: ((got: Context) => void)): void;
|
|
374
|
+
static get<T extends Model>(on: Model): Context | undefined;
|
|
363
375
|
id: string;
|
|
364
376
|
protected downstream: WeakMap<Model.Type<Model>, symbol>;
|
|
365
377
|
protected upstream: WeakMap<Model.Type<Model>, symbol>;
|
|
@@ -392,4 +404,4 @@ declare global {
|
|
|
392
404
|
}
|
|
393
405
|
}
|
|
394
406
|
|
|
395
|
-
export { Context, Model, Model as default, get, has, ref, set, use };
|
|
407
|
+
export { Context, Model, Model as default, effect, get, has, ref, set, use };
|
package/dist/index.js
CHANGED
|
@@ -23,6 +23,7 @@ __export(src_exports, {
|
|
|
23
23
|
Context: () => Context,
|
|
24
24
|
Model: () => Model,
|
|
25
25
|
default: () => Model,
|
|
26
|
+
effect: () => effect,
|
|
26
27
|
get: () => get,
|
|
27
28
|
has: () => has,
|
|
28
29
|
ref: () => ref,
|
|
@@ -35,6 +36,7 @@ module.exports = __toCommonJS(src_exports);
|
|
|
35
36
|
var DISPATCH = /* @__PURE__ */ new Set();
|
|
36
37
|
var OBSERVER = /* @__PURE__ */ new WeakMap();
|
|
37
38
|
var LISTENER = /* @__PURE__ */ new WeakMap();
|
|
39
|
+
var REQUIRED = /* @__PURE__ */ new WeakSet();
|
|
38
40
|
var onReady = () => null;
|
|
39
41
|
function addListener(subject, callback, select) {
|
|
40
42
|
let subs = LISTENER.get(subject);
|
|
@@ -59,11 +61,13 @@ function watch(from, key, value) {
|
|
|
59
61
|
LISTENER.set(value = Object.create(value), nested);
|
|
60
62
|
OBSERVER.set(value, observer);
|
|
61
63
|
}
|
|
64
|
+
if (value === void 0 && REQUIRED.has(from))
|
|
65
|
+
throw new Error(`${from}.${key} is required in this context.`);
|
|
62
66
|
}
|
|
63
67
|
return value;
|
|
64
68
|
}
|
|
65
69
|
var PENDING = /* @__PURE__ */ new WeakMap();
|
|
66
|
-
function
|
|
70
|
+
function emit(source, key) {
|
|
67
71
|
const subs = LISTENER.get(source);
|
|
68
72
|
const ready = !subs.has(onReady);
|
|
69
73
|
if (key === true && ready)
|
|
@@ -90,21 +94,21 @@ function event(source, key) {
|
|
|
90
94
|
});
|
|
91
95
|
PENDING.delete(source);
|
|
92
96
|
}
|
|
93
|
-
function queue(
|
|
97
|
+
function queue(event) {
|
|
94
98
|
if (!DISPATCH.size)
|
|
95
99
|
setTimeout(() => {
|
|
96
|
-
DISPATCH.forEach((
|
|
100
|
+
DISPATCH.forEach((event2) => {
|
|
97
101
|
try {
|
|
98
|
-
|
|
102
|
+
event2();
|
|
99
103
|
} catch (err) {
|
|
100
104
|
console.error(err);
|
|
101
105
|
}
|
|
102
106
|
});
|
|
103
107
|
DISPATCH.clear();
|
|
104
108
|
}, 0);
|
|
105
|
-
DISPATCH.add(
|
|
109
|
+
DISPATCH.add(event);
|
|
106
110
|
}
|
|
107
|
-
function effect(target, callback) {
|
|
111
|
+
function effect(target, callback, requireValues) {
|
|
108
112
|
const listeners = LISTENER.get(target);
|
|
109
113
|
let unset;
|
|
110
114
|
let reset;
|
|
@@ -122,6 +126,8 @@ function effect(target, callback) {
|
|
|
122
126
|
}
|
|
123
127
|
return reset;
|
|
124
128
|
});
|
|
129
|
+
if (requireValues)
|
|
130
|
+
REQUIRED.add(subscriber);
|
|
125
131
|
try {
|
|
126
132
|
const out = callback.call(subscriber, subscriber);
|
|
127
133
|
unset = typeof out == "function" ? out : void 0;
|
|
@@ -150,7 +156,7 @@ function effect(target, callback) {
|
|
|
150
156
|
}
|
|
151
157
|
|
|
152
158
|
// src/model.ts
|
|
153
|
-
var
|
|
159
|
+
var EXPORT;
|
|
154
160
|
var NAMES = /* @__PURE__ */ new WeakMap();
|
|
155
161
|
var STATE = /* @__PURE__ */ new WeakMap();
|
|
156
162
|
var NOTIFY = /* @__PURE__ */ new WeakMap();
|
|
@@ -235,16 +241,16 @@ var Model = class _Model {
|
|
|
235
241
|
}
|
|
236
242
|
if (arg1 === void 0) {
|
|
237
243
|
const values = {};
|
|
238
|
-
const current = !
|
|
244
|
+
const current = !EXPORT && (EXPORT = /* @__PURE__ */ new Map([[self, values]]));
|
|
239
245
|
for (let [key, value] of self) {
|
|
240
|
-
if (
|
|
241
|
-
value =
|
|
246
|
+
if (EXPORT.has(value))
|
|
247
|
+
value = EXPORT.get(value);
|
|
242
248
|
else if (value && typeof value.get === "function")
|
|
243
|
-
|
|
249
|
+
EXPORT.set(value, value = value.get());
|
|
244
250
|
values[key] = value;
|
|
245
251
|
}
|
|
246
252
|
if (current)
|
|
247
|
-
|
|
253
|
+
EXPORT = void 0;
|
|
248
254
|
return Object.freeze(values);
|
|
249
255
|
}
|
|
250
256
|
if (typeof arg2 == "function") {
|
|
@@ -267,11 +273,11 @@ var Model = class _Model {
|
|
|
267
273
|
return arg1.call(self, key, self);
|
|
268
274
|
});
|
|
269
275
|
if (arg1 === null)
|
|
270
|
-
return
|
|
276
|
+
return emit(this, null);
|
|
271
277
|
if (typeof arg1 == "object")
|
|
272
278
|
assign(self, arg1);
|
|
273
279
|
else if (arg1 == void 0)
|
|
274
|
-
|
|
280
|
+
emit(this, true);
|
|
275
281
|
else if (1 in arguments)
|
|
276
282
|
update(self, arg1, arg2, arg3);
|
|
277
283
|
else
|
|
@@ -301,7 +307,7 @@ var Model = class _Model {
|
|
|
301
307
|
*/
|
|
302
308
|
static new(...args) {
|
|
303
309
|
const instance = new this(...args);
|
|
304
|
-
|
|
310
|
+
emit(instance, true);
|
|
305
311
|
return instance;
|
|
306
312
|
}
|
|
307
313
|
/**
|
|
@@ -323,9 +329,6 @@ var Model = class _Model {
|
|
|
323
329
|
notify.add(listener);
|
|
324
330
|
return () => notify.delete(listener);
|
|
325
331
|
}
|
|
326
|
-
static at(from, cb) {
|
|
327
|
-
throw new Error(`Using context requires an adapter. If you are only testing, define \`get.context\` to simulate one.`);
|
|
328
|
-
}
|
|
329
332
|
};
|
|
330
333
|
define(Model.prototype, "toString", {
|
|
331
334
|
value() {
|
|
@@ -345,14 +348,14 @@ function fetch(subject, property, required) {
|
|
|
345
348
|
return value;
|
|
346
349
|
}
|
|
347
350
|
const error = new Error(`${subject}.${property} is not yet available.`);
|
|
348
|
-
const promise = new Promise((resolve,
|
|
351
|
+
const promise = new Promise((resolve, reject) => {
|
|
349
352
|
addListener(subject, (key) => {
|
|
350
353
|
if (key === property) {
|
|
351
354
|
resolve(state[key]);
|
|
352
355
|
return null;
|
|
353
356
|
}
|
|
354
357
|
if (key === null)
|
|
355
|
-
|
|
358
|
+
reject(new Error(`${subject} is destroyed.`));
|
|
356
359
|
});
|
|
357
360
|
});
|
|
358
361
|
throw Object.assign(promise, {
|
|
@@ -371,7 +374,7 @@ function update(subject, key, value, silent) {
|
|
|
371
374
|
return true;
|
|
372
375
|
if (value instanceof Model && !PARENT.has(value)) {
|
|
373
376
|
PARENT.set(value, subject);
|
|
374
|
-
|
|
377
|
+
emit(value, true);
|
|
375
378
|
}
|
|
376
379
|
state[key] = value;
|
|
377
380
|
if (silent !== true)
|
|
@@ -383,13 +386,13 @@ function push(subject, key, silent) {
|
|
|
383
386
|
PENDING2.set(subject, pending = /* @__PURE__ */ new Set());
|
|
384
387
|
if (!silent)
|
|
385
388
|
queue(() => {
|
|
386
|
-
|
|
389
|
+
emit(subject, false);
|
|
387
390
|
PENDING2.delete(subject);
|
|
388
391
|
});
|
|
389
392
|
}
|
|
390
393
|
pending.add(key);
|
|
391
394
|
if (!silent)
|
|
392
|
-
|
|
395
|
+
emit(subject, key);
|
|
393
396
|
}
|
|
394
397
|
var METHODS = new WeakMap([[Model, []]]);
|
|
395
398
|
function assign(to, values) {
|
|
@@ -429,6 +432,132 @@ function uid() {
|
|
|
429
432
|
return (Math.random() * 0.722 + 0.278).toString(36).substring(2, 8).toUpperCase();
|
|
430
433
|
}
|
|
431
434
|
|
|
435
|
+
// src/context.ts
|
|
436
|
+
var Register = /* @__PURE__ */ new WeakMap();
|
|
437
|
+
var Context = class _Context {
|
|
438
|
+
constructor(inputs) {
|
|
439
|
+
this.downstream = /* @__PURE__ */ new WeakMap();
|
|
440
|
+
this.upstream = /* @__PURE__ */ new WeakMap();
|
|
441
|
+
this.layer = /* @__PURE__ */ new Map();
|
|
442
|
+
if (inputs)
|
|
443
|
+
this.include(inputs);
|
|
444
|
+
}
|
|
445
|
+
static get(from, callback) {
|
|
446
|
+
const waiting = Register.get(from);
|
|
447
|
+
if (!callback)
|
|
448
|
+
return waiting instanceof _Context ? waiting : void 0;
|
|
449
|
+
if (waiting instanceof _Context)
|
|
450
|
+
callback(waiting);
|
|
451
|
+
else if (waiting)
|
|
452
|
+
waiting.push(callback);
|
|
453
|
+
else
|
|
454
|
+
Register.set(from, [callback]);
|
|
455
|
+
}
|
|
456
|
+
key(T, upstream) {
|
|
457
|
+
const table = upstream ? this.upstream : this.downstream;
|
|
458
|
+
let key = table.get(T);
|
|
459
|
+
if (!key) {
|
|
460
|
+
key = Symbol(T.name + (upstream ? " request" : ""));
|
|
461
|
+
table.set(T, key);
|
|
462
|
+
}
|
|
463
|
+
return key;
|
|
464
|
+
}
|
|
465
|
+
has(model) {
|
|
466
|
+
const key = this.key(model.constructor, true);
|
|
467
|
+
const result = this[key];
|
|
468
|
+
const waiting = Register.get(model);
|
|
469
|
+
if (waiting instanceof Array)
|
|
470
|
+
waiting.forEach((cb) => cb(this));
|
|
471
|
+
Register.set(model, this);
|
|
472
|
+
if (typeof result == "function")
|
|
473
|
+
return result(model);
|
|
474
|
+
}
|
|
475
|
+
get(Type) {
|
|
476
|
+
const result = this[this.key(Type)];
|
|
477
|
+
if (result === null)
|
|
478
|
+
throw new Error(`Did find ${Type} in context, but multiple were defined.`);
|
|
479
|
+
return result;
|
|
480
|
+
}
|
|
481
|
+
include(inputs, forEach) {
|
|
482
|
+
const init = /* @__PURE__ */ new Map();
|
|
483
|
+
Object.entries(inputs).forEach(([K, V]) => {
|
|
484
|
+
if (!(Model.is(V) || V instanceof Model))
|
|
485
|
+
throw new Error(`Context can only include Model or instance but got ${V}${K && " as " + K}.`);
|
|
486
|
+
});
|
|
487
|
+
for (const key in inputs) {
|
|
488
|
+
const input = inputs[key];
|
|
489
|
+
const exists = this.layer.get(key);
|
|
490
|
+
if (!exists) {
|
|
491
|
+
const instance = this.add(input);
|
|
492
|
+
this.layer.set(key, input);
|
|
493
|
+
init.set(instance, true);
|
|
494
|
+
} else if (exists !== input) {
|
|
495
|
+
this.pop();
|
|
496
|
+
this.id = uid();
|
|
497
|
+
this.include(inputs);
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
for (const [model, explicit] of init) {
|
|
501
|
+
model.set();
|
|
502
|
+
if (forEach)
|
|
503
|
+
forEach(model, explicit);
|
|
504
|
+
for (const [_key, value] of model)
|
|
505
|
+
if (PARENT.get(value) === model) {
|
|
506
|
+
this.add(value, true);
|
|
507
|
+
init.set(value, false);
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
put(T, I, implicit, writable) {
|
|
512
|
+
do {
|
|
513
|
+
const key = this.key(T, typeof I == "function");
|
|
514
|
+
const value = this.hasOwnProperty(key) ? null : I;
|
|
515
|
+
if (value || this[key] !== I && !implicit)
|
|
516
|
+
Object.defineProperty(this, key, {
|
|
517
|
+
configurable: true,
|
|
518
|
+
writable,
|
|
519
|
+
value
|
|
520
|
+
});
|
|
521
|
+
T = Object.getPrototypeOf(T);
|
|
522
|
+
} while (T !== Model);
|
|
523
|
+
}
|
|
524
|
+
add(input, implicit) {
|
|
525
|
+
let writable = true;
|
|
526
|
+
let T;
|
|
527
|
+
let I;
|
|
528
|
+
if (typeof input == "function") {
|
|
529
|
+
T = input;
|
|
530
|
+
I = new input();
|
|
531
|
+
} else {
|
|
532
|
+
I = input;
|
|
533
|
+
T = I.constructor;
|
|
534
|
+
writable = false;
|
|
535
|
+
}
|
|
536
|
+
this.has(I);
|
|
537
|
+
this.put(T, I, implicit, writable);
|
|
538
|
+
return I;
|
|
539
|
+
}
|
|
540
|
+
push(inputs) {
|
|
541
|
+
const next = Object.create(this);
|
|
542
|
+
next.layer = /* @__PURE__ */ new Map();
|
|
543
|
+
if (inputs)
|
|
544
|
+
next.include(inputs);
|
|
545
|
+
return next;
|
|
546
|
+
}
|
|
547
|
+
pop() {
|
|
548
|
+
const items = /* @__PURE__ */ new Set();
|
|
549
|
+
for (const key of Object.getOwnPropertySymbols(this)) {
|
|
550
|
+
const entry = Object.getOwnPropertyDescriptor(this, key);
|
|
551
|
+
if (entry.writable && entry.value)
|
|
552
|
+
items.add(entry.value);
|
|
553
|
+
delete this[key];
|
|
554
|
+
}
|
|
555
|
+
for (const model of items)
|
|
556
|
+
model.set(null);
|
|
557
|
+
this.layer.clear();
|
|
558
|
+
}
|
|
559
|
+
};
|
|
560
|
+
|
|
432
561
|
// src/instruction/use.ts
|
|
433
562
|
var INSTRUCT = /* @__PURE__ */ new Map();
|
|
434
563
|
function use(model, argument) {
|
|
@@ -500,20 +629,21 @@ Model.on((_, subject) => {
|
|
|
500
629
|
// src/instruction/get.ts
|
|
501
630
|
var STALE = /* @__PURE__ */ new WeakSet();
|
|
502
631
|
function get(arg0, arg1) {
|
|
503
|
-
return use((key, subject) => {
|
|
632
|
+
return use((key, subject, state) => {
|
|
504
633
|
let from = subject;
|
|
505
634
|
if (typeof arg0 == "symbol")
|
|
506
635
|
throw new Error(`Attempted to use an instruction result (probably use or get) as computed source for ${from}.${key}. This is not allowed.`);
|
|
507
636
|
let source = (resolve) => resolve(from);
|
|
508
637
|
if (arg0 instanceof Model) {
|
|
509
638
|
from = arg0;
|
|
510
|
-
} else if (arg0
|
|
639
|
+
} else if (Model.is(arg0)) {
|
|
511
640
|
const hasParent = PARENT.get(from);
|
|
512
641
|
if (!hasParent) {
|
|
513
642
|
if (arg1 === true)
|
|
514
643
|
throw new Error(`${from} may only exist as a child of type ${arg0}.`);
|
|
515
644
|
source = (resolve) => {
|
|
516
|
-
|
|
645
|
+
Context.get(from, (context) => {
|
|
646
|
+
const got = context.get(arg0);
|
|
517
647
|
if (got)
|
|
518
648
|
resolve(got);
|
|
519
649
|
else if (arg1 !== false)
|
|
@@ -532,10 +662,8 @@ function get(arg0, arg1) {
|
|
|
532
662
|
let connect2 = function(model) {
|
|
533
663
|
reset = effect(model, (current) => {
|
|
534
664
|
proxy = current;
|
|
535
|
-
if (!
|
|
536
|
-
compute2(
|
|
537
|
-
else if (STALE.delete(compute2))
|
|
538
|
-
compute2();
|
|
665
|
+
if (!(key in state) || STALE.delete(compute2))
|
|
666
|
+
compute2(!reset);
|
|
539
667
|
return (didUpdate) => {
|
|
540
668
|
if (didUpdate) {
|
|
541
669
|
STALE.add(compute2);
|
|
@@ -699,178 +827,49 @@ function attempt(fn) {
|
|
|
699
827
|
return compute();
|
|
700
828
|
}
|
|
701
829
|
|
|
702
|
-
// src/context.ts
|
|
703
|
-
var Expects = /* @__PURE__ */ new WeakMap();
|
|
704
|
-
var Context = class {
|
|
705
|
-
constructor(inputs) {
|
|
706
|
-
this.downstream = /* @__PURE__ */ new WeakMap();
|
|
707
|
-
this.upstream = /* @__PURE__ */ new WeakMap();
|
|
708
|
-
this.layer = /* @__PURE__ */ new Map();
|
|
709
|
-
if (inputs)
|
|
710
|
-
this.include(inputs);
|
|
711
|
-
}
|
|
712
|
-
static request(type, from, callback) {
|
|
713
|
-
let map = Expects.get(from);
|
|
714
|
-
if (!map)
|
|
715
|
-
Expects.set(from, map = /* @__PURE__ */ new Map());
|
|
716
|
-
map.set(type, callback);
|
|
717
|
-
}
|
|
718
|
-
key(T, upstream) {
|
|
719
|
-
const table = upstream ? this.upstream : this.downstream;
|
|
720
|
-
let key = table.get(T);
|
|
721
|
-
if (!key) {
|
|
722
|
-
key = Symbol(T.name + (upstream ? " request" : ""));
|
|
723
|
-
table.set(T, key);
|
|
724
|
-
}
|
|
725
|
-
return key;
|
|
726
|
-
}
|
|
727
|
-
has(model) {
|
|
728
|
-
const key = this.key(model.constructor, true);
|
|
729
|
-
const result = this[key];
|
|
730
|
-
if (typeof result == "function")
|
|
731
|
-
return result(model);
|
|
732
|
-
}
|
|
733
|
-
get(Type) {
|
|
734
|
-
const result = this[this.key(Type)];
|
|
735
|
-
if (result === null)
|
|
736
|
-
throw new Error(`Did find ${Type} in context, but multiple were defined.`);
|
|
737
|
-
return result;
|
|
738
|
-
}
|
|
739
|
-
include(inputs, forEach) {
|
|
740
|
-
const init = /* @__PURE__ */ new Map();
|
|
741
|
-
if (typeof inputs == "function" || inputs instanceof Model)
|
|
742
|
-
inputs = { [0]: inputs };
|
|
743
|
-
else if (!inputs)
|
|
744
|
-
reject(inputs);
|
|
745
|
-
Object.entries(inputs).forEach(([K, V]) => {
|
|
746
|
-
if (!(Model.is(V) || V instanceof Model))
|
|
747
|
-
reject(`${V} as ${K}`);
|
|
748
|
-
});
|
|
749
|
-
for (const key in inputs) {
|
|
750
|
-
const input = inputs[key];
|
|
751
|
-
const exists = this.layer.get(key);
|
|
752
|
-
if (!exists) {
|
|
753
|
-
const instance = this.add(input);
|
|
754
|
-
this.layer.set(key, input);
|
|
755
|
-
init.set(instance, true);
|
|
756
|
-
} else if (exists !== input) {
|
|
757
|
-
this.pop();
|
|
758
|
-
this.id = uid();
|
|
759
|
-
this.include(inputs);
|
|
760
|
-
}
|
|
761
|
-
}
|
|
762
|
-
for (const [model, explicit] of init) {
|
|
763
|
-
if (forEach)
|
|
764
|
-
forEach(model, explicit);
|
|
765
|
-
model.set();
|
|
766
|
-
this.has(model);
|
|
767
|
-
const expects = Expects.get(model);
|
|
768
|
-
if (expects)
|
|
769
|
-
for (let [T, callback] of expects)
|
|
770
|
-
this.put(T, callback);
|
|
771
|
-
for (const [_key, value] of model)
|
|
772
|
-
if (PARENT.get(value) === model) {
|
|
773
|
-
this.add(value, true);
|
|
774
|
-
init.set(value, false);
|
|
775
|
-
}
|
|
776
|
-
}
|
|
777
|
-
}
|
|
778
|
-
put(T, I, implicit, writable) {
|
|
779
|
-
do {
|
|
780
|
-
const key = this.key(T, typeof I == "function");
|
|
781
|
-
const value = this.hasOwnProperty(key) ? null : I;
|
|
782
|
-
if (value || this[key] !== I && !implicit)
|
|
783
|
-
Object.defineProperty(this, key, {
|
|
784
|
-
configurable: true,
|
|
785
|
-
writable,
|
|
786
|
-
value
|
|
787
|
-
});
|
|
788
|
-
T = Object.getPrototypeOf(T);
|
|
789
|
-
} while (T !== Model);
|
|
790
|
-
}
|
|
791
|
-
add(input, implicit) {
|
|
792
|
-
let writable = true;
|
|
793
|
-
let T;
|
|
794
|
-
let I;
|
|
795
|
-
if (typeof input == "function") {
|
|
796
|
-
T = input;
|
|
797
|
-
I = new input();
|
|
798
|
-
} else {
|
|
799
|
-
I = input;
|
|
800
|
-
T = I.constructor;
|
|
801
|
-
writable = false;
|
|
802
|
-
}
|
|
803
|
-
this.put(T, I, implicit, writable);
|
|
804
|
-
return I;
|
|
805
|
-
}
|
|
806
|
-
push(inputs) {
|
|
807
|
-
const next = Object.create(this);
|
|
808
|
-
next.layer = /* @__PURE__ */ new Map();
|
|
809
|
-
if (inputs)
|
|
810
|
-
next.include(inputs);
|
|
811
|
-
return next;
|
|
812
|
-
}
|
|
813
|
-
pop() {
|
|
814
|
-
const items = /* @__PURE__ */ new Set();
|
|
815
|
-
for (const key of Object.getOwnPropertySymbols(this)) {
|
|
816
|
-
const entry = Object.getOwnPropertyDescriptor(this, key);
|
|
817
|
-
if (entry.writable && entry.value)
|
|
818
|
-
items.add(entry.value);
|
|
819
|
-
delete this[key];
|
|
820
|
-
}
|
|
821
|
-
for (const model of items)
|
|
822
|
-
model.set(null);
|
|
823
|
-
this.layer.clear();
|
|
824
|
-
}
|
|
825
|
-
};
|
|
826
|
-
function reject(argument) {
|
|
827
|
-
throw new Error(`Context can only include Model or instance but got ${argument}.`);
|
|
828
|
-
}
|
|
829
|
-
|
|
830
830
|
// src/instruction/has.ts
|
|
831
831
|
function has(type, argument) {
|
|
832
832
|
return use((key, subject, state) => {
|
|
833
|
+
const expect = (callback) => Context.get(subject, (context) => context.put(type, callback));
|
|
833
834
|
if (typeof argument == "boolean") {
|
|
834
|
-
|
|
835
|
+
expect((model) => {
|
|
835
836
|
subject.set(key, model);
|
|
836
837
|
const remove = () => {
|
|
837
|
-
drop();
|
|
838
838
|
if (state[key] === model)
|
|
839
839
|
delete state[key];
|
|
840
840
|
};
|
|
841
|
-
|
|
841
|
+
model.get(null, remove);
|
|
842
842
|
return remove;
|
|
843
843
|
});
|
|
844
844
|
return { get: argument };
|
|
845
845
|
}
|
|
846
|
-
const
|
|
847
|
-
|
|
848
|
-
if (
|
|
846
|
+
const value = /* @__PURE__ */ new Set();
|
|
847
|
+
expect((model) => {
|
|
848
|
+
if (value.has(model))
|
|
849
849
|
return;
|
|
850
850
|
const remove = typeof argument == "function" ? argument(model) : void 0;
|
|
851
851
|
if (remove === false)
|
|
852
852
|
return;
|
|
853
|
-
|
|
853
|
+
value.add(model);
|
|
854
854
|
subject.set(key);
|
|
855
855
|
const done = () => {
|
|
856
856
|
drop();
|
|
857
857
|
if (typeof remove == "function")
|
|
858
858
|
remove();
|
|
859
|
-
|
|
859
|
+
value.delete(model);
|
|
860
860
|
subject.set(key);
|
|
861
861
|
};
|
|
862
862
|
const drop = model.get(null, done);
|
|
863
863
|
return done;
|
|
864
864
|
});
|
|
865
|
-
return {
|
|
866
|
-
value: children
|
|
867
|
-
};
|
|
865
|
+
return { value };
|
|
868
866
|
});
|
|
869
867
|
}
|
|
870
868
|
// Annotate the CommonJS export names for ESM import in node:
|
|
871
869
|
0 && (module.exports = {
|
|
872
870
|
Context,
|
|
873
871
|
Model,
|
|
872
|
+
effect,
|
|
874
873
|
get,
|
|
875
874
|
has,
|
|
876
875
|
ref,
|
package/dist/index.mjs
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
var DISPATCH = /* @__PURE__ */ new Set();
|
|
3
3
|
var OBSERVER = /* @__PURE__ */ new WeakMap();
|
|
4
4
|
var LISTENER = /* @__PURE__ */ new WeakMap();
|
|
5
|
+
var REQUIRED = /* @__PURE__ */ new WeakSet();
|
|
5
6
|
var onReady = () => null;
|
|
6
7
|
function addListener(subject, callback, select) {
|
|
7
8
|
let subs = LISTENER.get(subject);
|
|
@@ -26,11 +27,13 @@ function watch(from, key, value) {
|
|
|
26
27
|
LISTENER.set(value = Object.create(value), nested);
|
|
27
28
|
OBSERVER.set(value, observer);
|
|
28
29
|
}
|
|
30
|
+
if (value === void 0 && REQUIRED.has(from))
|
|
31
|
+
throw new Error(`${from}.${key} is required in this context.`);
|
|
29
32
|
}
|
|
30
33
|
return value;
|
|
31
34
|
}
|
|
32
35
|
var PENDING = /* @__PURE__ */ new WeakMap();
|
|
33
|
-
function
|
|
36
|
+
function emit(source, key) {
|
|
34
37
|
const subs = LISTENER.get(source);
|
|
35
38
|
const ready = !subs.has(onReady);
|
|
36
39
|
if (key === true && ready)
|
|
@@ -57,21 +60,21 @@ function event(source, key) {
|
|
|
57
60
|
});
|
|
58
61
|
PENDING.delete(source);
|
|
59
62
|
}
|
|
60
|
-
function queue(
|
|
63
|
+
function queue(event) {
|
|
61
64
|
if (!DISPATCH.size)
|
|
62
65
|
setTimeout(() => {
|
|
63
|
-
DISPATCH.forEach((
|
|
66
|
+
DISPATCH.forEach((event2) => {
|
|
64
67
|
try {
|
|
65
|
-
|
|
68
|
+
event2();
|
|
66
69
|
} catch (err) {
|
|
67
70
|
console.error(err);
|
|
68
71
|
}
|
|
69
72
|
});
|
|
70
73
|
DISPATCH.clear();
|
|
71
74
|
}, 0);
|
|
72
|
-
DISPATCH.add(
|
|
75
|
+
DISPATCH.add(event);
|
|
73
76
|
}
|
|
74
|
-
function effect(target, callback) {
|
|
77
|
+
function effect(target, callback, requireValues) {
|
|
75
78
|
const listeners = LISTENER.get(target);
|
|
76
79
|
let unset;
|
|
77
80
|
let reset;
|
|
@@ -89,6 +92,8 @@ function effect(target, callback) {
|
|
|
89
92
|
}
|
|
90
93
|
return reset;
|
|
91
94
|
});
|
|
95
|
+
if (requireValues)
|
|
96
|
+
REQUIRED.add(subscriber);
|
|
92
97
|
try {
|
|
93
98
|
const out = callback.call(subscriber, subscriber);
|
|
94
99
|
unset = typeof out == "function" ? out : void 0;
|
|
@@ -117,7 +122,7 @@ function effect(target, callback) {
|
|
|
117
122
|
}
|
|
118
123
|
|
|
119
124
|
// src/model.ts
|
|
120
|
-
var
|
|
125
|
+
var EXPORT;
|
|
121
126
|
var NAMES = /* @__PURE__ */ new WeakMap();
|
|
122
127
|
var STATE = /* @__PURE__ */ new WeakMap();
|
|
123
128
|
var NOTIFY = /* @__PURE__ */ new WeakMap();
|
|
@@ -202,16 +207,16 @@ var Model = class _Model {
|
|
|
202
207
|
}
|
|
203
208
|
if (arg1 === void 0) {
|
|
204
209
|
const values = {};
|
|
205
|
-
const current = !
|
|
210
|
+
const current = !EXPORT && (EXPORT = /* @__PURE__ */ new Map([[self, values]]));
|
|
206
211
|
for (let [key, value] of self) {
|
|
207
|
-
if (
|
|
208
|
-
value =
|
|
212
|
+
if (EXPORT.has(value))
|
|
213
|
+
value = EXPORT.get(value);
|
|
209
214
|
else if (value && typeof value.get === "function")
|
|
210
|
-
|
|
215
|
+
EXPORT.set(value, value = value.get());
|
|
211
216
|
values[key] = value;
|
|
212
217
|
}
|
|
213
218
|
if (current)
|
|
214
|
-
|
|
219
|
+
EXPORT = void 0;
|
|
215
220
|
return Object.freeze(values);
|
|
216
221
|
}
|
|
217
222
|
if (typeof arg2 == "function") {
|
|
@@ -234,11 +239,11 @@ var Model = class _Model {
|
|
|
234
239
|
return arg1.call(self, key, self);
|
|
235
240
|
});
|
|
236
241
|
if (arg1 === null)
|
|
237
|
-
return
|
|
242
|
+
return emit(this, null);
|
|
238
243
|
if (typeof arg1 == "object")
|
|
239
244
|
assign(self, arg1);
|
|
240
245
|
else if (arg1 == void 0)
|
|
241
|
-
|
|
246
|
+
emit(this, true);
|
|
242
247
|
else if (1 in arguments)
|
|
243
248
|
update(self, arg1, arg2, arg3);
|
|
244
249
|
else
|
|
@@ -268,7 +273,7 @@ var Model = class _Model {
|
|
|
268
273
|
*/
|
|
269
274
|
static new(...args) {
|
|
270
275
|
const instance = new this(...args);
|
|
271
|
-
|
|
276
|
+
emit(instance, true);
|
|
272
277
|
return instance;
|
|
273
278
|
}
|
|
274
279
|
/**
|
|
@@ -290,9 +295,6 @@ var Model = class _Model {
|
|
|
290
295
|
notify.add(listener);
|
|
291
296
|
return () => notify.delete(listener);
|
|
292
297
|
}
|
|
293
|
-
static at(from, cb) {
|
|
294
|
-
throw new Error(`Using context requires an adapter. If you are only testing, define \`get.context\` to simulate one.`);
|
|
295
|
-
}
|
|
296
298
|
};
|
|
297
299
|
define(Model.prototype, "toString", {
|
|
298
300
|
value() {
|
|
@@ -312,14 +314,14 @@ function fetch(subject, property, required) {
|
|
|
312
314
|
return value;
|
|
313
315
|
}
|
|
314
316
|
const error = new Error(`${subject}.${property} is not yet available.`);
|
|
315
|
-
const promise = new Promise((resolve,
|
|
317
|
+
const promise = new Promise((resolve, reject) => {
|
|
316
318
|
addListener(subject, (key) => {
|
|
317
319
|
if (key === property) {
|
|
318
320
|
resolve(state[key]);
|
|
319
321
|
return null;
|
|
320
322
|
}
|
|
321
323
|
if (key === null)
|
|
322
|
-
|
|
324
|
+
reject(new Error(`${subject} is destroyed.`));
|
|
323
325
|
});
|
|
324
326
|
});
|
|
325
327
|
throw Object.assign(promise, {
|
|
@@ -338,7 +340,7 @@ function update(subject, key, value, silent) {
|
|
|
338
340
|
return true;
|
|
339
341
|
if (value instanceof Model && !PARENT.has(value)) {
|
|
340
342
|
PARENT.set(value, subject);
|
|
341
|
-
|
|
343
|
+
emit(value, true);
|
|
342
344
|
}
|
|
343
345
|
state[key] = value;
|
|
344
346
|
if (silent !== true)
|
|
@@ -350,13 +352,13 @@ function push(subject, key, silent) {
|
|
|
350
352
|
PENDING2.set(subject, pending = /* @__PURE__ */ new Set());
|
|
351
353
|
if (!silent)
|
|
352
354
|
queue(() => {
|
|
353
|
-
|
|
355
|
+
emit(subject, false);
|
|
354
356
|
PENDING2.delete(subject);
|
|
355
357
|
});
|
|
356
358
|
}
|
|
357
359
|
pending.add(key);
|
|
358
360
|
if (!silent)
|
|
359
|
-
|
|
361
|
+
emit(subject, key);
|
|
360
362
|
}
|
|
361
363
|
var METHODS = new WeakMap([[Model, []]]);
|
|
362
364
|
function assign(to, values) {
|
|
@@ -396,6 +398,132 @@ function uid() {
|
|
|
396
398
|
return (Math.random() * 0.722 + 0.278).toString(36).substring(2, 8).toUpperCase();
|
|
397
399
|
}
|
|
398
400
|
|
|
401
|
+
// src/context.ts
|
|
402
|
+
var Register = /* @__PURE__ */ new WeakMap();
|
|
403
|
+
var Context = class _Context {
|
|
404
|
+
constructor(inputs) {
|
|
405
|
+
this.downstream = /* @__PURE__ */ new WeakMap();
|
|
406
|
+
this.upstream = /* @__PURE__ */ new WeakMap();
|
|
407
|
+
this.layer = /* @__PURE__ */ new Map();
|
|
408
|
+
if (inputs)
|
|
409
|
+
this.include(inputs);
|
|
410
|
+
}
|
|
411
|
+
static get(from, callback) {
|
|
412
|
+
const waiting = Register.get(from);
|
|
413
|
+
if (!callback)
|
|
414
|
+
return waiting instanceof _Context ? waiting : void 0;
|
|
415
|
+
if (waiting instanceof _Context)
|
|
416
|
+
callback(waiting);
|
|
417
|
+
else if (waiting)
|
|
418
|
+
waiting.push(callback);
|
|
419
|
+
else
|
|
420
|
+
Register.set(from, [callback]);
|
|
421
|
+
}
|
|
422
|
+
key(T, upstream) {
|
|
423
|
+
const table = upstream ? this.upstream : this.downstream;
|
|
424
|
+
let key = table.get(T);
|
|
425
|
+
if (!key) {
|
|
426
|
+
key = Symbol(T.name + (upstream ? " request" : ""));
|
|
427
|
+
table.set(T, key);
|
|
428
|
+
}
|
|
429
|
+
return key;
|
|
430
|
+
}
|
|
431
|
+
has(model) {
|
|
432
|
+
const key = this.key(model.constructor, true);
|
|
433
|
+
const result = this[key];
|
|
434
|
+
const waiting = Register.get(model);
|
|
435
|
+
if (waiting instanceof Array)
|
|
436
|
+
waiting.forEach((cb) => cb(this));
|
|
437
|
+
Register.set(model, this);
|
|
438
|
+
if (typeof result == "function")
|
|
439
|
+
return result(model);
|
|
440
|
+
}
|
|
441
|
+
get(Type) {
|
|
442
|
+
const result = this[this.key(Type)];
|
|
443
|
+
if (result === null)
|
|
444
|
+
throw new Error(`Did find ${Type} in context, but multiple were defined.`);
|
|
445
|
+
return result;
|
|
446
|
+
}
|
|
447
|
+
include(inputs, forEach) {
|
|
448
|
+
const init = /* @__PURE__ */ new Map();
|
|
449
|
+
Object.entries(inputs).forEach(([K, V]) => {
|
|
450
|
+
if (!(Model.is(V) || V instanceof Model))
|
|
451
|
+
throw new Error(`Context can only include Model or instance but got ${V}${K && " as " + K}.`);
|
|
452
|
+
});
|
|
453
|
+
for (const key in inputs) {
|
|
454
|
+
const input = inputs[key];
|
|
455
|
+
const exists = this.layer.get(key);
|
|
456
|
+
if (!exists) {
|
|
457
|
+
const instance = this.add(input);
|
|
458
|
+
this.layer.set(key, input);
|
|
459
|
+
init.set(instance, true);
|
|
460
|
+
} else if (exists !== input) {
|
|
461
|
+
this.pop();
|
|
462
|
+
this.id = uid();
|
|
463
|
+
this.include(inputs);
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
for (const [model, explicit] of init) {
|
|
467
|
+
model.set();
|
|
468
|
+
if (forEach)
|
|
469
|
+
forEach(model, explicit);
|
|
470
|
+
for (const [_key, value] of model)
|
|
471
|
+
if (PARENT.get(value) === model) {
|
|
472
|
+
this.add(value, true);
|
|
473
|
+
init.set(value, false);
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
put(T, I, implicit, writable) {
|
|
478
|
+
do {
|
|
479
|
+
const key = this.key(T, typeof I == "function");
|
|
480
|
+
const value = this.hasOwnProperty(key) ? null : I;
|
|
481
|
+
if (value || this[key] !== I && !implicit)
|
|
482
|
+
Object.defineProperty(this, key, {
|
|
483
|
+
configurable: true,
|
|
484
|
+
writable,
|
|
485
|
+
value
|
|
486
|
+
});
|
|
487
|
+
T = Object.getPrototypeOf(T);
|
|
488
|
+
} while (T !== Model);
|
|
489
|
+
}
|
|
490
|
+
add(input, implicit) {
|
|
491
|
+
let writable = true;
|
|
492
|
+
let T;
|
|
493
|
+
let I;
|
|
494
|
+
if (typeof input == "function") {
|
|
495
|
+
T = input;
|
|
496
|
+
I = new input();
|
|
497
|
+
} else {
|
|
498
|
+
I = input;
|
|
499
|
+
T = I.constructor;
|
|
500
|
+
writable = false;
|
|
501
|
+
}
|
|
502
|
+
this.has(I);
|
|
503
|
+
this.put(T, I, implicit, writable);
|
|
504
|
+
return I;
|
|
505
|
+
}
|
|
506
|
+
push(inputs) {
|
|
507
|
+
const next = Object.create(this);
|
|
508
|
+
next.layer = /* @__PURE__ */ new Map();
|
|
509
|
+
if (inputs)
|
|
510
|
+
next.include(inputs);
|
|
511
|
+
return next;
|
|
512
|
+
}
|
|
513
|
+
pop() {
|
|
514
|
+
const items = /* @__PURE__ */ new Set();
|
|
515
|
+
for (const key of Object.getOwnPropertySymbols(this)) {
|
|
516
|
+
const entry = Object.getOwnPropertyDescriptor(this, key);
|
|
517
|
+
if (entry.writable && entry.value)
|
|
518
|
+
items.add(entry.value);
|
|
519
|
+
delete this[key];
|
|
520
|
+
}
|
|
521
|
+
for (const model of items)
|
|
522
|
+
model.set(null);
|
|
523
|
+
this.layer.clear();
|
|
524
|
+
}
|
|
525
|
+
};
|
|
526
|
+
|
|
399
527
|
// src/instruction/use.ts
|
|
400
528
|
var INSTRUCT = /* @__PURE__ */ new Map();
|
|
401
529
|
function use(model, argument) {
|
|
@@ -467,20 +595,21 @@ Model.on((_, subject) => {
|
|
|
467
595
|
// src/instruction/get.ts
|
|
468
596
|
var STALE = /* @__PURE__ */ new WeakSet();
|
|
469
597
|
function get(arg0, arg1) {
|
|
470
|
-
return use((key, subject) => {
|
|
598
|
+
return use((key, subject, state) => {
|
|
471
599
|
let from = subject;
|
|
472
600
|
if (typeof arg0 == "symbol")
|
|
473
601
|
throw new Error(`Attempted to use an instruction result (probably use or get) as computed source for ${from}.${key}. This is not allowed.`);
|
|
474
602
|
let source = (resolve) => resolve(from);
|
|
475
603
|
if (arg0 instanceof Model) {
|
|
476
604
|
from = arg0;
|
|
477
|
-
} else if (arg0
|
|
605
|
+
} else if (Model.is(arg0)) {
|
|
478
606
|
const hasParent = PARENT.get(from);
|
|
479
607
|
if (!hasParent) {
|
|
480
608
|
if (arg1 === true)
|
|
481
609
|
throw new Error(`${from} may only exist as a child of type ${arg0}.`);
|
|
482
610
|
source = (resolve) => {
|
|
483
|
-
|
|
611
|
+
Context.get(from, (context) => {
|
|
612
|
+
const got = context.get(arg0);
|
|
484
613
|
if (got)
|
|
485
614
|
resolve(got);
|
|
486
615
|
else if (arg1 !== false)
|
|
@@ -499,10 +628,8 @@ function get(arg0, arg1) {
|
|
|
499
628
|
let connect2 = function(model) {
|
|
500
629
|
reset = effect(model, (current) => {
|
|
501
630
|
proxy = current;
|
|
502
|
-
if (!
|
|
503
|
-
compute2(
|
|
504
|
-
else if (STALE.delete(compute2))
|
|
505
|
-
compute2();
|
|
631
|
+
if (!(key in state) || STALE.delete(compute2))
|
|
632
|
+
compute2(!reset);
|
|
506
633
|
return (didUpdate) => {
|
|
507
634
|
if (didUpdate) {
|
|
508
635
|
STALE.add(compute2);
|
|
@@ -666,178 +793,49 @@ function attempt(fn) {
|
|
|
666
793
|
return compute();
|
|
667
794
|
}
|
|
668
795
|
|
|
669
|
-
// src/context.ts
|
|
670
|
-
var Expects = /* @__PURE__ */ new WeakMap();
|
|
671
|
-
var Context = class {
|
|
672
|
-
constructor(inputs) {
|
|
673
|
-
this.downstream = /* @__PURE__ */ new WeakMap();
|
|
674
|
-
this.upstream = /* @__PURE__ */ new WeakMap();
|
|
675
|
-
this.layer = /* @__PURE__ */ new Map();
|
|
676
|
-
if (inputs)
|
|
677
|
-
this.include(inputs);
|
|
678
|
-
}
|
|
679
|
-
static request(type, from, callback) {
|
|
680
|
-
let map = Expects.get(from);
|
|
681
|
-
if (!map)
|
|
682
|
-
Expects.set(from, map = /* @__PURE__ */ new Map());
|
|
683
|
-
map.set(type, callback);
|
|
684
|
-
}
|
|
685
|
-
key(T, upstream) {
|
|
686
|
-
const table = upstream ? this.upstream : this.downstream;
|
|
687
|
-
let key = table.get(T);
|
|
688
|
-
if (!key) {
|
|
689
|
-
key = Symbol(T.name + (upstream ? " request" : ""));
|
|
690
|
-
table.set(T, key);
|
|
691
|
-
}
|
|
692
|
-
return key;
|
|
693
|
-
}
|
|
694
|
-
has(model) {
|
|
695
|
-
const key = this.key(model.constructor, true);
|
|
696
|
-
const result = this[key];
|
|
697
|
-
if (typeof result == "function")
|
|
698
|
-
return result(model);
|
|
699
|
-
}
|
|
700
|
-
get(Type) {
|
|
701
|
-
const result = this[this.key(Type)];
|
|
702
|
-
if (result === null)
|
|
703
|
-
throw new Error(`Did find ${Type} in context, but multiple were defined.`);
|
|
704
|
-
return result;
|
|
705
|
-
}
|
|
706
|
-
include(inputs, forEach) {
|
|
707
|
-
const init = /* @__PURE__ */ new Map();
|
|
708
|
-
if (typeof inputs == "function" || inputs instanceof Model)
|
|
709
|
-
inputs = { [0]: inputs };
|
|
710
|
-
else if (!inputs)
|
|
711
|
-
reject(inputs);
|
|
712
|
-
Object.entries(inputs).forEach(([K, V]) => {
|
|
713
|
-
if (!(Model.is(V) || V instanceof Model))
|
|
714
|
-
reject(`${V} as ${K}`);
|
|
715
|
-
});
|
|
716
|
-
for (const key in inputs) {
|
|
717
|
-
const input = inputs[key];
|
|
718
|
-
const exists = this.layer.get(key);
|
|
719
|
-
if (!exists) {
|
|
720
|
-
const instance = this.add(input);
|
|
721
|
-
this.layer.set(key, input);
|
|
722
|
-
init.set(instance, true);
|
|
723
|
-
} else if (exists !== input) {
|
|
724
|
-
this.pop();
|
|
725
|
-
this.id = uid();
|
|
726
|
-
this.include(inputs);
|
|
727
|
-
}
|
|
728
|
-
}
|
|
729
|
-
for (const [model, explicit] of init) {
|
|
730
|
-
if (forEach)
|
|
731
|
-
forEach(model, explicit);
|
|
732
|
-
model.set();
|
|
733
|
-
this.has(model);
|
|
734
|
-
const expects = Expects.get(model);
|
|
735
|
-
if (expects)
|
|
736
|
-
for (let [T, callback] of expects)
|
|
737
|
-
this.put(T, callback);
|
|
738
|
-
for (const [_key, value] of model)
|
|
739
|
-
if (PARENT.get(value) === model) {
|
|
740
|
-
this.add(value, true);
|
|
741
|
-
init.set(value, false);
|
|
742
|
-
}
|
|
743
|
-
}
|
|
744
|
-
}
|
|
745
|
-
put(T, I, implicit, writable) {
|
|
746
|
-
do {
|
|
747
|
-
const key = this.key(T, typeof I == "function");
|
|
748
|
-
const value = this.hasOwnProperty(key) ? null : I;
|
|
749
|
-
if (value || this[key] !== I && !implicit)
|
|
750
|
-
Object.defineProperty(this, key, {
|
|
751
|
-
configurable: true,
|
|
752
|
-
writable,
|
|
753
|
-
value
|
|
754
|
-
});
|
|
755
|
-
T = Object.getPrototypeOf(T);
|
|
756
|
-
} while (T !== Model);
|
|
757
|
-
}
|
|
758
|
-
add(input, implicit) {
|
|
759
|
-
let writable = true;
|
|
760
|
-
let T;
|
|
761
|
-
let I;
|
|
762
|
-
if (typeof input == "function") {
|
|
763
|
-
T = input;
|
|
764
|
-
I = new input();
|
|
765
|
-
} else {
|
|
766
|
-
I = input;
|
|
767
|
-
T = I.constructor;
|
|
768
|
-
writable = false;
|
|
769
|
-
}
|
|
770
|
-
this.put(T, I, implicit, writable);
|
|
771
|
-
return I;
|
|
772
|
-
}
|
|
773
|
-
push(inputs) {
|
|
774
|
-
const next = Object.create(this);
|
|
775
|
-
next.layer = /* @__PURE__ */ new Map();
|
|
776
|
-
if (inputs)
|
|
777
|
-
next.include(inputs);
|
|
778
|
-
return next;
|
|
779
|
-
}
|
|
780
|
-
pop() {
|
|
781
|
-
const items = /* @__PURE__ */ new Set();
|
|
782
|
-
for (const key of Object.getOwnPropertySymbols(this)) {
|
|
783
|
-
const entry = Object.getOwnPropertyDescriptor(this, key);
|
|
784
|
-
if (entry.writable && entry.value)
|
|
785
|
-
items.add(entry.value);
|
|
786
|
-
delete this[key];
|
|
787
|
-
}
|
|
788
|
-
for (const model of items)
|
|
789
|
-
model.set(null);
|
|
790
|
-
this.layer.clear();
|
|
791
|
-
}
|
|
792
|
-
};
|
|
793
|
-
function reject(argument) {
|
|
794
|
-
throw new Error(`Context can only include Model or instance but got ${argument}.`);
|
|
795
|
-
}
|
|
796
|
-
|
|
797
796
|
// src/instruction/has.ts
|
|
798
797
|
function has(type, argument) {
|
|
799
798
|
return use((key, subject, state) => {
|
|
799
|
+
const expect = (callback) => Context.get(subject, (context) => context.put(type, callback));
|
|
800
800
|
if (typeof argument == "boolean") {
|
|
801
|
-
|
|
801
|
+
expect((model) => {
|
|
802
802
|
subject.set(key, model);
|
|
803
803
|
const remove = () => {
|
|
804
|
-
drop();
|
|
805
804
|
if (state[key] === model)
|
|
806
805
|
delete state[key];
|
|
807
806
|
};
|
|
808
|
-
|
|
807
|
+
model.get(null, remove);
|
|
809
808
|
return remove;
|
|
810
809
|
});
|
|
811
810
|
return { get: argument };
|
|
812
811
|
}
|
|
813
|
-
const
|
|
814
|
-
|
|
815
|
-
if (
|
|
812
|
+
const value = /* @__PURE__ */ new Set();
|
|
813
|
+
expect((model) => {
|
|
814
|
+
if (value.has(model))
|
|
816
815
|
return;
|
|
817
816
|
const remove = typeof argument == "function" ? argument(model) : void 0;
|
|
818
817
|
if (remove === false)
|
|
819
818
|
return;
|
|
820
|
-
|
|
819
|
+
value.add(model);
|
|
821
820
|
subject.set(key);
|
|
822
821
|
const done = () => {
|
|
823
822
|
drop();
|
|
824
823
|
if (typeof remove == "function")
|
|
825
824
|
remove();
|
|
826
|
-
|
|
825
|
+
value.delete(model);
|
|
827
826
|
subject.set(key);
|
|
828
827
|
};
|
|
829
828
|
const drop = model.get(null, done);
|
|
830
829
|
return done;
|
|
831
830
|
});
|
|
832
|
-
return {
|
|
833
|
-
value: children
|
|
834
|
-
};
|
|
831
|
+
return { value };
|
|
835
832
|
});
|
|
836
833
|
}
|
|
837
834
|
export {
|
|
838
835
|
Context,
|
|
839
836
|
Model,
|
|
840
837
|
Model as default,
|
|
838
|
+
effect,
|
|
841
839
|
get,
|
|
842
840
|
has,
|
|
843
841
|
ref,
|
package/package.json
CHANGED