querysub 0.167.0 → 0.169.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/package.json
CHANGED
|
@@ -1088,69 +1088,71 @@ export class PathValueProxyWatcher {
|
|
|
1088
1088
|
try {
|
|
1089
1089
|
let rawResult: Result;
|
|
1090
1090
|
const handling = watcher.options.nestedCalls;
|
|
1091
|
+
let curFunction = baseFunction;
|
|
1091
1092
|
if (handling === "inline") {
|
|
1092
|
-
|
|
1093
|
+
curFunction = () => inlineNestedCalls(baseFunction);
|
|
1094
|
+
}
|
|
1095
|
+
rawResult = interceptCalls({
|
|
1096
|
+
onCall(call, metadata) {
|
|
1097
|
+
if (PathValueProxyWatcher.BREAK_ON_CALL.size > 0 && !watcher.hasAnyUnsyncedAccesses()) {
|
|
1098
|
+
let hash = getPathStr2(call.ModuleId, call.FunctionId);
|
|
1099
|
+
if (PathValueProxyWatcher.BREAK_ON_CALL.has(hash)) {
|
|
1100
|
+
const unwatch = () => removeMatches(PathValueProxyWatcher.BREAK_ON_CALL, hash);
|
|
1101
|
+
debugger;
|
|
1102
|
+
unwatch;
|
|
1103
|
+
}
|
|
1104
|
+
}
|
|
1105
|
+
if (!watcher.options.canWrite) {
|
|
1106
|
+
throw new Error(`Cannot call a synced function in a watcher which does not have write permissions. If you want to call a function, you must also have write permissions.`);
|
|
1107
|
+
}
|
|
1108
|
+
if (handling === "throw") {
|
|
1109
|
+
// TODO: Support making inline calls, which is useful as it will check permissions. Although, it can
|
|
1110
|
+
// easily be slow, and adds a lot of complexity, so... maybe not... maybe always force the app
|
|
1111
|
+
// to do the permissions checks if they want them
|
|
1112
|
+
throw new Error(`Nested synced function calls are not allowed. Call the function directly, or use Querysub.onCommitFinished to wait for the function to finish.`);
|
|
1113
|
+
} else if (handling === "after" || handling === undefined) {
|
|
1114
|
+
|
|
1115
|
+
// We need to wait for predictions to finish, otherwise we run into situations
|
|
1116
|
+
// where we call a function which should change a parameter we want to pass
|
|
1117
|
+
// to another function, but because the first call didn't predict, the second
|
|
1118
|
+
// call gets a different values, causing all kinds of issues.
|
|
1119
|
+
if (watcher.pendingCalls.length === 0) {
|
|
1120
|
+
let waitPromise = onAllPredictionsFinished();
|
|
1121
|
+
if (waitPromise) {
|
|
1122
|
+
proxyWatcher.triggerOnPromiseFinish(waitPromise, {
|
|
1123
|
+
waitReason: "Waiting for predictions to finish",
|
|
1124
|
+
});
|
|
1125
|
+
}
|
|
1126
|
+
}
|
|
1127
|
+
|
|
1128
|
+
watcher.pendingCalls.push({ call, metadata });
|
|
1129
|
+
} else if (handling === "ignore") {
|
|
1130
|
+
} else if (handling === "inline") {
|
|
1131
|
+
throw new Error(`inlineNestedCalls should have prevented this call from being passed to us`);
|
|
1132
|
+
} else {
|
|
1133
|
+
let unhandled: never = handling;
|
|
1134
|
+
throw new Error(`Invalid handling type ${handling}`);
|
|
1135
|
+
}
|
|
1136
|
+
},
|
|
1137
|
+
code() {
|
|
1093
1138
|
return authorityStorage.temporaryOverride(options.overrides, () =>
|
|
1094
1139
|
runCodeWithDatabase(proxy, baseFunction)
|
|
1095
1140
|
);
|
|
1096
|
-
}
|
|
1097
|
-
}
|
|
1098
|
-
rawResult = interceptCalls({
|
|
1099
|
-
onCall(call, metadata) {
|
|
1100
|
-
if (PathValueProxyWatcher.BREAK_ON_CALL.size > 0 && !watcher.hasAnyUnsyncedAccesses()) {
|
|
1101
|
-
let hash = getPathStr2(call.ModuleId, call.FunctionId);
|
|
1102
|
-
if (PathValueProxyWatcher.BREAK_ON_CALL.has(hash)) {
|
|
1103
|
-
const unwatch = () => removeMatches(PathValueProxyWatcher.BREAK_ON_CALL, hash);
|
|
1104
|
-
debugger;
|
|
1105
|
-
unwatch;
|
|
1106
|
-
}
|
|
1107
|
-
}
|
|
1108
|
-
if (!watcher.options.canWrite) {
|
|
1109
|
-
throw new Error(`Cannot call a synced function in a watcher which does not have write permissions. If you want to call a function, you must also have write permissions.`);
|
|
1110
|
-
}
|
|
1111
|
-
if (handling === "throw") {
|
|
1112
|
-
// TODO: Support making inline calls, which is useful as it will check permissions. Although, it can
|
|
1113
|
-
// easily be slow, and adds a lot of complexity, so... maybe not... maybe always force the app
|
|
1114
|
-
// to do the permissions checks if they want them
|
|
1115
|
-
throw new Error(`Nested synced function calls are not allowed. Call the function directly, or use Querysub.onCommitFinished to wait for the function to finish.`);
|
|
1116
|
-
} else if (handling === "after" || handling === undefined) {
|
|
1117
|
-
|
|
1118
|
-
// We need to wait for predictions to finish, otherwise we run into situations
|
|
1119
|
-
// where we call a function which should change a parameter we want to pass
|
|
1120
|
-
// to another function, but because the first call didn't predict, the second
|
|
1121
|
-
// call gets a different values, causing all kinds of issues.
|
|
1122
|
-
if (watcher.pendingCalls.length === 0) {
|
|
1123
|
-
let waitPromise = onAllPredictionsFinished();
|
|
1124
|
-
if (waitPromise) {
|
|
1125
|
-
proxyWatcher.triggerOnPromiseFinish(waitPromise, {
|
|
1126
|
-
waitReason: "Waiting for predictions to finish",
|
|
1127
|
-
});
|
|
1128
|
-
}
|
|
1129
|
-
}
|
|
1141
|
+
},
|
|
1142
|
+
}) as Result;
|
|
1130
1143
|
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
);
|
|
1142
|
-
},
|
|
1143
|
-
}) as Result;
|
|
1144
|
+
// NOTE: Deep clone non-local paths. It's too confusing for a partial object to be returned. Any issues caused by
|
|
1145
|
+
// this (aka, returning the entire database), would also happen if we manually added deep clones before
|
|
1146
|
+
// we returned values (and both should be throttled at a framework level so we don't break the database).
|
|
1147
|
+
// - For local paths there is a risk that there are functions
|
|
1148
|
+
try {
|
|
1149
|
+
rawResult = deepCloneCborx(rawResult);
|
|
1150
|
+
} catch {
|
|
1151
|
+
// Unfortunately, cborx throws on functions.
|
|
1152
|
+
// TODO: Use a recursive clone technique that doesn't throw on functions
|
|
1153
|
+
rawResult = atomicObjectRead(rawResult);
|
|
1144
1154
|
}
|
|
1145
1155
|
|
|
1146
|
-
// We use atomic object read, as our callers don't want a proxy.
|
|
1147
|
-
// If they want to get a full object, they will have to destructure it themselves
|
|
1148
|
-
// (as for us to destructure it would require further synchronization, which...
|
|
1149
|
-
// is just annoying, and so we won't implement that unless it becomes very useful).
|
|
1150
|
-
// (Also, if the result is a proxy is confuses promises into thinking it is another promise,
|
|
1151
|
-
// which is annoying).
|
|
1152
|
-
rawResult = atomicObjectRead(rawResult);
|
|
1153
|
-
|
|
1154
1156
|
result = { result: rawResult };
|
|
1155
1157
|
watcher.consecutiveErrors = 0;
|
|
1156
1158
|
} catch (e: any) {
|