@expressive/mvc 0.72.0 → 0.73.1

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
@@ -1,983 +1,872 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
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
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
-
20
- // src/index.ts
21
- var index_exports = {};
22
- __export(index_exports, {
23
- Context: () => Context,
24
- METHOD: () => METHOD,
25
- Observable: () => Observable,
26
- State: () => State,
27
- addListener: () => addListener,
28
- default: () => State,
29
- event: () => event,
30
- get: () => get,
31
- ref: () => ref,
32
- set: () => set,
33
- use: () => use,
34
- watch: () => watch
35
- });
36
- module.exports = __toCommonJS(index_exports);
1
+ Object.defineProperty(exports, '__esModule', { value: true });
37
2
 
38
- // src/control.ts
39
- var Observable = Symbol("observe");
40
- var onReady = () => null;
41
- var LISTENERS = /* @__PURE__ */ new WeakMap();
42
- var PENDING = /* @__PURE__ */ new WeakMap();
43
- var PENDING_KEYS = /* @__PURE__ */ new WeakMap();
44
- var DISPATCH = /* @__PURE__ */ new Set();
3
+ //#region src/observable.ts
4
+ const Observable = Symbol("observe");
5
+ /** Placeholder event determines if state is initialized or not. */
6
+ const onReady = () => null;
7
+ const LISTENERS = /* @__PURE__ */ new WeakMap();
8
+ /** Events pending for a given object. */
9
+ const PENDING = /* @__PURE__ */ new WeakMap();
10
+ /** Update register. */
11
+ const PENDING_KEYS = /* @__PURE__ */ new WeakMap();
12
+ /** Central event dispatch. Bunches all updates to occur at same time. */
13
+ const DISPATCH = /* @__PURE__ */ new Set();
45
14
  function addListener(subject, callback, select) {
46
- let listeners = LISTENERS.get(subject);
47
- if (!listeners)
48
- LISTENERS.set(subject, listeners = /* @__PURE__ */ new Map([[onReady, void 0]]));
49
- if (select !== void 0 && !(select instanceof Set))
50
- select = /* @__PURE__ */ new Set([select]);
51
- if (!listeners.has(onReady) && !select) {
52
- callback.call(subject, true, subject);
53
- }
54
- listeners.set(callback, select);
55
- return () => listeners.delete(callback);
15
+ let listeners = LISTENERS.get(subject);
16
+ if (!listeners) LISTENERS.set(subject, listeners = new Map([[onReady, void 0]]));
17
+ if (select !== void 0 && !(select instanceof Set)) select = new Set([select]);
18
+ if (!listeners.has(onReady) && !select) callback.call(subject, true, subject);
19
+ listeners.set(callback, select);
20
+ return () => listeners.delete(callback);
56
21
  }
