@expressive/mvc 0.48.0 → 0.50.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.js CHANGED
@@ -9,9 +9,9 @@ var __export = (target, all) => {
9
9
  };
10
10
  var __copyProps = (to, from, except, desc) => {
11
11
  if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
12
+ for (let key2 of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key2) && key2 !== except)
14
+ __defProp(to, key2, { get: () => from[key2], enumerable: !(desc = __getOwnPropDesc(from, key2)) || desc.enumerable });
15
15
  }
16
16
  return to;
17
17
  };
@@ -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,
@@ -40,79 +41,66 @@ function addListener(subject, callback, select) {
40
41
  let subs = LISTENER.get(subject);
41
42
  if (!subs)
42
43
  LISTENER.set(subject, subs = /* @__PURE__ */ new Map([[onReady, false]]));
43
- const filter = 2 in arguments && /* @__PURE__ */ new Set([select]);
44
+ const filter = select !== void 0 && /* @__PURE__ */ new Set([select]);
44
45
  if (!filter && !subs.has(onReady))
45
46
  callback(true, subject);
46
47
  subs.set(callback, filter);
47
48
  return () => subs.delete(callback);
48
49
  }
49
- function watch(from, key, value) {
50
- const observer = OBSERVER.get(from);
51
- if (observer) {
52
- const listeners = LISTENER.get(from);
53
- listeners.set(
54
- observer,
55
- (listeners.get(observer) || /* @__PURE__ */ new Set()).add(key)
56
- );
57
- const nested = LISTENER.get(value);
58
- if (nested) {
59
- LISTENER.set(value = Object.create(value), nested);
60
- OBSERVER.set(value, observer);
61
- }
62
- }
63
- return value;
50
+ function watch(from, key2, value) {
51
+ const access = OBSERVER.get(from);
52
+ return access ? access(from, key2, value) : value;
64
53
  }
65
54
  var PENDING = /* @__PURE__ */ new WeakMap();
66
- function event(source, key) {
55
+ function emit(source, key2) {
67
56
  const subs = LISTENER.get(source);
68
57
  const ready = !subs.has(onReady);
69
- if (key === true && ready)
58
+ if (key2 === true && ready)
70
59
  return;
71
60
  let pending = PENDING.get(source);
72
61
  if (pending) {
73
- pending.add(key);
62
+ pending.add(key2);
74
63
  return;
75
64
  }
76
65
  PENDING.set(source, pending = new Set(
77
- key !== true && ready ? [key] : [true, key]
66
+ key2 !== true && ready ? [key2] : [true, key2]
78
67
  ));
79
- pending.forEach((key2) => {
80
- pending.delete(key2);
68
+ pending.forEach((key3) => {
69
+ pending.delete(key3);
81
70
  subs.forEach((select, callback) => {
82
71
  let after;
83
- if (!select || select.has(key2)) {
84
- if (after = callback.call(source, key2, source))
72
+ if (!select || select.has(key3)) {
73
+ if (after = callback.call(source, key3, source))
85
74
  queue(after);
86
75
  }
87
- if (after === null || key2 === null)
76
+ if (after === null || key3 === null)
88
77
  subs.delete(callback);
89
78
  });
90
79
  });
91
80
  PENDING.delete(source);
92
81
  }
93
- function queue(event2) {
82
+ function queue(event) {
94
83
  if (!DISPATCH.size)
95
84
  setTimeout(() => {
96
- DISPATCH.forEach((event3) => {
85
+ DISPATCH.forEach((event2) => {
97
86
  try {
98
- event3();
87
+ event2();
99
88
  } catch (err) {
100
89
  console.error(err);
101
90
  }
102
91
  });
103
92
  DISPATCH.clear();
104
93
  }, 0);
105
- DISPATCH.add(event2);
94
+ DISPATCH.add(event);
106
95
  }
107
- function effect(target, callback) {
96
+ function effect(target, callback, requireValues) {
108
97
  const listeners = LISTENER.get(target);
109
98
  let unset;
110
99
  let reset;
111
100
  function invoke() {
112
101
  let stale;
113
102
  const subscriber = Object.create(target);
114
- LISTENER.set(subscriber, listeners);
115
- OBSERVER.set(subscriber, () => {
103
+ function onUpdate() {
116
104
  if (stale)
117
105
  return null;
118
106
  stale = true;
@@ -121,7 +109,24 @@ function effect(target, callback) {
121
109
  unset = void 0;
122
110
  }
123
111
  return reset;
124
- });
112
+ }
113
+ function access(from, key2, value) {
114
+ if (value === void 0 && requireValues)
115
+ throw new Error(`${from}.${key2} is required in this context.`);
116
+ const listeners2 = LISTENER.get(from);
117
+ let listener = listeners2.get(onUpdate);
118
+ if (!listener)
119
+ listeners2.set(onUpdate, listener = /* @__PURE__ */ new Set());
120
+ listener.add(key2);
121
+ const nested = LISTENER.get(value);
122
+ if (nested) {
123
+ LISTENER.set(value = Object.create(value), nested);
124
+ OBSERVER.set(value, access);
125
+ }
126
+ return value;
127
+ }
128
+ LISTENER.set(subscriber, listeners);
129
+ OBSERVER.set(subscriber, access);
125
130
  try {
126
131
  const out = callback.call(subscriber, subscriber);
127
132
  unset = typeof out == "function" ? out : void 0;
@@ -134,12 +139,12 @@ function effect(target, callback) {
134
139
  throw err;
135
140
  }
136
141
  }
137
- addListener(target, (key) => {
138
- if (key === true)
142
+ addListener(target, (key2) => {
143
+ if (key2 === true)
139
144
  invoke();
140
145
  else if (!reset)
141
146
  return reset;
142
- if (key === null && unset)
147
+ if (key2 === null && unset)
143
148
  unset(null);
144
149
  });
145
150
  return () => {
@@ -193,15 +198,15 @@ var Model = class _Model {
193
198
  }
194
199
  done = cleanup;
195
200
  })();
196
- for (const key in this) {
197
- const desc = Object.getOwnPropertyDescriptor(this, key);
201
+ for (const key2 in this) {
202
+ const desc = Object.getOwnPropertyDescriptor(this, key2);
198
203
  if ("value" in desc) {
199
- update(this, key, desc.value, true);
200
- define(this, key, {
204
+ update(this, key2, desc.value, true);
205
+ define(this, key2, {
201
206
  configurable: false,
202
- set: (x) => update(this, key, x),
207
+ set: (x) => update(this, key2, x),
203
208
  get() {
204
- return watch(this, key, state[key]);
209
+ return watch(this, key2, state[key2]);
205
210
  }
206
211
  });
207
212
  }
@@ -236,12 +241,12 @@ var Model = class _Model {
236
241
  if (arg1 === void 0) {
237
242
  const values = {};
238
243
  const current = !EXPORT && (EXPORT = /* @__PURE__ */ new Map([[self, values]]));
239
- for (let [key, value] of self) {
244
+ for (let [key2, value] of self) {
240
245
  if (EXPORT.has(value))
241
246
  value = EXPORT.get(value);
242
247
  else if (value && typeof value.get === "function")
243
248
  EXPORT.set(value, value = value.get());
244
- values[key] = value;
249
+ values[key2] = value;
245
250
  }
246
251
  if (current)
247
252
  EXPORT = void 0;
@@ -262,16 +267,16 @@ var Model = class _Model {
262
267
  set(arg1, arg2, arg3) {
263
268
  const self = this.is;
264
269
  if (typeof arg1 == "function")
265
- return addListener(self, (key) => {
266
- if (typeof key == "string")
267
- return arg1.call(self, key, self);
270
+ return addListener(self, (key2) => {
271
+ if (typeof key2 == "string")
272
+ return arg1.call(self, key2, self);
268
273
  });
269
274
  if (arg1 === null)
270
- return event(this, null);
275
+ return emit(this, null);
271
276
  if (typeof arg1 == "object")
272
277
  assign(self, arg1);
273
278
  else if (arg1 == void 0)
274
- event(this, true);
279
+ emit(this, true);
275
280
  else if (1 in arguments)
276
281
  update(self, arg1, arg2, arg3);
277
282
  else
@@ -279,8 +284,8 @@ var Model = class _Model {
279
284
  if (PENDING2.has(self))
280
285
  return {
281
286
  then: (res) => new Promise((res2) => {
282
- const remove = addListener(self, (key) => {
283
- if (key !== true) {
287
+ const remove = addListener(self, (key2) => {
288
+ if (key2 !== true) {
284
289
  remove();
285
290
  return res2.bind(null, Array.from(PENDING2.get(self)));
286
291
  }
@@ -301,7 +306,7 @@ var Model = class _Model {
301
306
  */
302
307
  static new(...args) {
303
308
  const instance = new this(...args);
304
- event(instance, true);
309
+ emit(instance, true);
305
310
  return instance;
306
311
  }
307
312
  /**
@@ -343,12 +348,12 @@ function fetch(subject, property, required) {
343
348
  }
344
349
  const error = new Error(`${subject}.${property} is not yet available.`);
345
350
  const promise = new Promise((resolve, reject) => {
346
- addListener(subject, (key) => {
347
- if (key === property) {
348
- resolve(state[key]);
351
+ addListener(subject, (key2) => {
352
+ if (key2 === property) {
353
+ resolve(state[key2]);
349
354
  return null;
350
355
  }
351
- if (key === null)
356
+ if (key2 === null)
352
357
  reject(new Error(`${subject} is destroyed.`));
353
358
  });
354
359
  });
@@ -359,63 +364,70 @@ function fetch(subject, property, required) {
359
364
  stack: error.stack
360
365
  });
361
366
  }
362
- function update(subject, key, value, silent) {
367
+ function update(subject, key2, value, arg) {
363
368
  const state = STATE.get(subject);
364
369
  if (Object.isFrozen(state))
365
- throw new Error(`Tried to update ${String(key)} but ${subject} is destroyed.`);
366
- const previous = state[key];
370
+ throw new Error(`Tried to update ${String(key2)} but ${subject} is destroyed.`);
371
+ const previous = state[key2];
372
+ if (typeof arg == "function") {
373
+ const out = arg.call(subject, value, previous);
374
+ if (out === false)
375
+ return false;
376
+ if (typeof out == "function")
377
+ value = out();
378
+ }
367
379
  if (value === previous)
368
380
  return true;
369
381
  if (value instanceof Model && !PARENT.has(value)) {
370
382
  PARENT.set(value, subject);
371
- event(value, true);
383
+ emit(value, true);
372
384
  }
373
- state[key] = value;
374
- if (silent !== true)
375
- push(subject, key);
385
+ state[key2] = value;
386
+ if (arg !== true)
387
+ push(subject, key2);
376
388
  }
377
- function push(subject, key, silent) {
389
+ function push(subject, key2, silent) {
378
390
  let pending = PENDING2.get(subject);
379
391
  if (!pending) {
380
392
  PENDING2.set(subject, pending = /* @__PURE__ */ new Set());
381
393
  if (!silent)
382
394
  queue(() => {
383
- event(subject, false);
395
+ emit(subject, false);
384
396
  PENDING2.delete(subject);
385
397
  });
386
398
  }
387
- pending.add(key);
399
+ pending.add(key2);
388
400
  if (!silent)
389
- event(subject, key);
401
+ emit(subject, key2);
390
402
  }
391
403
  var METHODS = new WeakMap([[Model, []]]);
392
404
  function assign(to, values) {
393
405
  const methods = METHODS.get(to.constructor);
394
406
  const applicable = new Set(Object.keys(to).concat(methods));
395
- for (const key in values)
396
- if (applicable.has(key))
397
- to[key] = values[key];
407
+ for (const key2 in values)
408
+ if (applicable.has(key2))
409
+ to[key2] = values[key2];
398
410
  }
399
411
  function bindMethods(type) {
400
412
  let keys = METHODS.get(type);
401
413
  if (!keys) {
402
414
  METHODS.set(type, keys = bindMethods(Object.getPrototypeOf(type)).slice());
403
415
  const desc = Object.getOwnPropertyDescriptors(type.prototype);
404
- for (const key in desc)
405
- if (key != "constructor" && "value" in desc[key]) {
416
+ for (const key2 in desc)
417
+ if (key2 != "constructor" && "value" in desc[key2]) {
406
418
  let bind2 = function(method) {
407
419
  const value2 = method.bind(this.is);
408
420
  METHOD.set(value2, method);
409
- define(this.is, key, { value: value2, writable: true });
421
+ define(this.is, key2, { value: value2, writable: true });
410
422
  return value2;
411
423
  };
412
424
  var bind = bind2;
413
- let { value } = desc[key];
414
- keys.push(key);
415
- Object.defineProperty(type.prototype, key, {
425
+ let { value } = desc[key2];
426
+ keys.push(key2);
427
+ Object.defineProperty(type.prototype, key2, {
416
428
  set: bind2,
417
429
  get() {
418
- return this.hasOwnProperty(key) ? value : bind2.call(this, value);
430
+ return this.hasOwnProperty(key2) ? value : bind2.call(this, value);
419
431
  }
420
432
  });
421
433
  }
@@ -428,11 +440,21 @@ function uid() {
428
440
 
429
441
  // src/context.ts
430
442
  var Register = /* @__PURE__ */ new WeakMap();
443
+ var Upstream = /* @__PURE__ */ new WeakMap();
444
+ var Downstream = /* @__PURE__ */ new WeakMap();
445
+ function key(T, upstream) {
446
+ const table = upstream ? Upstream : Downstream;
447
+ let key2 = table.get(T);
448
+ if (!key2) {
449
+ key2 = Symbol(T.name + (upstream ? " request" : ""));
450
+ table.set(T, key2);
451
+ }
452
+ return key2;
453
+ }
431
454
  var Context = class _Context {
432
455
  constructor(inputs) {
433
- this.downstream = /* @__PURE__ */ new WeakMap();
434
- this.upstream = /* @__PURE__ */ new WeakMap();
435
456
  this.layer = /* @__PURE__ */ new Map();
457
+ this.cleanup = /* @__PURE__ */ new Set();
436
458
  if (inputs)
437
459
  this.include(inputs);
438
460
  }
@@ -447,43 +469,40 @@ var Context = class _Context {
447
469
  else
448
470
  Register.set(from, [callback]);
449
471
  }
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)];
472
+ get(Type, callback) {
473
+ if (callback)
474
+ return this.put(Type, callback);
475
+ const result = this[key(Type)];
471
476
  if (result === null)
472
477
  throw new Error(`Did find ${Type} in context, but multiple were defined.`);
473
478
  return result;
474
479
  }
480
+ push(inputs) {
481
+ const next = Object.create(this);
482
+ next.layer = /* @__PURE__ */ new Map();
483
+ next.cleanup = /* @__PURE__ */ new Set();
484
+ if (inputs)
485
+ next.include(inputs);
486
+ return next;
487
+ }
488
+ pop() {
489
+ for (const key2 of Object.getOwnPropertySymbols(this))
490
+ delete this[key2];
491
+ this.cleanup.forEach((cb) => cb());
492
+ this.layer.clear();
493
+ }
475
494
  include(inputs, forEach) {
476
495
  const init = /* @__PURE__ */ new Map();
477
496
  Object.entries(inputs).forEach(([K, V]) => {
478
497
  if (!(Model.is(V) || V instanceof Model))
479
498
  throw new Error(`Context can only include Model or instance but got ${V}${K && " as " + K}.`);
480
499
  });
481
- for (const key in inputs) {
482
- const input = inputs[key];
483
- const exists = this.layer.get(key);
500
+ for (const key2 in inputs) {
501
+ const input = inputs[key2];
502
+ const exists = this.layer.get(key2);
484
503
  if (!exists) {
485
504
  const instance = this.add(input);
486
- this.layer.set(key, input);
505
+ this.layer.set(key2, input);
487
506
  init.set(instance, true);
488
507
  } else if (exists !== input) {
489
508
  this.pop();
@@ -502,118 +521,101 @@ var Context = class _Context {
502
521
  }
503
522
  }
504
523
  }
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
524
  add(input, implicit) {
519
- let writable = true;
520
525
  let T;
521
526
  let I;
522
527
  if (typeof input == "function") {
523
528
  T = input;
524
529
  I = new input();
530
+ this.cleanup.add(() => I.set(null));
525
531
  } else {
526
532
  I = input;
527
533
  T = I.constructor;
528
- writable = false;
529
534
  }
530
- this.has(I);
531
- this.put(T, I, implicit, writable);
535
+ this.has(T, I);
536
+ this.put(T, I, implicit);
532
537
  return I;
533
538
  }
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;
539
+ has(type, model) {
540
+ do {
541
+ const K = key(type, true);
542
+ const result = this[K];
543
+ if (!result)
544
+ continue;
545
+ const callback = result(model);
546
+ if (callback)
547
+ this.cleanup.add(callback);
548
+ } while ((type = Object.getPrototypeOf(type)) !== Model);
549
+ const waiting = Register.get(model);
550
+ if (waiting instanceof Array)
551
+ waiting.forEach((cb) => cb(this));
552
+ Register.set(model, this);
540
553
  }
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();
554
+ put(T, I, implicit) {
555
+ do {
556
+ const K = key(T, typeof I == "function");
557
+ const value = this.hasOwnProperty(K) ? null : I;
558
+ if (value || this[K] !== I && !implicit)
559
+ Object.defineProperty(this, K, { configurable: true, value });
560
+ } while ((T = Object.getPrototypeOf(T)) !== Model);
552
561
  }
553
562
  };
554
563
 
555
564
  // src/instruction/use.ts
556
565
  var INSTRUCT = /* @__PURE__ */ new Map();
557
- function use(model, argument) {
566
+ function use(arg1, arg2) {
558
567
  const token = Symbol("instruction");
559
- if (Model.is(model)) {
560
- const type = model;
561
- const value = new model();
562
- model = (key, subject) => {
568
+ if (Model.is(arg1)) {
569
+ const type = arg1;
570
+ const value = new type();
571
+ arg1 = (key2, subject) => {
563
572
  function set2(next) {
564
- if (next ? !(next instanceof type) : argument !== false)
565
- throw new Error(`${subject}.${key} expected Model of type ${type} but got ${next && next.constructor}.`);
566
- update(subject, key, next);
567
- if (next && typeof argument == "function")
568
- argument(next);
573
+ if (next ? !(next instanceof type) : arg2 !== false)
574
+ throw new Error(`${subject}.${key2} expected Model of type ${type} but got ${next && next.constructor}.`);
575
+ update(subject, key2, next);
576
+ if (next && typeof arg2 == "function")
577
+ arg2(next);
569
578
  return false;
570
579
  }
571
580
  set2(value);
572
581
  return { set: set2, value };
573
582
  };
574
583
  }
575
- INSTRUCT.set(token, model);
584
+ INSTRUCT.set(token, arg1);
576
585
  return token;
577
586
  }
578
587
  Model.on((_, subject) => {
579
588
  const state = STATE.get(subject);
580
589
  const props = Object.getOwnPropertyDescriptors(subject);
581
- for (const key in props) {
582
- const { value } = props[key];
590
+ for (const key2 in props) {
591
+ const { value } = props[key2];
583
592
  const instruction = INSTRUCT.get(value);
584
- if (!instruction)
593
+ if (!instruction) {
594
+ if (value instanceof Model && key2 !== "is")
595
+ update(subject, key2, value);
585
596
  continue;
597
+ }
586
598
  INSTRUCT.delete(value);
587
- delete subject[key];
588
- const output = instruction.call(subject, key, subject, state);
599
+ delete subject[key2];
600
+ const output = instruction.call(subject, key2, subject, state);
589
601
  if (!output)
590
602
  continue;
591
603
  const desc = typeof output == "object" ? output : { get: output };
592
- const { enumerable = true } = desc;
593
604
  if ("value" in desc)
594
- state[key] = desc.value;
595
- Object.defineProperty(subject, key, {
596
- enumerable,
597
- set(next) {
598
- let { set: set2 } = desc;
599
- if (set2 === false)
600
- throw new Error(`${subject}.${key} is read-only.`);
601
- if (typeof set2 == "function") {
602
- const result = set2.call(subject, next, state[key]);
603
- if (result === false)
604
- return;
605
- if (typeof result == "function")
606
- next = result();
607
- set2 = false;
608
- }
609
- update(subject, key, next, !!set2);
610
- },
605
+ state[key2] = desc.value;
606
+ Object.defineProperty(subject, key2, {
607
+ enumerable: desc.enumerable !== false,
611
608
  get() {
612
609
  return watch(
613
610
  this,
614
- key,
615
- typeof desc.get == "function" ? desc.get(this) : fetch(subject, key, desc.get)
611
+ key2,
612
+ typeof desc.get == "function" ? desc.get(this) : fetch(subject, key2, desc.get)
616
613
  );
614
+ },
615
+ set(next) {
616
+ if (desc.set === false)
617
+ throw new Error(`${subject}.${key2} is read-only.`);
618
+ update(subject, key2, next, desc.set);
617
619
  }
618
620
  });
619
621
  }
@@ -623,10 +625,10 @@ Model.on((_, subject) => {
623
625
  // src/instruction/get.ts
624
626
  var STALE = /* @__PURE__ */ new WeakSet();
625
627
  function get(arg0, arg1) {
626
- return use((key, subject, state) => {
628
+ return use((key2, subject, state) => {
627
629
  let from = subject;
628
630
  if (typeof arg0 == "symbol")
629
- throw new Error(`Attempted to use an instruction result (probably use or get) as computed source for ${from}.${key}. This is not allowed.`);
631
+ throw new Error(`Attempted to use an instruction result (probably use or get) as computed source for ${from}.${key2}. This is not allowed.`);
630
632
  let source = (resolve) => resolve(from);
631
633
  if (arg0 instanceof Model) {
632
634
  from = arg0;
@@ -656,26 +658,26 @@ function get(arg0, arg1) {
656
658
  let connect2 = function(model) {
657
659
  reset = effect(model, (current) => {
658
660
  proxy = current;
659
- if (!(key in state) || STALE.delete(compute2))
661
+ if (!(key2 in state) || STALE.delete(compute2))
660
662
  compute2(!reset);
661
663
  return (didUpdate) => {
662
664
  if (didUpdate) {
663
665
  STALE.add(compute2);
664
- push(subject, key, true);
666
+ push(subject, key2, true);
665
667
  }
666
668
  };
667
669
  });
668
670
  }, compute2 = function(initial) {
669
671
  let next;
670
672
  try {
671
- next = getter.call(proxy, proxy, key);
673
+ next = getter.call(proxy, proxy, key2);
672
674
  } catch (err) {
673
- console.warn(`An exception was thrown while ${initial ? "initializing" : "refreshing"} ${subject}.${key}.`);
675
+ console.warn(`An exception was thrown while ${initial ? "initializing" : "refreshing"} ${subject}.${key2}.`);
674
676
  if (initial)
675
677
  throw err;
676
678
  console.error(err);
677
679
  }
678
- update(subject, key, next, !isAsync);
680
+ update(subject, key2, next, !isAsync);
679
681
  };
680
682
  var connect = connect2, compute = compute2;
681
683
  const getter = arg1;
@@ -689,10 +691,10 @@ function get(arg0, arg1) {
689
691
  }
690
692
  if (STALE.delete(compute2))
691
693
  compute2();
692
- return fetch(subject, key, !proxy);
694
+ return fetch(subject, key2, !proxy);
693
695
  };
694
696
  } else
695
- source((got) => subject.set(key, got));
697
+ source((got) => subject.set(key2, got));
696
698
  return { get: arg1 };
697
699
  });
698
700
  }
@@ -700,35 +702,35 @@ function get(arg0, arg1) {
700
702
  // src/instruction/ref.ts
701
703
  var define2 = Object.defineProperty;
702
704
  function ref(arg, arg2) {
703
- return use((key, subject, state) => {
705
+ return use((key2, subject, state) => {
704
706
  let value = {};
705
707
  if (arg === subject)
706
708
  subject.get(() => {
707
- for (const key2 in state)
709
+ for (const key3 in state)
708
710
  if (typeof arg2 == "function")
709
- define2(value, key2, {
711
+ define2(value, key3, {
710
712
  configurable: true,
711
713
  get() {
712
- const out = arg2(key2);
713
- define2(value, key2, { value: out });
714
+ const out = arg2(key3);
715
+ define2(value, key3, { value: out });
714
716
  return out;
715
717
  }
716
718
  });
717
719
  else {
718
- const get2 = () => state[key2];
719
- const set2 = (value2) => subject.set(key2, value2);
720
+ const get2 = () => state[key3];
721
+ const set2 = (value2) => subject.set(key3, value2);
720
722
  define2(set2, "current", { get: get2, set: set2 });
721
723
  define2(set2, "get", { value: get2 });
722
- define2(value, key2, { value: set2 });
724
+ define2(value, key3, { value: set2 });
723
725
  }
724
726
  });
725
727
  else if (typeof arg == "object")
726
728
  throw new Error("ref instruction does not support object which is not 'this'");
727
729
  else {
728
730
  let unSet;
729
- const get2 = () => state[key];
731
+ const get2 = () => state[key2];
730
732
  const set2 = (value2) => {
731
- if (!subject.set(key, value2) || !arg)
733
+ if (!subject.set(key2, value2) || !arg)
732
734
  return;
733
735
  if (unSet)
734
736
  unSet = void unSet(value2);
@@ -738,44 +740,44 @@ function ref(arg, arg2) {
738
740
  unSet = out;
739
741
  }
740
742
  };
741
- state[key] = null;
743
+ state[key2] = null;
742
744
  value = Object.defineProperties(set2, {
743
745
  current: { get: get2, set: set2 },
744
746
  get: { value: get2 }
745
747
  });
746
748
  }
747
- define2(subject, key, { value });
749
+ define2(subject, key2, { value });
748
750
  });
749
751
  }
750
752
 
751
753
  // src/instruction/set.ts
752
754
  function set(value, argument) {
753
- return use((key, subject) => {
755
+ return use((key2, subject) => {
754
756
  const output = {};
755
757
  if (typeof value == "function" || value instanceof Promise) {
756
758
  let init2 = function() {
757
759
  if (typeof value == "function")
758
760
  try {
759
- value = attempt(value.bind(subject, key, subject));
761
+ value = attempt(value.bind(subject, key2));
760
762
  } catch (err) {
761
- console.warn(`Generating initial value for ${subject}.${key} failed.`);
763
+ console.warn(`Generating initial value for ${subject}.${key2} failed.`);
762
764
  throw err;
763
765
  }
764
- output.get = typeof argument == "boolean" ? argument : void 0;
766
+ output.get = argument === true;
765
767
  if (value instanceof Promise) {
766
768
  value.then((value2) => {
767
- subject.set(key, value2);
769
+ subject.set(key2, value2);
768
770
  return value2;
769
771
  }).catch((err) => {
770
- subject.set(key);
772
+ subject.set(key2);
771
773
  output.get = () => {
772
774
  throw err;
773
775
  };
774
776
  });
775
777
  } else
776
- subject.set(key, value);
778
+ subject.set(key2, value);
777
779
  if (0 in arguments)
778
- return subject[key];
780
+ return subject[key2];
779
781
  };
780
782
  var init = init2;
781
783
  if (argument)
@@ -798,7 +800,7 @@ function set(value, argument) {
798
800
  } else
799
801
  output.set = (value2) => {
800
802
  output.get = void 0;
801
- subject.set(key, value2);
803
+ subject.set(key2, value2);
802
804
  };
803
805
  return output;
804
806
  });
@@ -822,47 +824,77 @@ function attempt(fn) {
822
824
  }
823
825
 
824
826
  // src/instruction/has.ts
825
- function has(type, argument) {
826
- return use((key, subject, state) => {
827
- const expect = (callback) => Context.get(subject, (context) => context.put(type, callback));
828
- if (typeof argument == "boolean") {
829
- expect((model) => {
830
- subject.set(key, model);
831
- const remove = () => {
832
- if (state[key] === model)
833
- delete state[key];
827
+ var APPLY = /* @__PURE__ */ new WeakMap();
828
+ function has(arg1, arg2) {
829
+ return use((key2, subject) => {
830
+ const applied = /* @__PURE__ */ new Set();
831
+ const update2 = () => {
832
+ subject.set(key2, Object.freeze(Array.from(applied)));
833
+ };
834
+ if (!Model.is(arg1)) {
835
+ if (APPLY.has(subject))
836
+ throw new Error(`'has' callback can only be used once per model.`);
837
+ APPLY.set(subject, (recipient) => {
838
+ let remove;
839
+ if (arg1) {
840
+ remove = arg1(recipient, subject);
841
+ if (remove === false)
842
+ return false;
843
+ }
844
+ applied.add(recipient);
845
+ update2();
846
+ return () => {
847
+ applied.delete(recipient);
848
+ update2();
849
+ if (typeof remove == "function")
850
+ remove();
834
851
  };
835
- model.get(null, remove);
836
- return remove;
837
852
  });
838
- return { get: argument };
839
- }
840
- const value = /* @__PURE__ */ new Set();
841
- expect((model) => {
842
- if (value.has(model))
843
- return;
844
- const remove = typeof argument == "function" ? argument(model) : void 0;
845
- if (remove === false)
846
- return;
847
- value.add(model);
848
- subject.set(key);
849
- const done = () => {
850
- drop();
851
- if (typeof remove == "function")
852
- remove();
853
- value.delete(model);
854
- subject.set(key);
855
- };
856
- const drop = model.get(null, done);
857
- return done;
858
- });
859
- return { value };
853
+ } else
854
+ Context.get(subject, (ctx) => ctx.get(arg1, (got) => {
855
+ let remove;
856
+ let disconnect;
857
+ if (applied.has(got))
858
+ return;
859
+ const callback = APPLY.get(got);
860
+ if (callback) {
861
+ const after = callback(subject);
862
+ if (after === false)
863
+ return;
864
+ if (typeof after == "function")
865
+ disconnect = after;
866
+ }
867
+ if (typeof arg2 == "function") {
868
+ const done2 = arg2(got, subject);
869
+ if (done2 === false)
870
+ return false;
871
+ remove = () => {
872
+ if (typeof done2 == "function")
873
+ done2();
874
+ };
875
+ }
876
+ applied.add(got);
877
+ update2();
878
+ const done = () => {
879
+ reset();
880
+ applied.delete(got);
881
+ update2();
882
+ if (disconnect)
883
+ disconnect();
884
+ if (typeof remove == "function")
885
+ remove();
886
+ };
887
+ const reset = got.get(null, done);
888
+ return done;
889
+ }));
890
+ return { value: [] };
860
891
  });
861
892
  }
862
893
  // Annotate the CommonJS export names for ESM import in node:
863
894
  0 && (module.exports = {
864
895
  Context,
865
896
  Model,
897
+ effect,
866
898
  get,
867
899
  has,
868
900
  ref,