@expressive/mvc 0.7.2 → 0.8.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.js CHANGED
@@ -26,10 +26,43 @@ function issues(register) {
26
26
  }
27
27
 
28
28
  const Oops$c = issues({
29
+ BadCallback: () => `Callback for effect-callback may only return a function.`
30
+ });
31
+ const { assign, create, defineProperty, entries, getPrototypeOf, getOwnPropertyNames, getOwnPropertyDescriptor, getOwnPropertySymbols, values } = Object;
32
+ function createEffect(callback) {
33
+ let unSet;
34
+ return function (value) {
35
+ if (typeof unSet == "function")
36
+ unSet();
37
+ unSet = callback.call(this, value);
38
+ if (unSet instanceof Promise)
39
+ unSet = undefined;
40
+ if (unSet && typeof unSet !== "function")
41
+ throw Oops$c.BadCallback();
42
+ };
43
+ }
44
+ function createValueEffect(callback) {
45
+ let unSet;
46
+ return function (value) {
47
+ if (typeof unSet == "function")
48
+ unSet(value);
49
+ const out = callback.call(this, value, this);
50
+ if (typeof out == "boolean")
51
+ return out;
52
+ if (!out || out instanceof Promise)
53
+ return;
54
+ if (typeof out == "function")
55
+ unSet = out;
56
+ else
57
+ throw Oops$c.BadCallback();
58
+ };
59
+ }
60
+
61
+ const Oops$b = issues({
29
62
  NotReady: (model, key) => `Value ${model}.${key} value is not yet available.`,
30
63
  });
