@expressive/mvc 0.4.4 → 0.4.7

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 CHANGED
@@ -239,7 +239,7 @@ declare namespace Instruction {
239
239
  */
240
240
  declare function apply<T = any>(instruction: Instruction<T>, name?: string): T;
241
241
 
242
- declare namespace from {
242
+ declare namespace get {
243
243
  type Function<T, O = any> = (this: O, on: O) => T;
244
244
  type Factory<T, O = any> = (key: string) => Function<T, O>;
245
245
  type Getter = (controller: Controller, key: string) => any;
@@ -251,16 +251,16 @@ declare namespace from {
251
251
  * @param compute - Compute function. Bound to a subscriber-proxy of source, returns output value. Will update automatically as input values change.
252
252
  * @param suspend - Value will throw suspense when evaulating to undefined.
253
253
  */
254
- declare function from<R, T>(source: T, compute: (this: T, on: T) => R, suspend: true): Exclude<R, undefined>;
255
- declare function from<R, T>(source: T, compute: (this: T, on: T) => R, suspend?: boolean): R;
254
+ declare function get<R, T>(source: T, compute: (this: T, on: T) => R, suspend: true): Exclude<R, undefined>;
255
+ declare function get<R, T>(source: T, compute: (this: T, on: T) => R, suspend?: boolean): R;
256
256
  /**
257
257
  * Implement a computed value; output is returned by function from provided factory.
258
258
  *
259
259
  * @param compute - Factory function to generate a getter to subscribe dependancies.
260
260
  * @param suspend - Value will throw suspense when evaulating to undefined.
261
261
  */
262
- declare function from<R, T>(compute: (property: string) => (this: T, state: T) => R, suspend: true): Exclude<R, undefined>;
263
- declare function from<R, T>(compute: (property: string) => (this: T, state: T) => R, suspend?: boolean): R;
262
+ declare function get<R, T>(compute: (property: string) => (this: T, state: T) => R, suspend: true): Exclude<R, undefined>;
263
+ declare function get<R, T>(compute: (property: string) => (this: T, state: T) => R, suspend?: boolean): R;
264
264
 
265
265
  declare namespace ref {
266
266
  type Callback<T, S = any> = (this: S, argument: T) => ((next: T) => void) | Promise<void> | void | boolean;
@@ -357,6 +357,12 @@ declare function set<T, S>(value: undefined, onUpdate: set.Callback<T, S>): T;
357
357
  declare function set<T>(value: T, onUpdate: set.Callback<T>): T;
358
358
  declare function set<T, S>(value: T, onUpdate: set.Callback<T, S>): T;
359
359
 
360
+ declare function use<K = any>(initial: SetConstructor): Set<K>;
361
+ declare function use<K = any, V = any>(initial: MapConstructor): Map<K, V>;
362
+ declare function use(initial: Set<unknown>): Set<any>;
363
+ declare function use(initial: Map<unknown, unknown>): Map<any, any>;
364
+ declare function use(from: () => Set<unknown>): Set<any>;
365
+ declare function use(from: () => Map<unknown, unknown>): Map<any, any>;
360
366
  /**
361
367
  * Create a placeholder for specified Model type.
362
368
  */
@@ -623,4 +629,4 @@ declare function useTap<T extends Stateful, K extends Model.Field<T>>(source: T
623
629
  declare function useTap<T extends Stateful, R>(source: T | (() => T) | useTap.Tappable, compute: (this: T, from: T) => R, expect: true): Exclude<R, undefined>;
624
630
  declare function useTap<T extends Stateful, R>(source: T | (() => T) | useTap.Tappable, compute: (this: T, from: T) => R, expect?: boolean): R;
625
631
 
626
- export { CONTROL, Consumer, Global, LOCAL, MVC as Model, Provider, STATE, Stateful, WHY, act, apply, array, MVC as default, from, parent, put, ref, set, tap, use, useFrom, useLocal, useModel, useTap };
632
+ export { CONTROL, Consumer, Global, LOCAL, MVC as Model, Provider, STATE, Stateful, WHY, act, apply, array, MVC as default, get as from, get, parent, put, ref, set, tap, use, useFrom, useLocal, useModel, useTap };
package/lib/index.esm.js CHANGED
@@ -166,7 +166,7 @@ const Oops$a = issues({
166
166
  const INFO = new WeakMap();
167
167
  const KEYS = new WeakMap();
168
168
  const ORDER = new WeakMap();
169
- function from(source, arg1, arg2) {
169
+ function get(source, arg1, arg2) {
170
170
  return apply(function from(key) {
171
171
  const { subject, state } = this;
172
172
  const required = arg2 === true || arg1 === true;
@@ -936,219 +936,135 @@ function parent(Expects, required) {
936
936
  });
937
937
  }
938
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();
939
+ const ANY = Symbol("any");
940
+ function keyed(control, property, initial) {
941
+ const context = new Map();
942
+ const users = new Map();
943
+ const watched = new WeakMap();
944
+ const update = new Set();
944
945
  const frozen = new Set();
946
+ let managed;
947
+ manage(initial);
945
948
  function reset() {
946
949
  frozen.clear();
947
950
  }
951
+ function watch(on, key) {
952
+ const include = watched.get(on);
953
+ if (include)
954
+ include.add(key);
955
+ }
948
956
  function emit(key) {
949
- observers.forEach(notify => notify(key));
950
- control.update(property);
951
957
  control.waiting.add(reset);
952
- }
953
- function init(local) {
954
- const proxy = create(managed);
955
- const using = new Set();
956
- observers.add(key => {
957
- if (frozen.has(local))
958
- return;
959
- if (using.has(key) || using.has(ANY$1) || key === ANY$1 && using.size) {
960
- const refresh = local.onUpdate(property, control);
961
- if (refresh) {
962
- frozen.add(local);
963
- refresh();
958
+ control.update(property);
959
+ update.forEach(notify => notify(key));
960
+ }
961
+ function manage(current) {
962
+ managed = create(current);
963
+ context.clear();
964
+ assign(managed, {
965
+ delete(key) {
966
+ emit(key);
967
+ return current.delete(key);
968
+ },
969
+ clear() {
970
+ emit(ANY);
971
+ current.clear();
972
+ },
973
+ has(key) {
974
+ watch(this, key);
975
+ return current.has(key);
976
+ },
977
+ keys() {
978
+ watch(this, ANY);
979
+ return current.keys();
980
+ },
981
+ values() {
982
+ watch(this, ANY);
983
+ return current.values();
984
+ },
985
+ entries() {
986
+ watch(this, ANY);
987
+ return current.entries();
988
+ },
989
+ [Symbol.iterator]() {
990
+ watch(this, ANY);
991
+ return current[Symbol.iterator]();
992
+ },
993
+ }, current instanceof Set
994
+ ? {
995
+ add(key) {
996
+ current.add(key);
997
+ emit(key);
998
+ return this;
964
999
  }
965
1000
  }
1001
+ : {
1002
+ get(key) {
1003
+ watch(this, ANY);
1004
+ return current.get(key);
1005
+ },
1006
+ set(key, value) {
1007
+ current.set(key, value);
1008
+ emit(key);
1009
+ return this;
1010
+ }
1011
+ });
1012
+ defineProperty(managed, "size", {
1013
+ get() {
1014
+ watch(this, ANY);
1015
+ return current.size;
1016
+ }
966
1017
  });
967
- local.add(property, false);
968
- context.set(local, proxy);
969
- proxy.watch = (key) => {
970
- if (!local.active)
971
- using.add(key);
972
- };
973
- return proxy;
974
- }
975
- return {
976
- value: initial,
977
- get(local) {
978
- if (!local)
979
- return managed;
980
- if (context.has(local))
981
- return context.get(local);
982
- return init(local);
983
- },
984
- set(next) {
985
- managed.source = next;
986
- control.state.set(property, next);
987
- emit(ANY$1);
988
- },
989
- destroy() {
990
- observers.clear();
991
- }
992
- };
993
- }
994
- class ManagedMap {
995
- constructor(source, emit) {
996
- this.source = source;
997
- this.emit = emit;
998
- }
999
- watch(_key) { }
1000
- set(key, value) {
1001
- this.source.set(key, value);
1002
- this.emit(key);
1003
- return this;
1004
- }
1005
- ;
1006
- delete(key) {
1007
- this.emit(key);
1008
- return this.source.delete(key);
1009
- }
1010
- ;
1011
- clear() {
1012
- this.emit(ANY$1);
1013
- this.source.clear();
1014
- }
1015
- get(key) {
1016
- this.watch(key);
1017
- return this.source.get(key);
1018
- }
1019
- ;
1020
- has(key) {
1021
- this.watch(key);
1022
- return this.source.has(key);
1023
- }
1024
- ;
1025
- values() {
1026
- this.watch(ANY$1);
1027
- return this.source.values();
1028
- }
1029
- keys() {
1030
- this.watch(ANY$1);
1031
- return this.source.keys();
1032
- }
1033
- entries() {
1034
- this.watch(ANY$1);
1035
- return this.source.entries();
1036
- }
1037
- ;
1038
- [Symbol.iterator]() {
1039
- this.watch(ANY$1);
1040
- return this.source[Symbol.iterator]();
1041
1018
  }
1042
- ;
1043
- get size() {
1044
- this.watch(ANY$1);
1045
- return this.source.size;
1046
- }
1047
- }
1048
-
1049
- const ANY = Symbol("any");
1050
- function managedSet(control, property, initial) {
1051
- const managed = new ManagedSet(initial, emit);
1052
- const context = new WeakMap();
1053
- const observers = new Set();
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) {
1019
+ function subscribe(local) {
1064
1020
  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();
1021
+ let watch = users.get(local);
1022
+ if (!watch) {
1023
+ const using = watch = new Set();
1024
+ users.set(local, using);
1025
+ function onEvent(key) {
1026
+ if (frozen.has(local))
1027
+ return;
1028
+ if (key === ANY || using.has(key) || using.has(ANY)) {
1029
+ const refresh = local.onUpdate(property, control);
1030
+ if (refresh) {
1031
+ frozen.add(local);
1032
+ refresh();
1033
+ }
1074
1034
  }
1075
1035
  }
1076
- });
1077
- local.add(property, false);
1036
+ local.add(property, false);
1037
+ local.dependant.add({
1038
+ commit() {
1039
+ if (using.size === 0)
1040
+ using.add(ANY);
1041
+ update.add(onEvent);
1042
+ },
1043
+ release() {
1044
+ update.delete(onEvent);
1045
+ }
1046
+ });
1047
+ }
1048
+ watched.set(proxy, watch);
1078
1049
  context.set(local, proxy);
1079
- proxy.watch = (key) => {
1080
- if (!local.active)
1081
- using.add(key);
1082
- };
1083
1050
  return proxy;
1084
1051
  }
1085
1052
  return {
1086
1053
  value: initial,
1087
1054
  get(local) {
1088
- if (!local)
1089
- return managed;
1090
- if (context.has(local))
1091
- return context.get(local);
1092
- return init(local);
1055
+ return local ?
1056
+ context.get(local) || subscribe(local) :
1057
+ managed;
1093
1058
  },
1094
1059
  set(next) {
1095
- managed.source = next;
1096
1060
  control.state.set(property, next);
1061
+ manage(next);
1097
1062
  emit(ANY);
1098
1063
  },
1099
1064
  destroy() {
1100
- observers.clear();
1065
+ update.clear();
1101
1066
  }
1102
1067
  };
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
1068
  }
1153
1069
 
1154
1070
  const Oops$5 = issues({
@@ -1158,15 +1074,11 @@ function use$1(input, argument) {
1158
1074
  return apply(function use(key) {
1159
1075
  const { state, subject } = this;
1160
1076
  if (typeof input === "function")
1161
- input = Model.isTypeof(input)
1162
- ? new input()
1163
- : input();
1077
+ input = "prototype" in input ? new input() : input();
1164
1078
  else if (input && typeof input !== "object")
1165
1079
  throw Oops$5.BadArgument(typeof input);
1166
- if (input instanceof Map)
1167
- return managedMap(this, key, input);
1168
- if (input instanceof Set)
1169
- return managedSet(this, key, input);
1080
+ if (input instanceof Map || input instanceof Set)
1081
+ return keyed(this, key, input);
1170
1082
  function onUpdate(next) {
1171
1083
  state.set(key, next);
1172
1084
  if (next) {
@@ -1609,5 +1521,5 @@ class Global extends MVC {
1609
1521
  }
1610
1522
  }
1611
1523
 
1612
- export { CONTROL, Consumer, Global, LOCAL, MVC as Model, Provider, STATE, WHY, act, apply, array, MVC as default, from, parent, put, ref, set, tap, use$1 as use, useFrom, useLocal, useModel, useTap };
1524
+ export { CONTROL, Consumer, Global, LOCAL, MVC as Model, Provider, STATE, WHY, act, apply, array, MVC as default, get as from, get, parent, put, ref, set, tap, use$1 as use, useFrom, useLocal, useModel, useTap };
1613
1525
  //# sourceMappingURL=index.esm.js.map