@expressive/mvc 0.35.5 → 0.35.6

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
@@ -6,21 +6,21 @@ declare namespace Model {
6
6
  /** Subset of `keyof T` which are not methods or defined by base Model U. **/
7
7
  type Field<T> = Exclude<keyof T, keyof Model>;
8
8
  type Key<T> = Field<T> | (string & {}) | number | symbol;
9
- /** Actual value stored in state. */
10
- type Actual<R> = R extends Ref<infer T> ? T : R extends Model ? State<R> : R;
11
9
  type Value<T extends Model, K extends Key<T>> = K extends keyof T ? T[K] extends Ref<infer V> ? V : T[K] : unknown;
12
10
  type OnUpdate<T extends Model, K extends Key<T>> = (this: T, value: Value<T, K>, key: K, thisArg: K) => void;
11
+ /** Export/Import compatible value for a given property in a Model. */
12
+ type Export<R> = R extends Ref<infer T> ? T : R extends Model ? State<R> : R;
13
13
  /**
14
14
  * Values from current state of given controller.
15
15
  * Differs from `Values` as values here will drill
16
16
  * into "real" values held by exotics like ref.
17
17
  */
18
18
  type State<T> = {
19
- [P in Field<T>]: Actual<T[P]>;
19
+ [P in Field<T>]: Export<T[P]>;
20
20
  };
21
21
  /** Object comperable to data found in T. */
22
22
  type Values<T> = {
23
- [P in Field<T>]?: Actual<T[P]>;
23
+ [P in Field<T>]?: Export<T[P]>;
24
24
  };
25
25
  /** Exotic value, where actual value is contained within. */
26
26
  type Ref<T = any> = {
@@ -28,7 +28,7 @@ declare namespace Model {
28
28
  current: T | null;
29
29
  };
30
30
  /** A callback function which is subscribed to parent and updates when values change. */
31
- type Effect<T> = (this: T, argument: T) => (() => void) | Promise<void> | null | void;
31
+ type Effect<T> = (this: T, argument: T) => ((update: boolean | null) => void) | Promise<void> | null | void;
32
32
  type Event<T extends Model> = (this: T, key: unknown, source: T) => (() => void) | void | null;
33
33
  namespace Instruction {
34
34
  type Getter<T> = (source: Model) => T;
@@ -59,18 +59,18 @@ declare class Model {
59
59
  get(): Model.State<this>;
60
60
  /** Run a function which will run automatically when accessed values change. */
61
61
  get(effect: Model.Effect<this>): () => void;
62
- /** Check if model is expired. */
63
- get(event: null): boolean;
64
- /** Callback when model is to be destroyed. */
65
- get(event: null, callback: () => void): () => void;
66
62
  get<T extends Model.Key<this>>(key: T, required?: boolean): Model.Value<this, T>;
67
63
  get<T extends Model.Key<this>>(key: T, callback: Model.OnUpdate<this, T>): () => void;
64
+ /** Check if model is expired. */
65
+ get(status: null): boolean;
66
+ /** Callback when model is to be destroyed. */
67
+ get(status: null, callback: () => void): () => void;
68
68
  /**
69
69
  * Get update in progress.
70
70
  *
71
71
  * @returns Promise which resolves object with updated values. Is `undefined` if there is no update.
72
72
  **/
73
- set(): Promise<Model.Values<this>> | undefined;
73
+ set(): PromiseLike<Model.Key<this>[]> | undefined;
74
74
  /**
75
75
  * Call a function when update occurs.
76
76
  *
@@ -84,15 +84,21 @@ declare class Model {
84
84
  set(callback: Model.Event<this>): () => boolean;
85
85
  /**
86
86
  * Declare an end to updates. This event is final and will freeze state.
87
+ * This event can be watched for as well, to run cleanup logic and internally will remove all listeners.
87
88
  */
88
- set(event: null): void;
89
+ set(status: null): void;
89
90
  /**
90
91
  * Push an update. This will not change the value of associated property.
91
92
  *
92
93
  * Useful where a property value internally has changed, but the object is the same.
93
94
  * For example: An array has pushed a new value, or a nested property is updated.
95
+ *
96
+ * You can also use this to dispatch arbitrary events as well. Symbols are generally
97
+ * recommended as non-property events, however you can use any string. If doing so,
98
+ * be sure to avoid collisions with property names - an easy way to do this will be to
99
+ * prefix your event with "!" and/or use dash-case. e.g. `set("!event")` or `set("my-event")`.
94
100
  */
95
- set(key: Model.Key<this>): void;
101
+ set(key: Model.Key<this>): PromiseLike<Model.Key<this>[]>;
96
102
  /**
97
103
  * Update a property with value.
98
104
  *
@@ -100,7 +106,7 @@ declare class Model {
100
106
  * @param value - value to update property with (if the same as current, no update will occur)
101
107
  * @param silent - if true, will not notify listeners of an update
102
108
  */
103
- set<K extends string>(key: K, value?: Model.Value<this, K>, silent?: boolean): void;
109
+ set<K extends string>(key: K, value?: Model.Value<this, K>, silent?: boolean): PromiseLike<Model.Key<this>[]> | undefined;
104
110
  /** Iterate over managed properties in this instance of Model. */
105
111
  [Symbol.iterator](): Iterator<[string, unknown]>;
106
112
  /**
@@ -276,21 +282,19 @@ declare function use<T extends Model>(model: T, ready?: (i: T) => void): T;
276
282
  declare function use<T extends {}, O = use.Object<T>>(data: T, ready?: (object: O) => void): O;
277
283
 
278
284
  declare namespace Context {
279
- type Inputs = {
280
- [key: string | number]: Model | Model.New;
281
- };
285
+ type Input = Model | Model.New<Model> | Record<string | number, Model | Model.New<Model>>;
282
286
  }
283
287
  declare class Context {
284
- static resolve(from: Model, callback: (context: Context) => void): void;
285
- constructor(inputs?: Context.Inputs);
288
+ static get(from: Model, callback: (context: Context) => void): void;
286
289
  key: string;
287
- private table;
288
- private layer;
289
- private has;
290
+ protected table: WeakMap<Model.Type<Model>, symbol>;
291
+ protected layer: Map<string | number, Model | Model.Type<Model>>;
292
+ constructor(inputs?: Context.Input);
293
+ protected has(T: Model.Type): keyof this;
290
294
  get<T extends Model>(Type: Model.Type<T>): T | undefined;
291
- include(inputs: Context.Inputs): Map<Model, boolean>;
295
+ include(inputs: Context.Input): Map<Model, boolean>;
292
296
  protected add<T extends Model>(input: T | Model.New<T>, implicit?: boolean): T;
293
- push(): this;
297
+ push(inputs?: Context.Input): this;
294
298
  pop(): void;
295
299
  }
296
300
 
package/dist/index.js CHANGED
@@ -102,7 +102,7 @@ function effect(target, callback) {
102
102
  return null;
103
103
  expired = true;
104
104
  if (refresh && unSet) {
105
- unSet();
105
+ unSet(true);
106
106
  unSet = void 0;
107
107
  }
108
108
  return refresh;
@@ -129,9 +129,11 @@ function effect(target, callback) {
129
129
  else if (!refresh)
130
130
  return refresh;
131
131
  if (key === null && unSet)
132
- unSet();
132
+ unSet(null);
133
133
  });
134
134
  return () => {
135
+ if (unSet)
136
+ unSet(false);
135
137
  refresh = null;
136
138
  };
137
139
  }
@@ -156,16 +158,19 @@ var Model = class _Model {
156
158
  break;
157
159
  Type = Object.getPrototypeOf(Type);
158
160
  }
159
- addListener(this, () => {
160
- for (const key in this) {
161
- const desc = Object.getOwnPropertyDescriptor(this, key);
161
+ const remove = addListener(this, (key) => {
162
+ remove();
163
+ if (key !== true)
164
+ event(this, true);
165
+ for (const key2 in this) {
166
+ const desc = Object.getOwnPropertyDescriptor(this, key2);
162
167
  if ("value" in desc) {
163
- state[key] = desc.value;
164
- define(this, key, {
168
+ state[key2] = desc.value;
169
+ define(this, key2, {
165
170
  enumerable: true,
166
- set: (x) => update(this, key, x),
171
+ set: (x) => update(this, key2, x),
167
172
  get() {
168
- return watch(this, key, state[key]);
173
+ return watch(this, key2, state[key2]);
169
174
  }
170
175
  });
171
176
  }
@@ -176,43 +181,25 @@ var Model = class _Model {
176
181
  value.set(null);
177
182
  Object.freeze(state);
178
183
  }, null);
179
- return null;
180
184
  });
181
185
  }
182
186
  get(arg1, arg2) {
183
187
  const self = this.is;
184
188
  if (typeof arg1 == "function")
185
189
  return effect(self, arg1);
186
- if (arg1 === void 0) {
187
- let get3 = function(value) {
188
- if (value instanceof _Model) {
189
- if (cache.has(value))
190
- return cache.get(value);
191
- const model = value;
192
- cache.set(value, value = {});
193
- for (const [key, val] of model)
194
- value[key] = get3(val);
195
- }
196
- return value;
197
- };
198
- var get2 = get3;
199
- const cache = /* @__PURE__ */ new WeakMap();
200
- return get3(self);
201
- }
202
- if (arg1 === null)
203
- if (typeof arg2 == "function")
204
- return addListener(self, arg2.bind(this, this), null);
205
- else
206
- return Object.isFrozen(STATE.get(self));
190
+ if (arg1 === void 0)
191
+ return extract(self);
207
192
  if (typeof arg2 == "function") {
193
+ if (arg1 === null)
194
+ return addListener(self, arg2.bind(this, this), null);
208
195
  const state = STATE.get(self);
209
196
  if (arg1 in state)
210
197
  arg2.call(this, state[arg1], arg1, this);
211
198
  return addListener(self, () => {
212
199
  arg2.call(this, arg1 in state ? state[arg1] : arg1, arg1, this);
213
200
  }, arg1);
214
- } else
215
- return fetch(self, arg1, arg2);
201
+ }
202
+ return arg1 === null ? Object.isFrozen(STATE.get(self)) : fetch(self, arg1, arg2);
216
203
  }
217
204
  set(arg1, arg2, arg3) {
218
205
  const self = this.is;
@@ -221,18 +208,24 @@ var Model = class _Model {
221
208
  if (typeof key == "string")
222
209
  return arg1.call(self, key, self);
223
210
  });
211
+ if (arg1 === null)
212
+ return event(this, null);
224
213
  if (arg1 !== void 0)
225
- return 1 in arguments ? update(self, arg1, arg2, arg3) : update(self, arg1);
226
- if (!PENDING.has(self))
227
- return;
228
- return new Promise((resolve) => {
229
- const remove = addListener(this, (key) => {
230
- if (key !== true) {
231
- remove();
232
- return resolve.bind(null, PENDING.get(self));
233
- }
234
- });
235
- });
214
+ if (1 in arguments)
215
+ update(self, arg1, arg2, arg3);
216
+ else
217
+ push(self, arg1);
218
+ if (PENDING.has(self))
219
+ return {
220
+ then: (res) => new Promise((res2) => {
221
+ const remove = addListener(self, (key) => {
222
+ if (key !== true) {
223
+ remove();
224
+ return res2.bind(null, Array.from(PENDING.get(self)));
225
+ }
226
+ });
227
+ }).then(res)
228
+ };
236
229
  }