31
64
  function suspend(source, key) {
32
- const error = Oops$c.NotReady(source.subject, key);
65
+ const error = Oops$b.NotReady(source.subject, key);
33
66
  const promise = new Promise(resolve => {
34
67
  const release = source.addListener(forKey => {
35
68
  if (forKey == key)
@@ -41,7 +74,7 @@ function suspend(source, key) {
41
74
  };
42
75
  });
43
76
  });
44
- return Object.assign(promise, {
77
+ return assign(promise, {
45
78
  toString: () => String(error),
46
79
  name: "Suspense",
47
80
  message: error.message,
@@ -69,7 +102,7 @@ function mayRetry(fn) {
69
102
  return compute();
70
103
  }
71
104
 
72
- const Oops$b = issues({
105
+ const Oops$a = issues({
73
106
  Failed: (parent, property, initial) => `An exception was thrown while ${initial ? "initializing" : "refreshing"} [${parent}.${property}].`
74
107
  });
75
108
  const INFO = new WeakMap();
@@ -86,7 +119,7 @@ function computeMode(self, source, setter, key, required) {
86
119
  return setter.call(sub.proxy, sub.proxy);
87
120
  }
88
121
  catch (err) {
89
- Oops$b.Failed(subject, key, initial).warn();
122
+ Oops$a.Failed(subject, key, initial).warn();
90
123
  throw err;
91
124
  }
92
125
  };
@@ -155,259 +188,20 @@ function flush(control) {
155
188
  KEYS.delete(control);
156
189
  }
157
190
 
158
- const Oops$a = issues({
159
- BadCallback: () => `Callback for effect-callback may only return a function.`
160
- });
161
- const { assign, create, defineProperty, entries, getPrototypeOf, getOwnPropertyNames, getOwnPropertyDescriptor, getOwnPropertySymbols, values } = Object;
162
- function createEffect(callback) {
163
- let unSet;
164
- return function (value) {
165
- if (typeof unSet == "function")
166
- unSet();
167
- unSet = callback.call(this, value);
168
- if (unSet instanceof Promise)
169
- unSet = undefined;
170
- if (unSet && typeof unSet !== "function")
171
- throw Oops$a.BadCallback();
172
- };
173
- }
174
- function createValueEffect(callback) {
175
- let unSet;
176
- return function (value) {
177
- if (typeof unSet == "function")
178
- unSet(value);
179
- const out = callback.call(this, value, this);
180
- if (typeof out == "boolean")
181
- return out;
182
- if (!out || out instanceof Promise)
183
- return;
184
- if (typeof out == "function")
185
- unSet = out;
186
- else
187
- throw Oops$a.BadCallback();
188
- };
189
- }
190
-
191
- const Oops$9 = issues({
192
- Timeout: (keys, timeout) => `No update for [${keys}] within ${timeout}.`,
193
- StrictUpdate: () => `Strict update() did not find pending updates.`,
194
- NoChaining: () => `Then called with undefined; update promise will never catch nor supports chaining.`
195
- });
196
- const WHY = Symbol("UPDATE");
197
- const LOCAL = Symbol("LOCAL");
198
- const STATE = Symbol("STATE");
199
- class Model {
200
- constructor() {
201
- defineProperty(this, CONTROL, {
202
- value: new Controller(this)
203
- });
204
- defineProperty(this, "is", {
205
- value: this
206
- });
207
- }
208
- get [STATE]() {
209
- return this.export();
210
- }
211
- get [WHY]() {
212
- return UPDATE.get(this);
213
- }
214
- on(select, handler, squash, once) {
215
- return ensure(this, control => {
216
- if (typeof select == "function")
217
- return control.addListener(select);
218
- const keys = typeof select == "string" ? [select] :
219
- select.length ? select : [...control.state.keys()];
220
- for (const key of keys)
221
- try {
222
- void this[key];
223
- }
224
- catch (e) { }
225
- const callback = squash
226
- ? () => {
227
- handler.call(this, getUpdate(this));
228
- }
229
- : () => {
230
- getUpdate(this)
231
- .filter(k => keys.includes(k))
232
- .forEach(k => {
233
- handler.call(this, control.state.get(k), k);
234
- });
235
- };
236
- const onEvent = once
237
- ? () => {
238
- remove();
239
- callback();
240
- }
241
- : callback;
242
- const remove = control.addListener(key => {
243
- if (keys.includes(key))
244
- return onEvent;
245
- });
246
- return remove;
247
- });
248
- }
249
- once(select, argument, squash) {
250
- if (typeof argument == "function")
251
- return this.on(select, argument, squash, true);
252
- if (typeof select == "string")
253
- select = [select];
254
- return new Promise((resolve, reject) => {
255
- const invoke = (key) => {
256
- if (!key) {
257
- clear();
258
- reject(Oops$9.Timeout(select, typeof argument == "number"
259
- ? `${argument}ms`
260
- : `lifetime of ${this}`));
261
- }
262
- else if (select.includes(key)) {
263
- clear();
264
- return resolve;
265
- }
266
- };
267
- const clear = ensure(this, x => {
268
- for (const key of select)
269
- try {
270
- void this[key];
271
- }
272
- catch (e) { }
273
- return x.addListener(invoke);
274
- });
275
- if (typeof argument == "number")
276
- setTimeout(invoke, argument);
277
- });
278
- }
279
- effect(callback, select) {
280
- const effect = createEffect(callback);
281
- return ensure(this, control => {
282
- let busy = false;
283
- let inject = this.is;
284
- const invoke = () => {
285
- if (busy)
286
- return;
287
- const output = mayRetry(() => {
288
- effect.call(inject, inject);
289
- });
290
- if (output instanceof Promise) {
291
- output.finally(() => busy = false);
292
- busy = true;
293
- }
294
- };
295
- if (!select) {
296
- const sub = control.subscribe(() => invoke);
297
- inject = sub.proxy;
298
- invoke();
299
- return sub.commit();
300
- }
301
- invoke();
302
- return control.addListener(key => {
303
- if (key === null) {
304
- if (!select.length)
305
- invoke();
306
- }
307
- else if (select.includes(key))
308
- return invoke;
309
- });
310
- });
311
- }
312
- // TODO: account for exotic properties
313
- import(source, select) {
314
- const { subject } = ensure(this);
315
- if (!select)
316
- select = getOwnPropertyNames(subject);
317
- for (const key of select)
318
- if (key in source)
319
- this[key] = source[key];
320
- }
321
- export(subset) {
322
- const { state } = ensure(this);
323
- const output = {};
324
- const keys = subset || state.keys();
325
- for (const key of keys)
326
- output[key] = state.get(key);
327
- return output;
328
- }
329
- update(arg, tag) {
330
- const target = ensure(this);
331
- const { frame, waiting } = target;
332
- if (typeof arg == "string") {
333
- target.update(arg);
334
- if (1 in arguments && arg in this) {
335
- const method = this[arg];
336
- if (typeof method == "function")
337
- if (typeof tag != "boolean")
338
- method.call(this, tag);
339
- else if (tag)
340
- method.call(this);
341
- }
342
- arg = undefined;
343
- }
344
- if (!frame.size && arg === true)
345
- return Promise.reject(Oops$9.StrictUpdate());
346
- return {
347
- then: (callback) => {
348
- if (!callback)
349
- throw Oops$9.NoChaining();
350
- if (frame.size || arg !== false)
351
- waiting.add(() => {
352
- callback(getUpdate(this));
353
- });
354
- else
355
- callback(false);
356
- }
357
- };
358
- }
359
- /**
360
- * Mark this instance for garbage-collection and send `willDestroy` event to all listeners.
361
- */
362
- destroy() {
363
- ensure(this).clear();
364
- }
365
- toString() {
366
- return this.constructor.name;
367
- }
368
- /**
369
- * Creates a new instance of this controller.
370
- *
371
- * Beyond `new this(...)`, method will activate managed-state.
372
- *
373
- * @param args - arguments sent to constructor
374
- */
375
- static create(...args) {
376
- const instance = new this(...args);
377
- ensure(instance);
378
- return instance;
379
- }
380
- /**
381
- * Static equivalent of `x instanceof this`.
382
- *
383
- * Will determine if provided class is a subtype of this one.
384
- */
385
- static isTypeof(maybe) {
386
- return (typeof maybe == "function" &&
387
- maybe.prototype instanceof this);
388
- }
389
- }
390
-
191
+ const REGISTER$1 = new WeakMap();
391
192
  class Subscriber {
392
193
  constructor(parent, onUpdate) {
194
+ this.parent = parent;
393
195
  this.onUpdate = onUpdate;
394
196
  this.active = false;
395
197
  this.dependant = new Set();
396
198
  const proxy = create(parent.subject);
397
199
  const using = new Map();
398
- const listen = this.add = (key, value) => {
399
- if (value !== undefined)
400
- using.set(key, value);
401
- else if (!using.has(key))
402
- using.set(key, true);
403
- };
404
- LISTEN.set(proxy, listen);
405
- defineProperty(proxy, LOCAL, { value: this });
200
+ REGISTER$1.set(proxy, this);
406
201
  defineProperty(this, "proxy", {
407
202
  configurable: true,
408
203
  get() {
409
- if (UPDATE.has(proxy))
410
- setTimeout(() => UPDATE.delete(proxy), 0);
204
+ hasUpdate(proxy);
411
205
  return proxy;
412
206
  }
413
207
  });
@@ -425,12 +219,15 @@ class Subscriber {
425
219
  notify = this.onUpdate(key, parent);
426
220
  if (!notify)
427
221
  return;
428
- const notate = () => {
429
- UPDATE.set(proxy, getUpdate(parent.subject).filter(k => using.has(k)));
430
- };
431
- parent.waiting.add(notate);
222
+ parent.waiting.add(() => addUpdate(proxy, using));
432
223
  parent.waiting.add(notify);
433
224
  });
225
+ this.add = (key, value) => {
226
+ if (value !== undefined)
227
+ using.set(key, value);
228
+ else if (!using.has(key))
229
+ using.set(key, true);
230
+ };
434
231
  this.commit = () => {
435
232
  this.active = true;
436
233
  this.dependant.forEach(x => x.commit());
@@ -441,25 +238,42 @@ class Subscriber {
441
238
  release();
442
239
  };
443
240
  }
241
+ static get(from) {
242
+ return REGISTER$1.get(from);
243
+ }
444
244
  }
445
245
 
446
- const UPDATE = new WeakMap();
447
- const LISTEN = new WeakMap();
448
- const CONTROL = Symbol("CONTROL");
246
+ const REGISTER = new WeakMap();
247
+ const UPDATE$1 = new WeakMap();
449
248
  function getUpdate(subject) {
450
- return UPDATE.get(subject);
249
+ return UPDATE$1.get(subject);
250
+ }
251
+ function setUpdate(subject, keys) {
252
+ UPDATE$1.set(subject, Array.from(keys));
253
+ setTimeout(() => UPDATE$1.delete(subject), 0);
254
+ }
255
+ /** Ensure a local update is dropped after use. */
256
+ function hasUpdate(proxy) {
257
+ if (UPDATE$1.has(proxy))
258
+ setTimeout(() => UPDATE$1.delete(proxy), 0);
259
+ }
260
+ /** Set local update for a subscribed context. */
261
+ function addUpdate(proxy, using) {
262
+ const parent = UPDATE$1.get(getPrototypeOf(proxy));
263
+ UPDATE$1.set(proxy, parent.filter(k => using.has(k)));
451
264
  }
452
- class Controller {
265
+ class Control {
453
266
  constructor(subject) {
454
267
  this.subject = subject;
455
268
  this.frame = new Set();
456
269
  this.waiting = new Set();
457
270
  this.followers = new Set();
271
+ REGISTER.set(subject, this);
458
272
  }
459
273
  subscribe(callback) {
460
274
  return new Subscriber(this, callback);
461
275
  }
462
- add(key) {
276
+ watch(key) {
463
277
  const { subject, state } = this;
464
278
  const { value } = getOwnPropertyDescriptor(subject, key);
465
279
  if (typeof value == "function")
@@ -478,9 +292,9 @@ class Controller {
478
292
  enumerable: false,
479
293
  set: this.ref(key),
480
294
  get() {
481
- const listen = LISTEN.get(this);
482
- if (listen)
483
- listen(key);
295
+ const sub = Subscriber.get(this);
296
+ if (sub)
297
+ sub.add(key);
484
298
  return state.get(key);
485
299
  }
486
300
  });
@@ -508,16 +322,13 @@ class Controller {
508
322
  };
509
323
  }
510
324
  update(key) {
511
- const { followers, frame, subject, waiting } = this;
325
+ const { followers, frame, waiting } = this;
512
326
  if (frame.has(key))
513
327
  return;
514
328
  else if (!frame.size)
515
329
  setTimeout(() => {
516
330
  flush(this);
517
- UPDATE.set(subject, Array.from(frame));
518
- setTimeout(() => {
519
- UPDATE.delete(subject);
520
- }, 0);
331
+ setUpdate(this.subject, frame);
521
332
  frame.clear();
522
333
  for (const notify of waiting)
523
334
  try {
@@ -540,36 +351,35 @@ class Controller {
540
351
  this.followers.clear();
541
352
  listeners.forEach(x => x(null, this));
542
353
  }
543
- }
544
- function ensure(subject, cb) {
545
- let control = subject[CONTROL];
546
- if (!control)
547
- defineProperty(subject, CONTROL, {
548
- value: control =
549
- new Controller(subject)
550
- });
551
- if (!control.state) {
552
- const { waiting } = control;
553
- if (cb) {
554
- let done;
555
- waiting.add(() => {
556
- done = cb(control);
557
- });
558
- return () => done && done();
354
+ static get(from) {
355
+ if (from && "is" in from)
356
+ from = from.is;
357
+ return REGISTER.get(from);
358
+ }
359
+ static for(subject, cb) {
360
+ const control = this.get(subject) || new this(subject);
361
+ if (!control.state) {
362
+ const { waiting } = control;
363
+ if (cb) {
364
+ let done;
365
+ waiting.add(() => {
366
+ done = cb(control);
367
+ });
368
+ return () => done && done();
369
+ }
370
+ control.state = new Map();
371
+ for (const key in subject)
372
+ control.watch(key);
373
+ control.waiting = new Set();
374
+ for (const cb of waiting)
375
+ cb();
559
376
  }
560
- control.state = new Map();
561
- for (const key in subject)
562
- control.add(key);
563
- const callback = Array.from(waiting);
564
- waiting.clear();
565
- for (const cb of callback)
566
- cb();
377
+ return cb ? cb(control) : control;
567
378
  }
568
- return cb ? cb(control) : control;
569
379
  }
570
380
 
571
381
  const PENDING = new Map();
572
- function apply(fn, label) {
382
+ function add(fn, label) {
573
383
  const name = label || fn.name || "pending";
574
384
  const placeholder = Symbol(`${name} instruction`);
575
385
  function setup(key) {
@@ -583,7 +393,7 @@ function apply(fn, label) {
583
393
  defineProperty(subject, key, output);
584
394
  return false;
585
395
  }
586
- let { get: onGet, set: onSet, suspense } = output;
396
+ let { get: onGet, set: onSet, suspend: shouldSuspend } = output;
587
397
  if ("value" in output)
588
398
  state.set(key, output.value);
589
399
  if ("recursive" in output && output.recursive)
@@ -603,12 +413,11 @@ function apply(fn, label) {
603
413
  ? this.ref(key, onSet)
604
414
  : undefined,
605
415
  get() {
606
- if (!state.has(key) && suspense)
416
+ if (!state.has(key) && shouldSuspend)
607
417
  throw suspend(control, key);
608
- const listen = LISTEN.get(this);
609
- const local = this[LOCAL];
610
- if (listen)
611
- listen(key);
418
+ const local = Subscriber.get(this);
419
+ if (local)
420
+ local.add(key);
612
421
  return onGet
613
422
  ? onGet(local)
614
423
  : state.get(key);
@@ -629,8 +438,8 @@ function getRecursive(key, from) {
629
438
  if (reset)
630
439
  reset();
631
440
  const value = from.state.get(key);
632
- if (value && CONTROL in value) {
633
- const child = ensure(value).subscribe(local.onUpdate);
441
+ if (Control.get(value)) {
442
+ const child = Control.for(value).subscribe(local.onUpdate);
634
443
  if (local.active)
635
444
  child.commit();
636
445
  local.dependant.add(child);
@@ -676,15 +485,15 @@ function __awaiter(thisArg, _arguments, P, generator) {
676
485
  });
677
486
  }
678
487
 
679
- const Oops$8 = issues({
488
+ const Oops$9 = issues({
680
489
  DuplicatePending: (key) => `Invoked action ${key} but one is already active.`
681
490
  });
682
491
  function act(task) {
683
- return apply(function act(key) {
492
+ return add(function act(key) {
684
493
  let pending = false;
685
494
  const invoke = (...args) => __awaiter(this, void 0, void 0, function* () {
686
495
  if (pending)
687
- return Promise.reject(Oops$8.DuplicatePending(key));
496
+ return Promise.reject(Oops$9.DuplicatePending(key));
688
497
  pending = true;
689
498
  this.update(key);
690
499
  try {
@@ -727,8 +536,8 @@ function factoryMode(self, output, key, required) {
727
536
  const suspend = () => {
728
537
  if (required === false)
729
538
  return undefined;
730
- const issue = Oops$7.NotReady(subject, key);
731
- Object.assign(pending, {
539
+ const issue = Oops$8.NotReady(subject, key);
540
+ assign(pending, {
732
541
  message: issue.message,
733
542
  stack: issue.stack
734
543
  });
@@ -744,7 +553,7 @@ function factoryMode(self, output, key, required) {
744
553
  };
745
554
  }
746
555
 
747
- const Oops$7 = issues({
556
+ const Oops$8 = issues({
748
557
  // BadSource: (model, property, got) =>
749
558
  // `Bad from-instruction provided to ${model}.${property}. Expects an arrow-function or a Model as source. Got ${got}.`,
750
559
  PeerNotAllowed: (model, property) => `Attempted to use an instruction result (probably use or tap) as computed source for ${model}.${property}. This is not possible.`,
@@ -754,14 +563,14 @@ const Oops$7 = issues({
754
563
  Failed: (parent, property, initial) => `An exception was thrown while ${initial ? "initializing" : "refreshing"} [${parent}.${property}].`
755
564
  });
756
565
  function get(arg0, arg1, arg2) {
757
- return apply(function get(key) {
566
+ return add(function get(key) {
758
567
  const { subject } = this;
759
568
  const computeRequired = arg1 === true || arg2 === true;
760
569
  const factoryRequired = arg1 !== false && arg2 !== false;
761
570
  let getter;
762
571
  // Easy mistake, using a peer, will always be unresolved.
763
572
  if (typeof arg0 == "symbol")
764
- throw Oops$7.PeerNotAllowed(subject, key);
573
+ throw Oops$8.PeerNotAllowed(subject, key);
765
574
  // if(typeof arg0 == "function" && /^[A-Z]/.test(arg0.name))
766
575
  // throw Oops.BadSource(subject, key, arg0);
767
576
  this.state.set(key, undefined);
@@ -783,7 +592,7 @@ function get(arg0, arg1, arg2) {
783
592
  }
784
593
  else if (typeof arg1 == "function") {
785
594
  // replace source controller in-case it is different
786
- source = ensure(arg0);
595
+ source = Control.for(arg0);
787
596
  setter = arg1;
788
597
  }
789
598
  else
@@ -795,7 +604,7 @@ function get(arg0, arg1, arg2) {
795
604
  init();
796
605
  }
797
606
  catch (err) {
798
- Oops$7.ComputeFailed(subject, key).warn();
607
+ Oops$8.ComputeFailed(subject, key).warn();
799
608
  throw err;
800
609
  }
801
610
  return () => {
@@ -807,12 +616,12 @@ function get(arg0, arg1, arg2) {
807
616
  }
808
617
 
809
618
  function ref(arg, mapper) {
810
- return apply(function ref(key) {
619
+ return add(function ref(key) {
811
620
  let value = {};
812
621
  if (typeof arg != "object")
813
622
  value = createRef(this, key, arg);
814
623
  else
815
- ensure(arg).state.forEach((_val, key) => {
624
+ Control.for(arg).state.forEach((_val, key) => {
816
625
  defineProperty(value, key, mapper ? {
817
626
  configurable: true,
818
627
  get() {
@@ -841,11 +650,11 @@ function set(value, argument) {
841
650
  argument = value;
842
651
  value = undefined;
843
652
  }
844
- return apply(function set(key) {
653
+ return add(function set(key) {
845
654
  if (value !== undefined)
846
655
  this.state.set(key, value);
847
656
  return {
848
- suspense: true,
657
+ suspend: true,
849
658
  set: typeof argument == "function"
850
659
  ? createValueEffect(argument)
851
660
  : undefined
@@ -1000,12 +809,12 @@ function createProxy(emit, watch) {
1000
809
  }
1001
810
 
1002
811
  const Parent = new WeakMap();
1003
- const Oops$6 = issues({
812
+ const Oops$7 = issues({
1004
813
  BadArgument: (type) => `Instruction \`use\` cannot accept argument type of ${type}.`,
1005
814
  NotReady: (model, key) => `Value ${model}.${key} value is not yet available.`
1006
815
  });
1007
816
  function use$1(input, argument) {
1008
- return apply(function use(key) {
817
+ return add(function use(key) {
1009
818
  const { state, subject } = this;
1010
819
  const required = argument !== false;
1011
820
  let pending;
@@ -1017,7 +826,7 @@ function use$1(input, argument) {
1017
826
  input = new input();
1018
827
  }
1019
828
  else if (input && typeof input !== "object")
1020
- throw Oops$6.BadArgument(typeof input);
829
+ throw Oops$7.BadArgument(typeof input);
1021
830
  if (input instanceof Map || input instanceof Set)
1022
831
  return keyed(this, key, input);
1023
832
  const onUpdate = (next) => {
@@ -1025,7 +834,7 @@ function use$1(input, argument) {
1025
834
  if (next) {
1026
835
  get = getRecursive(key, this);
1027
836
  Parent.set(next, subject);
1028
- ensure(next);
837
+ Control.for(next);
1029
838
  }
1030
839
  if (typeof argument == "function")
1031
840
  argument(next);
@@ -1034,8 +843,8 @@ function use$1(input, argument) {
1034
843
  const suspend = () => {
1035
844
  if (required === false)
1036
845
  return;
1037
- const issue = Oops$6.NotReady(subject, key);
1038
- Object.assign(pending, {
846
+ const issue = Oops$7.NotReady(subject, key);
847
+ assign(pending, {
1039
848
  message: issue.message,
1040
849
  stack: issue.stack
1041
850
  });
@@ -1079,25 +888,204 @@ function use$1(input, argument) {
1079
888
  });
1080
889
  }
1081
890
 
1082
- const Oops$5 = issues({
891
+ const Oops$6 = issues({
1083
892
  Required: (expects, child) => `New ${child} created standalone but requires parent of type ${expects}. Did you remember to create via use(${child})?`,
1084
893
  Unexpected: (expects, child, got) => `New ${child} created as child of ${got}, but must be instanceof ${expects}.`,
1085
894
  });
1086
- function has(Expects, required) {
1087
- return apply(function parent() {
895
+ function has(Type, required) {
896
+ return add(function parent() {
1088
897
  const child = this.subject;
1089
898
  const value = Parent.get(child);
1090
- const expected = Expects.name;
899
+ const expected = Type.name;
1091
900
  if (!value) {
1092
901
  if (required !== false)
1093
- throw Oops$5.Required(expected, child);
902
+ throw Oops$6.Required(expected, child);
1094
903
  }
1095
- else if (!(value instanceof Expects))
1096
- throw Oops$5.Unexpected(expected, child, value);
904
+ else if (!(value instanceof Type))
905
+ throw Oops$6.Unexpected(expected, child, value);
1097
906
  return { value };
1098
907
  });
1099
908
  }
1100
909
 
910
+ const Oops$5 = issues({
911
+ Timeout: (keys, timeout) => `No update for [${keys}] within ${timeout}.`,
912
+ StrictUpdate: () => `Strict update() did not find pending updates.`,
913
+ NoChaining: () => `Then called with undefined; update promise will never catch nor supports chaining.`
914
+ });
915
+ class Model {
916
+ constructor() {
917
+ new Control(this);
918
+ defineProperty(this, "is", { value: this });
919
+ }
920
+ on(select, argument, once) {
921
+ if (typeof select == "function")
922
+ return Control.for(this, x => x.addListener(select));
923
+ const single = typeof select == "string";
924
+ let keys = single ? [select] : select;
925
+ if (typeof argument !== "function")
926
+ return new Promise((resolve, reject) => {
927
+ const removeListener = Control.for(this, control => {
928
+ for (const key of keys)
929
+ try {
930
+ void this[key];
931
+ }
932
+ catch (e) { }
933
+ return control.addListener(key => {
934
+ if (!key) {
935
+ removeListener();
936
+ reject(Oops$5.Timeout(select, `lifetime of ${this}`));
937
+ }
938
+ else if (keys.includes(key)) {
939
+ removeListener();
940
+ return () => resolve(single ? control.state.get(key) : getUpdate(this));
941
+ }
942
+ });
943
+ });
944
+ if (typeof argument == "number")
945
+ setTimeout(() => {
946
+ removeListener();
947
+ reject(Oops$5.Timeout(select, `${argument}ms`));
948
+ }, argument);
949
+ });
950
+ return Control.for(this, control => {
951
+ if (!keys.length)
952
+ keys = [...control.state.keys()];
953
+ for (const key of keys)
954
+ try {
955
+ void this[key];
956
+ }
957
+ catch (e) { }
958
+ const callback = single
959
+ ? () => { argument.call(this, control.state.get(select), select); }
960
+ : () => { argument.call(this, getUpdate(this)); };
961
+ const onEvent = once
962
+ ? () => {
963
+ removeListener();
964
+ callback();
965
+ }
966
+ : callback;
967
+ const removeListener = control.addListener(key => {
968
+ if (keys.includes(key))
969
+ return onEvent;
970
+ });
971
+ return removeListener;
972
+ });
973
+ }
974
+ effect(callback, select) {
975
+ const effect = createEffect(callback);
976
+ return Control.for(this, control => {
977
+ let busy = false;
978
+ let inject = this.is;
979
+ const invoke = () => {
980
+ if (busy)
981
+ return;
982
+ const output = mayRetry(() => {
983
+ effect.call(inject, inject);
984
+ });
985
+ if (output instanceof Promise) {
986
+ output.finally(() => busy = false);
987
+ busy = true;
988
+ }
989
+ };
990
+ if (!select) {
991
+ const sub = control.subscribe(() => invoke);
992
+ inject = sub.proxy;
993
+ invoke();
994
+ return sub.commit();
995
+ }
996
+ invoke();
997
+ return control.addListener(key => {
998
+ if (key === null) {
999
+ if (!select.length)
1000
+ invoke();
1001
+ }
1002
+ else if (select.includes(key))
1003
+ return invoke;
1004
+ });
1005
+ });
1006
+ }
1007
+ export(subset) {
1008
+ const { state } = Control.for(this);
1009
+ const output = {};
1010
+ const keys = subset || state.keys();
1011
+ for (const key of keys)
1012
+ output[key] = state.get(key);
1013
+ return output;
1014
+ }
1015
+ update(arg1, arg2) {
1016
+ const control = Control.for(this);
1017
+ const { frame, state, waiting } = control;
1018
+ if (arg1 === true && !frame.size)
1019
+ return Promise.reject(Oops$5.StrictUpdate());
1020
+ if (typeof arg1 == "object") {
1021
+ for (const key in arg1)
1022
+ if (arg2 === true || (arg2 ? arg2.includes(key) : state.has(key))) {
1023
+ state.set(key, arg1[key]);
1024
+ control.update(key);
1025
+ }
1026
+ }
1027
+ else if (typeof arg1 == "string") {
1028
+ control.update(arg1);
1029
+ if (1 in arguments && arg1 in this) {
1030
+ const method = this[arg1];
1031
+ if (typeof method == "function")
1032
+ if (typeof arg2 != "boolean")
1033
+ method.call(this, arg2);
1034
+ else if (arg2)
1035
+ method.call(this);
1036
+ }
1037
+ arg1 = undefined;
1038
+ }
1039
+ return {
1040
+ then: (callback) => {
1041
+ if (!callback)
1042
+ throw Oops$5.NoChaining();
1043
+ if (frame.size || arg1 !== false)
1044
+ waiting.add(() => {
1045
+ callback(getUpdate(this));
1046
+ });
1047
+ else
1048
+ callback(false);
1049
+ }
1050
+ };
1051
+ }
1052
+ /**
1053
+ * Mark this instance for garbage-collection and send `willDestroy` event to all listeners.
1054
+ */
1055
+ kill() {
1056
+ Control.for(this).clear();
1057
+ }
1058
+ /**
1059
+ * Creates a new instance of this controller.
1060
+ *
1061
+ * Beyond `new this(...)`, method will activate managed-state.
1062
+ *
1063
+ * @param args - arguments sent to constructor
1064
+ */
1065
+ static new(...args) {
1066
+ const instance = new this(...args);
1067
+ Control.for(instance);
1068
+ return instance;
1069
+ }
1070
+ /**
1071
+ * Static equivalent of `x instanceof this`.
1072
+ *
1073
+ * Will determine if provided class is a subtype of this one.
1074
+ */
1075
+ static isTypeof(maybe) {
1076
+ return (typeof maybe == "function" &&
1077
+ maybe.prototype instanceof this);
1078
+ }
1079
+ }
1080
+ defineProperty(Model.prototype, "toString", {
1081
+ value() {
1082
+ return this.constructor.name;
1083
+ }
1084
+ });
1085
+
1086
+ const Oops$4 = issues({
1087
+ NotFound: (name) => `Couldn't find ${name} in context; did you forget to use a Provider?`
1088
+ });
1101
1089
  class Lookup {
1102
1090
  constructor() {
1103
1091
  this.table = new Map();
@@ -1134,20 +1122,19 @@ class Lookup {
1134
1122
  } while (T !== Model);
1135
1123
  }
1136
1124
  pop() {
1125
+ const items = new Set();
1137
1126
  for (const key of getOwnPropertySymbols(this)) {
1138
1127
  const entry = getOwnPropertyDescriptor(this, key);
1139
1128
  if (entry.writable && entry.value)
1140
- entry.value.destroy();
1129
+ items.add(entry.value);
1141
1130
  }
1131
+ for (const model of items)
1132
+ model.kill();
1142
1133
  }
1143
- }
1144
-
1134
+ }
1145
1135
  const LookupContext = React__default["default"].createContext(new Lookup());
1146
1136
  const useLookup = () => React__default["default"].useContext(LookupContext);
1147
- const Oops$4 = issues({
1148
- NotFound: (name) => `Couldn't find ${name} in context; did you forget to use a Provider?`
1149
- });
1150
- function useLocal(Type, arg) {
1137
+ function useContext(Type, arg) {
1151
1138
  const instance = useLookup().get(Type);
1152
1139
  if (!instance && arg !== false)
1153
1140
  throw Oops$4.NotFound(Type.name);
@@ -1155,7 +1142,7 @@ function useLocal(Type, arg) {
1155
1142
  case "string":
1156
1143
  return instance[arg];
1157
1144
  case "function":
1158
- React.useLayoutEffect(() => arg(instance), []);
1145
+ React__default["default"].useLayoutEffect(() => arg(instance), []);
1159
1146
  default:
1160
1147
  return instance;
1161
1148
  }
@@ -1168,7 +1155,7 @@ const Oops$3 = issues({
1168
1155
  const PendingContext = new WeakMap();
1169
1156
  const ContextWasUsed = new WeakMap();
1170
1157
  function tap(type, argument) {
1171
- return apply(function tap(key) {
1158
+ return add(function tap(key) {
1172
1159
  if ("set" in type)
1173
1160
  return {
1174
1161
  recursive: true,
@@ -1190,7 +1177,7 @@ function tap(type, argument) {
1190
1177
  });
1191
1178
  return {
1192
1179
  recursive: true,
1193
- suspense: true
1180
+ suspend: true
1194
1181
  };
1195
1182
  });
1196
1183
  }
@@ -1225,57 +1212,51 @@ function use(init) {
1225
1212
 
1226
1213
  function useModel(source, arg, arg2) {
1227
1214
  const instance = React__default["default"].useMemo(() => {
1228
- const cb = arg2 || arg;
1229
- const instance = typeof source == "function" ?
1230
- source.prototype instanceof Model ?
1231
- new source() :
1232
- source() :
1233
- source;
1234
- ensure(instance);
1235
- if (typeof cb == "function")
1236
- cb(instance);
1215
+ const callback = arg2 || arg;
1216
+ const instance = Model.isTypeof(source) ?
1217
+ source.new() :
1218
+ source();
1219
+ Control.for(instance);
1220
+ if (typeof callback == "function")
1221
+ callback(instance);
1237
1222
  return instance;
1238
1223
  }, []);
1224
+ usePeerContext(instance);
1239
1225
  if (Array.isArray(arg)) {
1240
1226
  const update = React.useState(0)[1];
1241
1227
  React__default["default"].useLayoutEffect(() => {
1242
1228
  if (arg.length && instance instanceof Model)
1243
- instance.on(arg, () => update(x => x + 1), true);
1229
+ instance.on(arg, () => update(x => x + 1));
1244
1230
  return () => {
1245
1231
  if (Model.isTypeof(source))
1246
- instance.destroy();
1232
+ instance.kill();
1247
1233
  };
1248
1234
  }, []);
1249
1235
  return instance;
1250
1236
  }
1251
- else {
1252
- const local = use(refresh => (ensure(instance).subscribe(() => refresh)));
1253
- if (typeof arg == "object") {
1254
- local.active = false;
1255
- if (typeof arg2 !== "object")
1256
- arg2 = getOwnPropertyNames(instance);
1257
- for (const key of arg2)
1258
- if (key in arg)
1259
- instance[key] = arg[key];
1260
- React__default["default"].useLayoutEffect(() => {
1261
- local.active = true;
1262
- });
1263
- }
1264
- React__default["default"].useLayoutEffect(() => {
1265
- local.commit();
1266
- return () => {
1267
- local.release();
1268
- if (Model.isTypeof(source))
1269
- instance.destroy();
1270
- };
1271
- }, []);
1272
- return local.proxy;
1237
+ const local = use(refresh => (Control.for(instance).subscribe(() => refresh)));
1238
+ if (typeof arg == "object") {
1239
+ local.active = false;
1240
+ if (typeof arg2 !== "object")
1241
+ arg2 = getOwnPropertyNames(instance);
1242
+ for (const key of arg2)
1243
+ if (key in arg)
1244
+ instance[key] = arg[key];
1273
1245
  }
1246
+ React__default["default"].useLayoutEffect(() => {
1247
+ local.commit();
1248
+ return () => {
1249
+ local.release();
1250
+ if (Model.isTypeof(source))
1251
+ instance.kill();
1252
+ };
1253
+ }, []);
1254
+ return local.proxy;
1274
1255
  }
1275
1256
 
1276
1257
  function useFrom(target, compute, suspend) {
1277
1258
  const local = use(refresh => {
1278
- const sub = ensure(target).subscribe(() => update);
1259
+ const sub = Control.for(target).subscribe(() => update);
1279
1260
  const spy = sub.proxy;
1280
1261
  let value = compute.call(spy, spy);
1281
1262
  let update;
@@ -1314,84 +1295,79 @@ function useFrom(target, compute, suspend) {
1314
1295
  return local.proxy;
1315
1296
  }
1316
1297
 
1317
- function useTap(source, path, expect) {
1298
+ function useTap(source, arg1, arg2) {
1318
1299
  const instance = React.useMemo(() => {
1319
1300
  if (typeof source == "object")
1320
1301
  return () => source;
1321
- if ("get" in source)
1322
- return () => source.get();
1323
- if ("prototype" in source)
1324
- return () => useLocal(source);
1325
- else
1326
- return source;
1302
+ if (MVC.isTypeof(source))
1303
+ return () => source.get(true);
1304
+ if (Model.isTypeof(source))
1305
+ return () => useContext(source);
1306
+ return source;
1327
1307
  }, [])();
1328
- if (typeof path == "function")
1329
- return useFrom(instance, path, expect);
1330
- const local = use(refresh => (ensure(instance).subscribe(() => refresh)));
1308
+ if (typeof arg1 == "function")
1309
+ return useFrom(instance, arg1, arg2);
1310
+ const local = use(refresh => (Control.for(instance).subscribe(() => refresh)));
1331
1311
  React__default["default"].useLayoutEffect(local.commit, []);
1332
- if (typeof path !== "undefined") {
1333
- const value = local.proxy[path];
1334
- if (value === undefined && expect)
1335
- throw suspend(ensure(instance), path);
1336
- return value;
1337
- }
1338
- return local.proxy;
1312
+ if (arg1 === undefined)
1313
+ return local.proxy;
1314
+ const value = local.proxy[arg1];
1315
+ if (value === undefined && arg2)
1316
+ throw suspend(local.parent, arg1);
1317
+ return value;
1339
1318
  }
1340
1319
 
1341
- /* istanbul ignore file */
1342
1320
  class MVC extends Model {
1343
- tap(path, expect) {
1344
- return useTap(this, path, expect);
1345
- }
1346
- use(arg, callback) {
1347
- return useModel(this, arg, callback);
1348
- }
1349
1321
  static get(arg) {
1350
- return useLocal(this, arg);
1322
+ return useContext(this, arg);
1351
1323
  }
1352
1324
  static tap(key, expect) {
1353
1325
  return useTap(this, key, expect);
1354
1326
  }
1355
- static new(arg) {
1356
- const instance = React__default["default"].useMemo(() => {
1357
- const instance = new this();
1358
- ensure(instance);
1359
- if (typeof arg == "function")
1360
- arg(instance);
1361
- else if (arg)
1362
- getOwnPropertyNames(instance).forEach(key => {
1363
- if (key in arg)
1364
- instance[key] = arg[key];
1365
- });
1366
- return instance;
1367
- }, []);
1368
- usePeerContext(instance.is);
1369
- return instance;
1370
- }
1371
1327
  static use(a, b) {
1372
- const instance = useModel(this, a, b);
1373
- usePeerContext(instance.is);
1374
- return instance;
1375
- }
1376
- /**
1377
- * @deprecated consider doing this manually - not worth minor efficiency gain over using.
1378
- */
1379
- static uses(apply, keys) {
1380
- return this.use(instance => {
1381
- instance.import(apply, keys);
1382
- });
1383
- }
1384
- /**
1385
- * @deprecated is now replaced by overload of `use` method.
1386
- */
1387
- static using(apply, keys) {
1388
- return this.use(apply, keys);
1328
+ return useModel(this, a, b);
1389
1329
  }
1390
1330
  static meta(path, expect) {
1391
1331
  return useTap(() => this, path, expect);
1392
1332
  }
1393
1333
  }
1394
1334
 
1335
+ const LOCAL = Symbol("LOCAL");
1336
+ const STATE = Symbol("STATE");
1337
+ const UPDATE = Symbol("UPDATE");
1338
+ const CONTROL = Symbol("CONTROL");
1339
+ Object.defineProperties(Model.prototype, {
1340
+ [CONTROL]: {
1341
+ get() {
1342
+ return Control.get(this);
1343
+ }
1344
+ },
1345
+ [LOCAL]: {
1346
+ get() {
1347
+ return Subscriber.get(this);
1348
+ }
1349
+ },
1350
+ [STATE]: {
1351
+ get() {
1352
+ const { state } = Control.get(this);
1353
+ const output = {};
1354
+ state.forEach((value, key) => output[key] = value);
1355
+ return output;
1356
+ }
1357
+ },
1358
+ [UPDATE]: {
1359
+ get() {
1360
+ return getUpdate(this);
1361
+ }
1362
+ }
1363
+ });
1364
+ const Debug = {
1365
+ CONTROL,
1366
+ LOCAL,
1367
+ STATE,
1368
+ UPDATE
1369
+ };
1370
+
1395
1371
  const Oops$2 = issues({
1396
1372
  BadProps: () => `Provider expects either a render function, 'get' or 'has' props.`
1397
1373
  });
@@ -1401,66 +1377,66 @@ function Consumer(props) {
1401
1377
  return children(useTap(type));
1402
1378
  const callback = has || get;
1403
1379
  if (typeof callback == "function")
1404
- callback(useLocal(type, !!has));
1380
+ callback(useContext(type, !!has));
1405
1381
  else
1406
1382
  throw Oops$2.BadProps();
1407
1383
  return null;
1408
1384
  }
1409
1385
 
1410
1386
  const Oops$1 = issues({
1411
- NoType: () => "Provider 'of' prop must be Model, typeof Model or a collection of them.",
1412
- PropDeprecated: () => "Provider `of` prop is deprecated, use `for` instead."
1387
+ NoType: () => "Provider 'for' prop must be Model, typeof Model or a collection of them."
1413
1388
  });
1414
1389
  function Provider(props) {
1415
- if ("of" in props)
1416
- throw Oops$1.PropDeprecated();
1417
- const from = useLookup();
1418
- const context = React__default["default"].useMemo(() => {
1419
- const I = props.for;
1420
- if (!I)
1390
+ const context = useNewContext(props.for);
1391
+ const render = props.children;
1392
+ useAppliedProps(context, props);
1393
+ React__default["default"].useLayoutEffect(() => () => context.pop(), []);
1394
+ return React__default["default"].createElement(LookupContext.Provider, { value: context }, typeof render == "function"
1395
+ ? React__default["default"].createElement(RenderFunction, { context, render })
1396
+ : render);
1397
+ }
1398
+ function useNewContext(include) {
1399
+ const ambient = useLookup();
1400
+ return React__default["default"].useMemo(() => {
1401
+ if (!include)
1421
1402
  throw Oops$1.NoType();
1422
- const layer = from.push();
1403
+ const layer = ambient.push();
1423
1404
  function register(I) {
1424
1405
  if (I instanceof Model)
1425
1406
  layer.inject(I.constructor, I, false);
1426
1407
  else
1427
- layer.inject(I, I.create(), true);
1408
+ layer.inject(I, I.new(), true);
1428
1409
  }
1429
- if (I instanceof Model || typeof I == "function")
1430
- register(I);
1410
+ if (include instanceof Model || typeof include == "function")
1411
+ register(include);
1431
1412
  else
1432
- values(I).forEach(register);
1413
+ values(include).forEach(register);
1433
1414
  for (const instance of layer.local)
1434
1415
  if (instance)
1435
1416
  for (const apply of getPending(instance))
1436
1417
  apply(layer);
1437
1418
  return layer;
1438
1419
  }, []);
1439
- const render = props.children;
1440
- useAppliedProps(context, props);
1441
- React__default["default"].useLayoutEffect(() => () => context.pop(), []);
1442
- return React__default["default"].createElement(LookupContext.Provider, { value: context }, typeof render == "function"
1443
- ? React__default["default"].createElement(RenderFunction, { context, render })
1444
- : render);
1445
1420
  }
1446
- function useAppliedProps(within, props) {
1447
- const update = React__default["default"].useMemo(() => {
1448
- const targets = within.local;
1449
- return function integrate(props) {
1450
- for (const [key, value] of entries(props))
1451
- if (!["of", "for", "children"].includes(key))
1452
- for (const into of targets)
1453
- if (into && key in into)
1454
- into[key] = value;
1421
+ function useAppliedProps(context, props) {
1422
+ const apply = React__default["default"].useMemo(() => {
1423
+ return (props) => {
1424
+ entries(props).forEach(([key, value]) => {
1425
+ if (key == "for" || key == "children")
1426
+ return;
1427
+ for (const into of context.local)
1428
+ if (into && key in into)
1429
+ into[key] = value;
1430
+ });
1455
1431
  };
1456
1432
  }, []);
1457
- update(props);
1433
+ apply(props);
1458
1434
  }
1459
1435
  function RenderFunction(props) {
1460
1436
  const hook = use(refresh => {
1461
1437
  const targets = props.context.local;
1462
1438
  if (targets.length == 1)
1463
- return ensure(targets[0]).subscribe(() => refresh);
1439
+ return Control.for(targets[0]).subscribe(() => refresh);
1464
1440
  return {};
1465
1441
  });
1466
1442
  if (hook.commit)
@@ -1469,17 +1445,31 @@ function RenderFunction(props) {
1469
1445
  }
1470
1446
 
1471
1447
  const Oops = issues({
1472
- DoesNotExist: (name) => `Tried to access singleton ${name}, but none exist! Did you forget to initialize?\nCall ${name}.create() before attempting to access, or consider using ${name}.use() instead.`,
1448
+ DoesNotExist: (name) => `Tried to access singleton ${name}, but none exist! Did you forget to initialize?\nCall ${name}.new() before attempting to access, or consider using ${name}.use() instead.`,
1473
1449
  AlreadyExists: (name) => `Shared instance of ${name} already exists! Consider unmounting existing, or use ${name}.reset() to force-delete it.`
1474
1450
  });
1475
1451
  const Active = new WeakMap();
1476
1452
  class Global extends MVC {
1477
- static create(...args) {
1453
+ constructor() {
1454
+ super();
1455
+ Active.set(this.constructor, this);
1456
+ }
1457
+ kill(force) {
1458
+ const type = this.constructor;
1459
+ if (type.keepAlive && !force)
1460
+ return false;
1461
+ super.kill();
1462
+ Active.delete(type);
1463
+ return true;
1464
+ }
1465
+ static new(...args) {
1478
1466
  if (Active.has(this))
1479
- throw Oops.AlreadyExists(this.name);
1467
+ if (this.keepAlive)
1468
+ return Active.get(this);
1469
+ else
1470
+ throw Oops.AlreadyExists(this.name);
1480
1471
  const instance = new this(...args);
1481
- ensure(instance);
1482
- Active.set(this, instance);
1472
+ Control.for(instance);
1483
1473
  return instance;
1484
1474
  }
1485
1475
  /**
@@ -1487,10 +1477,8 @@ class Global extends MVC {
1487
1477
  * Returns a thenable; resolves after successful update.
1488
1478
  * If instance does not already exist, one will be created.
1489
1479
  */
1490
- static set(updates) {
1491
- const instance = Active.get(this) || this.create();
1492
- instance.import(updates);
1493
- return instance.update(false);
1480
+ static set(values) {
1481
+ return this.get(true).update(values);
1494
1482
  }
1495
1483
  static get(arg) {
1496
1484
  const instance = Active.get(this);
@@ -1504,24 +1492,19 @@ class Global extends MVC {
1504
1492
  static reset() {
1505
1493
  const current = Active.get(this);
1506
1494
  if (current)
1507
- current.destroy();
1495
+ current.kill(true);
1508
1496
  }
1509
- destroy() {
1510
- super.destroy();
1511
- Active.delete(this.constructor);
1512
- }
1513
- }
1497
+ }
1498
+ Global.keepAlive = true;
1514
1499
 
1515
- exports.CONTROL = CONTROL;
1516
1500
  exports.Consumer = Consumer;
1501
+ exports.Debug = Debug;
1517
1502
  exports.Global = Global;
1518
- exports.LOCAL = LOCAL;
1503
+ exports.MVC = MVC;
1519
1504
  exports.Model = MVC;
1520
1505
  exports.Provider = Provider;
1521
- exports.STATE = STATE;
1522
- exports.WHY = WHY;
1523
1506
  exports.act = act;
1524
- exports.apply = apply;
1507
+ exports.add = add;
1525
1508
  exports["default"] = MVC;
1526
1509
  exports.get = get;
1527
1510
  exports.has = has;
@@ -1529,8 +1512,8 @@ exports.ref = ref;
1529
1512
  exports.set = set;
1530
1513
  exports.tap = tap;
1531
1514
  exports.use = use$1;
1515
+ exports.useContext = useContext;
1532
1516
  exports.useFrom = useFrom;
1533
- exports.useLocal = useLocal;
1534
1517
  exports.useModel = useModel;
1535
1518
  exports.useTap = useTap;
1536
1519
  //# sourceMappingURL=index.js.map