@expressive/mvc 0.52.1 → 0.53.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
@@ -22,8 +22,10 @@ var src_exports = {};
22
22
  __export(src_exports, {
23
23
  Context: () => Context,
24
24
  Model: () => Model,
25
+ addListener: () => addListener,
26
+ createEffect: () => createEffect,
27
+ createProxy: () => createProxy,
25
28
  default: () => Model,
26
- effect: () => effect,
27
29
  get: () => get,
28
30
  has: () => has,
29
31
  ref: () => ref,
@@ -33,73 +35,108 @@ __export(src_exports, {
33
35
  module.exports = __toCommonJS(src_exports);
34
36
 
35
37
  // src/control.ts
38
+ var onReady = () => null;
39
+ var LISTENERS = /* @__PURE__ */ new WeakMap();
40
+ var PENDING = /* @__PURE__ */ new WeakMap();
41
+ var PENDING_KEYS = /* @__PURE__ */ new WeakMap();
36
42
  var DISPATCH = /* @__PURE__ */ new Set();
37
43
  var OBSERVER = /* @__PURE__ */ new WeakMap();
38
- var LISTENER = /* @__PURE__ */ new WeakMap();
39
- var onReady = () => null;
40
44
  function addListener(subject, callback, select) {
41
- let subs = LISTENER.get(subject);
42
- if (!subs)
43
- LISTENER.set(subject, subs = /* @__PURE__ */ new Map([[onReady, false]]));
44
- const filter = select !== void 0 && /* @__PURE__ */ new Set([select]);
45
- if (!subs.has(onReady) && !filter)
46
- callback(true, subject);
47
- subs.set(callback, filter);
48
- return () => subs.delete(callback);
49
- }
50
- function watch(from, key2, value) {
51
- const access = OBSERVER.get(from);
52
- return access ? access(from, key2, value) : value;
45
+ let listeners = LISTENERS.get(subject);
46
+ if (!listeners)
47
+ LISTENERS.set(subject, listeners = /* @__PURE__ */ new Map([[onReady, void 0]]));
48
+ const filter = select === void 0 ? void 0 : /* @__PURE__ */ new Set([select]);
49
+ if (!listeners.has(onReady) && !filter)
50
+ callback.call(subject, true, subject);
51
+ listeners.set(callback, filter);
52
+ return () => listeners.delete(callback);
53
53
  }
54
- var PENDING = /* @__PURE__ */ new WeakMap();
55
- function emit(source, key2) {
56
- const subs = LISTENER.get(source);
57
- const ready = !subs.has(onReady);
58
- if (key2 === true && ready)
54
+ function emit(model, key2) {
55
+ const listeners = LISTENERS.get(model);
56
+ const notReady = listeners.has(onReady);
57
+ if (key2 === true && !notReady)
59
58
  return;
60
- let pending = PENDING.get(source);
61
- if (pending) {
62
- pending.add(key2);
59
+ let pending2 = PENDING.get(model);
60
+ if (pending2) {
61
+ pending2.add(key2);
63
62
  return;
64
63
  }
65
- PENDING.set(source, pending = new Set(
66
- key2 !== true && ready ? [key2] : [true, key2]
67
- ));
68
- pending.forEach((key3) => {
69
- pending.delete(key3);
70
- subs.forEach((select, callback) => {
71
- let after;
72
- if (!select || select.has(key3)) {
73
- if (after = callback.call(source, key3, source))
74
- queue(after);
64
+ PENDING.set(model, pending2 = new Set(notReady ? [true, key2] : [key2]));
65
+ for (const key3 of pending2)
66
+ for (const [callback, filter] of listeners)
67
+ if (!filter || filter.has(key3)) {
68
+ const after = callback.call(model, key3, model);
69
+ if (after)
70
+ enqueue(after);
71
+ else if (after === null)
72
+ listeners.delete(callback);
75
73
  }
76
- if (after === null || key3 === null)
77
- subs.delete(callback);
78
- });
79
- });
80
- PENDING.delete(source);
74
+ if (key2 === null)
75
+ listeners.clear();
76
+ PENDING.delete(model);
77
+ }
78
+ function event(subject, key2, silent) {
79
+ if (key2 === null)
80
+ return emit(subject, key2);
81
+ if (!key2)
82
+ return emit(subject, true);
83
+ let pending2 = PENDING_KEYS.get(subject);
84
+ if (!pending2) {
85
+ PENDING_KEYS.set(subject, pending2 = /* @__PURE__ */ new Set());
86
+ if (!silent)
87
+ enqueue(() => {
88
+ emit(subject, false);
89
+ PENDING_KEYS.delete(subject);
90
+ });
91
+ }
92
+ pending2.add(key2);
93
+ if (!silent)
94
+ emit(subject, key2);
81
95
  }
82
- function queue(event2) {
96
+ function pending(subject) {
97
+ if (PENDING_KEYS.has(subject))
98
+ return {
99
+ then: (res) => new Promise((res2) => {
100
+ const remove = addListener(subject, (key2) => {
101
+ if (key2 !== true) {
102
+ remove();
103
+ return res2.bind(null, Array.from(PENDING_KEYS.get(subject)));
104
+ }
105
+ });
106
+ }).then(res)
107
+ };
108
+ }
109
+ function enqueue(eventHandler) {
83
110
  if (!DISPATCH.size)
84
111
  setTimeout(() => {
85
- DISPATCH.forEach((event3) => {
112
+ DISPATCH.forEach((event2) => {
86
113
  try {
87
- event3();
114
+ event2();
88
115
  } catch (err) {
89
116
  console.error(err);
90
117
  }
91
118
  });
92
119
  DISPATCH.clear();
93
120
  }, 0);
94
- DISPATCH.add(event2);
121
+ DISPATCH.add(eventHandler);
122
+ }
123
+ function createProxy(from, observer) {
124
+ const proxy = Object.create(from);
125
+ OBSERVER.set(proxy, observer);
126
+ return proxy;
127
+ }
128
+ function watch(from, key2, value) {
129
+ const access = OBSERVER.get(from);
130
+ return access ? access(from, key2, value) : value;
95
131
  }
96
- function effect(target, callback, requireValues) {
97
- const listeners = LISTENER.get(target);
132
+ function createEffect(target, callback, requireValues) {
133
+ const listeners = LISTENERS.get(target);
98
134
  let unset;
99
135
  let reset;
100
136
  function invoke() {
101
137
  let stale;
102
- const subscriber = Object.create(target);
138
+ const subscriber = createProxy(target, access);
139
+ LISTENERS.set(subscriber, listeners);
103
140
  function onUpdate() {
104
141
  if (stale)
105
142
  return null;
@@ -113,20 +150,19 @@ function effect(target, callback, requireValues) {
113
150
  function access(from, key2, value) {
114
151
  if (value === void 0 && requireValues)
115
152
  throw new Error(`${from}.${key2} is required in this context.`);
116
- const listeners2 = LISTENER.get(from);
153
+ const listeners2 = LISTENERS.get(from);
117
154
  let listener = listeners2.get(onUpdate);
118
155
  if (!listener)
119
156
  listeners2.set(onUpdate, listener = /* @__PURE__ */ new Set());
120
157
  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
- }
158
+ const nested = LISTENERS.get(value);
159
+ if (nested)
160
+ LISTENERS.set(
161
+ value = createProxy(value, access),
162
+ nested
163
+ );
126
164
  return value;
127
165
  }
128
- LISTENER.set(subscriber, listeners);
129
- OBSERVER.set(subscriber, access);
130
166
  try {
131
167
  const out = callback.call(subscriber, subscriber);
132
168
  unset = typeof out == "function" ? out : void 0;
@@ -159,80 +195,55 @@ var define = Object.defineProperty;
159
195
  var ID = /* @__PURE__ */ new WeakMap();
160
196
  var STATE = /* @__PURE__ */ new WeakMap();
161
197
  var NOTIFY = /* @__PURE__ */ new WeakMap();
162
- var PENDING2 = /* @__PURE__ */ new WeakMap();
163
198
  var PARENT = /* @__PURE__ */ new WeakMap();
164
199
  var METHODS = /* @__PURE__ */ new WeakMap();
165
200
  var METHOD = /* @__PURE__ */ new WeakMap();
166
- var EXPORT;
167
- var Model = class _Model {
201
+ var Model = class {
168
202
  constructor(...args) {
169
- define(this, "is", { value: this });
170
- ID.set(this, `${this.constructor}-${uid()}`);
171
- STATE.set(this, {});
172
203
  prepare(this);
204
+ define(this, "is", { value: this });
173
205
  init(this, args);
174
206
  }
175
207
  get(arg1, arg2) {
176
208
  const self = this.is;
177
- if (arg1 === void 0)
178
- return values(self);
179
209
  if (typeof arg1 == "function") {
180
- let pending = /* @__PURE__ */ new Set();
181
- return effect(self, (state) => {
182
- const cb = arg1.call(state, state, pending);
210
+ let pending2 = /* @__PURE__ */ new Set();
211
+ return createEffect(self, (proxy) => {
212
+ const cb = arg1.call(proxy, proxy, pending2);
183
213
  return cb === null ? cb : (update2) => {
184
- pending = PENDING2.get(self);
214
+ pending2 = PENDING_KEYS.get(self);
185
215
  if (typeof cb == "function")
186
- return cb(update2);
216
+ cb(update2);
187
217
  };
188
218
  });
189
219
  }
190
- if (typeof arg2 == "function") {
191
- if (arg1 === null)
192
- return addListener(self, arg2.bind(this, this), null);
193
- const state = STATE.get(self);
194
- if (arg1 in state)
195
- arg2.call(this, state[arg1], arg1, this);
196
- return addListener(self, () => {
197
- arg2.call(this, arg1 in state ? state[arg1] : arg1, arg1, this);
198
- }, arg1);
199
- }
220
+ if (arg1 === void 0)
221
+ return snapshot(self);
222
+ if (typeof arg2 == "function")
223
+ return addListener(self, arg2, arg1);
200
224
  return arg1 === null ? Object.isFrozen(STATE.get(self)) : fetch(self, arg1, arg2);
201
225
  }
202
- set(arg1, arg2, arg3) {
226
+ set(arg1, arg2) {
203
227
  const self = this.is;
204
228
  if (typeof arg1 == "function")
205
229
  return addListener(self, (key2) => {
206
230
  if (typeof key2 == "string")
207
231
  return arg1.call(self, key2, self);
208
232
  });
209
- if (arg1 === null) {
210
- emit(this, null);
211
- return;
212
- }
213
- if (typeof arg1 == "object")
214
- assign(self, arg1);
215
- else if (arg1 == void 0)
216
- emit(this, true);
217
- else if (1 in arguments)
218
- update(self, arg1, arg2, arg3);
219
- else
233
+ if (arg1 && typeof arg1 == "object") {
234
+ const methods = METHODS.get(self.constructor);
235
+ for (const key2 in arg1)
236
+ if (methods.has(key2))
237
+ self[key2] = arg1[key2];
238
+ else if (key2 in self)
239
+ update(self, key2, arg1[key2], arg2 === true);
240
+ } else
220
241
  event(self, arg1);
221
- if (PENDING2.has(self))
222
- return {
223
- then: (res) => new Promise((res2) => {
224
- const remove = addListener(self, (key2) => {
225
- if (key2 !== true) {
226
- remove();
227
- return res2.bind(null, Array.from(PENDING2.get(self)));
228
- }
229
- });
230
- }).then(res)
231
- };
242
+ return pending(self);
232
243
  }
233
244
  /**
234
245
  * Iterate over managed properties in this instance of Model.
235
- * Yeilds the key and underlying value for each property.
246
+ * Yeilds the key and current value for each property.
236
247
  */
237
248
  [Symbol.iterator]() {
238
249
  return Object.entries(STATE.get(this.is))[Symbol.iterator]();
@@ -245,9 +256,8 @@ var Model = class _Model {
245
256
  * @param args - arguments sent to constructor
246
257
  */
247
258
  static new(...args) {
248
- _Model.is(this);
249
259
  const instance = new this(...args);
250
- emit(instance, true);
260
+ event(instance);
251
261
  return instance;
252
262
  }
253
263
  /**
@@ -257,9 +267,7 @@ var Model = class _Model {
257
267
  * methods and properties of this class.
258
268
  */
259
269
  static is(maybe) {
260
- if (maybe === _Model)
261
- throw new Error("Model is abstract and not a valid type.");
262
- return typeof maybe == "function" && maybe.prototype instanceof this;
270
+ return maybe === this || typeof maybe == "function" && maybe.prototype instanceof this;
263
271
  }
264
272
  /**
265
273
  * Register a callback to run when any instance of this Model is updated.
@@ -283,48 +291,48 @@ define(Model, "toString", {
283
291
  }
284
292
  });
285
293
  function prepare(model) {
294
+ let T = model.constructor;
295
+ if (T === Model)
296
+ throw new Error("Cannot create base Model.");
286
297
  const chain = [];
287
- let type = model.constructor;
288
298
  let keys2 = /* @__PURE__ */ new Set();
289
- while (type.name) {
290
- chain.unshift(type);
291
- type = Object.getPrototypeOf(type);
292
- }
293
- for (const type2 of chain) {
294
- for (const cb of NOTIFY.get(type2) || [])
299
+ ID.set(model, `${T}-${uid()}`);
300
+ while (T.name) {
301
+ for (const cb of NOTIFY.get(T) || [])
295
302
  addListener(model, cb);
296
- if (type2 == Model)
297
- continue;
298
- if (METHODS.has(type2)) {
299
- keys2 = METHODS.get(type2);
303
+ if (T === Model)
304
+ break;
305
+ else
306
+ chain.unshift(T);
307
+ T = Object.getPrototypeOf(T);
308
+ }
309
+ for (const type of chain) {
310
+ if (METHODS.has(type)) {
311
+ keys2 = METHODS.get(type);
300
312
  continue;
301
313
  }
302
- METHODS.set(type2, keys2 = new Set(keys2));
314
+ METHODS.set(type, keys2 = new Set(keys2));
303
315
  for (const [key2, { value }] of Object.entries(
304
- Object.getOwnPropertyDescriptors(type2.prototype)
316
+ Object.getOwnPropertyDescriptors(type.prototype)
305
317
  )) {
306
- let set3 = function(method) {
307
- const value2 = method.bind(this.is);
318
+ let bind2 = function(method = value) {
319
+ const value2 = method.bind(model);
308
320
  METHOD.set(value2, method);
309
- define(this.is, key2, { value: value2, writable: true });
321
+ define(model, key2, { value: value2, writable: true });
310
322
  return value2;
311
323
  };
312
- var set2 = set3;
324
+ var bind = bind2;
313
325
  if (!value || key2 == "constructor")
314
326
  continue;
315
327
  keys2.add(key2);
316
- Object.defineProperty(type2.prototype, key2, {
317
- set: set3,
318
- get() {
319
- return this.hasOwnProperty(key2) ? value : set3.call(this, value);
320
- }
321
- });
328
+ define(type.prototype, key2, { get: bind2, set: bind2 });
322
329
  }
323
330
  }
324
331
  }
325
332
  function init(model, args) {
326
- const done = /* @__PURE__ */ new Set();
327
- const state = STATE.get(model);
333
+ const methods = METHODS.get(model.constructor);
334
+ const state = {};
335
+ STATE.set(model, state);
328
336
  args = args.flat().filter((arg) => {
329
337
  if (typeof arg != "string")
330
338
  return true;
@@ -341,9 +349,12 @@ function init(model, args) {
341
349
  console.error(err);
342
350
  });
343
351
  else if (typeof use2 == "function")
344
- done.add(use2);
345
- else if (typeof use2 == "object")
346
- assign(model, use2);
352
+ addListener(model, use2, null);
353
+ else if (typeof use2 == "object") {
354
+ for (const key2 in use2)
355
+ if (key2 in model || methods.has(key2))
356
+ model[key2] = use2[key2];
357
+ }
347
358
  });
348
359
  for (const key2 in model) {
349
360
  const desc = Object.getOwnPropertyDescriptor(model, key2);
@@ -351,22 +362,30 @@ function init(model, args) {
351
362
  update(model, key2, desc.value, true);
352
363
  define(model, key2, {
353
364
  configurable: false,
354
- set: (x) => update(model, key2, x),
355
365
  get() {
356
366
  return watch(this, key2, state[key2]);
367
+ },
368
+ set(value) {
369
+ update(model, key2, value);
370
+ mayAdopt(model, value);
357
371
  }
358
372
  });
359
373
  }
360
374
  }
375
+ addListener(model, () => {
376
+ for (const [_, value] of model)
377
+ if (value instanceof Model && PARENT.get(value) === model)
378
+ value.set(null);
379
+ Object.freeze(state);
380
+ }, null);
361
381
  return null;
362
382
  });
363
- addListener(model, () => {
364
- done.forEach((x) => x());
365
- for (const [_, value] of model)
366
- if (value instanceof Model && PARENT.get(value) === model)
367
- value.set(null);
368
- Object.freeze(state);
369
- }, null);
383
+ }
384
+ function mayAdopt(parent, child) {
385
+ if (child instanceof Model && !PARENT.has(child)) {
386
+ PARENT.set(child, parent);
387
+ event(child);
388
+ }
370
389
  }
371
390
  function fetch(subject, property, required) {
372
391
  const state = STATE.get(subject);
@@ -393,19 +412,24 @@ function fetch(subject, property, required) {
393
412
  stack: error.stack
394
413
  });
395
414
  }
396
- function values(model) {
397
- const values2 = {};
398
- const current = !EXPORT && (EXPORT = /* @__PURE__ */ new Map([[model, values2]]));
415
+ var EXPORT;
416
+ function snapshot(model) {
417
+ const values = {};
418
+ let isNotRecursive;
419
+ if (!EXPORT) {
420
+ isNotRecursive = true;
421
+ EXPORT = /* @__PURE__ */ new Map([[model, values]]);
422
+ }
399
423
  for (let [key2, value] of model) {
400
424
  if (EXPORT.has(value))
401
425
  value = EXPORT.get(value);
402
- else if (value && typeof value.get === "function")
426
+ else if (value && typeof value == "object" && "get" in value && typeof value.get === "function")
403
427
  EXPORT.set(value, value = value.get());
404
- values2[key2] = value;
428
+ values[key2] = value;
405
429
  }
406
- if (current)
430
+ if (isNotRecursive)
407
431
  EXPORT = void 0;
408
- return Object.freeze(values2);
432
+ return Object.freeze(values);
409
433
  }
410
434
  function update(subject, key2, value, arg) {
411
435
  const state = STATE.get(subject);
@@ -420,46 +444,23 @@ function update(subject, key2, value, arg) {
420
444
  value = out();
421
445
  }
422
446
  if (value === previous)
423
- return true;
424
- if (value instanceof Model && !PARENT.has(value)) {
425
- PARENT.set(value, subject);
426
- emit(value, true);
427
- }
447
+ return;
428
448
  state[key2] = value;
429
449
  if (arg !== true)
430
450
  event(subject, key2);
431
- }
432
- function event(subject, key2, silent) {
433
- let pending = PENDING2.get(subject);
434
- if (!pending) {
435
- PENDING2.set(subject, pending = /* @__PURE__ */ new Set());
436
- if (!silent)
437
- queue(() => {
438
- emit(subject, false);
439
- PENDING2.delete(subject);
440
- });
441
- }
442
- pending.add(key2);
443
- if (!silent)
444
- emit(subject, key2);
445
- }
446
- function assign(to, values2) {
447
- const methods = METHODS.get(to.constructor);
448
- for (const key2 in values2)
449
- if (key2 in to || methods.has(key2))
450
- to[key2] = values2[key2];
451
+ return true;
451
452
  }
452
453
  function uid() {
453
- return (Math.random() * 0.722 + 0.278).toString(36).substring(2, 8).toUpperCase();
454
+ return (0.278 + Math.random() * 0.722).toString(36).substring(2, 8).toUpperCase();
454
455
  }
455
456
 
456
457
  // src/context.ts
457
- var Register = /* @__PURE__ */ new WeakMap();
458
- var Table = /* @__PURE__ */ new Map();
458
+ var LOOKUP = /* @__PURE__ */ new WeakMap();
459
+ var KEYS = /* @__PURE__ */ new Map();
459
460
  function key(T, upstream) {
460
- let K = Table.get(T);
461
+ let K = KEYS.get(T);
461
462
  if (!K)
462
- Table.set(T, K = Symbol(
463
+ KEYS.set(T, K = Symbol(
463
464
  typeof T == "symbol" ? "get " + T.description : String(T)
464
465
  ));
465
466
  return upstream ? key(K) : K;
@@ -479,7 +480,7 @@ var Context = class _Context {
479
480
  this.include(inputs);
480
481
  }
481
482
  static get(from, callback) {
482
- const waiting = Register.get(from);
483
+ const waiting = LOOKUP.get(from);
483
484
  if (waiting instanceof _Context) {
484
485
  if (callback)
485
486
  callback(waiting);
@@ -489,11 +490,14 @@ var Context = class _Context {
489
490
  if (waiting)
490
491
  waiting.push(callback);
491
492
  else
492
- Register.set(from, [callback]);
493
+ LOOKUP.set(from, [callback]);
493
494
  }
494
- get(Type, callback) {
495
- if (callback)
496
- Object.defineProperty(this, key(Type, true), { value: callback });
495
+ /** Run callback when a specified type is registered to a **child** context. */
496
+ has(Type, callback) {
497
+ define(this, key(Type, true), { value: callback });
498
+ }
499
+ /** Find specified type registered to a parent context. Returns undefined if none are found. */
500
+ get(Type) {
497
501
  const result = this[key(Type)];
498
502
  if (result === null)
499
503
  throw new Error(`Did find ${Type} in context, but multiple were defined.`);
@@ -515,9 +519,16 @@ var Context = class _Context {
515
519
  }
516
520
  include(inputs, forEach) {
517
521
  const init2 = /* @__PURE__ */ new Map();
522
+ if (typeof inputs == "function" || inputs instanceof Model)
523
+ inputs = { 0: inputs };
518
524
  Object.entries(inputs).forEach(([K, V]) => {
519
- if (!(Model.is(V) || V instanceof Model))
520
- throw new Error(`Context can only include Model or instance but got ${V}${K && " as " + K}.`);
525
+ if (Model.is(V) || V instanceof Model)
526
+ return;
527
+ if (K && K != V)
528
+ V = `${V} (as '${K}')`;
529
+ throw new Error(
530
+ `Context may only include instance or class \`extends Model\` but got ${V}.`
531
+ );
521
532
  });
522
533
  for (const key2 in inputs) {
523
534
  const input = inputs[key2];
@@ -534,8 +545,10 @@ var Context = class _Context {
534
545
  }
535
546
  for (const [model, explicit] of init2) {
536
547
  model.set();
537
- if (forEach)
548
+ if (typeof forEach == "function")
538
549
  forEach(model, explicit);
550
+ else if (forEach && explicit)
551
+ model.set(forEach);
539
552
  for (const [_key, value] of model)
540
553
  if (PARENT.get(value) === model) {
541
554
  this.add(value, true);
@@ -552,8 +565,8 @@ var Context = class _Context {
552
565
  I = new input();
553
566
  this.cleanup.add(() => I.set(null));
554
567
  } else {
568
+ T = input.constructor;
555
569
  I = input;
556
- T = I.constructor;
557
570
  }
558
571
  keys(T, true).forEach((K) => {
559
572
  const result = this[K];
@@ -566,15 +579,15 @@ var Context = class _Context {
566
579
  keys(T).forEach((K) => {
567
580
  const value = this.hasOwnProperty(K) ? null : I;
568
581
  if (value || this[K] !== I && !implicit)
569
- Object.defineProperty(this, K, {
582
+ define(this, K, {
570
583
  configurable: true,
571
584
  value
572
585
  });
573
586
  });
574
- const waiting = Register.get(I);
587
+ const waiting = LOOKUP.get(I);
575
588
  if (waiting instanceof Array)
576
589
  waiting.forEach((cb) => cb(this));
577
- Register.set(I, this);
590
+ LOOKUP.set(I, this);
578
591
  return I;
579
592
  }
580
593
  };
@@ -610,8 +623,7 @@ Model.on((_, model) => {
610
623
  const { value } = Object.getOwnPropertyDescriptor(model, key2);
611
624
  const instruction = INSTRUCT.get(value);
612
625
  if (!instruction) {
613
- if (value instanceof Model && key2 !== "is")
614
- update(model, key2, value);
626
+ mayAdopt(model, value);
615
627
  continue;
616
628
  }
617
629
  INSTRUCT.delete(value);
@@ -622,7 +634,7 @@ Model.on((_, model) => {
622
634
  const desc = typeof output == "object" ? output : { get: output };
623
635
  if ("value" in desc)
624
636
  state[key2] = desc.value;
625
- Object.defineProperty(model, key2, {
637
+ define(model, key2, {
626
638
  enumerable: desc.enumerable !== false,
627
639
  get() {
628
640
  return watch(
@@ -645,81 +657,84 @@ Model.on((_, model) => {
645
657
  var STALE = /* @__PURE__ */ new WeakSet();
646
658
  function get(arg0, arg1) {
647
659
  return use((key2, subject, state) => {
648
- let from = subject;
649
660
  if (typeof arg0 == "symbol")
650
- throw new Error(`Attempted to use an instruction result (probably use or get) as computed source for ${from}.${key2}. This is not allowed.`);
651
- let source = (resolve) => resolve(from);
652
- if (arg0 instanceof Model) {
653
- from = arg0;
654
- } else if (Model.is(arg0)) {
655
- const hasParent = PARENT.get(from);
661
+ throw new Error(`Attempted to use an instruction result (probably use or get) as computed source for ${subject}.${key2}. This is not allowed.`);
662
+ if (Model.is(arg0)) {
663
+ let assign2 = function(value) {
664
+ if (typeof arg1 == "function")
665
+ value.get((x) => arg1(x, key2));
666
+ update(subject, key2, value);
667
+ };
668
+ var assign = assign2;
669
+ const hasParent = PARENT.get(subject);
656
670
  if (!hasParent) {
657
671
  if (arg1 === true)
658
- throw new Error(`${from} may only exist as a child of type ${arg0}.`);
659
- source = (resolve) => {
660
- Context.get(from, (context) => {
661
- const got = context.get(arg0);
662
- if (got)
663
- resolve(got);
664
- else if (arg1 !== false)
665
- throw new Error(`Required ${arg0} not found in context for ${from}.`);
666
- });
667
- };
672
+ throw new Error(`${subject} may only exist as a child of type ${arg0}.`);
673
+ Context.get(subject, (context) => {
674
+ const model = context.get(arg0);
675
+ if (model)
676
+ assign2(model);
677
+ else if (arg1 !== false)
678
+ throw new Error(`Required ${arg0} not found in context for ${subject}.`);
679
+ });
668
680
  } else if (!arg0 || hasParent instanceof arg0)
669
- from = hasParent;
681
+ assign2(hasParent);
670
682
  else
671
- throw new Error(`New ${from} created as child of ${hasParent}, but must be instanceof ${arg0}.`);
683
+ throw new Error(`New ${subject} created as child of ${hasParent}, but must be instanceof ${arg0}.`);
684
+ return {
685
+ get: arg1 !== false
686
+ };
687
+ }
688
+ let from = subject;
689
+ if (arg0 instanceof Model) {
690
+ from = arg0;
672
691
  } else {
673
692
  const fn = METHOD.get(arg0) || arg0;
674
693
  arg1 = (p, k) => fn.call(p, k, p);
675
694
  }
676
- if (typeof arg1 == "function") {
677
- let connect2 = function(model) {
678
- reset = effect(model, (current) => {
679
- proxy = current;
680
- if (!(key2 in state) || STALE.delete(compute2))
681
- compute2(!reset);
682
- return (didUpdate) => {
683
- if (didUpdate) {
684
- STALE.add(compute2);
685
- event(subject, key2, true);
686
- }
687
- };
688
- });
689
- }, compute2 = function(initial) {
690
- let next;
691
- try {
692
- next = getter.call(proxy, proxy, key2);
693
- } catch (err) {
694
- console.warn(`An exception was thrown while ${initial ? "initializing" : "refreshing"} ${subject}.${key2}.`);
695
- if (initial)
696
- throw err;
697
- console.error(err);
698
- }
699
- update(subject, key2, next, !isAsync);
700
- };
701
- var connect = connect2, compute = compute2;
702
- const getter = arg1;
703
- let reset;
704
- let isAsync;
705
- let proxy;
706
- return () => {
707
- if (!proxy) {
708
- source(connect2);
709
- isAsync = true;
710
- }
711
- if (STALE.delete(compute2))
712
- compute2();
713
- return fetch(subject, key2, !proxy);
714
- };
715
- } else
716
- source((got) => subject.set(key2, got));
717
- return { get: arg1 };
695
+ const source = (resolve) => resolve(from);
696
+ const getter = arg1;
697
+ let reset;
698
+ let isAsync;
699
+ let proxy;
700
+ function connect(model) {
701
+ reset = createEffect(model, (current) => {
702
+ proxy = current;
703
+ if (!(key2 in state) || STALE.delete(compute))
704
+ compute(!reset);
705
+ return (didUpdate) => {
706
+ if (didUpdate) {
707
+ STALE.add(compute);
708
+ event(subject, key2, true);
709
+ }
710
+ };
711
+ });
712
+ }
713
+ function compute(initial) {
714
+ let next;
715
+ try {
716
+ next = getter.call(proxy, proxy, key2);
717
+ } catch (err) {
718
+ console.warn(`An exception was thrown while ${initial ? "initializing" : "refreshing"} ${subject}.${key2}.`);
719
+ if (initial)
720
+ throw err;
721
+ console.error(err);
722
+ }
723
+ update(subject, key2, next, !isAsync);
724
+ }
725
+ return () => {
726
+ if (!proxy) {
727
+ source(connect);
728
+ isAsync = true;
729
+ }
730
+ if (STALE.delete(compute))
731
+ compute();
732
+ return fetch(subject, key2, !proxy);
733
+ };
718
734
  });
719
735
  }
720
736
 
721
737
  // src/instruction/ref.ts
722
- var define2 = Object.defineProperty;
723
738
  function ref(arg, arg2) {
724
739
  return use((key2, subject, state) => {
725
740
  let value = {};
@@ -727,20 +742,22 @@ function ref(arg, arg2) {
727
742
  subject.get(() => {
728
743
  for (const key3 in state)
729
744
  if (typeof arg2 == "function")
730
- define2(value, key3, {
745
+ define(value, key3, {
731
746
  configurable: true,
732
747
  get() {
733
748
  const out = arg2(key3);
734
- define2(value, key3, { value: out });
749
+ define(value, key3, { value: out });
735
750
  return out;
736
751
  }
737
752
  });
738
753
  else {
739
754
  const get2 = () => state[key3];
740
- const set2 = (value2) => subject.set(key3, value2);
741
- define2(set2, "current", { get: get2, set: set2 });
742
- define2(set2, "get", { value: get2 });
743
- define2(value, key3, { value: set2 });
755
+ const set2 = (value2) => {
756
+ update(subject, key3, value2);
757
+ };
758
+ define(set2, "current", { get: get2, set: set2 });
759
+ define(set2, "get", { value: get2 });
760
+ define(value, key3, { value: set2 });
744
761
  }
745
762
  });
746
763
  else if (typeof arg == "object")
@@ -749,7 +766,7 @@ function ref(arg, arg2) {
749
766
  let unSet;
750
767
  const get2 = () => state[key2];
751
768
  const set2 = (value2) => {
752
- if (!subject.set(key2, value2) || !arg)
769
+ if (!update(subject, key2, value2) || !arg)
753
770
  return;
754
771
  if (unSet)
755
772
  unSet = void unSet(value2);
@@ -765,7 +782,7 @@ function ref(arg, arg2) {
765
782
  get: { value: get2 }
766
783
  });
767
784
  }
768
- define2(subject, key2, { value });
785
+ define(subject, key2, { value });
769
786
  });
770
787
  }
771
788
 
@@ -785,16 +802,16 @@ function set(value, argument) {
785
802
  output.get = argument === true;
786
803
  if (value instanceof Promise) {
787
804
  value.then((value2) => {
788
- subject.set(key2, value2);
805
+ update(subject, key2, value2);
789
806
  return value2;
790
807
  }).catch((err) => {
791
- subject.set(key2);
808
+ event(subject, key2);
792
809
  output.get = () => {
793
810
  throw err;
794
811
  };
795
812
  });
796
813
  } else
797
- subject.set(key2, value);
814
+ update(subject, key2, value);
798
815
  if (0 in arguments)
799
816
  return subject[key2];
800
817
  };
@@ -819,7 +836,7 @@ function set(value, argument) {
819
836
  } else
820
837
  output.set = (value2) => {
821
838
  output.get = void 0;
822
- subject.set(key2, value2);
839
+ update(subject, key2, value2);
823
840
  };
824
841
  return output;
825
842
  });
@@ -847,17 +864,17 @@ var APPLY = /* @__PURE__ */ new WeakMap();
847
864
  function has(arg1, arg2) {
848
865
  return use((key2, subject) => {
849
866
  const applied = /* @__PURE__ */ new Set();
850
- const update2 = () => {
851
- subject.set(key2, Object.freeze(Array.from(applied)));
867
+ const apply = () => {
868
+ update(subject, key2, Object.freeze(Array.from(applied)));
852
869
  };
853
870
  if (Model.is(arg1))
854
871
  Context.get(subject, (context) => {
855
- context.get(arg1, (got) => {
872
+ context.has(arg1, (model) => {
856
873
  let remove;
857
874
  let disconnect;
858
- if (applied.has(got))
875
+ if (applied.has(model))
859
876
  return;
860
- const callback = APPLY.get(got);
877
+ const callback = APPLY.get(model);
861
878
  if (callback) {
862
879
  const after = callback(subject);
863
880
  if (after === false)
@@ -866,7 +883,7 @@ function has(arg1, arg2) {
866
883
  disconnect = after;
867
884
  }
868
885
  if (typeof arg2 == "function") {
869
- const done2 = arg2(got, subject);
886
+ const done2 = arg2(model, subject);
870
887
  if (done2 === false)
871
888
  return false;
872
889
  remove = () => {
@@ -874,18 +891,18 @@ function has(arg1, arg2) {
874
891
  done2();
875
892
  };
876
893
  }
877
- applied.add(got);
878
- update2();
894
+ applied.add(model);
895
+ apply();
879
896
  const done = () => {
880
- reset();
881
- applied.delete(got);
882
- update2();
897
+ ignore();
898
+ applied.delete(model);
899
+ apply();
883
900
  if (disconnect)
884
901
  disconnect();
885
902
  if (typeof remove == "function")
886
903
  remove();
887
904
  };
888
- const reset = got.get(null, done);
905
+ const ignore = model.get(null, done);
889
906
  return done;
890
907
  });
891
908
  });
@@ -900,10 +917,10 @@ function has(arg1, arg2) {
900
917
  return false;
901
918
  }
902
919
  applied.add(recipient);
903
- update2();
920
+ apply();
904
921
  return () => {
905
922
  applied.delete(recipient);
906
- update2();
923
+ apply();
907
924
  if (typeof remove == "function")
908
925
  remove();
909
926
  };
@@ -916,7 +933,9 @@ function has(arg1, arg2) {
916
933
  0 && (module.exports = {
917
934
  Context,
918
935
  Model,
919
- effect,
936
+ addListener,
937
+ createEffect,
938
+ createProxy,
920
939
  get,
921
940
  has,
922
941
  ref,