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