@expressive/mvc 0.47.0 → 0.48.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 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> = string | Assign<T> | Callback<T> | Promise<Assign<T> | (() => void) | void> | void;
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 {
@@ -356,10 +355,11 @@ declare function has<T extends Model>(type: Model.Type<T>, required: boolean): T
356
355
  declare function has<T extends Model>(type: Model.Type<T>, arg?: has.Callback<T>): Set<T>;
357
356
 
358
357
  declare namespace Context {
359
- type Input = Model | Model.Type<Model> | Record<string | number, Model | Model.Type<Model>>;
358
+ type Input = Record<string | number, Model | Model.Type<Model>>;
360
359
  }
361
360
  declare class Context {
362
- static request<T extends Model>(type: Model.Type<T>, from: Model, callback: (got: T) => void): void;
361
+ static get<T extends Model>(on: Model, callback: ((got: Context) => void)): void;
362
+ static get<T extends Model>(on: Model): Context | undefined;
363
363
  id: string;
364
364
  protected downstream: WeakMap<Model.Type<Model>, symbol>;
365
365
  protected upstream: WeakMap<Model.Type<Model>, symbol>;
package/dist/index.js CHANGED
@@ -150,7 +150,7 @@ function effect(target, callback) {
150
150
  }
151
151
 
152
152
  // src/model.ts
153
- var FLATTEN;
153
+ var EXPORT;
154
154
  var NAMES = /* @__PURE__ */ new WeakMap();
155
155
  var STATE = /* @__PURE__ */ new WeakMap();
156
156
  var NOTIFY = /* @__PURE__ */ new WeakMap();
@@ -235,16 +235,16 @@ var Model = class _Model {
235
235
  }
236
236
  if (arg1 === void 0) {
237
237
  const values = {};
238
- const current = !FLATTEN && (FLATTEN = /* @__PURE__ */ new Map([[self, values]]));
238
+ const current = !EXPORT && (EXPORT = /* @__PURE__ */ new Map([[self, values]]));
239
239
  for (let [key, value] of self) {
240
- if (FLATTEN.has(value))
241
- value = FLATTEN.get(value);
240
+ if (EXPORT.has(value))
241
+ value = EXPORT.get(value);
242
242
  else if (value && typeof value.get === "function")
243
- FLATTEN.set(value, value = value.get());
243
+ EXPORT.set(value, value = value.get());
244
244
  values[key] = value;
245
245
  }
246
246
  if (current)
247
- FLATTEN = void 0;
247
+ EXPORT = void 0;
248
248
  return Object.freeze(values);
249
249
  }
250
250
  if (typeof arg2 == "function") {
@@ -323,9 +323,6 @@ var Model = class _Model {
323
323
  notify.add(listener);
324
324
  return () => notify.delete(listener);
325
325
  }
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
326
  };
330
327
  define(Model.prototype, "toString", {
331
328
  value() {
@@ -345,14 +342,14 @@ function fetch(subject, property, required) {
345
342
  return value;
346
343
  }
347
344
  const error = new Error(`${subject}.${property} is not yet available.`);
348
- const promise = new Promise((resolve, reject2) => {
345
+ const promise = new Promise((resolve, reject) => {
349
346
  addListener(subject, (key) => {
350
347
  if (key === property) {
351
348
  resolve(state[key]);
352
349
  return null;
353
350
  }
354
351
  if (key === null)
355
- reject2(new Error(`${subject} is destroyed.`));
352
+ reject(new Error(`${subject} is destroyed.`));
356
353
  });
357
354
  });
358
355
  throw Object.assign(promise, {
@@ -429,6 +426,132 @@ function uid() {
429
426
  return (Math.random() * 0.722 + 0.278).toString(36).substring(2, 8).toUpperCase();
430
427
  }
431
428
 
429
+ // src/context.ts
430
+ var Register = /* @__PURE__ */ new WeakMap();
431
+ var Context = class _Context {
432
+ constructor(inputs) {
433
+ this.downstream = /* @__PURE__ */ new WeakMap();
434
+ this.upstream = /* @__PURE__ */ new WeakMap();
435
+ this.layer = /* @__PURE__ */ new Map();
436
+ if (inputs)
437
+ this.include(inputs);
438
+ }
439
+ static get(from, callback) {
440
+ const waiting = Register.get(from);
441
+ if (!callback)
442
+ return waiting instanceof _Context ? waiting : void 0;
443
+ if (waiting instanceof _Context)
444
+ callback(waiting);
445
+ else if (waiting)
446
+ waiting.push(callback);
447
+ else
448
+ Register.set(from, [callback]);
449
+ }
450
+ key(T, upstream) {
451
+ const table = upstream ? this.upstream : this.downstream;
452
+ let key = table.get(T);
453
+ if (!key) {
454
+ key = Symbol(T.name + (upstream ? " request" : ""));
455
+ table.set(T, key);
456
+ }
457
+ return key;
458
+ }
459
+ has(model) {
460
+ const key = this.key(model.constructor, true);
461
+ const result = this[key];
462
+ const waiting = Register.get(model);
463
+ if (waiting instanceof Array)
464
+ waiting.forEach((cb) => cb(this));
465
+ Register.set(model, this);
466
+ if (typeof result == "function")
467
+ return result(model);
468
+ }
469
+ get(Type) {
470
+ const result = this[this.key(Type)];
471
+ if (result === null)
472
+ throw new Error(`Did find ${Type} in context, but multiple were defined.`);
473
+ return result;
474
+ }
475
+ include(inputs, forEach) {
476
+ const init = /* @__PURE__ */ new Map();
477
+ Object.entries(inputs).forEach(([K, V]) => {
478
+ if (!(Model.is(V) || V instanceof Model))
479
+ throw new Error(`Context can only include Model or instance but got ${V}${K && " as " + K}.`);
480
+ });
481
+ for (const key in inputs) {
482
+ const input = inputs[key];
483
+ const exists = this.layer.get(key);
484
+ if (!exists) {
485
+ const instance = this.add(input);
486
+ this.layer.set(key, input);
487
+ init.set(instance, true);
488
+ } else if (exists !== input) {
489
+ this.pop();
490
+ this.id = uid();
491
+ this.include(inputs);
492
+ }
493
+ }
494
+ for (const [model, explicit] of init) {
495
+ model.set();
496
+ if (forEach)
497
+ forEach(model, explicit);
498
+ for (const [_key, value] of model)
499
+ if (PARENT.get(value) === model) {
500
+ this.add(value, true);
501
+ init.set(value, false);
502
+ }
503
+ }
504
+ }
505
+ put(T, I, implicit, writable) {
506
+ do {
507
+ const key = this.key(T, typeof I == "function");
508
+ const value = this.hasOwnProperty(key) ? null : I;
509
+ if (value || this[key] !== I && !implicit)
510
+ Object.defineProperty(this, key, {
511
+ configurable: true,
512
+ writable,
513
+ value
514
+ });
515
+ T = Object.getPrototypeOf(T);
516
+ } while (T !== Model);
517
+ }
518
+ add(input, implicit) {
519
+ let writable = true;
520
+ let T;
521
+ let I;
522
+ if (typeof input == "function") {
523
+ T = input;
524
+ I = new input();
525
+ } else {
526
+ I = input;
527
+ T = I.constructor;
528
+ writable = false;
529
+ }
530
+ this.has(I);
531
+ this.put(T, I, implicit, writable);
532
+ return I;
533
+ }
534
+ push(inputs) {
535
+ const next = Object.create(this);
536
+ next.layer = /* @__PURE__ */ new Map();
537
+ if (inputs)
538
+ next.include(inputs);
539
+ return next;
540
+ }
541
+ pop() {
542
+ const items = /* @__PURE__ */ new Set();
543
+ for (const key of Object.getOwnPropertySymbols(this)) {
544
+ const entry = Object.getOwnPropertyDescriptor(this, key);
545
+ if (entry.writable && entry.value)
546
+ items.add(entry.value);
547
+ delete this[key];
548
+ }
549
+ for (const model of items)
550
+ model.set(null);
551
+ this.layer.clear();
552
+ }
553
+ };
554
+
432
555
  // src/instruction/use.ts
433
556
  var INSTRUCT = /* @__PURE__ */ new Map();
434
557
  function use(model, argument) {
@@ -500,20 +623,21 @@ Model.on((_, subject) => {
500
623
  // src/instruction/get.ts
501
624
  var STALE = /* @__PURE__ */ new WeakSet();
502
625
  function get(arg0, arg1) {
503
- return use((key, subject) => {
626
+ return use((key, subject, state) => {
504
627
  let from = subject;
505
628
  if (typeof arg0 == "symbol")
506
629
  throw new Error(`Attempted to use an instruction result (probably use or get) as computed source for ${from}.${key}. This is not allowed.`);
507
630
  let source = (resolve) => resolve(from);
508
631
  if (arg0 instanceof Model) {
509
632
  from = arg0;
510
- } else if (arg0.prototype instanceof Model) {
633
+ } else if (Model.is(arg0)) {
511
634
  const hasParent = PARENT.get(from);
512
635
  if (!hasParent) {
513
636
  if (arg1 === true)
514
637
  throw new Error(`${from} may only exist as a child of type ${arg0}.`);
515
638
  source = (resolve) => {
516
- arg0.at(from, (got) => {
639
+ Context.get(from, (context) => {
640
+ const got = context.get(arg0);
517
641
  if (got)
518
642
  resolve(got);
519
643
  else if (arg1 !== false)
@@ -532,10 +656,8 @@ function get(arg0, arg1) {
532
656
  let connect2 = function(model) {
533
657
  reset = effect(model, (current) => {
534
658
  proxy = current;
535
- if (!reset)
536
- compute2(true);
537
- else if (STALE.delete(compute2))
538
- compute2();
659
+ if (!(key in state) || STALE.delete(compute2))
660
+ compute2(!reset);
539
661
  return (didUpdate) => {
540
662
  if (didUpdate) {
541
663
  STALE.add(compute2);
@@ -699,172 +821,42 @@ function attempt(fn) {
699
821
  return compute();
700
822
  }
701
823
 
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
824
  // src/instruction/has.ts
831
825
  function has(type, argument) {
832
826
  return use((key, subject, state) => {
827
+ const expect = (callback) => Context.get(subject, (context) => context.put(type, callback));
833
828
  if (typeof argument == "boolean") {
834
- Context.request(type, subject, (model) => {
829
+ expect((model) => {
835
830
  subject.set(key, model);
836
831
  const remove = () => {
837
- drop();
838
832
  if (state[key] === model)
839
833
  delete state[key];
840
834
  };
841
- const drop = model.get(null, remove);
835
+ model.get(null, remove);
842
836
  return remove;
843
837
  });
844
838
  return { get: argument };
845
839
  }
846
- const children = /* @__PURE__ */ new Set();
847
- Context.request(type, subject, (model) => {
848
- if (children.has(model))
840
+ const value = /* @__PURE__ */ new Set();
841
+ expect((model) => {
842
+ if (value.has(model))
849
843
  return;
850
844
  const remove = typeof argument == "function" ? argument(model) : void 0;
851
845
  if (remove === false)
852
846
  return;
853
- children.add(model);
847
+ value.add(model);
854
848
  subject.set(key);
855
849
  const done = () => {
856
850
  drop();
857
851
  if (typeof remove == "function")
858
852
  remove();
859
- children.delete(model);
853
+ value.delete(model);
860
854
  subject.set(key);
861
855
  };
862
856
  const drop = model.get(null, done);
863
857
  return done;
864
858
  });
865
- return {
866
- value: children
867
- };
859
+ return { value };
868
860
  });
869
861
  }
870
862
  // Annotate the CommonJS export names for ESM import in node:
package/dist/index.mjs CHANGED
@@ -117,7 +117,7 @@ function effect(target, callback) {
117
117
  }
118
118
 
119
119
  // src/model.ts
120
- var FLATTEN;
120
+ var EXPORT;
121
121
  var NAMES = /* @__PURE__ */ new WeakMap();
122
122
  var STATE = /* @__PURE__ */ new WeakMap();
123
123
  var NOTIFY = /* @__PURE__ */ new WeakMap();
@@ -202,16 +202,16 @@ var Model = class _Model {
202
202
  }
203
203
  if (arg1 === void 0) {
204
204
  const values = {};
205
- const current = !FLATTEN && (FLATTEN = /* @__PURE__ */ new Map([[self, values]]));
205
+ const current = !EXPORT && (EXPORT = /* @__PURE__ */ new Map([[self, values]]));
206
206
  for (let [key, value] of self) {
207
- if (FLATTEN.has(value))
208
- value = FLATTEN.get(value);
207
+ if (EXPORT.has(value))
208
+ value = EXPORT.get(value);
209
209
  else if (value && typeof value.get === "function")
210
- FLATTEN.set(value, value = value.get());
210
+ EXPORT.set(value, value = value.get());
211
211
  values[key] = value;
212
212
  }
213
213
  if (current)
214
- FLATTEN = void 0;
214
+ EXPORT = void 0;
215
215
  return Object.freeze(values);
216
216
  }
217
217
  if (typeof arg2 == "function") {
@@ -290,9 +290,6 @@ var Model = class _Model {
290
290
  notify.add(listener);
291
291
  return () => notify.delete(listener);
292
292
  }
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
293
  };
297
294
  define(Model.prototype, "toString", {
298
295
  value() {
@@ -312,14 +309,14 @@ function fetch(subject, property, required) {
312
309
  return value;
313
310
  }
314
311
  const error = new Error(`${subject}.${property} is not yet available.`);
315
- const promise = new Promise((resolve, reject2) => {
312
+ const promise = new Promise((resolve, reject) => {
316
313
  addListener(subject, (key) => {
317
314
  if (key === property) {
318
315
  resolve(state[key]);
319
316
  return null;
320
317
  }
321
318
  if (key === null)
322
- reject2(new Error(`${subject} is destroyed.`));
319
+ reject(new Error(`${subject} is destroyed.`));
323
320
  });
324
321
  });
325
322
  throw Object.assign(promise, {
@@ -396,6 +393,132 @@ function uid() {
396
393
  return (Math.random() * 0.722 + 0.278).toString(36).substring(2, 8).toUpperCase();
397
394
  }
398
395
 
396
+ // src/context.ts
397
+ var Register = /* @__PURE__ */ new WeakMap();
398
+ var Context = class _Context {
399
+ constructor(inputs) {
400
+ this.downstream = /* @__PURE__ */ new WeakMap();
401
+ this.upstream = /* @__PURE__ */ new WeakMap();
402
+ this.layer = /* @__PURE__ */ new Map();
403
+ if (inputs)
404
+ this.include(inputs);
405
+ }
406
+ static get(from, callback) {
407
+ const waiting = Register.get(from);
408
+ if (!callback)
409
+ return waiting instanceof _Context ? waiting : void 0;
410
+ if (waiting instanceof _Context)
411
+ callback(waiting);
412
+ else if (waiting)
413
+ waiting.push(callback);
414
+ else
415
+ Register.set(from, [callback]);
416
+ }
417
+ key(T, upstream) {
418
+ const table = upstream ? this.upstream : this.downstream;
419
+ let key = table.get(T);
420
+ if (!key) {
421
+ key = Symbol(T.name + (upstream ? " request" : ""));
422
+ table.set(T, key);
423
+ }
424
+ return key;
425
+ }
426
+ has(model) {
427
+ const key = this.key(model.constructor, true);
428
+ const result = this[key];
429
+ const waiting = Register.get(model);
430
+ if (waiting instanceof Array)
431
+ waiting.forEach((cb) => cb(this));
432
+ Register.set(model, this);
433
+ if (typeof result == "function")
434
+ return result(model);
435
+ }
436
+ get(Type) {
437
+ const result = this[this.key(Type)];
438
+ if (result === null)
439
+ throw new Error(`Did find ${Type} in context, but multiple were defined.`);
440
+ return result;
441
+ }
442
+ include(inputs, forEach) {
443
+ const init = /* @__PURE__ */ new Map();
444
+ Object.entries(inputs).forEach(([K, V]) => {
445
+ if (!(Model.is(V) || V instanceof Model))
446
+ throw new Error(`Context can only include Model or instance but got ${V}${K && " as " + K}.`);
447
+ });
448
+ for (const key in inputs) {
449
+ const input = inputs[key];
450
+ const exists = this.layer.get(key);
451
+ if (!exists) {
452
+ const instance = this.add(input);
453
+ this.layer.set(key, input);
454
+ init.set(instance, true);
455
+ } else if (exists !== input) {
456
+ this.pop();
457
+ this.id = uid();
458
+ this.include(inputs);
459
+ }
460
+ }
461
+ for (const [model, explicit] of init) {
462
+ model.set();
463
+ if (forEach)
464
+ forEach(model, explicit);
465
+ for (const [_key, value] of model)
466
+ if (PARENT.get(value) === model) {
467
+ this.add(value, true);
468
+ init.set(value, false);
469
+ }
470
+ }
471
+ }
472
+ put(T, I, implicit, writable) {
473
+ do {
474
+ const key = this.key(T, typeof I == "function");
475
+ const value = this.hasOwnProperty(key) ? null : I;
476
+ if (value || this[key] !== I && !implicit)
477
+ Object.defineProperty(this, key, {
478
+ configurable: true,
479
+ writable,
480
+ value
481
+ });
482
+ T = Object.getPrototypeOf(T);
483
+ } while (T !== Model);
484
+ }
485
+ add(input, implicit) {
486
+ let writable = true;
487
+ let T;
488
+ let I;
489
+ if (typeof input == "function") {
490
+ T = input;
491
+ I = new input();
492
+ } else {
493
+ I = input;
494
+ T = I.constructor;
495
+ writable = false;
496
+ }
497
+ this.has(I);
498
+ this.put(T, I, implicit, writable);
499
+ return I;
500
+ }
501
+ push(inputs) {
502
+ const next = Object.create(this);
503
+ next.layer = /* @__PURE__ */ new Map();
504
+ if (inputs)
505
+ next.include(inputs);
506
+ return next;
507
+ }
508
+ pop() {
509
+ const items = /* @__PURE__ */ new Set();
510
+ for (const key of Object.getOwnPropertySymbols(this)) {
511
+ const entry = Object.getOwnPropertyDescriptor(this, key);
512
+ if (entry.writable && entry.value)
513
+ items.add(entry.value);
514
+ delete this[key];
515
+ }
516
+ for (const model of items)
517
+ model.set(null);
518
+ this.layer.clear();
519
+ }
520
+ };
521
+
399
522
  // src/instruction/use.ts
400
523
  var INSTRUCT = /* @__PURE__ */ new Map();
401
524
  function use(model, argument) {
@@ -467,20 +590,21 @@ Model.on((_, subject) => {
467
590
  // src/instruction/get.ts
468
591
  var STALE = /* @__PURE__ */ new WeakSet();
469
592
  function get(arg0, arg1) {
470
- return use((key, subject) => {
593
+ return use((key, subject, state) => {
471
594
  let from = subject;
472
595
  if (typeof arg0 == "symbol")
473
596
  throw new Error(`Attempted to use an instruction result (probably use or get) as computed source for ${from}.${key}. This is not allowed.`);
474
597
  let source = (resolve) => resolve(from);
475
598
  if (arg0 instanceof Model) {
476
599
  from = arg0;
477
- } else if (arg0.prototype instanceof Model) {
600
+ } else if (Model.is(arg0)) {
478
601
  const hasParent = PARENT.get(from);
479
602
  if (!hasParent) {
480
603
  if (arg1 === true)
481
604
  throw new Error(`${from} may only exist as a child of type ${arg0}.`);
482
605
  source = (resolve) => {
483
- arg0.at(from, (got) => {
606
+ Context.get(from, (context) => {
607
+ const got = context.get(arg0);
484
608
  if (got)
485
609
  resolve(got);
486
610
  else if (arg1 !== false)
@@ -499,10 +623,8 @@ function get(arg0, arg1) {
499
623
  let connect2 = function(model) {
500
624
  reset = effect(model, (current) => {
501
625
  proxy = current;
502
- if (!reset)
503
- compute2(true);
504
- else if (STALE.delete(compute2))
505
- compute2();
626
+ if (!(key in state) || STALE.delete(compute2))
627
+ compute2(!reset);
506
628
  return (didUpdate) => {
507
629
  if (didUpdate) {
508
630
  STALE.add(compute2);
@@ -666,172 +788,42 @@ function attempt(fn) {
666
788
  return compute();
667
789
  }
668
790
 
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
791
  // src/instruction/has.ts
798
792
  function has(type, argument) {
799
793
  return use((key, subject, state) => {
794
+ const expect = (callback) => Context.get(subject, (context) => context.put(type, callback));
800
795
  if (typeof argument == "boolean") {
801
- Context.request(type, subject, (model) => {
796
+ expect((model) => {
802
797
  subject.set(key, model);
803
798
  const remove = () => {
804
- drop();
805
799
  if (state[key] === model)
806
800
  delete state[key];
807
801
  };
808
- const drop = model.get(null, remove);
802
+ model.get(null, remove);
809
803
  return remove;
810
804
  });
811
805
  return { get: argument };
812
806
  }
813
- const children = /* @__PURE__ */ new Set();
814
- Context.request(type, subject, (model) => {
815
- if (children.has(model))
807
+ const value = /* @__PURE__ */ new Set();
808
+ expect((model) => {
809
+ if (value.has(model))
816
810
  return;
817
811
  const remove = typeof argument == "function" ? argument(model) : void 0;
818
812
  if (remove === false)
819
813
  return;
820
- children.add(model);
814
+ value.add(model);
821
815
  subject.set(key);
822
816
  const done = () => {
823
817
  drop();
824
818
  if (typeof remove == "function")
825
819
  remove();
826
- children.delete(model);
820
+ value.delete(model);
827
821
  subject.set(key);
828
822
  };
829
823
  const drop = model.get(null, done);
830
824
  return done;
831
825
  });
832
- return {
833
- value: children
834
- };
826
+ return { value };
835
827
  });
836
828
  }
837
829
  export {
package/package.json CHANGED
@@ -28,6 +28,6 @@
28
28
  "prebuild": "rm -rf dist",
29
29
  "preversion": "npm run test && npm run build"
30
30
  },
31
- "version": "0.47.0",
32
- "gitHead": "7c0ddd5ea9b7e08bd5aa21aa8e1ab65ceef17fcf"
31
+ "version": "0.48.0",
32
+ "gitHead": "1f5ddf82e800cf53bf867ac5e546ad3186ce8bf5"
33
33
  }