57
- function emit(state, key2) {
58
- const listeners = LISTENERS.get(state);
59
- const notReady = listeners.has(onReady);
60
- if (key2 === true && !notReady) return;
61
- let pending = PENDING.get(state);
62
- if (pending) {
63
- pending.add(key2);
64
- return;
65
- }
66
- PENDING.set(state, pending = new Set(notReady ? [true, key2] : [key2]));
67
- for (const key3 of pending)
68
- for (const [callback, filter] of listeners)
69
- if (!filter || filter.has(key3)) {
70
- const after = callback.call(state, key3, state);
71
- if (after) {
72
- enqueue(after);
73
- } else if (after === null) {
74
- listeners.delete(callback);
75
- }
76
- }
77
- if (key2 === null) listeners.clear();
78
- PENDING.delete(state);
22
+ function emit(state, key) {
23
+ const listeners = LISTENERS.get(state);
24
+ const notReady = listeners.has(onReady);
25
+ if (key === true && !notReady) return;
26
+ let pending = PENDING.get(state);
27
+ if (pending) {
28
+ pending.add(key);
29
+ return;
30
+ }
31
+ PENDING.set(state, pending = new Set(notReady ? [true, key] : [key]));
32
+ for (const key of pending) for (const [callback, filter] of listeners) if (!filter || filter.has(key)) {
33
+ const after = callback.call(state, key, state);
34
+ if (after) enqueue(after);
35
+ else if (after === null) listeners.delete(callback);
36
+ }
37
+ if (key === null) listeners.clear();
38
+ PENDING.delete(state);
79
39
  }
80
- function event(subject, key2, silent) {
81
- if (key2 === null) return emit(subject, key2);
82
- if (!key2) return emit(subject, true);
83
- let pending = PENDING_KEYS.get(subject);
84
- if (!pending) {
85
- PENDING_KEYS.set(subject, pending = /* @__PURE__ */ new Set());
86
- if (!silent)
87
- enqueue(() => {
88
- emit(subject, false);
89
- PENDING_KEYS.delete(subject);
90
- });
91
- }
92
- pending.add(key2);
93
- if (!silent) emit(subject, key2);
40
+ function event(subject, key, silent) {
41
+ if (key === null) return emit(subject, key);
42
+ if (!key) return emit(subject, true);
43
+ let pending = PENDING_KEYS.get(subject);
44
+ if (!pending) {
45
+ PENDING_KEYS.set(subject, pending = /* @__PURE__ */ new Set());
46
+ if (!silent) enqueue(() => {
47
+ emit(subject, false);
48
+ PENDING_KEYS.delete(subject);
49
+ });
50
+ }
51
+ pending.add(key);
52
+ if (!silent) emit(subject, key);
94
53
  }
95
54
  function enqueue(eventHandler) {
96
- if (!DISPATCH.size)
97
- setTimeout(() => {
98
- DISPATCH.forEach((event2) => {
99
- try {
100
- event2();
101
- } catch (err) {
102
- console.error(err);
103
- }
104
- });
105
- DISPATCH.clear();
106
- }, 0);
107
- DISPATCH.add(eventHandler);
55
+ if (!DISPATCH.size) setTimeout(() => {
56
+ DISPATCH.forEach((event) => {
57
+ try {
58
+ event();
59
+ } catch (err) {
60
+ console.error(err);
61
+ }
62
+ });
63
+ DISPATCH.clear();
64
+ }, 0);
65
+ DISPATCH.add(eventHandler);
108
66
  }
109
67
  function watch(target, callback, argument) {
110
- let unset;
111
- let reset;
112
- function invoke() {
113
- let ignore = true;
114
- function onUpdate() {
115
- if (ignore || reset === null) return;
116
- ignore = true;
117
- if (reset && unset) {
118
- unset(true);
119
- unset = void 0;
120
- }
121
- enqueue(invoke);
122
- return { then: enqueue };
123
- }
124
- try {
125
- const exit = enter(argument === false);
126
- const output = callback(target[Observable](onUpdate, argument === true));
127
- const flush = exit();
128
- ignore = false;
129
- reset = output === null ? null : invoke;
130
- unset = (key2) => {
131
- if (typeof output == "function") output(key2);
132
- flush();
133
- };
134
- } catch (err) {
135
- if (err instanceof Promise) {
136
- reset = void 0;
137
- err.then(invoke);
138
- } else {
139
- throw err;
140
- }
141
- }
142
- }
143
- function cleanup() {
144
- if (unset) unset(false);
145
- reset = null;
146
- }
147
- if (EffectContext && argument !== false) EffectContext.add(cleanup);
148
- addListener(target, (key2) => {
149
- if (key2 === true) invoke();
150
- else if (!reset) return reset;
151
- if (key2 === null && unset) unset(null);
152
- });
153
- return cleanup;
68
+ let unset;
69
+ let reset;
70
+ function invoke() {
71
+ let ignore = true;
72
+ function onUpdate() {
73
+ if (ignore || reset === null) return;
74
+ ignore = true;
75
+ if (reset && unset) {
76
+ unset(true);
77
+ unset = void 0;
78
+ }
79
+ enqueue(invoke);
80
+ return { then: enqueue };
81
+ }
82
+ try {
83
+ const exit = argument === false ? void 0 : scope();
84
+ const output = callback(target[Observable](onUpdate, argument === true));
85
+ const flush = exit ? exit() : () => {};
86
+ ignore = false;
87
+ reset = output === null ? null : invoke;
88
+ unset = (key) => {
89
+ if (typeof output == "function") output(key);
90
+ flush();
91
+ };
92
+ } catch (err) {
93
+ if (err instanceof Promise) {
94
+ reset = void 0;
95
+ err.then(invoke);
96
+ } else throw err;
97
+ }
98
+ }
99
+ function cleanup() {
100
+ if (unset) unset(false);
101
+ reset = null;
102
+ }
103
+ if (EffectContext && argument !== false) EffectContext.add(cleanup);
104
+ addListener(target, (key) => {
105
+ if (key === true) invoke();
106
+ else if (!reset) return reset;
107
+ if (key === null && unset) unset(null);
108
+ });
109
+ return cleanup;
154
110
  }
155
- var EffectContext;
156
- function enter(ignore) {
157
- if (ignore) return () => () => {
158
- };
159
- const last = EffectContext;
160
- const context = EffectContext = /* @__PURE__ */ new Set();
161
- return () => {
162
- EffectContext = last;
163
- return () => context.forEach((fn) => fn());
164
- };
111
+ let EffectContext;
112
+ function scope() {
113
+ const last = EffectContext;
114
+ const context = EffectContext = /* @__PURE__ */ new Set();
115
+ return () => {
116
+ EffectContext = last;
117
+ return () => context.forEach((fn) => fn());
118
+ };
165
119
  }
166
120
 
167
- // src/state.ts
168
- var define = Object.defineProperty;
169
- var ID = /* @__PURE__ */ new WeakMap();
170
- var STATE = /* @__PURE__ */ new WeakMap();
171
- var NOTIFY = /* @__PURE__ */ new WeakMap();
172
- var PARENT = /* @__PURE__ */ new WeakMap();
173
- var METHODS = /* @__PURE__ */ new WeakMap();
174
- var METHOD = /* @__PURE__ */ new WeakMap();
175
- var EXPORT;
121
+ //#endregion
122
+ //#region src/state.ts
123
+ const define = Object.defineProperty;
124
+ /** Register for all active states via string identifiers (usually unique). */
125
+ const ID = /* @__PURE__ */ new WeakMap();
126
+ /** Internal state assigned to states. */
127
+ const STATE = /* @__PURE__ */ new WeakMap();
128
+ /** External listeners for any given State. */
129
+ const NOTIFY = /* @__PURE__ */ new WeakMap();
130
+ /** Parent-child relationships. */
131
+ const PARENT = /* @__PURE__ */ new WeakMap();
132
+ /** List of methods defined by a given type. */
133
+ const METHODS = /* @__PURE__ */ new WeakMap();
134
+ /** Reference bound instance methods to real ones. */
135
+ const METHOD = /* @__PURE__ */ new WeakMap();
136
+ /** Currently accumulating export. Stores real values of placeholder properties such as ref() or child states. */
137
+ let EXPORT;
176
138
  var State = class {
177
- constructor(...args) {
178
- prepare(this);
179
- define(this, "is", { value: this });
180
- init(this, args);
181
- }
182
- [Observable](callback, required) {
183
- const watch2 = /* @__PURE__ */ new Set();
184
- const proxy = Object.create(this);
185
- addListener(this, (key2) => {
186
- if (watch2.has(key2)) callback();
187
- });
188
- OBSERVER.set(proxy, (key2, value) => {
189
- if (value === void 0 && required)
190
- throw new Error(`${this}.${key2} is required in this context.`);
191
- watch2.add(key2);
192
- if (value instanceof Object && Observable in value)
193
- return value[Observable](callback, required) || value;
194
- return value;
195
- });
196
- return proxy;
197
- }
198
- get(arg1, arg2) {
199
- const self = this.is;
200
- if (arg1 === void 0) return values(self);
201
- if (typeof arg1 == "function") return effect(self, arg1);
202
- if (typeof arg2 == "function") return addListener(self, arg2, arg1);
203
- if (arg1 === null) return Object.isFrozen(STATE.get(self));
204
- return access(self, arg1, arg2);
205
- }
206
- set(arg1, arg2, arg3) {
207
- const self = this.is;
208
- if (typeof arg1 == "function")
209
- return addListener(self, (key2) => {
210
- if (arg2 === key2 || arg2 === void 0 && typeof key2 == "string")
211
- return arg1.call(self, key2, self);
212
- });
213
- if (arg1 && typeof arg1 == "object") {
214
- assign(self, arg1, arg2 === true);
215
- } else if (!arg2) {
216
- event(self, arg1);
217
- } else if (arg3) {
218
- manage(self, arg1, arg2);
219
- } else {
220
- update(self, arg1, arg2);
221
- }
222
- const pending = PENDING_KEYS.get(this);
223
- if (pending)
224
- return {
225
- then: (res) => new Promise((res2) => {
226
- const remove = addListener(this, (key2) => {
227
- if (key2 !== true) {
228
- remove();
229
- return res2.bind(null, Array.from(pending));
230
- }
231
- });
232
- }).then(res)
233
- };
234
- }
235
- /**
236
- * Iterate over managed properties in this instance of State.
237
- * Yeilds the key and current value for each property.
238
- */
239
- [Symbol.iterator]() {
240
- return Object.entries(STATE.get(this.is))[Symbol.iterator]();
241
- }
242
- /**
243
- * Create and activate a new instance of this state.
244
- *
245
- * **Important** - Unlike `new this(...)` - this method also activates state.
246
- *
247
- * @param args - arguments sent to constructor
248
- */
249
- static new(...args) {
250
- const instance = new this(...args, (x) => {
251
- const cb = x.new && x.new();
252
- if (cb) x.set(cb, null);
253
- });
254
- event(instance);
255
- return instance;
256
- }
257
- /**
258
- * Static equivalent of `x instanceof this`.
259
- * Determines if provided class is a subtype of this one.
260
- * If so, language server will make available all static
261
- * methods and properties of this class.
262
- */
263
- static is(maybe) {
264
- return maybe === this || typeof maybe == "function" && maybe.prototype instanceof this;
265
- }
266
- /**
267
- * Register a callback to run when any instance of this State is updated.
268
- */
269
- static on(listener) {
270
- let notify = NOTIFY.get(this);
271
- if (!notify) NOTIFY.set(this, notify = /* @__PURE__ */ new Set());
272
- notify.add(listener);
273
- return () => notify.delete(listener);
274
- }
139
+ constructor(...args) {
140
+ prepare(this);
141
+ define(this, "is", { value: this });
142
+ init$1(this, ...args, (x) => x.new && x.new());
143
+ }
144
+ [Observable](callback, required) {
145
+ const watch = /* @__PURE__ */ new Set();
146
+ const proxy = Object.create(this);
147
+ addListener(this, (key) => {
148
+ if (watch.has(key)) callback();
149
+ });
150
+ OBSERVER.set(proxy, (key, value) => {
151
+ if (value === void 0 && required) throw new Error(`${this}.${key} is required in this context.`);
152
+ watch.add(key);
153
+ if (value instanceof Object && Observable in value) return value[Observable](callback, required) || value;
154
+ return value;
155
+ });
156
+ return proxy;
157
+ }
158
+ get(arg1, arg2) {
159
+ const self = this.is;
160
+ if (arg1 === void 0) return values(self);
161
+ if (typeof arg1 == "function") return effect(self, arg1);
162
+ if (typeof arg2 == "function") return addListener(self, arg2, arg1);
163
+ if (arg1 === null) return Object.isFrozen(STATE.get(self));
164
+ return access(self, arg1, arg2);
165
+ }
166
+ set(arg1, arg2, arg3) {
167
+ const self = this.is;
168
+ if (typeof arg1 == "function") return addListener(self, (key) => {
169
+ if (arg2 === key || arg2 === void 0 && typeof key == "string") return arg1.call(self, key, self);
170
+ });
171
+ if (arg1 && typeof arg1 == "object") assign(self, arg1, arg2 === true);
172
+ else if (!arg2) event(self, arg1);
173
+ else if (arg3) manage(self, arg1, arg2);
174
+ else update(self, arg1, arg2);
175
+ const pending = PENDING_KEYS.get(this);
176
+ if (pending) return { then: (resolve) => new Promise((res) => {
177
+ const remove = addListener(this, (key) => {
178
+ if (key !== true) {
179
+ remove();
180
+ return () => res(Array.from(pending));
181
+ }
182
+ });
183
+ }).then(resolve) };
184
+ }
185
+ /**
186
+ * Iterate over managed properties in this instance of State.
187
+ * Yeilds the key and current value for each property.
188
+ */
189
+ [Symbol.iterator]() {
190
+ return Object.entries(STATE.get(this.is))[Symbol.iterator]();
191
+ }
192
+ /**
193
+ * Create and activate a new instance of this state.
194
+ *
195
+ * **Important** - Unlike `new this(...)` - this method also activates state.
196
+ *
197
+ * @param args - arguments sent to constructor
198
+ */
199
+ static new(...args) {
200
+ const instance = new this(...args);
201
+ event(instance);
202
+ return instance;
203
+ }
204
+ /**
205
+ * Static equivalent of `x instanceof this`.
206
+ * Determines if provided class is a subtype of this one.
207
+ * If so, language server will make available all static
208
+ * methods and properties of this class.
209
+ */
210
+ static is(maybe) {
211
+ return maybe === this || typeof maybe == "function" && maybe.prototype instanceof this;
212
+ }
213
+ /**
214
+ * Register a callback to run when any instance of this State is updated.
215
+ */
216
+ static on(listener) {
217
+ let notify = NOTIFY.get(this);
218
+ if (!notify) NOTIFY.set(this, notify = /* @__PURE__ */ new Set());
219
+ notify.add(listener);
220
+ return () => notify.delete(listener);
221
+ }
275
222
  };
276
- define(State.prototype, "toString", {
277
- value() {
278
- return ID.get(this.is);
279
- }
280
- });
281
- define(State, "toString", {
282
- value() {
283
- return this.name;
284
- }
285
- });
223
+ define(State.prototype, "toString", { value() {
224
+ return ID.get(this.is);
225
+ } });
226
+ define(State, "toString", { value() {
227
+ return this.name;
228
+ } });
286
229
  function assign(subject, data, silent) {
287
- const methods = METHODS.get(subject.constructor);
288
- for (const key2 in data) {
289
- const bind = methods.get(key2);
290
- if (bind) bind.call(subject, data[key2]);
291
- else if (key2 in subject && key2 !== "is") {
292
- const desc = Object.getOwnPropertyDescriptor(subject, key2);
293
- const set2 = desc && desc.set;
294
- if (set2) {
295
- set2.call(subject, data[key2], silent);
296
- } else {
297
- subject[key2] = data[key2];
298
- }
299
- }
300
- }
230
+ const methods = METHODS.get(subject.constructor);
231
+ for (const key in data) {
232
+ const bind = methods.get(key);
233
+ if (bind) bind.call(subject, data[key]);
234
+ else if (key in subject && key !== "is") {
235
+ const desc = Object.getOwnPropertyDescriptor(subject, key);
236
+ const set = desc && desc.set;
237
+ if (set) set.call(subject, data[key], silent);
238
+ else subject[key] = data[key];
239
+ }
240
+ }
301
241
  }
242
+ /** Apply instructions and inherited event listeners. Ensure class metadata is ready. */
302
243
  function prepare(state) {
303
- let T = state.constructor;
304
- if (T === State) throw new Error("Cannot create base State.");
305
- const chain = [];
306
- let keys2 = /* @__PURE__ */ new Map();
307
- ID.set(state, `${T}-${uid()}`);
308
- while (T.name) {
309
- for (const cb of NOTIFY.get(T) || []) {
310
- addListener(state, cb);
311
- }
312
- if (T === State) break;
313
- else chain.unshift(T);
314
- T = Object.getPrototypeOf(T);
315
- }
316
- for (const type of chain) {
317
- if (METHODS.has(type)) {
318
- keys2 = METHODS.get(type);
319
- continue;
320
- }
321
- METHODS.set(type, keys2 = new Map(keys2));
322
- for (const [key2, { value }] of Object.entries(
323
- Object.getOwnPropertyDescriptors(type.prototype)
324
- )) {
325
- let bind2 = function(original) {
326
- const { is } = this;
327
- if (is.hasOwnProperty(key2) && !original) return value;
328
- const fn = original || value;
329
- const bound = fn.bind(is);
330
- METHOD.set(bound, fn);
331
- define(is, key2, { value: bound, writable: true });
332
- return bound;
333
- };
334
- var bind = bind2;
335
- if (!value || key2 == "constructor") continue;
336
- keys2.set(key2, bind2);
337
- define(type.prototype, key2, { get: bind2, set: bind2 });
338
- }
339
- }
244
+ let T = state.constructor;
245
+ if (T === State) throw new Error("Cannot create base State.");
246
+ const chain = [];
247
+ let keys = /* @__PURE__ */ new Map();
248
+ ID.set(state, `${T}-${uid()}`);
249
+ while (T.name) {
250
+ for (const cb of NOTIFY.get(T) || []) addListener(state, cb);
251
+ if (T === State) break;
252
+ else chain.unshift(T);
253
+ T = Object.getPrototypeOf(T);
254
+ }
255
+ for (const type of chain) {
256
+ if (METHODS.has(type)) {
257
+ keys = METHODS.get(type);
258
+ continue;
259
+ }
260
+ METHODS.set(type, keys = new Map(keys));
261
+ for (const [key, { value }] of Object.entries(Object.getOwnPropertyDescriptors(type.prototype))) {
262
+ if (!value || key == "constructor") continue;
263
+ function bind(original) {
264
+ const { is } = this;
265
+ if (is.hasOwnProperty(key) && !original) return value;
266
+ const fn = original || value;
267
+ const bound = fn.bind(is);
268
+ METHOD.set(bound, fn);
269
+ define(is, key, {
270
+ value: bound,
271
+ writable: true
272
+ });
273
+ return bound;
274
+ }
275
+ keys.set(key, bind);
276
+ define(type.prototype, key, {
277
+ get: bind,
278
+ set: bind
279
+ });
280
+ }
281
+ }
340
282
  }
341
- function init(self, args) {
342
- const state = {};
343
- STATE.set(self, state);
344
- args = args.flat().filter((arg) => {
345
- if (typeof arg == "string") ID.set(self, arg);
346
- else return true;
347
- });
348
- addListener(self, () => {
349
- if (!PARENT.has(self)) PARENT.set(self, null);
350
- for (const key2 in self) {
351
- const desc = Object.getOwnPropertyDescriptor(self, key2);
352
- if ("value" in desc) manage(self, key2, desc.value, true);
353
- }
354
- for (const arg of args) {
355
- const use2 = typeof arg == "function" ? arg.call(self, self) : arg;
356
- if (use2 instanceof Promise)
357
- use2.catch((err) => {
358
- console.error(`Async error in constructor for ${self}:`);
359
- console.error(err);
360
- });
361
- else if (Array.isArray(use2)) args.push(...use2);
362
- else if (typeof use2 == "function") addListener(self, use2, null);
363
- else if (typeof use2 == "object") assign(self, use2, true);
364
- }
365
- addListener(
366
- self,
367
- () => {
368
- for (const [_, value] of self)
369
- if (value instanceof State && PARENT.get(value) === self)
370
- value.set(null);
371
- Object.freeze(state);
372
- },
373
- null
374
- );
375
- return null;
376
- });
283
+ /**
284
+ * Apply state arguemnts, run callbacks and observe properties.
285
+ * Accumulate and handle cleanup events.
286
+ **/
287
+ function init$1(self, ...args) {
288
+ const state = {};
289
+ STATE.set(self, state);
290
+ args = args.flat().filter((arg) => {
291
+ if (typeof arg == "string") ID.set(self, arg);
292
+ else return true;
293
+ });
294
+ addListener(self, () => {
295
+ if (!PARENT.has(self)) PARENT.set(self, null);
296
+ for (const key in self) {
297
+ const desc = Object.getOwnPropertyDescriptor(self, key);
298
+ if ("value" in desc) manage(self, key, desc.value, true);
299
+ }
300
+ for (const arg of args) {
301
+ const use = typeof arg == "function" ? arg.call(self, self) : arg;
302
+ if (use instanceof Promise) use.catch((err) => {
303
+ console.error(`Async error in constructor for ${self}:`);
304
+ console.error(err);
305
+ });
306
+ else if (Array.isArray(use)) args.push(...use);
307
+ else if (typeof use == "function") addListener(self, use, null);
308
+ else if (typeof use == "object") assign(self, use, true);
309
+ }
310
+ addListener(self, () => {
311
+ for (const [_, value] of self) if (value instanceof State && PARENT.get(value) === self) value.set(null);
312
+ Object.freeze(state);
313
+ }, null);
314
+ return null;
315
+ });
316
+ }
317
+ function manage(target, key, value, silent) {
318
+ const state = STATE.get(target);
319
+ function get() {
320
+ return follow(this, key, state[key]);
321
+ }
322
+ function set(value, silent) {
323
+ update(target, key, value, silent);
324
+ if (value instanceof State && !PARENT.has(value)) {
325
+ PARENT.set(value, target);
326
+ event(value);
327
+ }
328
+ }
329
+ define(target, key, {
330
+ set,
331
+ get
332
+ });
333
+ set(value, silent);
377
334
  }
378
335
  function effect(target, fn) {
379
- const effect2 = METHOD.get(fn) || fn;
380
- let pending = /* @__PURE__ */ new Set();
381
- return watch(target, (proxy) => {
382
- const cb = effect2.call(proxy, proxy, pending);
383
- if (cb === null) return cb;
384
- return (update2) => {
385
- pending = PENDING_KEYS.get(target);
386
- if (typeof cb == "function") cb(update2);
387
- };
388
- });
336
+ const effect = METHOD.get(fn) || fn;
337
+ let pending = /* @__PURE__ */ new Set();
338
+ return watch(target, (proxy) => {
339
+ const cb = effect.call(proxy, proxy, pending);
340
+ if (cb === null) return cb;
341
+ return (update) => {
342
+ pending = PENDING_KEYS.get(target);
343
+ if (typeof cb == "function") cb(update);
344
+ };
345
+ });
389
346
  }
390
347
  function values(target) {
391
- const values2 = {};
392
- let isNotRecursive;
393
- if (!EXPORT) {
394
- isNotRecursive = true;
395
- EXPORT = /* @__PURE__ */ new Map([[target, values2]]);
396
- }
397
- for (let [key2, value] of target) {
398
- if (EXPORT.has(value)) value = EXPORT.get(value);
399
- else if (value && typeof value == "object" && "get" in value && typeof value.get === "function")
400
- EXPORT.set(value, value = value.get());
401
- values2[key2] = value;
402
- }
403
- if (isNotRecursive) EXPORT = void 0;
404
- return Object.freeze(values2);
405
- }
406
- function manage(target, key2, value, silent) {
407
- const state = STATE.get(target);
408
- function get2() {
409
- return follow(this, key2, state[key2]);
410
- }
411
- function set2(value2, silent2) {
412
- update(target, key2, value2, silent2);
413
- if (value2 instanceof State && !PARENT.has(value2)) {
414
- PARENT.set(value2, target);
415
- event(value2);
416
- }
417
- }
418
- define(target, key2, { set: set2, get: get2 });
419
- set2(value, silent);
348
+ const values = {};
349
+ let isNotRecursive;
350
+ if (!EXPORT) {
351
+ isNotRecursive = true;
352
+ EXPORT = new Map([[target, values]]);
353
+ }
354
+ for (let [key, value] of target) {
355
+ if (EXPORT.has(value)) value = EXPORT.get(value);
356
+ else if (value && typeof value == "object" && "get" in value && typeof value.get === "function") EXPORT.set(value, value = value.get());
357
+ values[key] = value;
358
+ }
359
+ if (isNotRecursive) EXPORT = void 0;
360
+ return Object.freeze(values);
420
361
  }
421
- var OBSERVER = /* @__PURE__ */ new WeakMap();
422
- function follow(from, key2, value) {
423
- const observe = OBSERVER.get(from);
424
- return observe ? observe(key2, value) : value;
362
+ const OBSERVER = /* @__PURE__ */ new WeakMap();
363
+ function follow(from, key, value) {
364
+ const observe = OBSERVER.get(from);
365
+ return observe ? observe(key, value) : value;
425
366
  }
426
367
  function access(subject, property, required) {
427
- const state = STATE.get(subject);
428
- if (property in state || required === false) {
429
- const value = state[property];
430
- if (value !== void 0 || !required) return value;
431
- }
432
- if (METHODS.get(subject.constructor).has(property))
433
- return METHOD.get(subject[property]);
434
- const error = new Error(`${subject}.${property} is not yet available.`);
435
- const promise = new Promise((resolve, reject) => {
436
- addListener(subject, (key2) => {
437
- if (key2 === property) {
438
- resolve(state[key2]);
439
- return null;
440
- }
441
- if (key2 === null) {
442
- reject(new Error(`${subject} is destroyed.`));
443
- }
444
- });
445
- });
446
- throw Object.assign(promise, {
447
- toString: () => String(error),
448
- name: "Suspense",
449
- message: error.message,
450
- stack: error.stack
451
- });
368
+ const state = STATE.get(subject);
369
+ if (property in state || required === false) {
370
+ const value = state[property];
371
+ if (value !== void 0 || !required) return value;
372
+ }
373
+ if (METHODS.get(subject.constructor).has(property)) return METHOD.get(subject[property]);
374
+ const error = /* @__PURE__ */ new Error(`${subject}.${property} is not yet available.`);
375
+ const promise = new Promise((resolve, reject) => {
376
+ addListener(subject, (key) => {
377
+ if (key === property) {
378
+ resolve(state[key]);
379
+ return null;
380
+ }
381
+ if (key === null) reject(/* @__PURE__ */ new Error(`${subject} is destroyed.`));
382
+ });
383
+ });
384
+ throw Object.assign(promise, {
385
+ toString: () => String(error),
386
+ name: "Suspense",
387
+ message: error.message,
388
+ stack: error.stack
389
+ });
452
390
  }
453
- function update(subject, key2, value, arg) {
454
- const state = STATE.get(subject);
455
- if (Object.isFrozen(state))
456
- throw new Error(
457
- `Tried to update ${subject}.${String(key2)} but state is destroyed.`
458
- );
459
- const previous = state[key2];
460
- if (typeof arg == "function") {
461
- const out = arg.call(subject, value, previous);
462
- if (out === false) return false;
463
- if (typeof out == "function") value = out();
464
- }
465
- if (value === previous && key2 in state) return;
466
- state[key2] = value;
467
- if (arg !== true) event(subject, key2);
468
- return true;
391
+ function update(subject, key, value, arg) {
392
+ const state = STATE.get(subject);
393
+ if (Object.isFrozen(state)) throw new Error(`Tried to update ${subject}.${String(key)} but state is destroyed.`);
394
+ const previous = state[key];
395
+ if (typeof arg == "function") {
396
+ const out = arg.call(subject, value, previous);
397
+ if (out === false) return false;
398
+ if (typeof out == "function") value = out();
399
+ }
400
+ if (value === previous && key in state) return;
401
+ state[key] = value;
402
+ if (arg !== true) event(subject, key);
403
+ return true;
469
404
  }
405
+ /** Random alphanumberic of length 6; always starts with a letter. */
470
406
  function uid() {
471
- return (0.278 + Math.random() * 0.722).toString(36).substring(2, 8).toUpperCase();
407
+ return (.278 + Math.random() * .722).toString(36).substring(2, 8).toUpperCase();
472
408
  }
473
409
 
474
- // src/instruction/use.ts
475
- var INSTRUCTION = /* @__PURE__ */ new Map();
410
+ //#endregion
411
+ //#region src/instruction/use.ts
412
+ const INSTRUCTION = /* @__PURE__ */ new Map();
476
413
  function use(arg1, arg2) {
477
- if (State.is(arg1)) arg1 = childInstruction(arg1, arg2);
478
- const token = Symbol("instruction-" + uid());
479
- INSTRUCTION.set(token, arg1);
480
- return token;
414
+ if (State.is(arg1)) arg1 = childInstruction(arg1, arg2);
415
+ const token = Symbol("instruction-" + uid());
416
+ INSTRUCTION.set(token, arg1);
417
+ return token;
481
418
  }
482
419
  function childInstruction(type, arg2) {
483
- return (key2, subject) => {
484
- function set2(next) {
485
- if (next ? !(next instanceof type) : arg2 !== false)
486
- throw new Error(
487
- `${subject}.${key2} expected State of type ${type} but got ${next && next.constructor}.`
488
- );
489
- update(subject, key2, next);
490
- if (next && typeof arg2 == "function") arg2(next);
491
- return false;
492
- }
493
- const value = new type();
494
- set2(value);
495
- PARENT.set(value, subject);
496
- value.set();
497
- return { set: set2 };
498
- };
420
+ return (key, subject) => {
421
+ function set(next) {
422
+ if (next ? !(next instanceof type) : arg2 !== false) throw new Error(`${subject}.${key} expected State of type ${type} but got ${next && next.constructor}.`);
423
+ update(subject, key, next);
424
+ if (next && typeof arg2 == "function") arg2(next);
425
+ return false;
426
+ }
427
+ const value = new type();
428
+ set(value);
429
+ PARENT.set(value, subject);
430
+ value.set();
431
+ return { set };
432
+ };
499
433
  }
500
- function init2() {
501
- const state = STATE.get(this);
502
- for (const key2 in this) {
503
- const { value } = Object.getOwnPropertyDescriptor(this, key2);
504
- const instruction = INSTRUCTION.get(value);
505
- if (!instruction) continue;
506
- INSTRUCTION.delete(value);
507
- delete this[key2];
508
- const output = instruction.call(this, key2, this, state);
509
- if (!output) continue;
510
- const desc = typeof output == "object" ? output : { get: output };
511
- if ("value" in desc) state[key2] = desc.value;
512
- const self = this;
513
- Object.defineProperty(self, key2, {
514
- enumerable: desc.enumerable !== false,
515
- get() {
516
- return follow(
517
- this,
518
- key2,
519
- typeof desc.get == "function" ? desc.get(this) : access(self, key2, desc.get)
520
- );
521
- },
522
- set(next) {
523
- if (desc.set === false) {
524
- throw new Error(`${self}.${key2} is read-only.`);
525
- }
526
- update(self, key2, next, desc.set);
527
- }
528
- });
529
- }
530
- return null;
434
+ function init() {
435
+ const state = STATE.get(this);
436
+ for (const key in this) {
437
+ const { value } = Object.getOwnPropertyDescriptor(this, key);
438
+ const instruction = INSTRUCTION.get(value);
439
+ if (!instruction) continue;
440
+ INSTRUCTION.delete(value);
441
+ delete this[key];
442
+ const output = instruction.call(this, key, this, state);
443
+ if (!output) continue;
444
+ const desc = typeof output == "object" ? output : { get: output };
445
+ if ("value" in desc) state[key] = desc.value;
446
+ const self = this;
447
+ Object.defineProperty(self, key, {
448
+ enumerable: desc.enumerable !== false,
449
+ get() {
450
+ return follow(this, key, typeof desc.get == "function" ? desc.get(this) : access(self, key, desc.get));
451
+ },
452
+ set(next) {
453
+ if (desc.set === false) throw new Error(`${self}.${key} is read-only.`);
454
+ update(self, key, next, desc.set);
455
+ }
456
+ });
457
+ }
458
+ return null;
531
459
  }
532
- State.on(init2);
460
+ State.on(init);
533
461
 
534
- // src/context.ts
535
- var LOOKUP = /* @__PURE__ */ new WeakMap();
536
- var KEYS = /* @__PURE__ */ new Map();
462
+ //#endregion
463
+ //#region src/context.ts
464
+ const LOOKUP = /* @__PURE__ */ new WeakMap();
465
+ const KEYS = /* @__PURE__ */ new Map();
537
466
  function key(T, upstream) {
538
- let K = KEYS.get(T);
539
- if (!K) {
540
- K = Symbol(typeof T == "symbol" ? "get " + T.description : String(T));
541
- KEYS.set(T, K);
542
- }
543
- return upstream ? key(K) : K;
467
+ let K = KEYS.get(T);
468
+ if (!K) {
469
+ K = Symbol(typeof T == "symbol" ? "get " + T.description : String(T));
470
+ KEYS.set(T, K);
471
+ }
472
+ return upstream ? key(K) : K;
544
473
  }
545
474
  function keys(from, upstream) {
546
- const keys2 = /* @__PURE__ */ new Set();
547
- do {
548
- keys2.add(key(from, upstream));
549
- from = Object.getPrototypeOf(from);
550
- } while (from !== State);
551
- return keys2;
475
+ const keys = /* @__PURE__ */ new Set();
476
+ do {
477
+ keys.add(key(from, upstream));
478
+ from = Object.getPrototypeOf(from);
479
+ } while (from !== State);
480
+ return keys;
552
481
  }
553
- var Context = class _Context {
554
- constructor(inputs) {
555
- this.id = uid();
556
- this.inputs = {};
557
- this.cleanup = /* @__PURE__ */ new Set();
558
- if (inputs) this.use(inputs);
559
- }
560
- static get({ is }, callback) {
561
- const context = LOOKUP.get(is);
562
- if (context instanceof _Context) {
563
- if (callback) callback(context);
564
- return context;
565
- }
566
- if (callback)
567
- if (context) context.push(callback);
568
- else LOOKUP.set(is, [callback]);
569
- }
570
- get(Type, arg2) {
571
- if (typeof arg2 == "function") {
572
- const k = key(Type, true);
573
- Object.defineProperty(this, k, {
574
- value: arg2,
575
- configurable: true
576
- });
577
- return () => {
578
- delete this[k];
579
- };
580
- }
581
- const result = this[key(Type)];
582
- if (result === null)
583
- throw new Error(
584
- `Did find ${Type} in context, but multiple were defined.`
585
- );
586
- if (result) return result;
587
- if (arg2) throw new Error(`Could not find ${Type} in context.`);
588
- }
589
- /**
590
- * Adds a State to this context.
591
- */
592
- add(input, implicit) {
593
- const cleanup = /* @__PURE__ */ new Set();
594
- let T;
595
- let I;
596
- if (typeof input == "function") {
597
- T = input;
598
- I = new input();
599
- } else {
600
- T = input.constructor;
601
- I = input;
602
- }
603
- keys(T, true).forEach((K) => {
604
- const expects = this[K];
605
- if (expects)
606
- addListener(I, (event2) => {
607
- if (event2 === true) {
608
- const cb = expects(I);
609
- if (cb) cleanup.add(cb);
610
- }
611
- return null;
612
- });
613
- });
614
- keys(T).forEach((K) => {
615
- const value = this.hasOwnProperty(K) ? null : I;
616
- if (value || this[K] !== I && !implicit)
617
- Object.defineProperty(this, K, {
618
- configurable: true,
619
- value
620
- });
621
- });
622
- this.cleanup.add(() => {
623
- cleanup.forEach((cb) => cb());
624
- if (I !== input) event(I, null);
625
- });
626
- const waiting = LOOKUP.get(I);
627
- if (waiting instanceof Array) waiting.forEach((cb) => cb(this));
628
- LOOKUP.set(I, this);
629
- return I;
630
- }
631
- /**
632
- * Register one or more States to this context.
633
- *
634
- * Context will add or remove States as needed to keep with provided input.
635
- *
636
- * @param inputs State, State class, or map of States / State classes to register.
637
- * @param forEach Optional callback to run for each State registered.
638
- */
639
- use(inputs, forEach) {
640
- const init3 = /* @__PURE__ */ new Map();
641
- if (typeof inputs == "function" || inputs instanceof State)
642
- inputs = { [0]: inputs };
643
- for (const [K, V] of Object.entries(inputs)) {
644
- if (!(State.is(V) || V instanceof State))
645
- throw new Error(
646
- `Context may only include instance or class \`extends State\` but got ${K == "0" || K == String(V) ? V : `${V} (as '${K}')`}.`
647
- );
648
- const exists = this.inputs[K];
649
- if (!exists) {
650
- init3.set(this.add(V), true);
651
- } else if (exists !== V) {
652
- this.pop();
653
- this.use(inputs);
654
- this.id = uid();
655
- return;
656
- }
657
- }
658
- for (const [state, explicit] of init3) {
659
- state.set();
660
- if (explicit && forEach) forEach(state);
661
- for (const [_key, value] of state)
662
- if (PARENT.get(value) === state) {
663
- this.add(value, true);
664
- init3.set(value, false);
665
- }
666
- }
667
- this.inputs = inputs;
668
- }
669
- /**
670
- * Create a child context, optionally registering one or more States to it.
671
- *
672
- * @param inputs State, State class, or map of States / State classes to register.
673
- */
674
- push(inputs) {
675
- const next = Object.create(this);
676
- this.cleanup = /* @__PURE__ */ new Set([() => next.pop(), ...this.cleanup]);
677
- next.inputs = {};
678
- next.cleanup = /* @__PURE__ */ new Set();
679
- if (inputs) next.use(inputs);
680
- return next;
681
- }
682
- /**
683
- * Remove all States from this context.
684
- *
685
- * Will also run any cleanup callbacks registered when States were added.
686
- */
687
- pop() {
688
- for (const key2 of Object.getOwnPropertySymbols(this)) delete this[key2];
689
- this.cleanup.forEach((cb) => cb());
690
- this.cleanup.clear();
691
- this.inputs = {};
692
- }
482
+ var Context = class Context {
483
+ static get({ is }, callback) {
484
+ const context = LOOKUP.get(is);
485
+ if (context instanceof Context) {
486
+ if (callback) callback(context);
487
+ return context;
488
+ }
489
+ if (callback) if (context) context.push(callback);
490
+ else LOOKUP.set(is, [callback]);
491
+ }
492
+ constructor(inputs) {
493
+ this.id = uid();
494
+ this.inputs = {};
495
+ this.cleanup = /* @__PURE__ */ new Set();
496
+ if (inputs) this.use(inputs);
497
+ }
498
+ get(Type, arg2) {
499
+ if (typeof arg2 == "function") {
500
+ const k = key(Type, true);
501
+ Object.defineProperty(this, k, {
502
+ value: arg2,
503
+ configurable: true
504
+ });
505
+ return () => {
506
+ delete this[k];
507
+ };
508
+ }
509
+ const result = this[key(Type)];
510
+ if (result === null) throw new Error(`Did find ${Type} in context, but multiple were defined.`);
511
+ if (result) return result;
512
+ if (arg2) throw new Error(`Could not find ${Type} in context.`);
513
+ }
514
+ /**
515
+ * Adds a State to this context.
516
+ */
517
+ add(input, implicit) {
518
+ const cleanup = /* @__PURE__ */ new Set();
519
+ let T;
520
+ let I;
521
+ if (typeof input == "function") {
522
+ T = input;
523
+ I = new input();
524
+ } else {
525
+ T = input.constructor;
526
+ I = input;
527
+ }
528
+ keys(T, true).forEach((K) => {
529
+ const expects = this[K];
530
+ if (expects) addListener(I, (event) => {
531
+ if (event === true) {
532
+ const cb = expects(I);
533
+ if (cb) cleanup.add(cb);
534
+ }
535
+ return null;
536
+ });
537
+ });
538
+ keys(T).forEach((K) => {
539
+ const value = this.hasOwnProperty(K) ? null : I;
540
+ if (value || this[K] !== I && !implicit) Object.defineProperty(this, K, {
541
+ configurable: true,
542
+ value
543
+ });
544
+ });
545
+ this.cleanup.add(() => {
546
+ cleanup.forEach((cb) => cb());
547
+ if (I !== input) event(I, null);
548
+ });
549
+ const waiting = LOOKUP.get(I);
550
+ if (waiting instanceof Array) waiting.forEach((cb) => cb(this));
551
+ LOOKUP.set(I, this);
552
+ return I;
553
+ }
554
+ /**
555
+ * Register one or more States to this context.
556
+ *
557
+ * Context will add or remove States as needed to keep with provided input.
558
+ *
559
+ * @param inputs State, State class, or map of States / State classes to register.
560
+ * @param forEach Optional callback to run for each State registered.
561
+ */
562
+ use(inputs, forEach) {
563
+ const init = /* @__PURE__ */ new Map();
564
+ if (typeof inputs == "function" || inputs instanceof State) inputs = { [0]: inputs };
565
+ for (const [K, V] of Object.entries(inputs)) {
566
+ if (!(State.is(V) || V instanceof State)) throw new Error(`Context may only include instance or class \`extends State\` but got ${K == "0" || K == String(V) ? V : `${V} (as '${K}')`}.`);
567
+ const exists = this.inputs[K];
568
+ if (!exists) init.set(this.add(V), true);
569
+ else if (exists !== V) {
570
+ this.pop();
571
+ this.use(inputs);
572
+ this.id = uid();
573
+ return;
574
+ }
575
+ }
576
+ for (const [state, explicit] of init) {
577
+ state.set();
578
+ if (explicit && forEach) forEach(state);
579
+ for (const [_key, value] of state) if (PARENT.get(value) === state) {
580
+ this.add(value, true);
581
+ init.set(value, false);
582
+ }
583
+ }
584
+ this.inputs = inputs;
585
+ }
586
+ /**
587
+ * Create a child context, optionally registering one or more States to it.
588
+ *
589
+ * @param inputs State, State class, or map of States / State classes to register.
590
+ */
591
+ push(inputs) {
592
+ const next = Object.create(this);
593
+ this.cleanup = new Set([() => next.pop(), ...this.cleanup]);
594
+ next.inputs = {};
595
+ next.cleanup = /* @__PURE__ */ new Set();
596
+ if (inputs) next.use(inputs);
597
+ return next;
598
+ }
599
+ /**
600
+ * Remove all States from this context.
601
+ *
602
+ * Will also run any cleanup callbacks registered when States were added.
603
+ */
604
+ pop() {
605
+ for (const key of Object.getOwnPropertySymbols(this)) delete this[key];
606
+ this.cleanup.forEach((cb) => cb());
607
+ this.cleanup.clear();
608
+ this.inputs = {};
609
+ }
693
610
  };
694
- Object.defineProperty(Context.prototype, "toString", {
695
- value() {
696
- return `Context-${this.id}`;
697
- }
698
- });
611
+ Object.defineProperty(Context.prototype, "toString", { value() {
612
+ return `Context-${this.id}`;
613
+ } });
699
614
 
700
- // src/instruction/get.ts
615
+ //#endregion
616
+ //#region src/instruction/get.ts
701
617
  function get(Type, arg1, arg2) {
702
- const isDownstream = arg1 === true;
703
- const isOptional = arg1 === false;
704
- return use((key2, subject) => {
705
- if (isDownstream) {
706
- const callback = typeof arg2 === "function" ? arg2 : void 0;
707
- const applied = /* @__PURE__ */ new Set();
708
- const reset = () => {
709
- update(subject, key2, Object.freeze(Array.from(applied)));
710
- };
711
- Context.get(subject, (context) => {
712
- context.get(Type, (state) => {
713
- let remove;
714
- let flush;
715
- if (applied.has(state)) return;
716
- if (callback) {
717
- const exit = enter();
718
- try {
719
- const done2 = callback(state, subject);
720
- if (done2 === false) return false;
721
- if (typeof done2 == "function") remove = done2;
722
- } finally {
723
- flush = exit();
724
- }
725
- }
726
- applied.add(state);
727
- reset();
728
- const done = () => {
729
- if (flush) flush();
730
- ignore();
731
- applied.delete(state);
732
- reset();
733
- if (typeof remove == "function") remove();
734
- remove = void 0;
735
- };
736
- const ignore = state.set(done, null);
737
- return done;
738
- });
739
- });
740
- return {
741
- value: [],
742
- enumerable: false
743
- };
744
- }
745
- const hasParent = PARENT.get(subject);
746
- function assign2(value) {
747
- if (typeof arg1 === "function") {
748
- const callback = arg1;
749
- const result = callback(value, subject);
750
- if (typeof result === "function") {
751
- subject.set(result, null);
752
- }
753
- }
754
- update(subject, key2, value);
755
- }
756
- if (hasParent && hasParent instanceof Type) {
757
- assign2(hasParent);
758
- return {};
759
- }
760
- Context.get(subject, (context) => {
761
- const self = context.get(Type);
762
- if (self) assign2(self);
763
- else if (!isOptional)
764
- throw new Error(
765
- `Required ${Type} not found in context for ${subject}.`
766
- );
767
- });
768
- return {
769
- get: !isOptional,
770
- enumerable: false
771
- };
772
- });
618
+ const isDownstream = arg1 === true;
619
+ const isOptional = arg1 === false;
620
+ return use((key, subject) => {
621
+ if (isDownstream) {
622
+ const callback = typeof arg2 === "function" ? arg2 : void 0;
623
+ const applied = /* @__PURE__ */ new Set();
624
+ const reset = () => {
625
+ update(subject, key, Object.freeze(Array.from(applied)));
626
+ };
627
+ Context.get(subject, (context) => {
628
+ context.get(Type, (state) => {
629
+ let remove;
630
+ let flush;
631
+ if (applied.has(state)) return;
632
+ if (callback) {
633
+ const exit = scope();
634
+ try {
635
+ const done = callback(state, subject);
636
+ if (done === false) return false;
637
+ if (typeof done == "function") remove = done;
638
+ } finally {
639
+ flush = exit();
640
+ }
641
+ }
642
+ applied.add(state);
643
+ reset();
644
+ const done = () => {
645
+ if (flush) flush();
646
+ ignore();
647
+ applied.delete(state);
648
+ reset();
649
+ if (typeof remove == "function") remove();
650
+ remove = void 0;
651
+ };
652
+ const ignore = state.set(done, null);
653
+ return done;
654
+ });
655
+ });
656
+ return {
657
+ value: [],
658
+ enumerable: false
659
+ };
660
+ }
661
+ const hasParent = PARENT.get(subject);
662
+ function assign(value) {
663
+ if (typeof arg1 === "function") {
664
+ const result = arg1(value, subject);
665
+ if (typeof result === "function") subject.set(result, null);
666
+ }
667
+ update(subject, key, value);
668
+ }
669
+ if (hasParent && hasParent instanceof Type) {
670
+ assign(hasParent);
671
+ return {};
672
+ }
673
+ Context.get(subject, (context) => {
674
+ const self = context.get(Type);
675
+ if (self && self !== subject) assign(self);
676
+ else if (!isOptional) throw new Error(`Required ${Type} not found in context for ${subject}.`);
677
+ });
678
+ return {
679
+ get: !isOptional,
680
+ enumerable: false
681
+ };
682
+ });
773
683
  }
774
684
 
775
- // src/instruction/set.ts
776
- var STALE = /* @__PURE__ */ new WeakSet();
685
+ //#endregion
686
+ //#region src/instruction/set.ts
687
+ const STALE = /* @__PURE__ */ new WeakSet();
777
688
  function set(value, argument) {
778
- return use((key2, subject, state) => {
779
- if (typeof value == "symbol")
780
- throw new Error(
781
- `Attempted to use an instruction result (probably use or get) as computed source for ${subject}.${key2}. This is not allowed.`
782
- );
783
- const property = {};
784
- if (value instanceof State || value === true) {
785
- let connect2 = function(self) {
786
- reset = watch(
787
- self,
788
- (current) => {
789
- proxy = current;
790
- if (!(key2 in state) || STALE.delete(compute2)) compute2(!reset);
791
- return (didUpdate) => {
792
- if (didUpdate) {
793
- STALE.add(compute2);
794
- event(subject, key2, true);
795
- }
796
- };
797
- },
798
- false
799
- );
800
- }, compute2 = function(initial) {
801
- let next;
802
- try {
803
- next = getter.call(proxy, proxy, key2);
804
- } catch (err) {
805
- console.warn(
806
- `An exception was thrown while ${initial ? "initializing" : "refreshing"} ${subject}.${key2}.`
807
- );
808
- if (initial) throw err;
809
- console.error(err);
810
- }
811
- update(subject, key2, next, !isAsync);
812
- };
813
- var connect = connect2, compute = compute2;
814
- let from = subject;
815
- let getter;
816
- if (value instanceof State) {
817
- from = value;
818
- getter = argument;
819
- } else {
820
- const fn = METHOD.get(argument) || argument;
821
- getter = (p, k) => fn.call(p, k, p);
822
- }
823
- const source = (resolve) => resolve(from);
824
- let reset;
825
- let isAsync;
826
- let proxy;
827
- return () => {
828
- if (!proxy) {
829
- source(connect2);
830
- isAsync = true;
831
- }
832
- if (STALE.delete(compute2)) compute2();
833
- return access(subject, key2, !proxy);
834
- };
835
- }
836
- if (typeof value == "function" || value instanceof Promise) {
837
- let init4 = function() {
838
- if (typeof value == "function")
839
- try {
840
- value = attempt(value.bind(subject, key2));
841
- } catch (err) {
842
- console.warn(
843
- `Generating initial value for ${subject}.${key2} failed.`
844
- );
845
- throw err;
846
- }
847
- property.get = argument !== false;
848
- const set2 = (value2) => subject[key2] = value2;
849
- if (value instanceof Promise)
850
- value.then(set2, (error) => {
851
- event(subject, key2);
852
- property.get = () => {
853
- throw error;
854
- };
855
- });
856
- else set2(value);
857
- if (argument) return null;
858
- return subject[key2];
859
- };
860
- var init3 = init4;
861
- if (argument) {
862
- addListener(subject, init4, true);
863
- } else {
864
- property.get = init4;
865
- }
866
- } else if (value !== void 0) {
867
- property.value = value;
868
- }
869
- if (typeof argument == "function") {
870
- let unset;
871
- property.set = function(value2, previous) {
872
- const exit = enter();
873
- const returns = argument.call(this, value2, previous);
874
- const flush = exit();
875
- if (returns === false) return false;
876
- if (typeof unset == "function") unset(value2);
877
- unset = (next) => {
878
- if (typeof returns == "function") returns(next);
879
- flush();
880
- };
881
- };
882
- } else
883
- property.set = (value2) => {
884
- property.get = void 0;
885
- update(subject, key2, value2);
886
- };
887
- return property;
888
- });
689
+ return use((key, subject, state) => {
690
+ if (typeof value == "symbol") throw new Error(`Attempted to use an instruction result (probably use or get) as computed source for ${subject}.${key}. This is not allowed.`);
691
+ const property = {};
692
+ if (value instanceof State || value === true) {
693
+ let from = subject;
694
+ let getter;
695
+ if (value instanceof State) {
696
+ from = value;
697
+ getter = argument;
698
+ } else {
699
+ const fn = METHOD.get(argument) || argument;
700
+ getter = ((p, k) => fn.call(p, k, p));
701
+ }
702
+ const source = (resolve) => resolve(from);
703
+ let reset;
704
+ let isAsync;
705
+ let proxy;
706
+ function connect(self) {
707
+ reset = watch(self, (current) => {
708
+ proxy = current;
709
+ if (!(key in state) || STALE.delete(compute)) compute(!reset);
710
+ return (didUpdate) => {
711
+ if (didUpdate) {
712
+ STALE.add(compute);
713
+ event(subject, key, true);
714
+ }
715
+ };
716
+ }, false);
717
+ }
718
+ function compute(initial) {
719
+ let next;
720
+ try {
721
+ next = getter.call(proxy, proxy, key);
722
+ } catch (err) {
723
+ console.warn(`An exception was thrown while ${initial ? "initializing" : "refreshing"} ${subject}.${key}.`);
724
+ if (initial) throw err;
725
+ console.error(err);
726
+ }
727
+ update(subject, key, next, !isAsync);
728
+ }
729
+ return () => {
730
+ if (!proxy) {
731
+ source(connect);
732
+ isAsync = true;
733
+ }
734
+ if (STALE.delete(compute)) compute();
735
+ return access(subject, key, !proxy);
736
+ };
737
+ }
738
+ if (typeof value == "function" || value instanceof Promise) {
739
+ function init() {
740
+ if (typeof value == "function") try {
741
+ value = attempt(value.bind(subject, key));
742
+ } catch (err) {
743
+ console.warn(`Generating initial value for ${subject}.${key} failed.`);
744
+ throw err;
745
+ }
746
+ property.get = argument !== false;
747
+ const set = (value) => subject[key] = value;
748
+ if (value instanceof Promise) value.then(set, (error) => {
749
+ event(subject, key);
750
+ property.get = () => {
751
+ throw error;
752
+ };
753
+ });
754
+ else set(value);
755
+ if (argument) return null;
756
+ return subject[key];
757
+ }
758
+ if (argument) addListener(subject, init, true);
759
+ else property.get = init;
760
+ } else if (value !== void 0) property.value = value;
761
+ if (typeof argument == "function") {
762
+ let unset;
763
+ property.set = function(value, previous) {
764
+ const exit = scope();
765
+ const returns = argument.call(this, value, previous);
766
+ const flush = exit();
767
+ if (returns === false) return false;
768
+ if (typeof unset == "function") unset(value);
769
+ unset = (next) => {
770
+ if (typeof returns == "function") returns(next);
771
+ flush();
772
+ };
773
+ };
774
+ } else property.set = (value) => {
775
+ property.get = void 0;
776
+ update(subject, key, value);
777
+ };
778
+ return property;
779
+ });
889
780
  }
890
781
  function attempt(fn) {
891
- function retry(err) {
892
- if (err instanceof Promise) return err.then(compute);
893
- else throw err;
894
- }
895
- function compute() {
896
- try {
897
- const output = fn();
898
- return output instanceof Promise ? output.catch(retry) : output;
899
- } catch (err) {
900
- return retry(err);
901
- }
902
- }
903
- return compute();
782
+ function retry(err) {
783
+ if (err instanceof Promise) return err.then(compute);
784
+ else throw err;
785
+ }
786
+ function compute() {
787
+ try {
788
+ const output = fn();
789
+ return output instanceof Promise ? output.catch(retry) : output;
790
+ } catch (err) {
791
+ return retry(err);
792
+ }
793
+ }
794
+ return compute();
904
795
  }
905
796
 
906
- // src/instruction/ref.ts
907
- var { defineProperty, defineProperties } = Object;
797
+ //#endregion
798
+ //#region src/instruction/ref.ts
799
+ const { defineProperty, defineProperties } = Object;
908
800
  function ref(arg, arg2) {
909
- return use((key2, subject, state) => {
910
- let value = {};
911
- const method = (key3, from) => (callback) => callback ? addListener(subject, () => callback(from[key3]), key3) : from[key3];
912
- if (arg === subject)
913
- addListener(
914
- subject,
915
- () => {
916
- for (const key3 in subject)
917
- if (typeof arg2 == "function")
918
- defineProperty(value, key3, {
919
- configurable: true,
920
- get() {
921
- const out = arg2(key3);
922
- defineProperty(value, key3, { value: out });
923
- return out;
924
- }
925
- });
926
- else {
927
- const get2 = method(key3, subject);
928
- const set2 = (x) => subject[key3] = x;
929
- defineProperties(set2, {
930
- current: { get: get2, set: set2 },
931
- get: { value: get2 },
932
- is: { value: subject },
933
- key: { value: key3 }
934
- });
935
- defineProperty(value, key3, { value: set2 });
936
- }
937
- return null;
938
- },
939
- true
940
- );
941
- else if (typeof arg == "object")
942
- throw new Error(
943
- "ref instruction does not support object which is not 'this'"
944
- );
945
- else {
946
- let unset;
947
- const get2 = method(key2, state);
948
- const set2 = (value2) => {
949
- if (!update(subject, key2, value2) || !arg) return;
950
- if (unset) unset = void unset(value2);
951
- if (value2 === null && arg2 !== false) return;
952
- const exit = enter();
953
- const out = arg.call(subject, value2);
954
- const flush = exit();
955
- unset = (key3) => {
956
- if (typeof out == "function") out(key3);
957
- flush();
958
- };
959
- };
960
- state[key2] = null;
961
- value = defineProperty({ get: get2, key: key2, is: subject }, "current", {
962
- get: get2,
963
- set: set2
964
- });
965
- }
966
- defineProperty(subject, key2, { value });
967
- });
801
+ return use((key, subject, state) => {
802
+ let value = {};
803
+ const method = (key, from) => (callback) => callback ? addListener(subject, () => callback(from[key]), key) : from[key];
804
+ if (arg === subject) addListener(subject, () => {
805
+ for (const key in subject) if (typeof arg2 == "function") defineProperty(value, key, {
806
+ configurable: true,
807
+ get() {
808
+ const out = arg2(key);
809
+ defineProperty(value, key, { value: out });
810
+ return out;
811
+ }
812
+ });
813
+ else {
814
+ const get = method(key, subject);
815
+ const set = (x) => subject[key] = x;
816
+ defineProperties(set, {
817
+ current: {
818
+ get,
819
+ set
820
+ },
821
+ get: { value: get },
822
+ is: { value: subject },
823
+ key: { value: key }
824
+ });
825
+ defineProperty(value, key, { value: set });
826
+ }
827
+ return null;
828
+ }, true);
829
+ else if (typeof arg == "object") throw new Error("ref instruction does not support object which is not 'this'");
830
+ else {
831
+ let unset;
832
+ const get = method(key, state);
833
+ const set = (value) => {
834
+ if (!update(subject, key, value) || !arg) return;
835
+ if (unset) unset = void unset(value);
836
+ if (value === null && arg2 !== false) return;
837
+ const exit = scope();
838
+ const out = arg.call(subject, value);
839
+ const flush = exit();
840
+ unset = (key) => {
841
+ if (typeof out == "function") out(key);
842
+ flush();
843
+ };
844
+ };
845
+ state[key] = null;
846
+ value = defineProperty({
847
+ get,
848
+ key,
849
+ is: subject
850
+ }, "current", {
851
+ get,
852
+ set
853
+ });
854
+ }
855
+ defineProperty(subject, key, { value });
856
+ });
968
857
  }
969
- // Annotate the CommonJS export names for ESM import in node:
970
- 0 && (module.exports = {
971
- Context,
972
- METHOD,
973
- Observable,
974
- State,
975
- addListener,
976
- event,
977
- get,
978
- ref,
979
- set,
980
- use,
981
- watch
982
- });
858
+
859
+ //#endregion
860
+ exports.Context = Context;
861
+ exports.METHOD = METHOD;
862
+ exports.Observable = Observable;
863
+ exports.State = State;
864
+ exports.addListener = addListener;
865
+ exports.default = State;
866
+ exports.event = event;
867
+ exports.get = get;
868
+ exports.ref = ref;
869
+ exports.set = set;
870
+ exports.use = use;
871
+ exports.watch = watch;
983
872
  //# sourceMappingURL=index.js.map