@expressive/mvc 0.35.0 → 0.35.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +15 -22
- package/dist/index.js +86 -65
- package/dist/index.mjs +86 -65
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
type Predicate = (key: string) => boolean | void;
|
|
2
1
|
declare namespace Model {
|
|
3
2
|
/** Any type of Model, using own class constructor as its identifier. */
|
|
4
3
|
type Type<T extends Model = Model> = abstract new (...args: any[]) => T;
|
|
@@ -10,6 +9,7 @@ declare namespace Model {
|
|
|
10
9
|
/** Actual value stored in state. */
|
|
11
10
|
type Value<R> = R extends Ref<infer T> ? T : R extends Model ? Export<R> : R;
|
|
12
11
|
type ValueOf<T extends Model, K extends Any<T>> = K extends keyof T ? T[K] extends Ref<infer V> ? V : T[K] : unknown;
|
|
12
|
+
type ValueCallback<T extends Model, K extends Any<T>> = (this: T, value: Model.ValueOf<T, K>, key: K, thisArg: K) => void;
|
|
13
13
|
/**
|
|
14
14
|
* Values from current state of given controller.
|
|
15
15
|
* Differs from `Values` as values here will drill
|
|
@@ -28,8 +28,8 @@ declare namespace Model {
|
|
|
28
28
|
current: T | null;
|
|
29
29
|
};
|
|
30
30
|
/** A callback function which is subscribed to parent and updates when values change. */
|
|
31
|
-
type Effect<T> = (this: T, argument: T) =>
|
|
32
|
-
type Event = (this:
|
|
31
|
+
type Effect<T> = (this: T, argument: T) => (() => void) | Promise<void> | null | void;
|
|
32
|
+
type Event<T extends Model> = (this: T, key: unknown, source: T) => (() => void) | void | null;
|
|
33
33
|
namespace Instruction {
|
|
34
34
|
type Getter<T> = (source: Model) => T;
|
|
35
35
|
type Setter<T> = (value: T, previous: T) => boolean | void | (() => T);
|
|
@@ -58,41 +58,33 @@ declare class Model {
|
|
|
58
58
|
/** Pull current values from state. Flattens all models and exotic values amongst properties. */
|
|
59
59
|
get(): Model.Export<this>;
|
|
60
60
|
/** Run a function which will run automatically when accessed values change. */
|
|
61
|
-
get(effect: Model.Effect<this>):
|
|
62
|
-
get<T extends string>(key: T, required: true): Exclude<Model.ValueOf<this, T>, undefined>;
|
|
61
|
+
get(effect: Model.Effect<this>): () => void;
|
|
63
62
|
get<T extends string>(key: T, required?: boolean): Model.ValueOf<this, T>;
|
|
63
|
+
get<T extends string>(key: T, callback: Model.ValueCallback<this, T>): () => void;
|
|
64
64
|
/**
|
|
65
|
-
*
|
|
66
|
-
* Returns a promise which resolves updated keys. If no update, will resolve to `false`.
|
|
67
|
-
**/
|
|
68
|
-
set(): Promise<Model.Values<this> | false>;
|
|
69
|
-
/**
|
|
70
|
-
* Expect an update to state within a set time.
|
|
71
|
-
*
|
|
72
|
-
* @param timeout - milliseconds to wait for update
|
|
73
|
-
* @param predicate - optional function to filter for specific updates. If returns true, update is accepted.
|
|
65
|
+
* Get update in progress.
|
|
74
66
|
*
|
|
75
|
-
* @returns a promise
|
|
76
|
-
|
|
77
|
-
set(
|
|
67
|
+
* @returns a promise which resolves object with updated values. Is `undefined` if no update.
|
|
68
|
+
**/
|
|
69
|
+
set(): Promise<Model.Values<this>> | undefined;
|
|
78
70
|
/**
|
|
79
71
|
* Call a function whenever an update occurs.
|
|
80
72
|
*
|
|
81
73
|
* @param callback
|
|
82
74
|
* Note: This will be called for every assignment which changes the value.
|
|
83
75
|
* To run logic on final value only, this callback may return a function.
|
|
84
|
-
* Returning the same function for
|
|
76
|
+
* Returning the same function for one or more will ensure it is only called once.
|
|
85
77
|
*
|
|
86
|
-
* @returns a function to remove listener.
|
|
78
|
+
* @returns a function to remove listener. Will return `true` if removed, `false` if inactive already.
|
|
87
79
|
*/
|
|
88
|
-
set(callback: Model.Event): () => boolean;
|
|
80
|
+
set(callback: Model.Event<this>): () => boolean;
|
|
89
81
|
/**
|
|
90
82
|
* Push an update without changing the value of associated property.
|
|
91
83
|
*
|
|
92
84
|
* This is useful where a property value internally has changed, but the object remains the same.
|
|
93
85
|
* For example: An array which has pushed a new value, or a change to nested property.
|
|
94
86
|
*/
|
|
95
|
-
set(key: string): void;
|
|
87
|
+
set(key: string | symbol): void;
|
|
96
88
|
/**
|
|
97
89
|
* Declare an end to updates. This event will freeze state.
|
|
98
90
|
*/
|
|
@@ -122,9 +114,10 @@ declare class Model {
|
|
|
122
114
|
* methods and properties of this class.
|
|
123
115
|
*/
|
|
124
116
|
static is<T extends Model.Type>(this: T, maybe: any): maybe is T;
|
|
117
|
+
static on<T extends Model>(this: Model.Type<T>, event: Model.Event<T>): () => boolean;
|
|
125
118
|
}
|
|
126
119
|
|
|
127
|
-
declare function add<T = any
|
|
120
|
+
declare function add<T = any>(instruction: Model.Instruction): T;
|
|
128
121
|
|
|
129
122
|
declare namespace get {
|
|
130
123
|
type Function<T, S = any> = (this: S, on: S) => T;
|
package/dist/index.js
CHANGED
|
@@ -41,10 +41,10 @@ function onReady() {
|
|
|
41
41
|
function addListener(to, fn) {
|
|
42
42
|
let subs = LISTENER.get(to);
|
|
43
43
|
if (!subs)
|
|
44
|
-
LISTENER.set(to, subs = (/* @__PURE__ */ new Map()).set(onReady,
|
|
44
|
+
LISTENER.set(to, subs = (/* @__PURE__ */ new Map()).set(onReady, void 0));
|
|
45
45
|
if (!subs.has(onReady))
|
|
46
46
|
fn(true, to);
|
|
47
|
-
subs.set(fn,
|
|
47
|
+
subs.set(fn, void 0);
|
|
48
48
|
return () => subs.delete(fn);
|
|
49
49
|
}
|
|
50
50
|
function watch(from, key, value) {
|
|
@@ -138,28 +138,32 @@ function effect(target, callback) {
|
|
|
138
138
|
// src/model.ts
|
|
139
139
|
var ID = /* @__PURE__ */ new WeakMap();
|
|
140
140
|
var PARENT = /* @__PURE__ */ new WeakMap();
|
|
141
|
-
var INSTRUCT = /* @__PURE__ */ new Map();
|
|
142
|
-
var PENDING = /* @__PURE__ */ new WeakMap();
|
|
143
141
|
var STATE = /* @__PURE__ */ new WeakMap();
|
|
142
|
+
var NOTIFY = /* @__PURE__ */ new WeakMap();
|
|
143
|
+
var PENDING = /* @__PURE__ */ new WeakMap();
|
|
144
144
|
var define = Object.defineProperty;
|
|
145
145
|
var Model = class _Model {
|
|
146
146
|
constructor(id) {
|
|
147
|
+
let Type = this.constructor;
|
|
147
148
|
const state = {};
|
|
148
149
|
define(this, "is", { value: this });
|
|
149
|
-
ID.set(this, `${this.constructor}-${id ? String(id) : uid()}`);
|
|
150
150
|
STATE.set(this, state);
|
|
151
|
+
ID.set(this, `${Type}-${id ? String(id) : uid()}`);
|
|
151
152
|
function onNull(key) {
|
|
152
153
|
if (key === null)
|
|
153
154
|
Object.freeze(state);
|
|
154
155
|
}
|
|
156
|
+
while (true) {
|
|
157
|
+
new Set(NOTIFY.get(Type)).forEach((x) => addListener(this, x));
|
|
158
|
+
if (Type === _Model)
|
|
159
|
+
break;
|
|
160
|
+
Type = Object.getPrototypeOf(Type);
|
|
161
|
+
}
|
|
155
162
|
addListener(this, () => {
|
|
156
163
|
for (const key in this) {
|
|
157
|
-
const
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
instruction(this, key, state);
|
|
161
|
-
else {
|
|
162
|
-
state[key] = property.value;
|
|
164
|
+
const desc = Object.getOwnPropertyDescriptor(this, key);
|
|
165
|
+
if ("value" in desc) {
|
|
166
|
+
state[key] = desc.value;
|
|
163
167
|
define(this, key, {
|
|
164
168
|
enumerable: true,
|
|
165
169
|
set: (x) => update(this, key, x),
|
|
@@ -176,7 +180,16 @@ var Model = class _Model {
|
|
|
176
180
|
get(arg1, arg2) {
|
|
177
181
|
const self = this.is;
|
|
178
182
|
if (typeof arg1 == "string")
|
|
179
|
-
|
|
183
|
+
if (typeof arg2 == "function") {
|
|
184
|
+
const state = STATE.get(self);
|
|
185
|
+
if (arg1 in state)
|
|
186
|
+
arg2.call(this, state[arg1], arg1, this);
|
|
187
|
+
return addListener(self, (key) => {
|
|
188
|
+
if (key === arg1)
|
|
189
|
+
arg2.call(this, arg1 in state ? state[key] : key, key, this);
|
|
190
|
+
});
|
|
191
|
+
} else
|
|
192
|
+
return fetch(self, arg1, arg2);
|
|
180
193
|
if (arg1)
|
|
181
194
|
return effect(self, arg1);
|
|
182
195
|
const cache = /* @__PURE__ */ new WeakMap();
|
|
@@ -198,27 +211,19 @@ var Model = class _Model {
|
|
|
198
211
|
if (typeof arg1 == "function")
|
|
199
212
|
return addListener(self, (key) => {
|
|
200
213
|
if (typeof key == "string")
|
|
201
|
-
return arg1.call(
|
|
214
|
+
return arg1.call(self, key, self);
|
|
202
215
|
});
|
|
203
|
-
if (
|
|
216
|
+
if (arg1 !== void 0)
|
|
204
217
|
return 1 in arguments ? update(self, arg1, arg2, arg3) : update(self, arg1);
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
return;
|
|
209
|
-
}
|
|
218
|
+
if (!PENDING.has(self))
|
|
219
|
+
return;
|
|
220
|
+
return new Promise((resolve) => {
|
|
210
221
|
const remove = addListener(this, (key) => {
|
|
211
|
-
if (key
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
remove();
|
|
216
|
-
return resolve.bind(null, PENDING.get(self));
|
|
222
|
+
if (key !== true) {
|
|
223
|
+
remove();
|
|
224
|
+
return resolve.bind(null, PENDING.get(self));
|
|
225
|
+
}
|
|
217
226
|
});
|
|
218
|
-
const timeout = typeof arg1 == "number" && setTimeout(() => {
|
|
219
|
-
remove();
|
|
220
|
-
reject(arg1);
|
|
221
|
-
}, arg1);
|
|
222
227
|
});
|
|
223
228
|
}
|
|
224
229
|
/** Iterate over managed properties in this instance of Model. */
|
|
@@ -246,6 +251,13 @@ var Model = class _Model {
|
|
|
246
251
|
static is(maybe) {
|
|
247
252
|
return typeof maybe == "function" && maybe.prototype instanceof this;
|
|
248
253
|
}
|
|
254
|
+
static on(event2) {
|
|
255
|
+
let notify = NOTIFY.get(this);
|
|
256
|
+
if (!notify)
|
|
257
|
+
NOTIFY.set(this, notify = /* @__PURE__ */ new Set());
|
|
258
|
+
notify.add(event2);
|
|
259
|
+
return () => notify.delete(event2);
|
|
260
|
+
}
|
|
249
261
|
};
|
|
250
262
|
define(Model.prototype, "toString", {
|
|
251
263
|
value() {
|
|
@@ -285,15 +297,15 @@ function fetch(subject, property, required) {
|
|
|
285
297
|
function update(subject, key, value, silent) {
|
|
286
298
|
const state = STATE.get(subject);
|
|
287
299
|
let pending = PENDING.get(subject);
|
|
288
|
-
if (typeof key == "string") {
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
300
|
+
if (typeof key == "string" && 2 in arguments) {
|
|
301
|
+
const previous = state[key];
|
|
302
|
+
if (value === previous)
|
|
303
|
+
return true;
|
|
304
|
+
state[key] = value;
|
|
305
|
+
if (silent === true)
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
if (key !== true && key) {
|
|
297
309
|
if (!pending) {
|
|
298
310
|
PENDING.set(subject, pending = {});
|
|
299
311
|
queue(() => {
|
|
@@ -301,7 +313,7 @@ function update(subject, key, value, silent) {
|
|
|
301
313
|
PENDING.delete(subject);
|
|
302
314
|
});
|
|
303
315
|
}
|
|
304
|
-
pending[key] = value;
|
|
316
|
+
pending[key] = key in state ? value : true;
|
|
305
317
|
}
|
|
306
318
|
event(subject, key);
|
|
307
319
|
}
|
|
@@ -310,10 +322,20 @@ function uid() {
|
|
|
310
322
|
}
|
|
311
323
|
|
|
312
324
|
// src/instruction/add.ts
|
|
325
|
+
var INSTRUCT = /* @__PURE__ */ new Map();
|
|
313
326
|
function add(instruction) {
|
|
314
|
-
const
|
|
315
|
-
INSTRUCT.set(
|
|
316
|
-
|
|
327
|
+
const token = Symbol("instruction");
|
|
328
|
+
INSTRUCT.set(token, instruction);
|
|
329
|
+
return token;
|
|
330
|
+
}
|
|
331
|
+
Model.on((_, subject) => {
|
|
332
|
+
const state = STATE.get(subject);
|
|
333
|
+
for (const key in subject) {
|
|
334
|
+
const { value } = Object.getOwnPropertyDescriptor(subject, key);
|
|
335
|
+
const instruction = INSTRUCT.get(value);
|
|
336
|
+
if (!instruction)
|
|
337
|
+
continue;
|
|
338
|
+
INSTRUCT.delete(value);
|
|
317
339
|
delete subject[key];
|
|
318
340
|
const output = instruction.call(subject, key, subject, state);
|
|
319
341
|
if (!output)
|
|
@@ -346,9 +368,9 @@ function add(instruction) {
|
|
|
346
368
|
);
|
|
347
369
|
}
|
|
348
370
|
});
|
|
349
|
-
}
|
|
350
|
-
return
|
|
351
|
-
}
|
|
371
|
+
}
|
|
372
|
+
return null;
|
|
373
|
+
});
|
|
352
374
|
|
|
353
375
|
// src/context.ts
|
|
354
376
|
var Context = class {
|
|
@@ -416,8 +438,8 @@ var Context = class {
|
|
|
416
438
|
if (value || I !== this[key] && !implicit)
|
|
417
439
|
Object.defineProperty(this, key, {
|
|
418
440
|
configurable: true,
|
|
419
|
-
|
|
420
|
-
|
|
441
|
+
writable,
|
|
442
|
+
value
|
|
421
443
|
});
|
|
422
444
|
T = Object.getPrototypeOf(T);
|
|
423
445
|
} while (T !== Model);
|
|
@@ -524,24 +546,23 @@ function ref(arg, arg2) {
|
|
|
524
546
|
return add((key, subject, state) => {
|
|
525
547
|
let value = {};
|
|
526
548
|
if (arg === subject)
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
get: () => state[key2],
|
|
541
|
-
|
|
542
|
-
}
|
|
543
|
-
|
|
544
|
-
}
|
|
549
|
+
subject.get(() => {
|
|
550
|
+
for (const key2 in state)
|
|
551
|
+
if (typeof arg2 == "function")
|
|
552
|
+
define2(value, key2, {
|
|
553
|
+
configurable: true,
|
|
554
|
+
get() {
|
|
555
|
+
const out = arg2(key2);
|
|
556
|
+
define2(value, key2, { value: out });
|
|
557
|
+
return out;
|
|
558
|
+
}
|
|
559
|
+
});
|
|
560
|
+
else {
|
|
561
|
+
const set2 = (value2) => subject.set(key2, value2);
|
|
562
|
+
define2(set2, "current", { get: () => state[key2], set: set2 });
|
|
563
|
+
define2(value, key2, { value: set2 });
|
|
564
|
+
}
|
|
565
|
+
});
|
|
545
566
|
else if (typeof arg == "object")
|
|
546
567
|
throw new Error("ref instruction does not support object which is not 'this'");
|
|
547
568
|
else {
|
package/dist/index.mjs
CHANGED
|
@@ -8,10 +8,10 @@ function onReady() {
|
|
|
8
8
|
function addListener(to, fn) {
|
|
9
9
|
let subs = LISTENER.get(to);
|
|
10
10
|
if (!subs)
|
|
11
|
-
LISTENER.set(to, subs = (/* @__PURE__ */ new Map()).set(onReady,
|
|
11
|
+
LISTENER.set(to, subs = (/* @__PURE__ */ new Map()).set(onReady, void 0));
|
|
12
12
|
if (!subs.has(onReady))
|
|
13
13
|
fn(true, to);
|
|
14
|
-
subs.set(fn,
|
|
14
|
+
subs.set(fn, void 0);
|
|
15
15
|
return () => subs.delete(fn);
|
|
16
16
|
}
|
|
17
17
|
function watch(from, key, value) {
|
|
@@ -105,28 +105,32 @@ function effect(target, callback) {
|
|
|
105
105
|
// src/model.ts
|
|
106
106
|
var ID = /* @__PURE__ */ new WeakMap();
|
|
107
107
|
var PARENT = /* @__PURE__ */ new WeakMap();
|
|
108
|
-
var INSTRUCT = /* @__PURE__ */ new Map();
|
|
109
|
-
var PENDING = /* @__PURE__ */ new WeakMap();
|
|
110
108
|
var STATE = /* @__PURE__ */ new WeakMap();
|
|
109
|
+
var NOTIFY = /* @__PURE__ */ new WeakMap();
|
|
110
|
+
var PENDING = /* @__PURE__ */ new WeakMap();
|
|
111
111
|
var define = Object.defineProperty;
|
|
112
112
|
var Model = class _Model {
|
|
113
113
|
constructor(id) {
|
|
114
|
+
let Type = this.constructor;
|
|
114
115
|
const state = {};
|
|
115
116
|
define(this, "is", { value: this });
|
|
116
|
-
ID.set(this, `${this.constructor}-${id ? String(id) : uid()}`);
|
|
117
117
|
STATE.set(this, state);
|
|
118
|
+
ID.set(this, `${Type}-${id ? String(id) : uid()}`);
|
|
118
119
|
function onNull(key) {
|
|
119
120
|
if (key === null)
|
|
120
121
|
Object.freeze(state);
|
|
121
122
|
}
|
|
123
|
+
while (true) {
|
|
124
|
+
new Set(NOTIFY.get(Type)).forEach((x) => addListener(this, x));
|
|
125
|
+
if (Type === _Model)
|
|
126
|
+
break;
|
|
127
|
+
Type = Object.getPrototypeOf(Type);
|
|
128
|
+
}
|
|
122
129
|
addListener(this, () => {
|
|
123
130
|
for (const key in this) {
|
|
124
|
-
const
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
instruction(this, key, state);
|
|
128
|
-
else {
|
|
129
|
-
state[key] = property.value;
|
|
131
|
+
const desc = Object.getOwnPropertyDescriptor(this, key);
|
|
132
|
+
if ("value" in desc) {
|
|
133
|
+
state[key] = desc.value;
|
|
130
134
|
define(this, key, {
|
|
131
135
|
enumerable: true,
|
|
132
136
|
set: (x) => update(this, key, x),
|
|
@@ -143,7 +147,16 @@ var Model = class _Model {
|
|
|
143
147
|
get(arg1, arg2) {
|
|
144
148
|
const self = this.is;
|
|
145
149
|
if (typeof arg1 == "string")
|
|
146
|
-
|
|
150
|
+
if (typeof arg2 == "function") {
|
|
151
|
+
const state = STATE.get(self);
|
|
152
|
+
if (arg1 in state)
|
|
153
|
+
arg2.call(this, state[arg1], arg1, this);
|
|
154
|
+
return addListener(self, (key) => {
|
|
155
|
+
if (key === arg1)
|
|
156
|
+
arg2.call(this, arg1 in state ? state[key] : key, key, this);
|
|
157
|
+
});
|
|
158
|
+
} else
|
|
159
|
+
return fetch(self, arg1, arg2);
|
|
147
160
|
if (arg1)
|
|
148
161
|
return effect(self, arg1);
|
|
149
162
|
const cache = /* @__PURE__ */ new WeakMap();
|
|
@@ -165,27 +178,19 @@ var Model = class _Model {
|
|
|
165
178
|
if (typeof arg1 == "function")
|
|
166
179
|
return addListener(self, (key) => {
|
|
167
180
|
if (typeof key == "string")
|
|
168
|
-
return arg1.call(
|
|
181
|
+
return arg1.call(self, key, self);
|
|
169
182
|
});
|
|
170
|
-
if (
|
|
183
|
+
if (arg1 !== void 0)
|
|
171
184
|
return 1 in arguments ? update(self, arg1, arg2, arg3) : update(self, arg1);
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
return;
|
|
176
|
-
}
|
|
185
|
+
if (!PENDING.has(self))
|
|
186
|
+
return;
|
|
187
|
+
return new Promise((resolve) => {
|
|
177
188
|
const remove = addListener(this, (key) => {
|
|
178
|
-
if (key
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
remove();
|
|
183
|
-
return resolve.bind(null, PENDING.get(self));
|
|
189
|
+
if (key !== true) {
|
|
190
|
+
remove();
|
|
191
|
+
return resolve.bind(null, PENDING.get(self));
|
|
192
|
+
}
|
|
184
193
|
});
|
|
185
|
-
const timeout = typeof arg1 == "number" && setTimeout(() => {
|
|
186
|
-
remove();
|
|
187
|
-
reject(arg1);
|
|
188
|
-
}, arg1);
|
|
189
194
|
});
|
|
190
195
|
}
|
|
191
196
|
/** Iterate over managed properties in this instance of Model. */
|
|
@@ -213,6 +218,13 @@ var Model = class _Model {
|
|
|
213
218
|
static is(maybe) {
|
|
214
219
|
return typeof maybe == "function" && maybe.prototype instanceof this;
|
|
215
220
|
}
|
|
221
|
+
static on(event2) {
|
|
222
|
+
let notify = NOTIFY.get(this);
|
|
223
|
+
if (!notify)
|
|
224
|
+
NOTIFY.set(this, notify = /* @__PURE__ */ new Set());
|
|
225
|
+
notify.add(event2);
|
|
226
|
+
return () => notify.delete(event2);
|
|
227
|
+
}
|
|
216
228
|
};
|
|
217
229
|
define(Model.prototype, "toString", {
|
|
218
230
|
value() {
|
|
@@ -252,15 +264,15 @@ function fetch(subject, property, required) {
|
|
|
252
264
|
function update(subject, key, value, silent) {
|
|
253
265
|
const state = STATE.get(subject);
|
|
254
266
|
let pending = PENDING.get(subject);
|
|
255
|
-
if (typeof key == "string") {
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
267
|
+
if (typeof key == "string" && 2 in arguments) {
|
|
268
|
+
const previous = state[key];
|
|
269
|
+
if (value === previous)
|
|
270
|
+
return true;
|
|
271
|
+
state[key] = value;
|
|
272
|
+
if (silent === true)
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
if (key !== true && key) {
|
|
264
276
|
if (!pending) {
|
|
265
277
|
PENDING.set(subject, pending = {});
|
|
266
278
|
queue(() => {
|
|
@@ -268,7 +280,7 @@ function update(subject, key, value, silent) {
|
|
|
268
280
|
PENDING.delete(subject);
|
|
269
281
|
});
|
|
270
282
|
}
|
|
271
|
-
pending[key] = value;
|
|
283
|
+
pending[key] = key in state ? value : true;
|
|
272
284
|
}
|
|
273
285
|
event(subject, key);
|
|
274
286
|
}
|
|
@@ -277,10 +289,20 @@ function uid() {
|
|
|
277
289
|
}
|
|
278
290
|
|
|
279
291
|
// src/instruction/add.ts
|
|
292
|
+
var INSTRUCT = /* @__PURE__ */ new Map();
|
|
280
293
|
function add(instruction) {
|
|
281
|
-
const
|
|
282
|
-
INSTRUCT.set(
|
|
283
|
-
|
|
294
|
+
const token = Symbol("instruction");
|
|
295
|
+
INSTRUCT.set(token, instruction);
|
|
296
|
+
return token;
|
|
297
|
+
}
|
|
298
|
+
Model.on((_, subject) => {
|
|
299
|
+
const state = STATE.get(subject);
|
|
300
|
+
for (const key in subject) {
|
|
301
|
+
const { value } = Object.getOwnPropertyDescriptor(subject, key);
|
|
302
|
+
const instruction = INSTRUCT.get(value);
|
|
303
|
+
if (!instruction)
|
|
304
|
+
continue;
|
|
305
|
+
INSTRUCT.delete(value);
|
|
284
306
|
delete subject[key];
|
|
285
307
|
const output = instruction.call(subject, key, subject, state);
|
|
286
308
|
if (!output)
|
|
@@ -313,9 +335,9 @@ function add(instruction) {
|
|
|
313
335
|
);
|
|
314
336
|
}
|
|
315
337
|
});
|
|
316
|
-
}
|
|
317
|
-
return
|
|
318
|
-
}
|
|
338
|
+
}
|
|
339
|
+
return null;
|
|
340
|
+
});
|
|
319
341
|
|
|
320
342
|
// src/context.ts
|
|
321
343
|
var Context = class {
|
|
@@ -383,8 +405,8 @@ var Context = class {
|
|
|
383
405
|
if (value || I !== this[key] && !implicit)
|
|
384
406
|
Object.defineProperty(this, key, {
|
|
385
407
|
configurable: true,
|
|
386
|
-
|
|
387
|
-
|
|
408
|
+
writable,
|
|
409
|
+
value
|
|
388
410
|
});
|
|
389
411
|
T = Object.getPrototypeOf(T);
|
|
390
412
|
} while (T !== Model);
|
|
@@ -491,24 +513,23 @@ function ref(arg, arg2) {
|
|
|
491
513
|
return add((key, subject, state) => {
|
|
492
514
|
let value = {};
|
|
493
515
|
if (arg === subject)
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
get: () => state[key2],
|
|
508
|
-
|
|
509
|
-
}
|
|
510
|
-
|
|
511
|
-
}
|
|
516
|
+
subject.get(() => {
|
|
517
|
+
for (const key2 in state)
|
|
518
|
+
if (typeof arg2 == "function")
|
|
519
|
+
define2(value, key2, {
|
|
520
|
+
configurable: true,
|
|
521
|
+
get() {
|
|
522
|
+
const out = arg2(key2);
|
|
523
|
+
define2(value, key2, { value: out });
|
|
524
|
+
return out;
|
|
525
|
+
}
|
|
526
|
+
});
|
|
527
|
+
else {
|
|
528
|
+
const set2 = (value2) => subject.set(key2, value2);
|
|
529
|
+
define2(set2, "current", { get: () => state[key2], set: set2 });
|
|
530
|
+
define2(value, key2, { value: set2 });
|
|
531
|
+
}
|
|
532
|
+
});
|
|
512
533
|
else if (typeof arg == "object")
|
|
513
534
|
throw new Error("ref instruction does not support object which is not 'this'");
|
|
514
535
|
else {
|
package/package.json
CHANGED