@expressive/mvc 0.9.6 → 0.10.1
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 +81 -89
- package/lib/index.esm.js +166 -162
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +166 -163
- package/lib/index.js.map +1 -1
- package/package.json +1 -1
package/lib/index.esm.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import React, { useState, useMemo } from 'react';
|
|
2
2
|
|
|
3
|
-
const { assign, create, defineProperties, defineProperty, entries, getPrototypeOf, getOwnPropertyNames, getOwnPropertyDescriptor, getOwnPropertySymbols, values } = Object;
|
|
3
|
+
const { assign, create, defineProperties, defineProperty, entries, getPrototypeOf, getOwnPropertyNames, getOwnPropertyDescriptor, getOwnPropertySymbols, values } = Object;
|
|
4
|
+
function unique(array) {
|
|
5
|
+
return Array.from(new Set(array));
|
|
6
|
+
}
|
|
4
7
|
|
|
5
8
|
class Issue extends Error {
|
|
6
9
|
constructor() {
|
|
@@ -651,6 +654,7 @@ function createValueEffect(callback) {
|
|
|
651
654
|
function ref(arg, mapper) {
|
|
652
655
|
return add(function ref(key) {
|
|
653
656
|
let value = {};
|
|
657
|
+
this.state.set(key, undefined);
|
|
654
658
|
if (typeof arg != "object")
|
|
655
659
|
value = createRef(this, key, arg);
|
|
656
660
|
else
|
|
@@ -947,31 +951,31 @@ const Oops$6 = issues({
|
|
|
947
951
|
StrictNoUpdate: () => `Update is not expected but one is in progress!`
|
|
948
952
|
});
|
|
949
953
|
function addEventListener(source, arg1, arg2, arg3) {
|
|
954
|
+
if (typeof arg1 == "string")
|
|
955
|
+
arg1 = [arg1];
|
|
956
|
+
return Control.for(source, control => {
|
|
957
|
+
for (const key of arg1)
|
|
958
|
+
try {
|
|
959
|
+
void source[key];
|
|
960
|
+
}
|
|
961
|
+
catch (e) { }
|
|
962
|
+
const removeListener = control.addListener(key => {
|
|
963
|
+
if (!key && !arg1.length)
|
|
964
|
+
arg2.call(source, []);
|
|
965
|
+
if (arg1.includes(key)) {
|
|
966
|
+
if (arg3)
|
|
967
|
+
removeListener();
|
|
968
|
+
return arg2.bind(source);
|
|
969
|
+
}
|
|
970
|
+
});
|
|
971
|
+
return removeListener;
|
|
972
|
+
});
|
|
973
|
+
}
|
|
974
|
+
function awaitUpdate(source, arg1, arg2) {
|
|
950
975
|
const single = typeof arg1 == "string";
|
|
951
976
|
const keys = typeof arg1 == "string" ? [arg1] :
|
|
952
977
|
typeof arg1 == "object" ? arg1 :
|
|
953
978
|
undefined;
|
|
954
|
-
if (typeof arg2 == "function" && keys)
|
|
955
|
-
return Control.for(source, control => {
|
|
956
|
-
for (const key of keys)
|
|
957
|
-
try {
|
|
958
|
-
void source[key];
|
|
959
|
-
}
|
|
960
|
-
catch (e) { }
|
|
961
|
-
const invoke = single
|
|
962
|
-
? () => arg2.call(source, control.state.get(arg1), arg1)
|
|
963
|
-
: (frame) => arg2.call(source, frame);
|
|
964
|
-
const removeListener = control.addListener(key => {
|
|
965
|
-
if (!key && !keys.length)
|
|
966
|
-
invoke([]);
|
|
967
|
-
if (keys.includes(key)) {
|
|
968
|
-
if (arg3)
|
|
969
|
-
removeListener();
|
|
970
|
-
return invoke;
|
|
971
|
-
}
|
|
972
|
-
});
|
|
973
|
-
return removeListener;
|
|
974
|
-
});
|
|
975
979
|
return new Promise((resolve, reject) => {
|
|
976
980
|
const timeout = (message) => {
|
|
977
981
|
const k = keys ? keys.join(", ") : "any";
|
|
@@ -1036,34 +1040,47 @@ class Model {
|
|
|
1036
1040
|
on(arg1, arg2, arg3) {
|
|
1037
1041
|
if (typeof arg1 == "function")
|
|
1038
1042
|
return createEffect(this.is, arg1, arg2);
|
|
1039
|
-
|
|
1043
|
+
if (typeof arg2 != "function")
|
|
1044
|
+
return awaitUpdate(this.is, arg1, arg2);
|
|
1045
|
+
if (arg1)
|
|
1046
|
+
return addEventListener(this.is, arg1, arg2, arg3);
|
|
1040
1047
|
}
|
|
1041
|
-
|
|
1048
|
+
get(arg1, arg2) {
|
|
1042
1049
|
const { state } = Control.for(this);
|
|
1043
|
-
const
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1050
|
+
const extract = typeof arg1 == "string"
|
|
1051
|
+
? () => state.get(arg1)
|
|
1052
|
+
: () => {
|
|
1053
|
+
const output = {};
|
|
1054
|
+
for (const key of arg1 || state.keys())
|
|
1055
|
+
output[key] = state.get(key);
|
|
1056
|
+
return output;
|
|
1057
|
+
};
|
|
1058
|
+
if (!arg1 || arg2 === undefined)
|
|
1059
|
+
return extract();
|
|
1060
|
+
if (typeof arg2 == "function")
|
|
1061
|
+
return this.on(arg1, () => arg2(extract()));
|
|
1062
|
+
const timeout = typeof arg2 == "number" ? arg2 : undefined;
|
|
1063
|
+
return this.on(arg1, timeout).then(extract);
|
|
1048
1064
|
}
|
|
1049
|
-
|
|
1065
|
+
set(arg1, arg2) {
|
|
1050
1066
|
const control = Control.for(this);
|
|
1051
|
-
if (typeof arg1 == "object")
|
|
1052
|
-
for (const key in arg1)
|
|
1067
|
+
if (typeof arg1 == "object")
|
|
1068
|
+
for (const key in arg1) {
|
|
1053
1069
|
if (arg2 === true || (arg2 ? arg2.includes(key) : control.state.has(key))) {
|
|
1054
1070
|
control.state.set(key, arg1[key]);
|
|
1055
1071
|
control.update(key);
|
|
1056
1072
|
}
|
|
1057
|
-
|
|
1073
|
+
}
|
|
1058
1074
|
else if (typeof arg1 == "string") {
|
|
1059
1075
|
control.update(arg1);
|
|
1060
|
-
if (1 in arguments
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1076
|
+
if (1 in arguments) {
|
|
1077
|
+
if (control.state.has(arg1))
|
|
1078
|
+
control.state.set(arg1, arg2);
|
|
1079
|
+
else if (arg1 in this) {
|
|
1080
|
+
const method = this[arg1];
|
|
1081
|
+
if (typeof method == "function")
|
|
1064
1082
|
method.call(this, arg2);
|
|
1065
|
-
|
|
1066
|
-
method.call(this);
|
|
1083
|
+
}
|
|
1067
1084
|
}
|
|
1068
1085
|
}
|
|
1069
1086
|
return {
|
|
@@ -1077,7 +1094,7 @@ class Model {
|
|
|
1077
1094
|
/**
|
|
1078
1095
|
* Clean up side effects and mark this instance for garbage-collection.
|
|
1079
1096
|
*/
|
|
1080
|
-
|
|
1097
|
+
end() {
|
|
1081
1098
|
Control.for(this).clear();
|
|
1082
1099
|
}
|
|
1083
1100
|
/**
|
|
@@ -1116,9 +1133,7 @@ class Lookup {
|
|
|
1116
1133
|
this.table = new Map();
|
|
1117
1134
|
}
|
|
1118
1135
|
get local() {
|
|
1119
|
-
return [
|
|
1120
|
-
...new Set(getOwnPropertySymbols(this).map(symbol => this[symbol]))
|
|
1121
|
-
];
|
|
1136
|
+
return unique(getOwnPropertySymbols(this).map(symbol => this[symbol]));
|
|
1122
1137
|
}
|
|
1123
1138
|
key(T) {
|
|
1124
1139
|
let key = this.table.get(T);
|
|
@@ -1131,10 +1146,7 @@ class Lookup {
|
|
|
1131
1146
|
get(T) {
|
|
1132
1147
|
return this[this.key(T)];
|
|
1133
1148
|
}
|
|
1134
|
-
|
|
1135
|
-
return create(this);
|
|
1136
|
-
}
|
|
1137
|
-
inject(T, I, writable) {
|
|
1149
|
+
add(T, I, writable) {
|
|
1138
1150
|
do {
|
|
1139
1151
|
const key = this.key(T);
|
|
1140
1152
|
const conflict = this.hasOwnProperty(key);
|
|
@@ -1146,6 +1158,9 @@ class Lookup {
|
|
|
1146
1158
|
T = getPrototypeOf(T);
|
|
1147
1159
|
} while (T !== Model);
|
|
1148
1160
|
}
|
|
1161
|
+
push() {
|
|
1162
|
+
return create(this);
|
|
1163
|
+
}
|
|
1149
1164
|
pop() {
|
|
1150
1165
|
const items = new Set();
|
|
1151
1166
|
for (const key of getOwnPropertySymbols(this)) {
|
|
@@ -1154,40 +1169,33 @@ class Lookup {
|
|
|
1154
1169
|
items.add(entry.value);
|
|
1155
1170
|
}
|
|
1156
1171
|
for (const model of items)
|
|
1157
|
-
model.
|
|
1172
|
+
model.end();
|
|
1158
1173
|
}
|
|
1159
1174
|
}
|
|
1160
1175
|
const LookupContext = React.createContext(new Lookup());
|
|
1161
1176
|
const useLookup = () => React.useContext(LookupContext);
|
|
1162
|
-
function useContext(Type,
|
|
1177
|
+
function useContext(Type, required) {
|
|
1163
1178
|
const instance = useLookup().get(Type);
|
|
1164
|
-
if (!instance &&
|
|
1179
|
+
if (!instance && required !== false)
|
|
1165
1180
|
throw Oops$4.NotFound(Type.name);
|
|
1166
|
-
|
|
1167
|
-
case "string":
|
|
1168
|
-
return instance[arg];
|
|
1169
|
-
case "function":
|
|
1170
|
-
React.useLayoutEffect(() => arg(instance), []);
|
|
1171
|
-
default:
|
|
1172
|
-
return instance;
|
|
1173
|
-
}
|
|
1181
|
+
return instance;
|
|
1174
1182
|
}
|
|
1175
1183
|
|
|
1176
1184
|
const Oops$3 = issues({
|
|
1177
1185
|
NotAllowed: (parent, child) => `Global '${parent}' attempted to attach '${child}' but it is not also a singleton.`,
|
|
1178
1186
|
AmbientRequired: (requested, requester, key) => `Attempted to find an instance of ${requested} in context. It is required for [${requester}.${key}], but one could not be found.`
|
|
1179
1187
|
});
|
|
1180
|
-
const
|
|
1181
|
-
const
|
|
1188
|
+
const Pending = new WeakMap();
|
|
1189
|
+
const Applied = new WeakMap();
|
|
1182
1190
|
function tap(type, argument) {
|
|
1183
1191
|
return add(function tap(key) {
|
|
1184
|
-
if (
|
|
1192
|
+
if (type.global)
|
|
1185
1193
|
return {
|
|
1186
1194
|
recursive: true,
|
|
1187
1195
|
value: type.get()
|
|
1188
1196
|
};
|
|
1189
1197
|
const { subject } = this;
|
|
1190
|
-
if (
|
|
1198
|
+
if (subject.constructor.global)
|
|
1191
1199
|
throw Oops$3.NotAllowed(subject, type.name);
|
|
1192
1200
|
getPending(subject).push(context => {
|
|
1193
1201
|
let instance = context.get(type);
|
|
@@ -1207,24 +1215,24 @@ function tap(type, argument) {
|
|
|
1207
1215
|
});
|
|
1208
1216
|
}
|
|
1209
1217
|
function usePeerContext(subject) {
|
|
1210
|
-
if (
|
|
1211
|
-
if (
|
|
1218
|
+
if (Applied.has(subject)) {
|
|
1219
|
+
if (Applied.get(subject))
|
|
1212
1220
|
useLookup();
|
|
1213
1221
|
return;
|
|
1214
1222
|
}
|
|
1215
|
-
const pending =
|
|
1223
|
+
const pending = Pending.get(subject);
|
|
1216
1224
|
if (pending) {
|
|
1217
1225
|
const local = useLookup();
|
|
1218
1226
|
for (const init of pending)
|
|
1219
1227
|
init(local);
|
|
1220
|
-
|
|
1228
|
+
Pending.delete(subject);
|
|
1221
1229
|
}
|
|
1222
|
-
|
|
1230
|
+
Applied.set(subject, !!pending);
|
|
1223
1231
|
}
|
|
1224
1232
|
function getPending(subject) {
|
|
1225
|
-
let pending =
|
|
1233
|
+
let pending = Pending.get(subject);
|
|
1226
1234
|
if (!pending)
|
|
1227
|
-
|
|
1235
|
+
Pending.set(subject, pending = []);
|
|
1228
1236
|
return pending;
|
|
1229
1237
|
}
|
|
1230
1238
|
|
|
@@ -1235,9 +1243,9 @@ function use(init) {
|
|
|
1235
1243
|
return state[0];
|
|
1236
1244
|
}
|
|
1237
1245
|
|
|
1238
|
-
function
|
|
1246
|
+
function useNew(source, arg1, arg2) {
|
|
1239
1247
|
const instance = React.useMemo(() => {
|
|
1240
|
-
const callback = arg2 ||
|
|
1248
|
+
const callback = arg2 || arg1;
|
|
1241
1249
|
const instance = Model.isTypeof(source) ?
|
|
1242
1250
|
source.new() :
|
|
1243
1251
|
source();
|
|
@@ -1247,27 +1255,27 @@ function useModel(source, arg, arg2) {
|
|
|
1247
1255
|
return instance;
|
|
1248
1256
|
}, []);
|
|
1249
1257
|
usePeerContext(instance);
|
|
1250
|
-
if (Array.isArray(
|
|
1258
|
+
if (Array.isArray(arg1)) {
|
|
1251
1259
|
const update = useState(0)[1];
|
|
1252
1260
|
React.useLayoutEffect(() => {
|
|
1253
|
-
if (
|
|
1254
|
-
instance.on(
|
|
1261
|
+
if (arg1.length && instance instanceof Model)
|
|
1262
|
+
instance.on(arg1, () => update(x => x + 1));
|
|
1255
1263
|
return () => {
|
|
1256
1264
|
if (Model.isTypeof(source))
|
|
1257
|
-
instance.
|
|
1265
|
+
instance.end();
|
|
1258
1266
|
};
|
|
1259
1267
|
}, []);
|
|
1260
1268
|
return instance;
|
|
1261
1269
|
}
|
|
1262
1270
|
const local = use(refresh => (Control.for(instance).subscribe(() => refresh)));
|
|
1263
|
-
if (typeof
|
|
1264
|
-
local.assign(
|
|
1271
|
+
if (typeof arg1 == "object")
|
|
1272
|
+
local.assign(arg1, arg2);
|
|
1265
1273
|
React.useLayoutEffect(() => {
|
|
1266
1274
|
local.commit();
|
|
1267
1275
|
return () => {
|
|
1268
1276
|
local.release();
|
|
1269
1277
|
if (Model.isTypeof(source))
|
|
1270
|
-
instance.
|
|
1278
|
+
instance.end();
|
|
1271
1279
|
};
|
|
1272
1280
|
}, []);
|
|
1273
1281
|
return local.proxy;
|
|
@@ -1316,9 +1324,11 @@ function useValue(source, compute, suspend) {
|
|
|
1316
1324
|
}
|
|
1317
1325
|
defineProperty(sub, "proxy", {
|
|
1318
1326
|
get() {
|
|
1319
|
-
if (value
|
|
1327
|
+
if (value !== undefined)
|
|
1328
|
+
return value;
|
|
1329
|
+
if (suspend)
|
|
1320
1330
|
throw new Promise(res => retry = res);
|
|
1321
|
-
return
|
|
1331
|
+
return null;
|
|
1322
1332
|
}
|
|
1323
1333
|
});
|
|
1324
1334
|
return sub;
|
|
@@ -1333,7 +1343,7 @@ function useTap(source, arg1, arg2) {
|
|
|
1333
1343
|
return () => source;
|
|
1334
1344
|
if (Model.isTypeof(source))
|
|
1335
1345
|
return "get" in source
|
|
1336
|
-
? () => source.get(
|
|
1346
|
+
? () => source.get()
|
|
1337
1347
|
: () => useContext(source);
|
|
1338
1348
|
return source;
|
|
1339
1349
|
}, [])();
|
|
@@ -1349,22 +1359,72 @@ function useTap(source, arg1, arg2) {
|
|
|
1349
1359
|
return value;
|
|
1350
1360
|
}
|
|
1351
1361
|
|
|
1362
|
+
const Global$1 = new WeakMap();
|
|
1363
|
+
const Oops$2 = issues({
|
|
1364
|
+
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.`,
|
|
1365
|
+
AlreadyExists: (name) => `Shared instance of ${name} already exists! Consider unmounting existing, or use ${name}.reset() to force-delete it.`
|
|
1366
|
+
});
|
|
1352
1367
|
class MVC extends Model {
|
|
1353
|
-
|
|
1354
|
-
|
|
1368
|
+
end(force) {
|
|
1369
|
+
const type = this.constructor;
|
|
1370
|
+
if (type.keepAlive && !force)
|
|
1371
|
+
return false;
|
|
1372
|
+
super.end();
|
|
1373
|
+
Global$1.delete(type);
|
|
1374
|
+
return true;
|
|
1375
|
+
}
|
|
1376
|
+
static new(...args) {
|
|
1377
|
+
if (Global$1.has(this))
|
|
1378
|
+
if (this.keepAlive)
|
|
1379
|
+
return Global$1.get(this);
|
|
1380
|
+
else
|
|
1381
|
+
throw Oops$2.AlreadyExists(this.name);
|
|
1382
|
+
const instance = super.new(...args);
|
|
1383
|
+
if (this.global)
|
|
1384
|
+
Global$1.set(this, instance);
|
|
1385
|
+
return instance;
|
|
1386
|
+
}
|
|
1387
|
+
static get(arg1, arg2) {
|
|
1388
|
+
let instance;
|
|
1389
|
+
const required = arg1 === undefined || arg1 === true;
|
|
1390
|
+
if (this.global) {
|
|
1391
|
+
instance = Global$1.get(this);
|
|
1392
|
+
if (!instance && required)
|
|
1393
|
+
throw Oops$2.DoesNotExist(this.name);
|
|
1394
|
+
}
|
|
1395
|
+
else
|
|
1396
|
+
instance = useContext(this, required);
|
|
1397
|
+
function callback(effect) {
|
|
1398
|
+
try {
|
|
1399
|
+
React.useLayoutEffect(() => effect(instance), []);
|
|
1400
|
+
}
|
|
1401
|
+
catch (err) {
|
|
1402
|
+
if (instance)
|
|
1403
|
+
instance.on(effect, []);
|
|
1404
|
+
else
|
|
1405
|
+
effect(undefined);
|
|
1406
|
+
}
|
|
1407
|
+
}
|
|
1408
|
+
if (typeof arg1 === "string")
|
|
1409
|
+
return instance[arg1];
|
|
1410
|
+
if (typeof arg1 === "function" && instance)
|
|
1411
|
+
callback(arg1);
|
|
1412
|
+
else if (arg2)
|
|
1413
|
+
callback(arg2);
|
|
1414
|
+
return instance;
|
|
1355
1415
|
}
|
|
1356
1416
|
static tap(key, expect) {
|
|
1357
1417
|
return useTap(this, key, expect);
|
|
1358
1418
|
}
|
|
1359
1419
|
static use(a, b) {
|
|
1360
|
-
return
|
|
1420
|
+
return useNew(this, a, b);
|
|
1361
1421
|
}
|
|
1362
1422
|
static meta(path, expect) {
|
|
1363
1423
|
return useTap(() => this, path, expect);
|
|
1364
1424
|
}
|
|
1365
1425
|
}
|
|
1366
1426
|
|
|
1367
|
-
const Oops$
|
|
1427
|
+
const Oops$1 = issues({
|
|
1368
1428
|
BadProps: () => `Provider expects either a render function, 'get' or 'has' props.`
|
|
1369
1429
|
});
|
|
1370
1430
|
function Consumer(props) {
|
|
@@ -1375,58 +1435,50 @@ function Consumer(props) {
|
|
|
1375
1435
|
if (typeof callback == "function")
|
|
1376
1436
|
callback(useContext(type, !!has));
|
|
1377
1437
|
else
|
|
1378
|
-
throw Oops$
|
|
1438
|
+
throw Oops$1.BadProps();
|
|
1379
1439
|
return null;
|
|
1380
1440
|
}
|
|
1381
1441
|
|
|
1382
|
-
const Oops
|
|
1442
|
+
const Oops = issues({
|
|
1383
1443
|
NoType: () => "Provider 'for' prop must be Model, typeof Model or a collection of them."
|
|
1384
1444
|
});
|
|
1385
1445
|
function Provider(props) {
|
|
1386
|
-
const context = useNewContext(props.for);
|
|
1446
|
+
const context = useNewContext(props.for, props.and);
|
|
1387
1447
|
const render = props.children;
|
|
1388
|
-
useAppliedProps(context, props);
|
|
1389
1448
|
React.useLayoutEffect(() => () => context.pop(), []);
|
|
1390
1449
|
return React.createElement(LookupContext.Provider, { value: context }, typeof render == "function"
|
|
1391
1450
|
? React.createElement(RenderFunction, { context, render })
|
|
1392
1451
|
: render);
|
|
1393
1452
|
}
|
|
1394
|
-
function useNewContext(include) {
|
|
1453
|
+
function useNewContext(include, assign) {
|
|
1395
1454
|
const ambient = useLookup();
|
|
1396
|
-
|
|
1455
|
+
const context = React.useMemo(() => {
|
|
1397
1456
|
if (!include)
|
|
1398
|
-
throw Oops
|
|
1399
|
-
const
|
|
1457
|
+
throw Oops.NoType();
|
|
1458
|
+
const next = ambient.push();
|
|
1400
1459
|
function register(I) {
|
|
1401
1460
|
if (I instanceof Model)
|
|
1402
|
-
|
|
1461
|
+
next.add(I.constructor, I, false);
|
|
1403
1462
|
else
|
|
1404
|
-
|
|
1463
|
+
next.add(I, I.new(), true);
|
|
1405
1464
|
}
|
|
1406
1465
|
if (include instanceof Model || typeof include == "function")
|
|
1407
1466
|
register(include);
|
|
1408
1467
|
else
|
|
1409
1468
|
values(include).forEach(register);
|
|
1410
|
-
for (const instance of
|
|
1469
|
+
for (const instance of next.local)
|
|
1411
1470
|
if (instance)
|
|
1412
1471
|
for (const apply of getPending(instance))
|
|
1413
|
-
apply(
|
|
1414
|
-
return
|
|
1415
|
-
}, []);
|
|
1416
|
-
}
|
|
1417
|
-
function useAppliedProps(context, props) {
|
|
1418
|
-
const apply = React.useMemo(() => {
|
|
1419
|
-
return (props) => {
|
|
1420
|
-
entries(props).forEach(([key, value]) => {
|
|
1421
|
-
if (key == "for" || key == "children")
|
|
1422
|
-
return;
|
|
1423
|
-
for (const into of context.local)
|
|
1424
|
-
if (into && key in into)
|
|
1425
|
-
into[key] = value;
|
|
1426
|
-
});
|
|
1427
|
-
};
|
|
1472
|
+
apply(next);
|
|
1473
|
+
return next;
|
|
1428
1474
|
}, []);
|
|
1429
|
-
|
|
1475
|
+
if (assign) {
|
|
1476
|
+
for (const key in assign)
|
|
1477
|
+
for (const into of context.local)
|
|
1478
|
+
if (into && key in into)
|
|
1479
|
+
into[key] = assign[key];
|
|
1480
|
+
}
|
|
1481
|
+
return context;
|
|
1430
1482
|
}
|
|
1431
1483
|
function RenderFunction(props) {
|
|
1432
1484
|
const hook = use(refresh => {
|
|
@@ -1440,57 +1492,9 @@ function RenderFunction(props) {
|
|
|
1440
1492
|
return props.render(hook.proxy);
|
|
1441
1493
|
}
|
|
1442
1494
|
|
|
1443
|
-
const Oops = issues({
|
|
1444
|
-
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.`,
|
|
1445
|
-
AlreadyExists: (name) => `Shared instance of ${name} already exists! Consider unmounting existing, or use ${name}.reset() to force-delete it.`
|
|
1446
|
-
});
|
|
1447
|
-
const Active = new WeakMap();
|
|
1448
1495
|
class Global extends MVC {
|
|
1449
|
-
constructor() {
|
|
1450
|
-
super();
|
|
1451
|
-
Active.set(this.constructor, this);
|
|
1452
|
-
}
|
|
1453
|
-
destroy(force) {
|
|
1454
|
-
const type = this.constructor;
|
|
1455
|
-
if (type.keepAlive && !force)
|
|
1456
|
-
return false;
|
|
1457
|
-
Control.for(this).clear();
|
|
1458
|
-
Active.delete(type);
|
|
1459
|
-
return true;
|
|
1460
|
-
}
|
|
1461
|
-
static new(...args) {
|
|
1462
|
-
if (Active.has(this))
|
|
1463
|
-
if (this.keepAlive)
|
|
1464
|
-
return Active.get(this);
|
|
1465
|
-
else
|
|
1466
|
-
throw Oops.AlreadyExists(this.name);
|
|
1467
|
-
const instance = new this(...args);
|
|
1468
|
-
Control.for(instance);
|
|
1469
|
-
return instance;
|
|
1470
|
-
}
|
|
1471
|
-
/**
|
|
1472
|
-
* Update the active instance of this class.
|
|
1473
|
-
* Returns a thenable; resolves after successful update.
|
|
1474
|
-
* If instance does not already exist, one will be created.
|
|
1475
|
-
*/
|
|
1476
|
-
static set(values) {
|
|
1477
|
-
return this.get(true).update(values);
|
|
1478
|
-
}
|
|
1479
|
-
static get(arg) {
|
|
1480
|
-
const instance = Active.get(this);
|
|
1481
|
-
if (!instance && arg !== false)
|
|
1482
|
-
throw Oops.DoesNotExist(this.name);
|
|
1483
|
-
return (typeof arg == "string" ?
|
|
1484
|
-
instance[arg] :
|
|
1485
|
-
instance);
|
|
1486
|
-
}
|
|
1487
|
-
/** Destroy current instance of Global, if it exists. */
|
|
1488
|
-
static reset() {
|
|
1489
|
-
const current = Active.get(this);
|
|
1490
|
-
if (current)
|
|
1491
|
-
current.destroy(true);
|
|
1492
|
-
}
|
|
1493
1496
|
}
|
|
1497
|
+
Global.global = true;
|
|
1494
1498
|
Global.keepAlive = true;
|
|
1495
1499
|
|
|
1496
1500
|
const LOCAL = "$debug local";
|
|
@@ -1530,5 +1534,5 @@ const Debug = {
|
|
|
1530
1534
|
UPDATE
|
|
1531
1535
|
};
|
|
1532
1536
|
|
|
1533
|
-
export { Consumer, Debug, Global, MVC, MVC as Model, Provider, add, MVC as default, get, has, ref, run, set, tap, use$1 as use, useContext,
|
|
1537
|
+
export { Consumer, Debug, Global, MVC, MVC as Model, Provider, add, MVC as default, get, has, ref, run, set, tap, use$1 as use, useContext, useNew, useTap };
|
|
1534
1538
|
//# sourceMappingURL=index.esm.js.map
|