@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.mjs CHANGED
@@ -7,79 +7,66 @@ function addListener(subject, callback, select) {
7
7
  let subs = LISTENER.get(subject);
8
8
  if (!subs)
9
9
  LISTENER.set(subject, subs = /* @__PURE__ */ new Map([[onReady, false]]));
10
- const filter = 2 in arguments && /* @__PURE__ */ new Set([select]);
10
+ const filter = select !== void 0 && /* @__PURE__ */ new Set([select]);
11
11
  if (!filter && !subs.has(onReady))
12
12
  callback(true, subject);
13
13
  subs.set(callback, filter);
14
14
  return () => subs.delete(callback);
15
15
  }
16
- function watch(from, key, value) {
17
- const observer = OBSERVER.get(from);
18
- if (observer) {
19
- const listeners = LISTENER.get(from);
20
- listeners.set(
21
- observer,
22
- (listeners.get(observer) || /* @__PURE__ */ new Set()).add(key)
23
- );
24
- const nested = LISTENER.get(value);
25
- if (nested) {
26
- LISTENER.set(value = Object.create(value), nested);
27
- OBSERVER.set(value, observer);
28
- }
29
- }
30
- return value;
16
+ function watch(from, key2, value) {
17
+ const access = OBSERVER.get(from);
18
+ return access ? access(from, key2, value) : value;
31
19
  }
32
20
  var PENDING = /* @__PURE__ */ new WeakMap();
33
- function event(source, key) {
21
+ function emit(source, key2) {
34
22
  const subs = LISTENER.get(source);
35
23
  const ready = !subs.has(onReady);
36
- if (key === true && ready)
24
+ if (key2 === true && ready)
37
25
  return;
38
26
  let pending = PENDING.get(source);
39
27
  if (pending) {
40
- pending.add(key);
28
+ pending.add(key2);
41
29
  return;
42
30
  }
43
31
  PENDING.set(source, pending = new Set(
44
- key !== true && ready ? [key] : [true, key]
32
+ key2 !== true && ready ? [key2] : [true, key2]
45
33
  ));
46
- pending.forEach((key2) => {
47
- pending.delete(key2);
34
+ pending.forEach((key3) => {
35
+ pending.delete(key3);
48
36
  subs.forEach((select, callback) => {
49
37
  let after;
50
- if (!select || select.has(key2)) {
51
- if (after = callback.call(source, key2, source))
38
+ if (!select || select.has(key3)) {
39
+ if (after = callback.call(source, key3, source))
52
40
  queue(after);
53
41
  }
54
- if (after === null || key2 === null)
42
+ if (after === null || key3 === null)
55
43
  subs.delete(callback);
56
44
  });
57
45
  });
58
46
  PENDING.delete(source);
59
47
  }
60
- function queue(event2) {
48
+ function queue(event) {
61
49
  if (!DISPATCH.size)
62
50
  setTimeout(() => {
63
- DISPATCH.forEach((event3) => {
51
+ DISPATCH.forEach((event2) => {
64
52
  try {
65
- event3();
53
+ event2();
66
54
  } catch (err) {
67
55
  console.error(err);
68
56
  }
69
57
  });
70
58
  DISPATCH.clear();
71
59
  }, 0);
72
- DISPATCH.add(event2);
60
+ DISPATCH.add(event);
73
61
  }
74
- function effect(target, callback) {
62
+ function effect(target, callback, requireValues) {
75
63
  const listeners = LISTENER.get(target);
76
64
  let unset;
77
65
  let reset;
78
66
  function invoke() {
79
67
  let stale;
80
68
  const subscriber = Object.create(target);
81
- LISTENER.set(subscriber, listeners);
82
- OBSERVER.set(subscriber, () => {
69
+ function onUpdate() {
83
70
  if (stale)
84
71
  return null;
85
72
  stale = true;
@@ -88,7 +75,24 @@ function effect(target, callback) {
88
75
  unset = void 0;
89
76
  }
90
77
  return reset;
91
- });
78
+ }
79
+ function access(from, key2, value) {
80
+ if (value === void 0 && requireValues)
81
+ throw new Error(`${from}.${key2} is required in this context.`);
82
+ const listeners2 = LISTENER.get(from);
83
+ let listener = listeners2.get(onUpdate);
84
+ if (!listener)
85
+ listeners2.set(onUpdate, listener = /* @__PURE__ */ new Set());
86
+ listener.add(key2);
87
+ const nested = LISTENER.get(value);
88
+ if (nested) {
89
+ LISTENER.set(value = Object.create(value), nested);
90
+ OBSERVER.set(value, access);
91
+ }
92
+ return value;
93
+ }
94
+ LISTENER.set(subscriber, listeners);
95
+ OBSERVER.set(subscriber, access);
92
96
  try {
93
97
  const out = callback.call(subscriber, subscriber);
94
98
  unset = typeof out == "function" ? out : void 0;
@@ -101,12 +105,12 @@ function effect(target, callback) {
101
105
  throw err;
102
106
  }
103
107
  }
104
- addListener(target, (key) => {
105
- if (key === true)
108
+ addListener(target, (key2) => {
109
+ if (key2 === true)
106
110
  invoke();
107
111
  else if (!reset)
108
112
  return reset;
109
- if (key === null && unset)
113
+ if (key2 === null && unset)
110
114
  unset(null);
111
115
  });
112
116
  return () => {
@@ -160,15 +164,15 @@ var Model = class _Model {
160
164
  }
161
165
  done = cleanup;
162
166
  })();
163
- for (const key in this) {
164
- const desc = Object.getOwnPropertyDescriptor(this, key);
167
+ for (const key2 in this) {
168
+ const desc = Object.getOwnPropertyDescriptor(this, key2);
165
169
  if ("value" in desc) {
166
- update(this, key, desc.value, true);
167
- define(this, key, {
170
+ update(this, key2, desc.value, true);
171
+ define(this, key2, {
168
172
  configurable: false,
169
- set: (x) => update(this, key, x),
173
+ set: (x) => update(this, key2, x),
170
174
  get() {
171
- return watch(this, key, state[key]);
175
+ return watch(this, key2, state[key2]);
172
176
  }
173
177
  });
174
178
  }
@@ -203,12 +207,12 @@ var Model = class _Model {
203
207
  if (arg1 === void 0) {
204
208
  const values = {};
205
209
  const current = !EXPORT && (EXPORT = /* @__PURE__ */ new Map([[self, values]]));
206
- for (let [key, value] of self) {
210
+ for (let [key2, value] of self) {
207
211
  if (EXPORT.has(value))
208
212
  value = EXPORT.get(value);
209
213
  else if (value && typeof value.get === "function")
210
214
  EXPORT.set(value, value = value.get());
211
- values[key] = value;
215
+ values[key2] = value;
212
216
  }
213
217
  if (current)
214
218
  EXPORT = void 0;
@@ -229,16 +233,16 @@ var Model = class _Model {
229
233
  set(arg1, arg2, arg3) {
230
234
  const self = this.is;
231
235
  if (typeof arg1 == "function")
232
- return addListener(self, (key) => {
233
- if (typeof key == "string")
234
- return arg1.call(self, key, self);
236
+ return addListener(self, (key2) => {
237
+ if (typeof key2 == "string")
238
+ return arg1.call(self, key2, self);
235
239
  });
236
240
  if (arg1 === null)
237
- return event(this, null);
241
+ return emit(this, null);
238
242
  if (typeof arg1 == "object")
239
243
  assign(self, arg1);
240
244
  else if (arg1 == void 0)
241
- event(this, true);
245
+ emit(this, true);
242
246
  else if (1 in arguments)
243
247
  update(self, arg1, arg2, arg3);
244
248
  else
@@ -246,8 +250,8 @@ var Model = class _Model {
246
250
  if (PENDING2.has(self))
247
251
  return {
248
252
  then: (res) => new Promise((res2) => {
249
- const remove = addListener(self, (key) => {
250
- if (key !== true) {
253
+ const remove = addListener(self, (key2) => {
254
+ if (key2 !== true) {
251
255
  remove();
252
256
  return res2.bind(null, Array.from(PENDING2.get(self)));
253
257
  }
@@ -268,7 +272,7 @@ var Model = class _Model {
268
272
  */
269
273
  static new(...args) {
270
274
  const instance = new this(...args);
271
- event(instance, true);
275
+ emit(instance, true);
272
276
  return instance;
273
277
  }
274
278
  /**
@@ -310,12 +314,12 @@ function fetch(subject, property, required) {
310
314
  }
311
315
  const error = new Error(`${subject}.${property} is not yet available.`);
312
316
  const promise = new Promise((resolve, reject) => {
313
- addListener(subject, (key) => {
314
- if (key === property) {
315
- resolve(state[key]);
317
+ addListener(subject, (key2) => {
318
+ if (key2 === property) {
319
+ resolve(state[key2]);
316
320
  return null;
317
321
  }
318
- if (key === null)
322
+ if (key2 === null)
319
323
  reject(new Error(`${subject} is destroyed.`));
320
324
  });
321
325
  });
@@ -326,63 +330,70 @@ function fetch(subject, property, required) {
326
330
  stack: error.stack
327
331
  });
328
332
  }
329
- function update(subject, key, value, silent) {
333
+ function update(subject, key2, value, arg) {
330
334
  const state = STATE.get(subject);
331
335
  if (Object.isFrozen(state))
332
- throw new Error(`Tried to update ${String(key)} but ${subject} is destroyed.`);
333
- const previous = state[key];
336
+ throw new Error(`Tried to update ${String(key2)} but ${subject} is destroyed.`);
337
+ const previous = state[key2];
338
+ if (typeof arg == "function") {
339
+ const out = arg.call(subject, value, previous);
340
+ if (out === false)
341
+ return false;
342
+ if (typeof out == "function")
343
+ value = out();
344
+ }
334
345
  if (value === previous)
335
346
  return true;
336
347
  if (value instanceof Model && !PARENT.has(value)) {
337
348
  PARENT.set(value, subject);
338
- event(value, true);
349
+ emit(value, true);
339
350
  }
340
- state[key] = value;
341
- if (silent !== true)
342
- push(subject, key);
351
+ state[key2] = value;
352
+ if (arg !== true)
353
+ push(subject, key2);
343
354
  }
344
- function push(subject, key, silent) {
355
+ function push(subject, key2, silent) {
345
356
  let pending = PENDING2.get(subject);
346
357
  if (!pending) {
347
358
  PENDING2.set(subject, pending = /* @__PURE__ */ new Set());
348
359
  if (!silent)
349
360
  queue(() => {
350
- event(subject, false);
361
+ emit(subject, false);
351
362
  PENDING2.delete(subject);
352
363
  });
353
364
  }
354
- pending.add(key);
365
+ pending.add(key2);
355
366
  if (!silent)
356
- event(subject, key);
367
+ emit(subject, key2);
357
368
  }
358
369
  var METHODS = new WeakMap([[Model, []]]);
359
370
  function assign(to, values) {
360
371
  const methods = METHODS.get(to.constructor);
361
372
  const applicable = new Set(Object.keys(to).concat(methods));
362
- for (const key in values)
363
- if (applicable.has(key))
364
- to[key] = values[key];
373
+ for (const key2 in values)
374
+ if (applicable.has(key2))
375
+ to[key2] = values[key2];
365
376
  }
366
377
  function bindMethods(type) {
367
378
  let keys = METHODS.get(type);
368
379
  if (!keys) {
369
380
  METHODS.set(type, keys = bindMethods(Object.getPrototypeOf(type)).slice());
370
381
  const desc = Object.getOwnPropertyDescriptors(type.prototype);
371
- for (const key in desc)
372
- if (key != "constructor" && "value" in desc[key]) {
382
+ for (const key2 in desc)
383
+ if (key2 != "constructor" && "value" in desc[key2]) {
373
384
  let bind2 = function(method) {
374
385
  const value2 = method.bind(this.is);
375
386
  METHOD.set(value2, method);
376
- define(this.is, key, { value: value2, writable: true });
387
+ define(this.is, key2, { value: value2, writable: true });
377
388
  return value2;
378
389
  };
379
390
  var bind = bind2;
380
- let { value } = desc[key];
381
- keys.push(key);
382
- Object.defineProperty(type.prototype, key, {
391
+ let { value } = desc[key2];
392
+ keys.push(key2);
393
+ Object.defineProperty(type.prototype, key2, {
383
394
  set: bind2,
384
395
  get() {
385
- return this.hasOwnProperty(key) ? value : bind2.call(this, value);
396
+ return this.hasOwnProperty(key2) ? value : bind2.call(this, value);
386
397
  }
387
398
  });
388
399
  }
@@ -395,11 +406,21 @@ function uid() {
395
406
 
396
407
  // src/context.ts
397
408
  var Register = /* @__PURE__ */ new WeakMap();
409
+ var Upstream = /* @__PURE__ */ new WeakMap();
410
+ var Downstream = /* @__PURE__ */ new WeakMap();
411
+ function key(T, upstream) {
412
+ const table = upstream ? Upstream : Downstream;
413
+ let key2 = table.get(T);
414
+ if (!key2) {
415
+ key2 = Symbol(T.name + (upstream ? " request" : ""));
416
+ table.set(T, key2);
417
+ }
418
+ return key2;
419
+ }
398
420
  var Context = class _Context {
399
421
  constructor(inputs) {
400
- this.downstream = /* @__PURE__ */ new WeakMap();
401
- this.upstream = /* @__PURE__ */ new WeakMap();
402
422
  this.layer = /* @__PURE__ */ new Map();
423
+ this.cleanup = /* @__PURE__ */ new Set();
403
424
  if (inputs)
404
425
  this.include(inputs);
405
426
  }
@@ -414,43 +435,40 @@ var Context = class _Context {
414
435
  else
415
436
  Register.set(from, [callback]);
416
437
  }
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
+ get(Type, callback) {
439
+ if (callback)
440
+ return this.put(Type, callback);
441
+ const result = this[key(Type)];
438
442
  if (result === null)
439
443
  throw new Error(`Did find ${Type} in context, but multiple were defined.`);
440
444
  return result;
441
445
  }
446
+ push(inputs) {
447
+ const next = Object.create(this);
448
+ next.layer = /* @__PURE__ */ new Map();
449
+ next.cleanup = /* @__PURE__ */ new Set();
450
+ if (inputs)
451
+ next.include(inputs);
452
+ return next;
453
+ }
454
+ pop() {
455
+ for (const key2 of Object.getOwnPropertySymbols(this))
456
+ delete this[key2];
457
+ this.cleanup.forEach((cb) => cb());
458
+ this.layer.clear();
459
+ }
442
460
  include(inputs, forEach) {
443
461
  const init = /* @__PURE__ */ new Map();
444
462
  Object.entries(inputs).forEach(([K, V]) => {
445
463
  if (!(Model.is(V) || V instanceof Model))
446
464
  throw new Error(`Context can only include Model or instance but got ${V}${K && " as " + K}.`);
447
465
  });
448
- for (const key in inputs) {
449
- const input = inputs[key];
450
- const exists = this.layer.get(key);
466
+ for (const key2 in inputs) {
467
+ const input = inputs[key2];
468
+ const exists = this.layer.get(key2);
451
469
  if (!exists) {
452
470
  const instance = this.add(input);
453
- this.layer.set(key, input);
471
+ this.layer.set(key2, input);
454
472
  init.set(instance, true);
455
473
  } else if (exists !== input) {
456
474
  this.pop();
@@ -469,118 +487,101 @@ var Context = class _Context {
469
487
  }
470
488
  }
471
489
  }
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
490
  add(input, implicit) {
486
- let writable = true;
487
491
  let T;
488
492
  let I;
489
493
  if (typeof input == "function") {
490
494
  T = input;
491
495
  I = new input();
496
+ this.cleanup.add(() => I.set(null));
492
497
  } else {
493
498
  I = input;
494
499
  T = I.constructor;
495
- writable = false;
496
500
  }
497
- this.has(I);
498
- this.put(T, I, implicit, writable);
501
+ this.has(T, I);
502
+ this.put(T, I, implicit);
499
503
  return I;
500
504
  }
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;
505
+ has(type, model) {
506
+ do {
507
+ const K = key(type, true);
508
+ const result = this[K];
509
+ if (!result)
510
+ continue;
511
+ const callback = result(model);
512
+ if (callback)
513
+ this.cleanup.add(callback);
514
+ } while ((type = Object.getPrototypeOf(type)) !== Model);
515
+ const waiting = Register.get(model);
516
+ if (waiting instanceof Array)
517
+ waiting.forEach((cb) => cb(this));
518
+ Register.set(model, this);
507
519
  }
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();
520
+ put(T, I, implicit) {
521
+ do {
522
+ const K = key(T, typeof I == "function");
523
+ const value = this.hasOwnProperty(K) ? null : I;
524
+ if (value || this[K] !== I && !implicit)
525
+ Object.defineProperty(this, K, { configurable: true, value });
526
+ } while ((T = Object.getPrototypeOf(T)) !== Model);
519
527
  }
520
528
  };
521
529
 
522
530
  // src/instruction/use.ts
523
531
  var INSTRUCT = /* @__PURE__ */ new Map();
524
- function use(model, argument) {
532
+ function use(arg1, arg2) {
525
533
  const token = Symbol("instruction");
526
- if (Model.is(model)) {
527
- const type = model;
528
- const value = new model();
529
- model = (key, subject) => {
534
+ if (Model.is(arg1)) {
535
+ const type = arg1;
536
+ const value = new type();
537
+ arg1 = (key2, subject) => {
530
538
  function set2(next) {
531
- if (next ? !(next instanceof type) : argument !== false)
532
- throw new Error(`${subject}.${key} expected Model of type ${type} but got ${next && next.constructor}.`);
533
- update(subject, key, next);
534
- if (next && typeof argument == "function")
535
- argument(next);
539
+ if (next ? !(next instanceof type) : arg2 !== false)
540
+ throw new Error(`${subject}.${key2} expected Model of type ${type} but got ${next && next.constructor}.`);
541
+ update(subject, key2, next);
542
+ if (next && typeof arg2 == "function")
543
+ arg2(next);
536
544
  return false;
537
545
  }
538
546
  set2(value);
539
547
  return { set: set2, value };
540
548
  };
541
549
  }
542
- INSTRUCT.set(token, model);
550
+ INSTRUCT.set(token, arg1);
543
551
  return token;
544
552
  }
545
553
  Model.on((_, subject) => {
546
554
  const state = STATE.get(subject);
547
555
  const props = Object.getOwnPropertyDescriptors(subject);
548
- for (const key in props) {
549
- const { value } = props[key];
556
+ for (const key2 in props) {
557
+ const { value } = props[key2];
550
558
  const instruction = INSTRUCT.get(value);
551
- if (!instruction)
559
+ if (!instruction) {
560
+ if (value instanceof Model && key2 !== "is")
561
+ update(subject, key2, value);
552
562
  continue;
563
+ }
553
564
  INSTRUCT.delete(value);
554
- delete subject[key];
555
- const output = instruction.call(subject, key, subject, state);
565
+ delete subject[key2];
566
+ const output = instruction.call(subject, key2, subject, state);
556
567
  if (!output)
557
568
  continue;
558
569
  const desc = typeof output == "object" ? output : { get: output };
559
- const { enumerable = true } = desc;
560
570
  if ("value" in desc)
561
- state[key] = desc.value;
562
- Object.defineProperty(subject, key, {
563
- enumerable,
564
- set(next) {
565
- let { set: set2 } = desc;
566
- if (set2 === false)
567
- throw new Error(`${subject}.${key} is read-only.`);
568
- if (typeof set2 == "function") {
569
- const result = set2.call(subject, next, state[key]);
570
- if (result === false)
571
- return;
572
- if (typeof result == "function")
573
- next = result();
574
- set2 = false;
575
- }
576
- update(subject, key, next, !!set2);
577
- },
571
+ state[key2] = desc.value;
572
+ Object.defineProperty(subject, key2, {
573
+ enumerable: desc.enumerable !== false,
578
574
  get() {
579
575
  return watch(
580
576
  this,
581
- key,
582
- typeof desc.get == "function" ? desc.get(this) : fetch(subject, key, desc.get)
577
+ key2,
578
+ typeof desc.get == "function" ? desc.get(this) : fetch(subject, key2, desc.get)
583
579
  );
580
+ },
581
+ set(next) {
582
+ if (desc.set === false)
583
+ throw new Error(`${subject}.${key2} is read-only.`);
584
+ update(subject, key2, next, desc.set);
584
585
  }
585
586
  });
586
587
  }
@@ -590,10 +591,10 @@ Model.on((_, subject) => {
590
591
  // src/instruction/get.ts
591
592
  var STALE = /* @__PURE__ */ new WeakSet();
592
593
  function get(arg0, arg1) {
593
- return use((key, subject, state) => {
594
+ return use((key2, subject, state) => {
594
595
  let from = subject;
595
596
  if (typeof arg0 == "symbol")
596
- throw new Error(`Attempted to use an instruction result (probably use or get) as computed source for ${from}.${key}. This is not allowed.`);
597
+ throw new Error(`Attempted to use an instruction result (probably use or get) as computed source for ${from}.${key2}. This is not allowed.`);
597
598
  let source = (resolve) => resolve(from);
598
599
  if (arg0 instanceof Model) {
599
600
  from = arg0;
@@ -623,26 +624,26 @@ function get(arg0, arg1) {
623
624
  let connect2 = function(model) {
624
625
  reset = effect(model, (current) => {
625
626
  proxy = current;
626
- if (!(key in state) || STALE.delete(compute2))
627
+ if (!(key2 in state) || STALE.delete(compute2))
627
628
  compute2(!reset);
628
629
  return (didUpdate) => {
629
630
  if (didUpdate) {
630
631
  STALE.add(compute2);
631
- push(subject, key, true);
632
+ push(subject, key2, true);
632
633
  }
633
634
  };
634
635
  });
635
636
  }, compute2 = function(initial) {
636
637
  let next;
637
638
  try {
638
- next = getter.call(proxy, proxy, key);
639
+ next = getter.call(proxy, proxy, key2);
639
640
  } catch (err) {
640
- console.warn(`An exception was thrown while ${initial ? "initializing" : "refreshing"} ${subject}.${key}.`);
641
+ console.warn(`An exception was thrown while ${initial ? "initializing" : "refreshing"} ${subject}.${key2}.`);
641
642
  if (initial)
642
643
  throw err;
643
644
  console.error(err);
644
645
  }
645
- update(subject, key, next, !isAsync);
646
+ update(subject, key2, next, !isAsync);
646
647
  };
647
648
  var connect = connect2, compute = compute2;
648
649
  const getter = arg1;
@@ -656,10 +657,10 @@ function get(arg0, arg1) {
656
657
  }
657
658
  if (STALE.delete(compute2))
658
659
  compute2();
659
- return fetch(subject, key, !proxy);
660
+ return fetch(subject, key2, !proxy);
660
661
  };
661
662
  } else
662
- source((got) => subject.set(key, got));
663
+ source((got) => subject.set(key2, got));
663
664
  return { get: arg1 };
664
665
  });
665
666
  }
@@ -667,35 +668,35 @@ function get(arg0, arg1) {
667
668
  // src/instruction/ref.ts
668
669
  var define2 = Object.defineProperty;
669
670
  function ref(arg, arg2) {
670
- return use((key, subject, state) => {
671
+ return use((key2, subject, state) => {
671
672
  let value = {};
672
673
  if (arg === subject)
673
674
  subject.get(() => {
674
- for (const key2 in state)
675
+ for (const key3 in state)
675
676
  if (typeof arg2 == "function")
676
- define2(value, key2, {
677
+ define2(value, key3, {
677
678
  configurable: true,
678
679
  get() {
679
- const out = arg2(key2);
680
- define2(value, key2, { value: out });
680
+ const out = arg2(key3);
681
+ define2(value, key3, { value: out });
681
682
  return out;
682
683
  }
683
684
  });
684
685
  else {
685
- const get2 = () => state[key2];
686
- const set2 = (value2) => subject.set(key2, value2);
686
+ const get2 = () => state[key3];
687
+ const set2 = (value2) => subject.set(key3, value2);
687
688
  define2(set2, "current", { get: get2, set: set2 });
688
689
  define2(set2, "get", { value: get2 });
689
- define2(value, key2, { value: set2 });
690
+ define2(value, key3, { value: set2 });
690
691
  }
691
692
  });
692
693
  else if (typeof arg == "object")
693
694
  throw new Error("ref instruction does not support object which is not 'this'");
694
695
  else {
695
696
  let unSet;
696
- const get2 = () => state[key];
697
+ const get2 = () => state[key2];
697
698
  const set2 = (value2) => {
698
- if (!subject.set(key, value2) || !arg)
699
+ if (!subject.set(key2, value2) || !arg)
699
700
  return;
700
701
  if (unSet)
701
702
  unSet = void unSet(value2);
@@ -705,44 +706,44 @@ function ref(arg, arg2) {
705
706
  unSet = out;
706
707
  }
707
708
  };
708
- state[key] = null;
709
+ state[key2] = null;
709
710
  value = Object.defineProperties(set2, {
710
711
  current: { get: get2, set: set2 },
711
712
  get: { value: get2 }
712
713
  });
713
714
  }
714
- define2(subject, key, { value });
715
+ define2(subject, key2, { value });
715
716
  });
716
717
  }
717
718
 
718
719
  // src/instruction/set.ts
719
720
  function set(value, argument) {
720
- return use((key, subject) => {
721
+ return use((key2, subject) => {
721
722
  const output = {};
722
723
  if (typeof value == "function" || value instanceof Promise) {
723
724
  let init2 = function() {
724
725
  if (typeof value == "function")
725
726
  try {
726
- value = attempt(value.bind(subject, key, subject));
727
+ value = attempt(value.bind(subject, key2));
727
728
  } catch (err) {
728
- console.warn(`Generating initial value for ${subject}.${key} failed.`);
729
+ console.warn(`Generating initial value for ${subject}.${key2} failed.`);
729
730
  throw err;
730
731
  }
731
- output.get = typeof argument == "boolean" ? argument : void 0;
732
+ output.get = argument === true;
732
733
  if (value instanceof Promise) {
733
734
  value.then((value2) => {
734
- subject.set(key, value2);
735
+ subject.set(key2, value2);
735
736
  return value2;
736
737
  }).catch((err) => {
737
- subject.set(key);
738
+ subject.set(key2);
738
739
  output.get = () => {
739
740
  throw err;
740
741
  };
741
742
  });
742
743
  } else
743
- subject.set(key, value);
744
+ subject.set(key2, value);
744
745
  if (0 in arguments)
745
- return subject[key];
746
+ return subject[key2];
746
747
  };
747
748
  var init = init2;
748
749
  if (argument)
@@ -765,7 +766,7 @@ function set(value, argument) {
765
766
  } else
766
767
  output.set = (value2) => {
767
768
  output.get = void 0;
768
- subject.set(key, value2);
769
+ subject.set(key2, value2);
769
770
  };
770
771
  return output;
771
772
  });
@@ -789,47 +790,77 @@ function attempt(fn) {
789
790
  }
790
791
 
791
792
  // src/instruction/has.ts
792
- function has(type, argument) {
793
- return use((key, subject, state) => {
794
- const expect = (callback) => Context.get(subject, (context) => context.put(type, callback));
795
- if (typeof argument == "boolean") {
796
- expect((model) => {
797
- subject.set(key, model);
798
- const remove = () => {
799
- if (state[key] === model)
800
- delete state[key];
793
+ var APPLY = /* @__PURE__ */ new WeakMap();
794
+ function has(arg1, arg2) {
795
+ return use((key2, subject) => {
796
+ const applied = /* @__PURE__ */ new Set();
797
+ const update2 = () => {
798
+ subject.set(key2, Object.freeze(Array.from(applied)));
799
+ };
800
+ if (!Model.is(arg1)) {
801
+ if (APPLY.has(subject))
802
+ throw new Error(`'has' callback can only be used once per model.`);
803
+ APPLY.set(subject, (recipient) => {
804
+ let remove;
805
+ if (arg1) {
806
+ remove = arg1(recipient, subject);
807
+ if (remove === false)
808
+ return false;
809
+ }
810
+ applied.add(recipient);
811
+ update2();
812
+ return () => {
813
+ applied.delete(recipient);
814
+ update2();
815
+ if (typeof remove == "function")
816
+ remove();
801
817
  };
802
- model.get(null, remove);
803
- return remove;
804
818
  });
805
- return { get: argument };
806
- }
807
- const value = /* @__PURE__ */ new Set();
808
- expect((model) => {
809
- if (value.has(model))
810
- return;
811
- const remove = typeof argument == "function" ? argument(model) : void 0;
812
- if (remove === false)
813
- return;
814
- value.add(model);
815
- subject.set(key);
816
- const done = () => {
817
- drop();
818
- if (typeof remove == "function")
819
- remove();
820
- value.delete(model);
821
- subject.set(key);
822
- };
823
- const drop = model.get(null, done);
824
- return done;
825
- });
826
- return { value };
819
+ } else
820
+ Context.get(subject, (ctx) => ctx.get(arg1, (got) => {
821
+ let remove;
822
+ let disconnect;
823
+ if (applied.has(got))
824
+ return;
825
+ const callback = APPLY.get(got);
826
+ if (callback) {
827
+ const after = callback(subject);
828
+ if (after === false)
829
+ return;
830
+ if (typeof after == "function")
831
+ disconnect = after;
832
+ }
833
+ if (typeof arg2 == "function") {
834
+ const done2 = arg2(got, subject);
835
+ if (done2 === false)
836
+ return false;
837
+ remove = () => {
838
+ if (typeof done2 == "function")
839
+ done2();
840
+ };
841
+ }
842
+ applied.add(got);
843
+ update2();
844
+ const done = () => {
845
+ reset();
846
+ applied.delete(got);
847
+ update2();
848
+ if (disconnect)
849
+ disconnect();
850
+ if (typeof remove == "function")
851
+ remove();
852
+ };
853
+ const reset = got.get(null, done);
854
+ return done;
855
+ }));
856
+ return { value: [] };
827
857
  });
828
858
  }
829
859
  export {
830
860
  Context,
831
861
  Model,
832
862
  Model as default,
863
+ effect,
833
864
  get,
834
865
  has,
835
866
  ref,