237
230
  /** Iterate over managed properties in this instance of Model. */
238
231
  [Symbol.iterator]() {
@@ -285,14 +278,14 @@ function fetch(subject, property, required) {
285
278
  return value;
286
279
  }
287
280
  const error = new Error(`${subject}.${property} is not yet available.`);
288
- const promise = new Promise((resolve, reject) => {
281
+ const promise = new Promise((resolve, reject2) => {
289
282
  addListener(subject, (key) => {
290
283
  if (key === property) {
291
284
  resolve(state[key]);
292
285
  return null;
293
286
  }
294
287
  if (key === null)
295
- reject(new Error(`${subject} is destroyed.`));
288
+ reject2(new Error(`${subject} is destroyed.`));
296
289
  });
297
290
  });
298
291
  throw Object.assign(promise, {
@@ -304,26 +297,42 @@ function fetch(subject, property, required) {
304
297
  }
305
298
  function update(subject, key, value, silent) {
306
299
  const state = STATE.get(subject);
300
+ if (Object.isFrozen(state))
301
+ throw new Error(`Tried to update ${String(key)} but ${subject} is destroyed.`);
302
+ const previous = state[key];
303
+ if (value === previous)
304
+ return true;
305
+ state[key] = value;
306
+ if (silent === true)
307
+ return;
308
+ push(subject, key);
309
+ }
310
+ function push(subject, key) {
307
311
  let pending = PENDING.get(subject);
308
- if (typeof key == "string" && 2 in arguments) {
309
- const previous = state[key];
310
- if (value === previous)
311
- return true;
312
- state[key] = value;
313
- if (silent === true)
314
- return;
312
+ if (!pending) {
313
+ PENDING.set(subject, pending = /* @__PURE__ */ new Set());
314
+ queue(() => {
315
+ event(subject, false);
316
+ PENDING.delete(subject);
317
+ });
315
318
  }
316
- if (key !== true && key) {
317
- if (!pending) {
318
- PENDING.set(subject, pending = {});
319
- queue(() => {
320
- event(subject, false);
321
- PENDING.delete(subject);
322
- });
319
+ pending.add(key);
320
+ event(subject, key);
321
+ }
322
+ function extract(from) {
323
+ const cache = /* @__PURE__ */ new WeakMap();
324
+ function get2(value) {
325
+ if (value instanceof Model) {
326
+ if (cache.has(value))
327
+ return cache.get(value);
328
+ const model = value;
329
+ cache.set(value, value = {});
330
+ for (const [key, val] of model)
331
+ value[key] = get2(val);
323
332
  }
324
- pending[key] = key in state ? value : true;
333
+ return value;
325
334
  }
326
- event(subject, key);
335
+ return get2(from);
327
336
  }
328
337
  function uid() {
329
338
  return (Math.random() * 0.722 + 0.278).toString(36).substring(2, 8).toUpperCase();
@@ -388,7 +397,7 @@ var Context = class {
388
397
  if (inputs)
389
398
  this.include(inputs);
390
399
  }
391
- static resolve(from, callback) {
400
+ static get() {
392
401
  throw new Error(`Using context requires an adapter. If you are only testing, define \`get.context\` to simulate one.`);
393
402
  }
394
403
  has(T) {
@@ -407,6 +416,14 @@ var Context = class {
407
416
  }
408
417
  include(inputs) {
409
418
  const init = /* @__PURE__ */ new Map();
419
+ if (typeof inputs == "function" || inputs instanceof Model)
420
+ inputs = { [0]: inputs };
421
+ else if (!inputs)
422
+ reject(inputs);
423
+ Object.entries(inputs).forEach(([K, V]) => {
424
+ if (!(Model.is(V) || V instanceof Model))
425
+ reject(`${V} as ${K}`);
426
+ });
410
427
  for (const key in inputs) {
411
428
  const input = inputs[key];
412
429
  const exists = this.layer.get(key);
@@ -453,9 +470,11 @@ var Context = class {
453
470
  } while (T !== Model);
454
471
  return I;
455
472
  }
456
- push() {
473
+ push(inputs) {
457
474
  const next = Object.create(this);
458
475
  next.layer = /* @__PURE__ */ new Map();
476
+ if (inputs)
477
+ next.include(inputs);
459
478
  return next;
460
479
  }
461
480
  pop() {
@@ -471,6 +490,9 @@ var Context = class {
471
490
  this.layer.clear();
472
491
  }
473
492
  };
493
+ function reject(argument) {
494
+ throw new Error(`Context can only include Model or instance but got ${argument}.`);
495
+ }
474
496
 
475
497
  // src/instruction/get.ts
476
498
  function get(arg0, arg1) {
@@ -487,7 +509,7 @@ function get(arg0, arg1) {
487
509
  if (arg1 === true)
488
510
  throw new Error(`${from} may only exist as a child of type ${arg0}.`);
489
511
  source = (resolve) => {
490
- Context.resolve(from, (context) => {
512
+ Context.get(from, (context) => {
491
513
  const model = context.get(arg0);
492
514
  if (model)
493
515
  resolve(model);
@@ -519,9 +541,11 @@ function compute(subject, key, source, setter) {
519
541
  compute2(true);
520
542
  else if (STALE.delete(compute2))
521
543
  compute2();
522
- return () => {
523
- STALE.add(compute2);
524
- subject.set(key);
544
+ return (reason) => {
545
+ if (reason) {
546
+ STALE.add(compute2);
547
+ subject.set(key);
548
+ }
525
549
  };
526
550
  });
527
551
  }
@@ -576,7 +600,7 @@ function ref(arg, arg2) {
576
600
  else {
577
601
  let unSet;
578
602
  const set2 = (value2) => {
579
- if (subject.set(key, value2) || !arg)
603
+ if (!subject.set(key, value2) || !arg)
580
604
  return;
581
605
  if (unSet)
582
606
  unSet = void unSet(value2);
package/dist/index.mjs CHANGED
@@ -69,7 +69,7 @@ function effect(target, callback) {
69
69
  return null;
70
70
  expired = true;
71
71
  if (refresh && unSet) {
72
- unSet();
72
+ unSet(true);
73
73
  unSet = void 0;
74
74
  }
75
75
  return refresh;
@@ -96,9 +96,11 @@ function effect(target, callback) {
96
96
  else if (!refresh)
97
97
  return refresh;
98
98
  if (key === null && unSet)
99
- unSet();
99
+ unSet(null);
100
100
  });
101
101
  return () => {
102
+ if (unSet)
103
+ unSet(false);
102
104
  refresh = null;
103
105
  };
104
106
  }
@@ -123,16 +125,19 @@ var Model = class _Model {
123
125
  break;
124
126
  Type = Object.getPrototypeOf(Type);
125
127
  }
126
- addListener(this, () => {
127
- for (const key in this) {
128
- const desc = Object.getOwnPropertyDescriptor(this, key);
128
+ const remove = addListener(this, (key) => {
129
+ remove();
130
+ if (key !== true)
131
+ event(this, true);
132
+ for (const key2 in this) {
133
+ const desc = Object.getOwnPropertyDescriptor(this, key2);
129
134
  if ("value" in desc) {
130
- state[key] = desc.value;
131
- define(this, key, {
135
+ state[key2] = desc.value;
136
+ define(this, key2, {
132
137
  enumerable: true,
133
- set: (x) => update(this, key, x),
138
+ set: (x) => update(this, key2, x),
134
139
  get() {
135
- return watch(this, key, state[key]);
140
+ return watch(this, key2, state[key2]);
136
141
  }
137
142
  });
138
143
  }
@@ -143,43 +148,25 @@ var Model = class _Model {
143
148
  value.set(null);
144
149
  Object.freeze(state);
145
150
  }, null);
146
- return null;
147
151
  });
148
152
  }
149
153
  get(arg1, arg2) {
150
154
  const self = this.is;
151
155
  if (typeof arg1 == "function")
152
156
  return effect(self, arg1);
153
- if (arg1 === void 0) {
154
- let get3 = function(value) {
155
- if (value instanceof _Model) {
156
- if (cache.has(value))
157
- return cache.get(value);
158
- const model = value;
159
- cache.set(value, value = {});
160
- for (const [key, val] of model)
161
- value[key] = get3(val);
162
- }
163
- return value;
164
- };
165
- var get2 = get3;
166
- const cache = /* @__PURE__ */ new WeakMap();
167
- return get3(self);
168
- }
169
- if (arg1 === null)
170
- if (typeof arg2 == "function")
171
- return addListener(self, arg2.bind(this, this), null);
172
- else
173
- return Object.isFrozen(STATE.get(self));
157
+ if (arg1 === void 0)
158
+ return extract(self);
174
159
  if (typeof arg2 == "function") {
160
+ if (arg1 === null)
161
+ return addListener(self, arg2.bind(this, this), null);
175
162
  const state = STATE.get(self);
176
163
  if (arg1 in state)
177
164
  arg2.call(this, state[arg1], arg1, this);
178
165
  return addListener(self, () => {
179
166
  arg2.call(this, arg1 in state ? state[arg1] : arg1, arg1, this);
180
167
  }, arg1);
181
- } else
182
- return fetch(self, arg1, arg2);
168
+ }
169
+ return arg1 === null ? Object.isFrozen(STATE.get(self)) : fetch(self, arg1, arg2);
183
170
  }
184
171
  set(arg1, arg2, arg3) {
185
172
  const self = this.is;
@@ -188,18 +175,24 @@ var Model = class _Model {
188
175
  if (typeof key == "string")
189
176
  return arg1.call(self, key, self);
190
177
  });
178
+ if (arg1 === null)
179
+ return event(this, null);
191
180
  if (arg1 !== void 0)
192
- return 1 in arguments ? update(self, arg1, arg2, arg3) : update(self, arg1);
193
- if (!PENDING.has(self))
194
- return;
195
- return new Promise((resolve) => {
196
- const remove = addListener(this, (key) => {
197
- if (key !== true) {
198
- remove();
199
- return resolve.bind(null, PENDING.get(self));
200
- }
201
- });
202
- });
181
+ if (1 in arguments)
182
+ update(self, arg1, arg2, arg3);
183
+ else
184
+ push(self, arg1);
185
+ if (PENDING.has(self))
186
+ return {
187
+ then: (res) => new Promise((res2) => {
188
+ const remove = addListener(self, (key) => {
189
+ if (key !== true) {
190
+ remove();
191
+ return res2.bind(null, Array.from(PENDING.get(self)));
192
+ }
193
+ });
194
+ }).then(res)
195
+ };
203
196
  }
204
197
  /** Iterate over managed properties in this instance of Model. */
205
198
  [Symbol.iterator]() {
@@ -252,14 +245,14 @@ function fetch(subject, property, required) {
252
245
  return value;
253
246
  }
254
247
  const error = new Error(`${subject}.${property} is not yet available.`);
255
- const promise = new Promise((resolve, reject) => {
248
+ const promise = new Promise((resolve, reject2) => {
256
249
  addListener(subject, (key) => {
257
250
  if (key === property) {
258
251
  resolve(state[key]);
259
252
  return null;
260
253
  }
261
254
  if (key === null)
262
- reject(new Error(`${subject} is destroyed.`));
255
+ reject2(new Error(`${subject} is destroyed.`));
263
256
  });
264
257
  });
265
258
  throw Object.assign(promise, {
@@ -271,26 +264,42 @@ function fetch(subject, property, required) {
271
264
  }
272
265
  function update(subject, key, value, silent) {
273
266
  const state = STATE.get(subject);
267
+ if (Object.isFrozen(state))
268
+ throw new Error(`Tried to update ${String(key)} but ${subject} is destroyed.`);
269
+ const previous = state[key];
270
+ if (value === previous)
271
+ return true;
272
+ state[key] = value;
273
+ if (silent === true)
274
+ return;
275
+ push(subject, key);
276
+ }
277
+ function push(subject, key) {
274
278
  let pending = PENDING.get(subject);
275
- if (typeof key == "string" && 2 in arguments) {
276
- const previous = state[key];
277
- if (value === previous)
278
- return true;
279
- state[key] = value;
280
- if (silent === true)
281
- return;
279
+ if (!pending) {
280
+ PENDING.set(subject, pending = /* @__PURE__ */ new Set());
281
+ queue(() => {
282
+ event(subject, false);
283
+ PENDING.delete(subject);
284
+ });
282
285
  }
283
- if (key !== true && key) {
284
- if (!pending) {
285
- PENDING.set(subject, pending = {});
286
- queue(() => {
287
- event(subject, false);
288
- PENDING.delete(subject);
289
- });
286
+ pending.add(key);
287
+ event(subject, key);
288
+ }
289
+ function extract(from) {
290
+ const cache = /* @__PURE__ */ new WeakMap();
291
+ function get2(value) {
292
+ if (value instanceof Model) {
293
+ if (cache.has(value))
294
+ return cache.get(value);
295
+ const model = value;
296
+ cache.set(value, value = {});
297
+ for (const [key, val] of model)
298
+ value[key] = get2(val);
290
299
  }
291
- pending[key] = key in state ? value : true;
300
+ return value;
292
301
  }
293
- event(subject, key);
302
+ return get2(from);
294
303
  }
295
304
  function uid() {
296
305
  return (Math.random() * 0.722 + 0.278).toString(36).substring(2, 8).toUpperCase();
@@ -355,7 +364,7 @@ var Context = class {
355
364
  if (inputs)
356
365
  this.include(inputs);
357
366
  }
358
- static resolve(from, callback) {
367
+ static get() {
359
368
  throw new Error(`Using context requires an adapter. If you are only testing, define \`get.context\` to simulate one.`);
360
369
  }
361
370
  has(T) {
@@ -374,6 +383,14 @@ var Context = class {
374
383
  }
375
384
  include(inputs) {
376
385
  const init = /* @__PURE__ */ new Map();
386
+ if (typeof inputs == "function" || inputs instanceof Model)
387
+ inputs = { [0]: inputs };
388
+ else if (!inputs)
389
+ reject(inputs);
390
+ Object.entries(inputs).forEach(([K, V]) => {
391
+ if (!(Model.is(V) || V instanceof Model))
392
+ reject(`${V} as ${K}`);
393
+ });
377
394
  for (const key in inputs) {
378
395
  const input = inputs[key];
379
396
  const exists = this.layer.get(key);
@@ -420,9 +437,11 @@ var Context = class {
420
437
  } while (T !== Model);
421
438
  return I;
422
439
  }
423
- push() {
440
+ push(inputs) {
424
441
  const next = Object.create(this);
425
442
  next.layer = /* @__PURE__ */ new Map();
443
+ if (inputs)
444
+ next.include(inputs);
426
445
  return next;
427
446
  }
428
447
  pop() {
@@ -438,6 +457,9 @@ var Context = class {
438
457
  this.layer.clear();
439
458
  }
440
459
  };
460
+ function reject(argument) {
461
+ throw new Error(`Context can only include Model or instance but got ${argument}.`);
462
+ }
441
463
 
442
464
  // src/instruction/get.ts
443
465
  function get(arg0, arg1) {
@@ -454,7 +476,7 @@ function get(arg0, arg1) {
454
476
  if (arg1 === true)
455
477
  throw new Error(`${from} may only exist as a child of type ${arg0}.`);
456
478
  source = (resolve) => {
457
- Context.resolve(from, (context) => {
479
+ Context.get(from, (context) => {
458
480
  const model = context.get(arg0);
459
481
  if (model)
460
482
  resolve(model);
@@ -486,9 +508,11 @@ function compute(subject, key, source, setter) {
486
508
  compute2(true);
487
509
  else if (STALE.delete(compute2))
488
510
  compute2();
489
- return () => {
490
- STALE.add(compute2);
491
- subject.set(key);
511
+ return (reason) => {
512
+ if (reason) {
513
+ STALE.add(compute2);
514
+ subject.set(key);
515
+ }
492
516
  };
493
517
  });
494
518
  }
@@ -543,7 +567,7 @@ function ref(arg, arg2) {
543
567
  else {
544
568
  let unSet;
545
569
  const set2 = (value2) => {
546
- if (subject.set(key, value2) || !arg)
570
+ if (!subject.set(key, value2) || !arg)
547
571
  return;
548
572
  if (unSet)
549
573
  unSet = void unSet(value2);
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.35.5",
32
- "gitHead": "8c45e620bda976235dcc4ffbb66c948db02650bc"
31
+ "version": "0.35.6",
32
+ "gitHead": "35d41f894a2cb042e7fdbb7fde16ec4eab76efdf"
33
33
  }