@expressive/mvc 0.4.5 → 0.5.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/lib/index.d.ts +41 -43
- package/lib/index.esm.js +410 -561
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +411 -563
- package/lib/index.js.map +1 -1
- package/package.json +1 -1
package/lib/index.esm.js
CHANGED
|
@@ -1,30 +1,5 @@
|
|
|
1
1
|
import React, { useLayoutEffect, useState, useMemo } from 'react';
|
|
2
2
|
|
|
3
|
-
/*! *****************************************************************************
|
|
4
|
-
Copyright (c) Microsoft Corporation.
|
|
5
|
-
|
|
6
|
-
Permission to use, copy, modify, and/or distribute this software for any
|
|
7
|
-
purpose with or without fee is hereby granted.
|
|
8
|
-
|
|
9
|
-
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
10
|
-
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
11
|
-
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
12
|
-
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
13
|
-
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
14
|
-
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
15
|
-
PERFORMANCE OF THIS SOFTWARE.
|
|
16
|
-
***************************************************************************** */
|
|
17
|
-
|
|
18
|
-
function __awaiter(thisArg, _arguments, P, generator) {
|
|
19
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
20
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
21
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
22
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
23
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
24
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
25
|
-
});
|
|
26
|
-
}
|
|
27
|
-
|
|
28
3
|
class Issue extends Error {
|
|
29
4
|
constructor() {
|
|
30
5
|
super(...arguments);
|
|
@@ -87,78 +62,6 @@ function mayRetry(fn) {
|
|
|
87
62
|
}
|
|
88
63
|
|
|
89
64
|
const Oops$b = issues({
|
|
90
|
-
BadCallback: () => `Callback for effect-callback may only return a function.`
|
|
91
|
-
});
|
|
92
|
-
const { assign, create, defineProperty, entries, getPrototypeOf, getOwnPropertyNames, getOwnPropertyDescriptor, getOwnPropertySymbols, values } = Object;
|
|
93
|
-
function define(target, key, value) {
|
|
94
|
-
defineProperty(target, key, { value });
|
|
95
|
-
}
|
|
96
|
-
function defineLazy(object, property, init) {
|
|
97
|
-
defineProperty(object, property, {
|
|
98
|
-
configurable: true,
|
|
99
|
-
get() {
|
|
100
|
-
const value = init.call(this);
|
|
101
|
-
defineProperty(this, property, { value });
|
|
102
|
-
return value;
|
|
103
|
-
}
|
|
104
|
-
});
|
|
105
|
-
}
|
|
106
|
-
function createEffect(callback) {
|
|
107
|
-
let unSet;
|
|
108
|
-
return function (value) {
|
|
109
|
-
if (typeof unSet == "function")
|
|
110
|
-
unSet();
|
|
111
|
-
unSet = callback.call(this, value);
|
|
112
|
-
if (unSet instanceof Promise)
|
|
113
|
-
unSet = undefined;
|
|
114
|
-
if (unSet && typeof unSet !== "function")
|
|
115
|
-
throw Oops$b.BadCallback();
|
|
116
|
-
};
|
|
117
|
-
}
|
|
118
|
-
function createValueEffect(callback) {
|
|
119
|
-
let unSet;
|
|
120
|
-
return function (value) {
|
|
121
|
-
if (typeof unSet == "function")
|
|
122
|
-
unSet(value);
|
|
123
|
-
const out = callback.call(this, value, this);
|
|
124
|
-
if (typeof out == "boolean")
|
|
125
|
-
return out;
|
|
126
|
-
if (!out || out instanceof Promise)
|
|
127
|
-
return;
|
|
128
|
-
if (typeof out == "function")
|
|
129
|
-
unSet = out;
|
|
130
|
-
else
|
|
131
|
-
throw Oops$b.BadCallback();
|
|
132
|
-
};
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
function ensure(subject, cb) {
|
|
136
|
-
let control = subject[CONTROL];
|
|
137
|
-
if (!control) {
|
|
138
|
-
control = new Controller(subject);
|
|
139
|
-
define(subject, CONTROL, control);
|
|
140
|
-
}
|
|
141
|
-
if (!control.state) {
|
|
142
|
-
const { waiting } = control;
|
|
143
|
-
if (cb) {
|
|
144
|
-
let done;
|
|
145
|
-
waiting.add(() => {
|
|
146
|
-
done = cb(control);
|
|
147
|
-
});
|
|
148
|
-
return () => done && done();
|
|
149
|
-
}
|
|
150
|
-
control.state = new Map();
|
|
151
|
-
for (const key in subject)
|
|
152
|
-
control.add(key);
|
|
153
|
-
const callback = Array.from(waiting);
|
|
154
|
-
waiting.clear();
|
|
155
|
-
for (const cb of callback)
|
|
156
|
-
cb();
|
|
157
|
-
}
|
|
158
|
-
return cb ? cb(control) : control;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
const Oops$a = issues({
|
|
162
65
|
BadSource: (model, property, got) => `Bad from-instruction provided to ${model}.${property}. Expects an arrow-function or a Model as source. Got ${got}.`,
|
|
163
66
|
PeerNotAllowed: (model, property) => `Attempted to use an instruction result (probably use or tap) as computed source for ${model}.${property}. This is not possible.`,
|
|
164
67
|
Failed: (parent, property, initial) => `An exception was thrown while ${initial ? "initializing" : "refreshing"} [${parent}.${property}].`
|
|
@@ -166,8 +69,8 @@ const Oops$a = issues({
|
|
|
166
69
|
const INFO = new WeakMap();
|
|
167
70
|
const KEYS = new WeakMap();
|
|
168
71
|
const ORDER = new WeakMap();
|
|
169
|
-
function
|
|
170
|
-
return apply(function
|
|
72
|
+
function get(source, arg1, arg2) {
|
|
73
|
+
return apply(function get(key) {
|
|
171
74
|
const { subject, state } = this;
|
|
172
75
|
const required = arg2 === true || arg1 === true;
|
|
173
76
|
let getSource;
|
|
@@ -175,7 +78,7 @@ function from(source, arg1, arg2) {
|
|
|
175
78
|
arg1 = undefined;
|
|
176
79
|
// Easy mistake, using a peer, will always be unresolved.
|
|
177
80
|
if (typeof source == "symbol")
|
|
178
|
-
throw Oops$
|
|
81
|
+
throw Oops$b.PeerNotAllowed(subject, key);
|
|
179
82
|
// replace source controller in-case it is different
|
|
180
83
|
if (typeof source == "object")
|
|
181
84
|
getSource = () => ensure(source);
|
|
@@ -186,24 +89,23 @@ function from(source, arg1, arg2) {
|
|
|
186
89
|
}
|
|
187
90
|
// Regular function is too ambiguous so not allowed.
|
|
188
91
|
else
|
|
189
|
-
throw Oops$
|
|
92
|
+
throw Oops$b.BadSource(subject, key, source);
|
|
190
93
|
const setter = arg1;
|
|
191
94
|
const info = { key, parent: this };
|
|
192
95
|
let sub;
|
|
193
96
|
let order = ORDER.get(this);
|
|
194
97
|
if (!order)
|
|
195
98
|
ORDER.set(this, order = []);
|
|
196
|
-
state.set(key, undefined);
|
|
197
99
|
const compute = (initial) => {
|
|
198
100
|
try {
|
|
199
101
|
return setter.call(sub.proxy, sub.proxy);
|
|
200
102
|
}
|
|
201
103
|
catch (err) {
|
|
202
|
-
Oops$
|
|
104
|
+
Oops$b.Failed(subject, key, initial).warn();
|
|
203
105
|
throw err;
|
|
204
106
|
}
|
|
205
107
|
};
|
|
206
|
-
const
|
|
108
|
+
const refresh = () => {
|
|
207
109
|
let value;
|
|
208
110
|
try {
|
|
209
111
|
value = compute(false);
|
|
@@ -219,19 +121,18 @@ function from(source, arg1, arg2) {
|
|
|
219
121
|
}
|
|
220
122
|
}
|
|
221
123
|
};
|
|
222
|
-
const
|
|
124
|
+
const update = (_key, source) => {
|
|
223
125
|
if (source !== this) {
|
|
224
|
-
|
|
126
|
+
refresh();
|
|
225
127
|
return;
|
|
226
128
|
}
|
|
227
129
|
let pending = KEYS.get(this);
|
|
228
130
|
if (!pending)
|
|
229
131
|
KEYS.set(this, pending = []);
|
|
230
|
-
pending.push(
|
|
132
|
+
pending.push(refresh);
|
|
231
133
|
};
|
|
232
134
|
const create = () => {
|
|
233
|
-
|
|
234
|
-
sub = control.subscribe(dependancyDidUpdate);
|
|
135
|
+
sub = getSource().subscribe(update);
|
|
235
136
|
try {
|
|
236
137
|
const value = compute(true);
|
|
237
138
|
state.set(key, value);
|
|
@@ -242,10 +143,11 @@ function from(source, arg1, arg2) {
|
|
|
242
143
|
}
|
|
243
144
|
finally {
|
|
244
145
|
sub.commit();
|
|
245
|
-
order.push(
|
|
146
|
+
order.push(refresh);
|
|
246
147
|
}
|
|
247
148
|
};
|
|
248
|
-
|
|
149
|
+
state.set(key, undefined);
|
|
150
|
+
INFO.set(refresh, info);
|
|
249
151
|
return () => {
|
|
250
152
|
const value = sub ? state.get(key) : create();
|
|
251
153
|
if (value === undefined && required)
|
|
@@ -270,6 +172,39 @@ function flush(control) {
|
|
|
270
172
|
KEYS.delete(control);
|
|
271
173
|
}
|
|
272
174
|
|
|
175
|
+
const Oops$a = issues({
|
|
176
|
+
BadCallback: () => `Callback for effect-callback may only return a function.`
|
|
177
|
+
});
|
|
178
|
+
const { assign, create, defineProperty, entries, getPrototypeOf, getOwnPropertyNames, getOwnPropertyDescriptor, getOwnPropertySymbols, values } = Object;
|
|
179
|
+
function createEffect(callback) {
|
|
180
|
+
let unSet;
|
|
181
|
+
return function (value) {
|
|
182
|
+
if (typeof unSet == "function")
|
|
183
|
+
unSet();
|
|
184
|
+
unSet = callback.call(this, value);
|
|
185
|
+
if (unSet instanceof Promise)
|
|
186
|
+
unSet = undefined;
|
|
187
|
+
if (unSet && typeof unSet !== "function")
|
|
188
|
+
throw Oops$a.BadCallback();
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
function createValueEffect(callback) {
|
|
192
|
+
let unSet;
|
|
193
|
+
return function (value) {
|
|
194
|
+
if (typeof unSet == "function")
|
|
195
|
+
unSet(value);
|
|
196
|
+
const out = callback.call(this, value, this);
|
|
197
|
+
if (typeof out == "boolean")
|
|
198
|
+
return out;
|
|
199
|
+
if (!out || out instanceof Promise)
|
|
200
|
+
return;
|
|
201
|
+
if (typeof out == "function")
|
|
202
|
+
unSet = out;
|
|
203
|
+
else
|
|
204
|
+
throw Oops$a.BadCallback();
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
|
|
273
208
|
class Subscriber {
|
|
274
209
|
constructor(parent, onUpdate) {
|
|
275
210
|
this.onUpdate = onUpdate;
|
|
@@ -277,7 +212,7 @@ class Subscriber {
|
|
|
277
212
|
this.dependant = new Set();
|
|
278
213
|
const proxy = create(parent.subject);
|
|
279
214
|
const using = new Map();
|
|
280
|
-
|
|
215
|
+
defineProperty(proxy, LOCAL, { value: this });
|
|
281
216
|
defineProperty(this, "proxy", {
|
|
282
217
|
configurable: true,
|
|
283
218
|
get() {
|
|
@@ -298,15 +233,13 @@ class Subscriber {
|
|
|
298
233
|
}
|
|
299
234
|
else if (handler === true)
|
|
300
235
|
notify = this.onUpdate(key, parent);
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
UPDATE.set(proxy,
|
|
236
|
+
if (!notify)
|
|
237
|
+
return;
|
|
238
|
+
const notate = () => {
|
|
239
|
+
UPDATE.set(proxy, getUpdate(parent.subject).filter(k => using.has(k)));
|
|
305
240
|
};
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
parent.waiting.add(notify);
|
|
309
|
-
}
|
|
241
|
+
parent.waiting.add(notate);
|
|
242
|
+
parent.waiting.add(notify);
|
|
310
243
|
});
|
|
311
244
|
this.commit = () => {
|
|
312
245
|
this.active = true;
|
|
@@ -326,123 +259,37 @@ class Subscriber {
|
|
|
326
259
|
}
|
|
327
260
|
}
|
|
328
261
|
|
|
329
|
-
const UPDATE = new WeakMap();
|
|
330
|
-
function getUpdate(subject) {
|
|
331
|
-
return UPDATE.get(subject);
|
|
332
|
-
}
|
|
333
|
-
class Controller {
|
|
334
|
-
constructor(subject) {
|
|
335
|
-
this.subject = subject;
|
|
336
|
-
this.frame = new Set();
|
|
337
|
-
this.waiting = new Set();
|
|
338
|
-
this.followers = new Set();
|
|
339
|
-
}
|
|
340
|
-
subscribe(callback) {
|
|
341
|
-
return new Subscriber(this, callback);
|
|
342
|
-
}
|
|
343
|
-
add(key) {
|
|
344
|
-
const { subject, state } = this;
|
|
345
|
-
const { value } = getOwnPropertyDescriptor(subject, key);
|
|
346
|
-
if (typeof value == "function")
|
|
347
|
-
return;
|
|
348
|
-
if (typeof value == "symbol") {
|
|
349
|
-
const instruction = PENDING.get(value);
|
|
350
|
-
if (instruction)
|
|
351
|
-
instruction.call(this, key, this);
|
|
352
|
-
return;
|
|
353
|
-
}
|
|
354
|
-
state.set(key, value);
|
|
355
|
-
defineProperty(subject, key, {
|
|
356
|
-
enumerable: false,
|
|
357
|
-
set: this.ref(key),
|
|
358
|
-
get() {
|
|
359
|
-
const local = this[LOCAL];
|
|
360
|
-
if (local)
|
|
361
|
-
local.add(key);
|
|
362
|
-
return state.get(key);
|
|
363
|
-
}
|
|
364
|
-
});
|
|
365
|
-
}
|
|
366
|
-
addListener(listener) {
|
|
367
|
-
this.followers.add(listener);
|
|
368
|
-
return () => {
|
|
369
|
-
this.followers.delete(listener);
|
|
370
|
-
};
|
|
371
|
-
}
|
|
372
|
-
ref(key, handler) {
|
|
373
|
-
const { subject, state } = this;
|
|
374
|
-
return (value) => {
|
|
375
|
-
if (state.get(key) == value)
|
|
376
|
-
return;
|
|
377
|
-
if (handler)
|
|
378
|
-
switch (handler.call(subject, value)) {
|
|
379
|
-
case true:
|
|
380
|
-
this.update(key);
|
|
381
|
-
case false:
|
|
382
|
-
return;
|
|
383
|
-
}
|
|
384
|
-
state.set(key, value);
|
|
385
|
-
this.update(key);
|
|
386
|
-
};
|
|
387
|
-
}
|
|
388
|
-
update(key) {
|
|
389
|
-
const { followers, frame, subject, waiting } = this;
|
|
390
|
-
if (frame.has(key))
|
|
391
|
-
return;
|
|
392
|
-
else if (!frame.size)
|
|
393
|
-
setTimeout(() => {
|
|
394
|
-
flush(this);
|
|
395
|
-
UPDATE.set(subject, Array.from(frame));
|
|
396
|
-
setTimeout(() => {
|
|
397
|
-
UPDATE.delete(subject);
|
|
398
|
-
}, 0);
|
|
399
|
-
frame.clear();
|
|
400
|
-
for (const notify of waiting)
|
|
401
|
-
try {
|
|
402
|
-
waiting.delete(notify);
|
|
403
|
-
notify();
|
|
404
|
-
}
|
|
405
|
-
catch (err) {
|
|
406
|
-
console.error(err);
|
|
407
|
-
}
|
|
408
|
-
}, 0);
|
|
409
|
-
frame.add(key);
|
|
410
|
-
for (const callback of followers) {
|
|
411
|
-
const event = callback(key, this);
|
|
412
|
-
if (typeof event == "function")
|
|
413
|
-
waiting.add(event);
|
|
414
|
-
}
|
|
415
|
-
}
|
|
416
|
-
clear() {
|
|
417
|
-
const listeners = [...this.followers];
|
|
418
|
-
this.followers.clear();
|
|
419
|
-
listeners.forEach(x => x(null, this));
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
|
|
423
262
|
const Oops$9 = issues({
|
|
424
263
|
Timeout: (keys, timeout) => `No update for [${keys}] within ${timeout}.`,
|
|
425
264
|
StrictUpdate: () => `Strict update() did not find pending updates.`,
|
|
426
265
|
NoChaining: () => `Then called with undefined; update promise will never catch nor supports chaining.`
|
|
427
266
|
});
|
|
428
|
-
const CONTROL = Symbol("CONTROL");
|
|
429
267
|
const WHY = Symbol("UPDATE");
|
|
430
268
|
const LOCAL = Symbol("LOCAL");
|
|
431
269
|
const STATE = Symbol("STATE");
|
|
432
270
|
class Model {
|
|
433
271
|
constructor() {
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
272
|
+
defineProperty(this, CONTROL, {
|
|
273
|
+
value: new Controller(this)
|
|
274
|
+
});
|
|
275
|
+
defineProperty(this, "is", {
|
|
276
|
+
value: this
|
|
277
|
+
});
|
|
278
|
+
defineProperty(this, "set", {
|
|
279
|
+
configurable: true,
|
|
280
|
+
get: () => {
|
|
281
|
+
const controller = ensure(this);
|
|
282
|
+
const value = (key, value) => {
|
|
283
|
+
controller.state.set(key, value);
|
|
284
|
+
controller.update(key);
|
|
285
|
+
};
|
|
286
|
+
for (const key of controller.state.keys())
|
|
287
|
+
defineProperty(value, key, {
|
|
288
|
+
value: controller.ref(key)
|
|
289
|
+
});
|
|
290
|
+
defineProperty(this, "set", { value });
|
|
291
|
+
return value;
|
|
292
|
+
}
|
|
446
293
|
});
|
|
447
294
|
}
|
|
448
295
|
get [STATE]() {
|
|
@@ -628,6 +475,127 @@ class Model {
|
|
|
628
475
|
}
|
|
629
476
|
}
|
|
630
477
|
|
|
478
|
+
const UPDATE = new WeakMap();
|
|
479
|
+
const CONTROL = Symbol("CONTROL");
|
|
480
|
+
function getUpdate(subject) {
|
|
481
|
+
return UPDATE.get(subject);
|
|
482
|
+
}
|
|
483
|
+
class Controller {
|
|
484
|
+
constructor(subject) {
|
|
485
|
+
this.subject = subject;
|
|
486
|
+
this.frame = new Set();
|
|
487
|
+
this.waiting = new Set();
|
|
488
|
+
this.followers = new Set();
|
|
489
|
+
}
|
|
490
|
+
subscribe(callback) {
|
|
491
|
+
return new Subscriber(this, callback);
|
|
492
|
+
}
|
|
493
|
+
add(key) {
|
|
494
|
+
const { subject, state } = this;
|
|
495
|
+
const { value } = getOwnPropertyDescriptor(subject, key);
|
|
496
|
+
if (typeof value == "function")
|
|
497
|
+
return;
|
|
498
|
+
if (typeof value == "symbol") {
|
|
499
|
+
const instruction = PENDING.get(value);
|
|
500
|
+
if (instruction)
|
|
501
|
+
instruction.call(this, key, this);
|
|
502
|
+
return;
|
|
503
|
+
}
|
|
504
|
+
state.set(key, value);
|
|
505
|
+
defineProperty(subject, key, {
|
|
506
|
+
enumerable: false,
|
|
507
|
+
set: this.ref(key),
|
|
508
|
+
get() {
|
|
509
|
+
const local = this[LOCAL];
|
|
510
|
+
if (local)
|
|
511
|
+
local.add(key);
|
|
512
|
+
return state.get(key);
|
|
513
|
+
}
|
|
514
|
+
});
|
|
515
|
+
}
|
|
516
|
+
addListener(listener) {
|
|
517
|
+
this.followers.add(listener);
|
|
518
|
+
return () => {
|
|
519
|
+
this.followers.delete(listener);
|
|
520
|
+
};
|
|
521
|
+
}
|
|
522
|
+
ref(key, handler) {
|
|
523
|
+
const { subject, state } = this;
|
|
524
|
+
return (value) => {
|
|
525
|
+
if (state.get(key) == value)
|
|
526
|
+
return;
|
|
527
|
+
if (handler)
|
|
528
|
+
switch (handler.call(subject, value)) {
|
|
529
|
+
case true:
|
|
530
|
+
this.update(key);
|
|
531
|
+
case false:
|
|
532
|
+
return;
|
|
533
|
+
}
|
|
534
|
+
state.set(key, value);
|
|
535
|
+
this.update(key);
|
|
536
|
+
};
|
|
537
|
+
}
|
|
538
|
+
update(key) {
|
|
539
|
+
const { followers, frame, subject, waiting } = this;
|
|
540
|
+
if (frame.has(key))
|
|
541
|
+
return;
|
|
542
|
+
else if (!frame.size)
|
|
543
|
+
setTimeout(() => {
|
|
544
|
+
flush(this);
|
|
545
|
+
UPDATE.set(subject, Array.from(frame));
|
|
546
|
+
setTimeout(() => {
|
|
547
|
+
UPDATE.delete(subject);
|
|
548
|
+
}, 0);
|
|
549
|
+
frame.clear();
|
|
550
|
+
for (const notify of waiting)
|
|
551
|
+
try {
|
|
552
|
+
waiting.delete(notify);
|
|
553
|
+
notify();
|
|
554
|
+
}
|
|
555
|
+
catch (err) {
|
|
556
|
+
console.error(err);
|
|
557
|
+
}
|
|
558
|
+
}, 0);
|
|
559
|
+
frame.add(key);
|
|
560
|
+
for (const callback of followers) {
|
|
561
|
+
const event = callback(key, this);
|
|
562
|
+
if (typeof event == "function")
|
|
563
|
+
waiting.add(event);
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
clear() {
|
|
567
|
+
const listeners = [...this.followers];
|
|
568
|
+
this.followers.clear();
|
|
569
|
+
listeners.forEach(x => x(null, this));
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
function ensure(subject, cb) {
|
|
573
|
+
let control = subject[CONTROL];
|
|
574
|
+
if (!control)
|
|
575
|
+
defineProperty(subject, CONTROL, {
|
|
576
|
+
value: control =
|
|
577
|
+
new Controller(subject)
|
|
578
|
+
});
|
|
579
|
+
if (!control.state) {
|
|
580
|
+
const { waiting } = control;
|
|
581
|
+
if (cb) {
|
|
582
|
+
let done;
|
|
583
|
+
waiting.add(() => {
|
|
584
|
+
done = cb(control);
|
|
585
|
+
});
|
|
586
|
+
return () => done && done();
|
|
587
|
+
}
|
|
588
|
+
control.state = new Map();
|
|
589
|
+
for (const key in subject)
|
|
590
|
+
control.add(key);
|
|
591
|
+
const callback = Array.from(waiting);
|
|
592
|
+
waiting.clear();
|
|
593
|
+
for (const cb of callback)
|
|
594
|
+
cb();
|
|
595
|
+
}
|
|
596
|
+
return cb ? cb(control) : control;
|
|
597
|
+
}
|
|
598
|
+
|
|
631
599
|
const PENDING = new Map();
|
|
632
600
|
function apply(fn, label) {
|
|
633
601
|
const name = label || fn.name || "pending";
|
|
@@ -646,11 +614,11 @@ function apply(fn, label) {
|
|
|
646
614
|
defineProperty(subject, key, output);
|
|
647
615
|
return false;
|
|
648
616
|
}
|
|
617
|
+
let { get: onGet, set: onSet, suspense } = output;
|
|
618
|
+
if ("value" in output)
|
|
619
|
+
state.set(key, output.value);
|
|
649
620
|
if ("recursive" in output && output.recursive)
|
|
650
|
-
|
|
651
|
-
const desc = output;
|
|
652
|
-
if ("value" in desc)
|
|
653
|
-
state.set(key, desc.value);
|
|
621
|
+
onGet = getRecursive(key, this);
|
|
654
622
|
if ("destroy" in output) {
|
|
655
623
|
const { destroy } = output;
|
|
656
624
|
if (destroy)
|
|
@@ -659,57 +627,84 @@ function apply(fn, label) {
|
|
|
659
627
|
destroy();
|
|
660
628
|
});
|
|
661
629
|
}
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
local
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
630
|
+
defineProperty(subject, key, {
|
|
631
|
+
enumerable: output.enumerable,
|
|
632
|
+
set: onSet !== false
|
|
633
|
+
? this.ref(key, onSet)
|
|
634
|
+
: undefined,
|
|
635
|
+
get() {
|
|
636
|
+
if (!state.has(key) && suspense)
|
|
637
|
+
throw suspend(control, key);
|
|
638
|
+
const local = this[LOCAL];
|
|
639
|
+
if (local)
|
|
640
|
+
local.add(key);
|
|
641
|
+
return onGet
|
|
642
|
+
? onGet(local)
|
|
643
|
+
: state.get(key);
|
|
644
|
+
}
|
|
645
|
+
});
|
|
677
646
|
}
|
|
678
647
|
PENDING.set(placeholder, setup);
|
|
679
648
|
return placeholder;
|
|
680
649
|
}
|
|
681
650
|
function getRecursive(key, from) {
|
|
682
651
|
const context = new WeakMap();
|
|
683
|
-
const { state } = from;
|
|
684
652
|
return (local) => {
|
|
685
653
|
if (!local)
|
|
686
|
-
return state.get(key);
|
|
654
|
+
return from.state.get(key);
|
|
687
655
|
if (!context.has(local)) {
|
|
688
|
-
let
|
|
656
|
+
let reset;
|
|
689
657
|
const init = () => {
|
|
690
|
-
if (
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
context.set(local, undefined);
|
|
694
|
-
child = undefined;
|
|
695
|
-
}
|
|
696
|
-
const value = state.get(key);
|
|
658
|
+
if (reset)
|
|
659
|
+
reset();
|
|
660
|
+
const value = from.state.get(key);
|
|
697
661
|
if (value && CONTROL in value) {
|
|
698
|
-
child = ensure(value).subscribe(local.onUpdate);
|
|
662
|
+
const child = ensure(value).subscribe(local.onUpdate);
|
|
699
663
|
if (local.active)
|
|
700
664
|
child.commit();
|
|
701
665
|
local.dependant.add(child);
|
|
702
666
|
context.set(local, child.proxy);
|
|
667
|
+
reset = () => {
|
|
668
|
+
child.release();
|
|
669
|
+
local.dependant.delete(child);
|
|
670
|
+
context.set(local, undefined);
|
|
671
|
+
reset = undefined;
|
|
672
|
+
};
|
|
703
673
|
}
|
|
704
674
|
return true;
|
|
705
675
|
};
|
|
706
|
-
init();
|
|
707
676
|
local.add(key, init);
|
|
677
|
+
init();
|
|
708
678
|
}
|
|
709
679
|
return context.get(local);
|
|
710
680
|
};
|
|
711
681
|
}
|
|
712
682
|
|
|
683
|
+
/*! *****************************************************************************
|
|
684
|
+
Copyright (c) Microsoft Corporation.
|
|
685
|
+
|
|
686
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
687
|
+
purpose with or without fee is hereby granted.
|
|
688
|
+
|
|
689
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
690
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
691
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
692
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
693
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
694
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
695
|
+
PERFORMANCE OF THIS SOFTWARE.
|
|
696
|
+
***************************************************************************** */
|
|
697
|
+
|
|
698
|
+
function __awaiter(thisArg, _arguments, P, generator) {
|
|
699
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
700
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
701
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
702
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
703
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
704
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
705
|
+
});
|
|
706
|
+
}
|
|
707
|
+
|
|
713
708
|
const Oops$8 = issues({
|
|
714
709
|
DuplicatePending: (key) => `Invoked action ${key} but one is already active.`
|
|
715
710
|
});
|
|
@@ -740,74 +735,6 @@ function act(task) {
|
|
|
740
735
|
});
|
|
741
736
|
}
|
|
742
737
|
|
|
743
|
-
class Managed extends Array {
|
|
744
|
-
constructor(onUpdate) {
|
|
745
|
-
super();
|
|
746
|
-
this.lastUpdate = [0, 0];
|
|
747
|
-
this.update = (from, to) => {
|
|
748
|
-
this.lastUpdate = [from, to];
|
|
749
|
-
onUpdate();
|
|
750
|
-
};
|
|
751
|
-
}
|
|
752
|
-
push(...items) {
|
|
753
|
-
const { length } = this;
|
|
754
|
-
const end = super.push(...items);
|
|
755
|
-
this.update(length, end);
|
|
756
|
-
return end;
|
|
757
|
-
}
|
|
758
|
-
unshift(...items) {
|
|
759
|
-
const end = super.push(...items);
|
|
760
|
-
this.update(0, end);
|
|
761
|
-
return end;
|
|
762
|
-
}
|
|
763
|
-
splice(start, deleteCount, ...rest) {
|
|
764
|
-
const end = deleteCount !== rest.length ? Infinity : deleteCount;
|
|
765
|
-
this.update(start, end);
|
|
766
|
-
return super.splice(start, deleteCount, ...rest);
|
|
767
|
-
}
|
|
768
|
-
}
|
|
769
|
-
function array() {
|
|
770
|
-
return apply(function array(key) {
|
|
771
|
-
const context = new WeakMap();
|
|
772
|
-
const array = new Managed(() => this.update(key));
|
|
773
|
-
const getLocal = (context) => {
|
|
774
|
-
const proxy = Object.create(array);
|
|
775
|
-
let rangeA = 0;
|
|
776
|
-
let rangeB = 0;
|
|
777
|
-
const onUpdate = () => {
|
|
778
|
-
const [lastA, lastB] = array.lastUpdate;
|
|
779
|
-
if (rangeA <= lastB && rangeB >= lastA)
|
|
780
|
-
return true;
|
|
781
|
-
};
|
|
782
|
-
const listen = (eventA, eventB) => {
|
|
783
|
-
if (context.active)
|
|
784
|
-
return;
|
|
785
|
-
context.add(key, onUpdate);
|
|
786
|
-
rangeA = Math.min(rangeA, eventA);
|
|
787
|
-
rangeB = Math.max(rangeB, eventB);
|
|
788
|
-
};
|
|
789
|
-
proxy[Symbol.iterator] = () => {
|
|
790
|
-
listen(0, Infinity);
|
|
791
|
-
return array[Symbol.iterator]();
|
|
792
|
-
};
|
|
793
|
-
return proxy;
|
|
794
|
-
};
|
|
795
|
-
return {
|
|
796
|
-
value: array,
|
|
797
|
-
set: false,
|
|
798
|
-
get: (local) => {
|
|
799
|
-
if (!local)
|
|
800
|
-
return this.state.get(key);
|
|
801
|
-
if (context.has(local))
|
|
802
|
-
return context.get(local);
|
|
803
|
-
const output = getLocal(local);
|
|
804
|
-
context.set(local, output);
|
|
805
|
-
return output;
|
|
806
|
-
}
|
|
807
|
-
};
|
|
808
|
-
});
|
|
809
|
-
}
|
|
810
|
-
|
|
811
738
|
function ref(callback) {
|
|
812
739
|
return apply(function ref(key) {
|
|
813
740
|
const value = this.ref(key, callback && createValueEffect(callback));
|
|
@@ -830,9 +757,8 @@ const Oops$7 = issues({
|
|
|
830
757
|
function put(factory, argument) {
|
|
831
758
|
return apply(function set(key) {
|
|
832
759
|
const { subject, state } = this;
|
|
833
|
-
const required = argument === true ||
|
|
834
|
-
|
|
835
|
-
let get;
|
|
760
|
+
const required = argument === true ||
|
|
761
|
+
argument === undefined;
|
|
836
762
|
let pending;
|
|
837
763
|
let error;
|
|
838
764
|
const init = () => {
|
|
@@ -855,6 +781,14 @@ function put(factory, argument) {
|
|
|
855
781
|
state.set(key, output);
|
|
856
782
|
return output;
|
|
857
783
|
};
|
|
784
|
+
if (required)
|
|
785
|
+
try {
|
|
786
|
+
init();
|
|
787
|
+
}
|
|
788
|
+
catch (err) {
|
|
789
|
+
Oops$7.Failed(subject, key).warn();
|
|
790
|
+
throw err;
|
|
791
|
+
}
|
|
858
792
|
const suspend = () => {
|
|
859
793
|
if (required === false)
|
|
860
794
|
return undefined;
|
|
@@ -865,30 +799,21 @@ function put(factory, argument) {
|
|
|
865
799
|
});
|
|
866
800
|
throw pending;
|
|
867
801
|
};
|
|
868
|
-
|
|
869
|
-
try {
|
|
870
|
-
init();
|
|
871
|
-
}
|
|
872
|
-
catch (err) {
|
|
873
|
-
Oops$7.Failed(subject, key).warn();
|
|
874
|
-
throw err;
|
|
875
|
-
}
|
|
876
|
-
get = () => {
|
|
802
|
+
const get = () => {
|
|
877
803
|
if (pending)
|
|
878
804
|
return suspend();
|
|
879
805
|
if (error)
|
|
880
806
|
throw error;
|
|
881
807
|
if (state.has(key))
|
|
882
808
|
return state.get(key);
|
|
883
|
-
|
|
809
|
+
const output = init();
|
|
884
810
|
return pending
|
|
885
811
|
? suspend()
|
|
886
812
|
: output;
|
|
887
813
|
};
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
set = (value) => {
|
|
814
|
+
const set = typeof argument == "function"
|
|
815
|
+
? createValueEffect(argument)
|
|
816
|
+
: (value) => {
|
|
892
817
|
if (value === undefined && required)
|
|
893
818
|
throw Oops$7.NonOptional(subject, key);
|
|
894
819
|
};
|
|
@@ -916,257 +841,162 @@ function set(value, argument) {
|
|
|
916
841
|
});
|
|
917
842
|
}
|
|
918
843
|
|
|
919
|
-
const
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
Unexpected: (expects, child, got) => `New ${child} created as child of ${got}, but must be instanceof ${expects}.`,
|
|
923
|
-
});
|
|
924
|
-
function parent(Expects, required) {
|
|
925
|
-
return apply(function parent() {
|
|
926
|
-
const child = this.subject;
|
|
927
|
-
const value = Parent.get(child);
|
|
928
|
-
const expected = Expects.name;
|
|
929
|
-
if (!value) {
|
|
930
|
-
if (required !== false)
|
|
931
|
-
throw Oops$6.Required(expected, child);
|
|
932
|
-
}
|
|
933
|
-
else if (!(value instanceof Expects))
|
|
934
|
-
throw Oops$6.Unexpected(expected, child, value);
|
|
935
|
-
return { value };
|
|
936
|
-
});
|
|
937
|
-
}
|
|
938
|
-
|
|
939
|
-
const ANY$1 = Symbol("any");
|
|
940
|
-
function managedMap(control, property, initial) {
|
|
941
|
-
const managed = new ManagedMap(initial, emit);
|
|
942
|
-
const context = new WeakMap();
|
|
943
|
-
const observers = new Set();
|
|
844
|
+
const ANY = Symbol("any");
|
|
845
|
+
function keyed(control, property, initial) {
|
|
846
|
+
const init = createProxy(emit, watch);
|
|
944
847
|
const frozen = new Set();
|
|
945
|
-
|
|
946
|
-
|
|
848
|
+
const context = new Map();
|
|
849
|
+
const users = new Map();
|
|
850
|
+
const watched = new WeakMap();
|
|
851
|
+
const update = new Set();
|
|
852
|
+
let managed = init(initial);
|
|
853
|
+
function watch(on, key) {
|
|
854
|
+
const include = watched.get(on);
|
|
855
|
+
if (include)
|
|
856
|
+
include.add(key);
|
|
947
857
|
}
|
|
948
858
|
function emit(key) {
|
|
949
|
-
observers.forEach(notify => notify(key));
|
|
950
859
|
control.update(property);
|
|
951
|
-
control.waiting.add(
|
|
860
|
+
control.waiting.add(() => frozen.clear());
|
|
861
|
+
update.forEach(notify => notify(key));
|
|
952
862
|
}
|
|
953
|
-
function
|
|
863
|
+
function subscribe(local) {
|
|
954
864
|
const proxy = create(managed);
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
refresh();
|
|
865
|
+
let watch = users.get(local);
|
|
866
|
+
if (!watch) {
|
|
867
|
+
const using = watch = new Set();
|
|
868
|
+
users.set(local, using);
|
|
869
|
+
function onEvent(key) {
|
|
870
|
+
if (frozen.has(local))
|
|
871
|
+
return;
|
|
872
|
+
if (key === ANY || using.has(key) || using.has(ANY)) {
|
|
873
|
+
const refresh = local.onUpdate(property, control);
|
|
874
|
+
if (refresh) {
|
|
875
|
+
frozen.add(local);
|
|
876
|
+
refresh();
|
|
877
|
+
}
|
|
964
878
|
}
|
|
965
879
|
}
|
|
966
|
-
|
|
967
|
-
|
|
880
|
+
local.add(property, false);
|
|
881
|
+
local.dependant.add({
|
|
882
|
+
commit() {
|
|
883
|
+
if (using.size === 0)
|
|
884
|
+
using.add(ANY);
|
|
885
|
+
update.add(onEvent);
|
|
886
|
+
},
|
|
887
|
+
release() {
|
|
888
|
+
update.delete(onEvent);
|
|
889
|
+
}
|
|
890
|
+
});
|
|
891
|
+
}
|
|
892
|
+
watched.set(proxy, watch);
|
|
968
893
|
context.set(local, proxy);
|
|
969
|
-
proxy.watch = (key) => {
|
|
970
|
-
if (!local.active)
|
|
971
|
-
using.add(key);
|
|
972
|
-
};
|
|
973
894
|
return proxy;
|
|
974
895
|
}
|
|
975
896
|
return {
|
|
976
897
|
value: initial,
|
|
977
898
|
get(local) {
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
return context.get(local);
|
|
982
|
-
return init(local);
|
|
899
|
+
return local ?
|
|
900
|
+
context.get(local) || subscribe(local) :
|
|
901
|
+
managed;
|
|
983
902
|
},
|
|
984
903
|
set(next) {
|
|
985
|
-
managed.source = next;
|
|
986
904
|
control.state.set(property, next);
|
|
987
|
-
|
|
905
|
+
managed = init(next);
|
|
906
|
+
context.clear();
|
|
907
|
+
emit(ANY);
|
|
988
908
|
},
|
|
989
909
|
destroy() {
|
|
990
|
-
|
|
910
|
+
update.clear();
|
|
911
|
+
context.clear();
|
|
991
912
|
}
|
|
992
913
|
};
|
|
993
914
|
}
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
const frozen = new Set();
|
|
1055
|
-
function reset() {
|
|
1056
|
-
frozen.clear();
|
|
1057
|
-
}
|
|
1058
|
-
function emit(key) {
|
|
1059
|
-
observers.forEach(notify => notify(key));
|
|
1060
|
-
control.update(property);
|
|
1061
|
-
control.waiting.add(reset);
|
|
1062
|
-
}
|
|
1063
|
-
function init(local) {
|
|
1064
|
-
const proxy = create(managed);
|
|
1065
|
-
const using = new Set();
|
|
1066
|
-
observers.add(key => {
|
|
1067
|
-
if (frozen.has(local))
|
|
1068
|
-
return;
|
|
1069
|
-
if (using.has(key) || using.has(ANY) || key === ANY && using.size) {
|
|
1070
|
-
const refresh = local.onUpdate(property, control);
|
|
1071
|
-
if (refresh) {
|
|
1072
|
-
frozen.add(local);
|
|
1073
|
-
refresh();
|
|
915
|
+
function createProxy(emit, watch) {
|
|
916
|
+
return (from) => {
|
|
917
|
+
const proxy = create(from);
|
|
918
|
+
assign(proxy, {
|
|
919
|
+
from,
|
|
920
|
+
delete(key) {
|
|
921
|
+
emit(key);
|
|
922
|
+
return from.delete(key);
|
|
923
|
+
},
|
|
924
|
+
clear() {
|
|
925
|
+
emit(ANY);
|
|
926
|
+
from.clear();
|
|
927
|
+
},
|
|
928
|
+
has(key) {
|
|
929
|
+
watch(this, key);
|
|
930
|
+
return from.has(key);
|
|
931
|
+
},
|
|
932
|
+
keys() {
|
|
933
|
+
watch(this, ANY);
|
|
934
|
+
return from.keys();
|
|
935
|
+
},
|
|
936
|
+
values() {
|
|
937
|
+
watch(this, ANY);
|
|
938
|
+
return from.values();
|
|
939
|
+
},
|
|
940
|
+
entries() {
|
|
941
|
+
watch(this, ANY);
|
|
942
|
+
return from.entries();
|
|
943
|
+
},
|
|
944
|
+
forEach(callbackfn, thisArg) {
|
|
945
|
+
const acc = [];
|
|
946
|
+
from.forEach((a, b, c) => {
|
|
947
|
+
const result = callbackfn.call(thisArg, a, b, c);
|
|
948
|
+
if (result !== undefined)
|
|
949
|
+
acc.push(result);
|
|
950
|
+
});
|
|
951
|
+
watch(this, ANY);
|
|
952
|
+
return acc;
|
|
953
|
+
},
|
|
954
|
+
[Symbol.iterator]() {
|
|
955
|
+
watch(this, ANY);
|
|
956
|
+
return from[Symbol.iterator]();
|
|
957
|
+
},
|
|
958
|
+
}, from instanceof Set
|
|
959
|
+
? {
|
|
960
|
+
add(key) {
|
|
961
|
+
from.add(key);
|
|
962
|
+
emit(key);
|
|
963
|
+
return this;
|
|
964
|
+
}
|
|
965
|
+
}
|
|
966
|
+
: {
|
|
967
|
+
get(key) {
|
|
968
|
+
watch(this, ANY);
|
|
969
|
+
return from.get(key);
|
|
970
|
+
},
|
|
971
|
+
set(key, value) {
|
|
972
|
+
from.set(key, value);
|
|
973
|
+
emit(key);
|
|
974
|
+
return this;
|
|
1074
975
|
}
|
|
976
|
+
});
|
|
977
|
+
defineProperty(proxy, "size", {
|
|
978
|
+
get() {
|
|
979
|
+
watch(this, ANY);
|
|
980
|
+
return from.size;
|
|
1075
981
|
}
|
|
1076
982
|
});
|
|
1077
|
-
local.add(property, false);
|
|
1078
|
-
context.set(local, proxy);
|
|
1079
|
-
proxy.watch = (key) => {
|
|
1080
|
-
if (!local.active)
|
|
1081
|
-
using.add(key);
|
|
1082
|
-
};
|
|
1083
983
|
return proxy;
|
|
1084
|
-
}
|
|
1085
|
-
return {
|
|
1086
|
-
value: initial,
|
|
1087
|
-
get(local) {
|
|
1088
|
-
if (!local)
|
|
1089
|
-
return managed;
|
|
1090
|
-
if (context.has(local))
|
|
1091
|
-
return context.get(local);
|
|
1092
|
-
return init(local);
|
|
1093
|
-
},
|
|
1094
|
-
set(next) {
|
|
1095
|
-
managed.source = next;
|
|
1096
|
-
control.state.set(property, next);
|
|
1097
|
-
emit(ANY);
|
|
1098
|
-
},
|
|
1099
|
-
destroy() {
|
|
1100
|
-
observers.clear();
|
|
1101
|
-
}
|
|
1102
984
|
};
|
|
1103
|
-
}
|
|
1104
|
-
class ManagedSet {
|
|
1105
|
-
constructor(source, emit) {
|
|
1106
|
-
this.source = source;
|
|
1107
|
-
this.emit = emit;
|
|
1108
|
-
}
|
|
1109
|
-
watch(_key) { }
|
|
1110
|
-
add(key) {
|
|
1111
|
-
this.source.add(key);
|
|
1112
|
-
this.emit(key);
|
|
1113
|
-
return this;
|
|
1114
|
-
}
|
|
1115
|
-
;
|
|
1116
|
-
delete(key) {
|
|
1117
|
-
this.emit(key);
|
|
1118
|
-
return this.source.delete(key);
|
|
1119
|
-
}
|
|
1120
|
-
;
|
|
1121
|
-
clear() {
|
|
1122
|
-
this.emit(ANY);
|
|
1123
|
-
this.source.clear();
|
|
1124
|
-
}
|
|
1125
|
-
has(key) {
|
|
1126
|
-
this.watch(key);
|
|
1127
|
-
return this.source.has(key);
|
|
1128
|
-
}
|
|
1129
|
-
;
|
|
1130
|
-
values() {
|
|
1131
|
-
this.watch(ANY);
|
|
1132
|
-
return this.source.values();
|
|
1133
|
-
}
|
|
1134
|
-
keys() {
|
|
1135
|
-
this.watch(ANY);
|
|
1136
|
-
return this.source.keys();
|
|
1137
|
-
}
|
|
1138
|
-
entries() {
|
|
1139
|
-
this.watch(ANY);
|
|
1140
|
-
return this.source.entries();
|
|
1141
|
-
}
|
|
1142
|
-
;
|
|
1143
|
-
[Symbol.iterator]() {
|
|
1144
|
-
this.watch(ANY);
|
|
1145
|
-
return this.source[Symbol.iterator]();
|
|
1146
|
-
}
|
|
1147
|
-
;
|
|
1148
|
-
get size() {
|
|
1149
|
-
this.watch(ANY);
|
|
1150
|
-
return this.source.size;
|
|
1151
|
-
}
|
|
1152
985
|
}
|
|
1153
986
|
|
|
1154
|
-
const
|
|
987
|
+
const Parent = new WeakMap();
|
|
988
|
+
const Oops$6 = issues({
|
|
1155
989
|
BadArgument: (type) => `Instruction \`use\` cannot accept argument type of ${type}.`,
|
|
1156
990
|
});
|
|
1157
991
|
function use$1(input, argument) {
|
|
1158
992
|
return apply(function use(key) {
|
|
1159
993
|
const { state, subject } = this;
|
|
1160
994
|
if (typeof input === "function")
|
|
1161
|
-
input =
|
|
1162
|
-
? new input()
|
|
1163
|
-
: input();
|
|
995
|
+
input = "prototype" in input ? new input() : input();
|
|
1164
996
|
else if (input && typeof input !== "object")
|
|
1165
|
-
throw Oops$
|
|
1166
|
-
if (input instanceof Map)
|
|
1167
|
-
return
|
|
1168
|
-
if (input instanceof Set)
|
|
1169
|
-
return managedSet(this, key, input);
|
|
997
|
+
throw Oops$6.BadArgument(typeof input);
|
|
998
|
+
if (input instanceof Map || input instanceof Set)
|
|
999
|
+
return keyed(this, key, input);
|
|
1170
1000
|
function onUpdate(next) {
|
|
1171
1001
|
state.set(key, next);
|
|
1172
1002
|
if (next) {
|
|
@@ -1186,6 +1016,25 @@ function use$1(input, argument) {
|
|
|
1186
1016
|
});
|
|
1187
1017
|
}
|
|
1188
1018
|
|
|
1019
|
+
const Oops$5 = issues({
|
|
1020
|
+
Required: (expects, child) => `New ${child} created standalone but requires parent of type ${expects}. Did you remember to create via use(${child})?`,
|
|
1021
|
+
Unexpected: (expects, child, got) => `New ${child} created as child of ${got}, but must be instanceof ${expects}.`,
|
|
1022
|
+
});
|
|
1023
|
+
function has(Expects, required) {
|
|
1024
|
+
return apply(function parent() {
|
|
1025
|
+
const child = this.subject;
|
|
1026
|
+
const value = Parent.get(child);
|
|
1027
|
+
const expected = Expects.name;
|
|
1028
|
+
if (!value) {
|
|
1029
|
+
if (required !== false)
|
|
1030
|
+
throw Oops$5.Required(expected, child);
|
|
1031
|
+
}
|
|
1032
|
+
else if (!(value instanceof Expects))
|
|
1033
|
+
throw Oops$5.Unexpected(expected, child, value);
|
|
1034
|
+
return { value };
|
|
1035
|
+
});
|
|
1036
|
+
}
|
|
1037
|
+
|
|
1189
1038
|
class Lookup {
|
|
1190
1039
|
constructor() {
|
|
1191
1040
|
this.table = new Map();
|
|
@@ -1470,12 +1319,12 @@ class MVC extends Model {
|
|
|
1470
1319
|
});
|
|
1471
1320
|
return instance;
|
|
1472
1321
|
}, []);
|
|
1473
|
-
usePeerContext(instance.
|
|
1322
|
+
usePeerContext(instance.is);
|
|
1474
1323
|
return instance;
|
|
1475
1324
|
}
|
|
1476
1325
|
static use(a, b) {
|
|
1477
1326
|
const instance = useModel(this, a, b);
|
|
1478
|
-
usePeerContext(instance.
|
|
1327
|
+
usePeerContext(instance.is);
|
|
1479
1328
|
return instance;
|
|
1480
1329
|
}
|
|
1481
1330
|
/**
|
|
@@ -1609,5 +1458,5 @@ class Global extends MVC {
|
|
|
1609
1458
|
}
|
|
1610
1459
|
}
|
|
1611
1460
|
|
|
1612
|
-
export { CONTROL, Consumer, Global, LOCAL, MVC as Model, Provider, STATE, WHY, act, apply,
|
|
1461
|
+
export { CONTROL, Consumer, Global, LOCAL, MVC as Model, Provider, STATE, WHY, act, apply, MVC as default, get, has, put, ref, set, tap, use$1 as use, useFrom, useLocal, useModel, useTap };
|
|
1613
1462
|
//# sourceMappingURL=index.esm.js.map
|