wrangler 4.38.0 → 4.39.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/config-schema.json +123 -25
- package/package.json +9 -9
- package/templates/remoteBindings/ProxyServerWorker.ts +3 -3
- package/wrangler-dist/ProxyServerWorker.js +2010 -650
- package/wrangler-dist/cli.d.ts +84 -23
- package/wrangler-dist/cli.js +5681 -3460
- package/wrangler-dist/metafile-cjs.json +1 -1
@@ -1,13 +1,22 @@
|
|
1
|
-
// ../../
|
2
|
-
|
3
|
-
Symbol.
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
1
|
+
// ../../node_modules/.pnpm/capnweb@0.1.0/node_modules/capnweb/dist/index.js
|
2
|
+
if (!Symbol.dispose) {
|
3
|
+
Symbol.dispose = Symbol.for("dispose");
|
4
|
+
}
|
5
|
+
if (!Symbol.asyncDispose) {
|
6
|
+
Symbol.asyncDispose = Symbol.for("asyncDispose");
|
7
|
+
}
|
8
|
+
var workersModuleName = navigator.userAgent === "Cloudflare-Workers" ? "cloudflare:workers" : null;
|
9
|
+
var workersModule;
|
10
|
+
if (workersModuleName) {
|
11
|
+
workersModule = await import(
|
12
|
+
/* @vite-ignore */
|
13
|
+
workersModuleName
|
14
|
+
);
|
15
|
+
}
|
16
|
+
var RpcTarget = workersModule ? workersModule.RpcTarget : class {
|
8
17
|
};
|
9
|
-
function
|
10
|
-
switch (typeof
|
18
|
+
function typeForRpc(value) {
|
19
|
+
switch (typeof value) {
|
11
20
|
case "boolean":
|
12
21
|
case "number":
|
13
22
|
case "string":
|
@@ -17,12 +26,16 @@ function T(s9) {
|
|
17
26
|
case "object":
|
18
27
|
case "function":
|
19
28
|
break;
|
29
|
+
case "bigint":
|
30
|
+
return "bigint";
|
20
31
|
default:
|
21
32
|
return "unsupported";
|
22
33
|
}
|
23
|
-
if (
|
24
|
-
|
25
|
-
|
34
|
+
if (value === null) {
|
35
|
+
return "primitive";
|
36
|
+
}
|
37
|
+
let prototype = Object.getPrototypeOf(value);
|
38
|
+
switch (prototype) {
|
26
39
|
case Object.prototype:
|
27
40
|
return "object";
|
28
41
|
case Function.prototype:
|
@@ -31,25 +44,49 @@ function T(s9) {
|
|
31
44
|
return "array";
|
32
45
|
case Date.prototype:
|
33
46
|
return "date";
|
34
|
-
case
|
47
|
+
case Uint8Array.prototype:
|
48
|
+
return "bytes";
|
49
|
+
// TODO: All other structured clone types.
|
50
|
+
case RpcStub.prototype:
|
35
51
|
return "stub";
|
36
|
-
case
|
52
|
+
case RpcPromise.prototype:
|
37
53
|
return "rpc-promise";
|
54
|
+
// TODO: Promise<T> or thenable
|
38
55
|
default:
|
39
|
-
|
56
|
+
if (workersModule) {
|
57
|
+
if (prototype == workersModule.RpcStub.prototype || value instanceof workersModule.ServiceStub) {
|
58
|
+
return "rpc-target";
|
59
|
+
} else if (prototype == workersModule.RpcPromise.prototype || prototype == workersModule.RpcProperty.prototype) {
|
60
|
+
return "rpc-thenable";
|
61
|
+
}
|
62
|
+
}
|
63
|
+
if (value instanceof RpcTarget) {
|
64
|
+
return "rpc-target";
|
65
|
+
}
|
66
|
+
if (value instanceof Error) {
|
67
|
+
return "error";
|
68
|
+
}
|
69
|
+
return "unsupported";
|
40
70
|
}
|
41
71
|
}
|
42
|
-
|
72
|
+
function mapNotLoaded() {
|
73
|
+
throw new Error("RPC map() implementation was not loaded.");
|
74
|
+
}
|
75
|
+
var mapImpl = { applyMap: mapNotLoaded, sendMap: mapNotLoaded };
|
76
|
+
var StubHook = class {
|
43
77
|
};
|
44
|
-
var
|
45
|
-
constructor(
|
78
|
+
var ErrorStubHook = class extends StubHook {
|
79
|
+
constructor(error) {
|
46
80
|
super();
|
47
|
-
this.error =
|
81
|
+
this.error = error;
|
48
82
|
}
|
49
|
-
call(
|
83
|
+
call(path, args) {
|
50
84
|
return this;
|
51
85
|
}
|
52
|
-
|
86
|
+
map(path, captures, instructions) {
|
87
|
+
return this;
|
88
|
+
}
|
89
|
+
get(path) {
|
53
90
|
return this;
|
54
91
|
}
|
55
92
|
dup() {
|
@@ -58,991 +95,2314 @@ var f = class extends y {
|
|
58
95
|
pull() {
|
59
96
|
return Promise.reject(this.error);
|
60
97
|
}
|
98
|
+
ignoreUnhandledRejections() {
|
99
|
+
}
|
61
100
|
dispose() {
|
62
101
|
}
|
63
|
-
onBroken(
|
102
|
+
onBroken(callback) {
|
64
103
|
try {
|
65
|
-
|
66
|
-
} catch (
|
67
|
-
Promise.resolve(
|
104
|
+
callback(this.error);
|
105
|
+
} catch (err) {
|
106
|
+
Promise.resolve(err);
|
107
|
+
}
|
108
|
+
}
|
109
|
+
};
|
110
|
+
var DISPOSED_HOOK = new ErrorStubHook(
|
111
|
+
new Error("Attempted to use RPC stub after it has been disposed.")
|
112
|
+
);
|
113
|
+
var doCall = (hook, path, params) => {
|
114
|
+
return hook.call(path, params);
|
115
|
+
};
|
116
|
+
function withCallInterceptor(interceptor, callback) {
|
117
|
+
let oldValue = doCall;
|
118
|
+
doCall = interceptor;
|
119
|
+
try {
|
120
|
+
return callback();
|
121
|
+
} finally {
|
122
|
+
doCall = oldValue;
|
123
|
+
}
|
124
|
+
}
|
125
|
+
var RAW_STUB = Symbol("realStub");
|
126
|
+
var PROXY_HANDLERS = {
|
127
|
+
apply(target, thisArg, argumentsList) {
|
128
|
+
let stub = target.raw;
|
129
|
+
return new RpcPromise(doCall(
|
130
|
+
stub.hook,
|
131
|
+
stub.pathIfPromise || [],
|
132
|
+
RpcPayload.fromAppParams(argumentsList)
|
133
|
+
), []);
|
134
|
+
},
|
135
|
+
get(target, prop, receiver) {
|
136
|
+
let stub = target.raw;
|
137
|
+
if (prop === RAW_STUB) {
|
138
|
+
return stub;
|
139
|
+
} else if (prop in RpcPromise.prototype) {
|
140
|
+
return stub[prop];
|
141
|
+
} else if (typeof prop === "string") {
|
142
|
+
return new RpcPromise(
|
143
|
+
stub.hook,
|
144
|
+
stub.pathIfPromise ? [...stub.pathIfPromise, prop] : [prop]
|
145
|
+
);
|
146
|
+
} else if (prop === Symbol.dispose && (!stub.pathIfPromise || stub.pathIfPromise.length == 0)) {
|
147
|
+
return () => {
|
148
|
+
stub.hook.dispose();
|
149
|
+
stub.hook = DISPOSED_HOOK;
|
150
|
+
};
|
151
|
+
} else {
|
152
|
+
return void 0;
|
68
153
|
}
|
154
|
+
},
|
155
|
+
has(target, prop) {
|
156
|
+
let stub = target.raw;
|
157
|
+
if (prop === RAW_STUB) {
|
158
|
+
return true;
|
159
|
+
} else if (prop in RpcPromise.prototype) {
|
160
|
+
return prop in stub;
|
161
|
+
} else if (typeof prop === "string") {
|
162
|
+
return true;
|
163
|
+
} else if (prop === Symbol.dispose && (!stub.pathIfPromise || stub.pathIfPromise.length == 0)) {
|
164
|
+
return true;
|
165
|
+
} else {
|
166
|
+
return false;
|
167
|
+
}
|
168
|
+
},
|
169
|
+
construct(target, args) {
|
170
|
+
throw new Error("An RPC stub cannot be used as a constructor.");
|
171
|
+
},
|
172
|
+
defineProperty(target, property, attributes) {
|
173
|
+
throw new Error("Can't define properties on RPC stubs.");
|
174
|
+
},
|
175
|
+
deleteProperty(target, p) {
|
176
|
+
throw new Error("Can't delete properties on RPC stubs.");
|
177
|
+
},
|
178
|
+
getOwnPropertyDescriptor(target, p) {
|
179
|
+
return void 0;
|
180
|
+
},
|
181
|
+
getPrototypeOf(target) {
|
182
|
+
return Object.getPrototypeOf(target.raw);
|
183
|
+
},
|
184
|
+
isExtensible(target) {
|
185
|
+
return false;
|
186
|
+
},
|
187
|
+
ownKeys(target) {
|
188
|
+
return [];
|
189
|
+
},
|
190
|
+
preventExtensions(target) {
|
191
|
+
return true;
|
192
|
+
},
|
193
|
+
set(target, p, newValue, receiver) {
|
194
|
+
throw new Error("Can't assign properties on RPC stubs.");
|
195
|
+
},
|
196
|
+
setPrototypeOf(target, v) {
|
197
|
+
throw new Error("Can't override prototype of RPC stubs.");
|
69
198
|
}
|
70
199
|
};
|
71
|
-
var
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
}
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
}, getOwnPropertyDescriptor(s9, e) {
|
91
|
-
}, getPrototypeOf(s9) {
|
92
|
-
return Object.getPrototypeOf(s9.raw);
|
93
|
-
}, isExtensible(s9) {
|
94
|
-
return false;
|
95
|
-
}, ownKeys(s9) {
|
96
|
-
return [];
|
97
|
-
}, preventExtensions(s9) {
|
98
|
-
return true;
|
99
|
-
}, set(s9, e, t, r) {
|
100
|
-
throw new Error("Can't assign properties on RPC stubs.");
|
101
|
-
}, setPrototypeOf(s9, e) {
|
102
|
-
throw new Error("Can't override prototype of RPC stubs.");
|
103
|
-
} };
|
104
|
-
var h = class s extends E {
|
105
|
-
constructor(e, t) {
|
106
|
-
if (super(), !(e instanceof y)) {
|
107
|
-
let o = e;
|
108
|
-
if (o instanceof E || o instanceof Function ? e = C.create(o, void 0) : e = new w(b.fromApp(o)), t) throw new TypeError("RpcStub constructor expected one argument, received two.");
|
109
|
-
}
|
110
|
-
this.hook = e, this.pathIfPromise = t;
|
111
|
-
let r = () => {
|
200
|
+
var RpcStub = class _RpcStub extends RpcTarget {
|
201
|
+
// Although `hook` and `path` are declared `public` here, they are effectively hidden by the
|
202
|
+
// proxy.
|
203
|
+
constructor(hook, pathIfPromise) {
|
204
|
+
super();
|
205
|
+
if (!(hook instanceof StubHook)) {
|
206
|
+
let value = hook;
|
207
|
+
if (value instanceof RpcTarget || value instanceof Function) {
|
208
|
+
hook = TargetStubHook.create(value, void 0);
|
209
|
+
} else {
|
210
|
+
hook = new PayloadStubHook(RpcPayload.fromAppReturn(value));
|
211
|
+
}
|
212
|
+
if (pathIfPromise) {
|
213
|
+
throw new TypeError("RpcStub constructor expected one argument, received two.");
|
214
|
+
}
|
215
|
+
}
|
216
|
+
this.hook = hook;
|
217
|
+
this.pathIfPromise = pathIfPromise;
|
218
|
+
let func = () => {
|
112
219
|
};
|
113
|
-
|
220
|
+
func.raw = this;
|
221
|
+
return new Proxy(func, PROXY_HANDLERS);
|
114
222
|
}
|
115
223
|
hook;
|
116
224
|
pathIfPromise;
|
117
225
|
dup() {
|
118
|
-
let
|
119
|
-
|
226
|
+
let target = this[RAW_STUB];
|
227
|
+
if (target.pathIfPromise) {
|
228
|
+
return new _RpcStub(target.hook.get(target.pathIfPromise));
|
229
|
+
} else {
|
230
|
+
return new _RpcStub(target.hook.dup());
|
231
|
+
}
|
232
|
+
}
|
233
|
+
onRpcBroken(callback) {
|
234
|
+
this[RAW_STUB].hook.onBroken(callback);
|
120
235
|
}
|
121
|
-
|
122
|
-
this[
|
236
|
+
map(func) {
|
237
|
+
let { hook, pathIfPromise } = this[RAW_STUB];
|
238
|
+
return mapImpl.sendMap(hook, pathIfPromise || [], func);
|
123
239
|
}
|
124
240
|
};
|
125
|
-
var
|
126
|
-
|
127
|
-
|
241
|
+
var RpcPromise = class extends RpcStub {
|
242
|
+
// TODO: Support passing target value or promise to constructor.
|
243
|
+
constructor(hook, pathIfPromise) {
|
244
|
+
super(hook, pathIfPromise);
|
128
245
|
}
|
129
|
-
then(
|
130
|
-
return
|
246
|
+
then(onfulfilled, onrejected) {
|
247
|
+
return pullPromise(this).then(...arguments);
|
131
248
|
}
|
132
|
-
catch(
|
133
|
-
return
|
249
|
+
catch(onrejected) {
|
250
|
+
return pullPromise(this).catch(...arguments);
|
134
251
|
}
|
135
|
-
finally(
|
136
|
-
return
|
252
|
+
finally(onfinally) {
|
253
|
+
return pullPromise(this).finally(...arguments);
|
137
254
|
}
|
138
255
|
};
|
139
|
-
function
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
256
|
+
function unwrapStubTakingOwnership(stub) {
|
257
|
+
let { hook, pathIfPromise } = stub[RAW_STUB];
|
258
|
+
if (pathIfPromise && pathIfPromise.length > 0) {
|
259
|
+
return hook.get(pathIfPromise);
|
260
|
+
} else {
|
261
|
+
return hook;
|
262
|
+
}
|
145
263
|
}
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
264
|
+
function unwrapStubAndDup(stub) {
|
265
|
+
let { hook, pathIfPromise } = stub[RAW_STUB];
|
266
|
+
if (pathIfPromise) {
|
267
|
+
return hook.get(pathIfPromise);
|
268
|
+
} else {
|
269
|
+
return hook.dup();
|
151
270
|
}
|
152
|
-
|
153
|
-
|
271
|
+
}
|
272
|
+
function unwrapStubNoProperties(stub) {
|
273
|
+
let { hook, pathIfPromise } = stub[RAW_STUB];
|
274
|
+
if (pathIfPromise && pathIfPromise.length > 0) {
|
275
|
+
return void 0;
|
154
276
|
}
|
155
|
-
|
156
|
-
|
277
|
+
return hook;
|
278
|
+
}
|
279
|
+
function unwrapStubOrParent(stub) {
|
280
|
+
return stub[RAW_STUB].hook;
|
281
|
+
}
|
282
|
+
function unwrapStubAndPath(stub) {
|
283
|
+
return stub[RAW_STUB];
|
284
|
+
}
|
285
|
+
async function pullPromise(promise) {
|
286
|
+
let { hook, pathIfPromise } = promise[RAW_STUB];
|
287
|
+
if (pathIfPromise.length > 0) {
|
288
|
+
hook = hook.get(pathIfPromise);
|
157
289
|
}
|
158
|
-
|
159
|
-
|
160
|
-
|
290
|
+
let payload = await hook.pull();
|
291
|
+
return payload.deliverResolve();
|
292
|
+
}
|
293
|
+
var RpcPayload = class _RpcPayload {
|
294
|
+
// Private constructor; use factory functions above to construct.
|
295
|
+
constructor(value, source, stubs, promises) {
|
296
|
+
this.value = value;
|
297
|
+
this.source = source;
|
298
|
+
this.stubs = stubs;
|
299
|
+
this.promises = promises;
|
300
|
+
}
|
301
|
+
// Create a payload from a value passed as params to an RPC from the app.
|
302
|
+
//
|
303
|
+
// The payload does NOT take ownership of any stubs in `value`, and but promises not to modify
|
304
|
+
// `value`. If the payload is delivered locally, `value` will be deep-copied first, so as not
|
305
|
+
// to have the sender and recipient end up sharing the same mutable object. `value` will not be
|
306
|
+
// touched again after the call returns synchronously (returns a promise) -- by that point,
|
307
|
+
// the value has either been copied or serialized to the wire.
|
308
|
+
static fromAppParams(value) {
|
309
|
+
return new _RpcPayload(value, "params");
|
310
|
+
}
|
311
|
+
// Create a payload from a value return from an RPC implementation by the app.
|
312
|
+
//
|
313
|
+
// Unlike fromAppParams(), in this case the payload takes ownership of all stubs in `value`, and
|
314
|
+
// may hold onto `value` for an arbitarily long time (e.g. to serve pipelined requests). It
|
315
|
+
// will still avoid modifying `value` and will make a deep copy if it is delivered locally.
|
316
|
+
static fromAppReturn(value) {
|
317
|
+
return new _RpcPayload(value, "return");
|
318
|
+
}
|
319
|
+
// Combine an array of payloads into a single payload whose value is an array. Ownership of all
|
320
|
+
// stubs is transferred from the inputs to the outputs, hence if the output is disposed, the
|
321
|
+
// inputs should not be. (In case of exception, nothing is disposed, though.)
|
322
|
+
static fromArray(array) {
|
323
|
+
let stubs = [];
|
324
|
+
let promises = [];
|
325
|
+
let resultArray = [];
|
326
|
+
for (let payload of array) {
|
327
|
+
payload.ensureDeepCopied();
|
328
|
+
for (let stub of payload.stubs) {
|
329
|
+
stubs.push(stub);
|
330
|
+
}
|
331
|
+
for (let promise of payload.promises) {
|
332
|
+
if (promise.parent === payload) {
|
333
|
+
promise = {
|
334
|
+
parent: resultArray,
|
335
|
+
property: resultArray.length,
|
336
|
+
promise: promise.promise
|
337
|
+
};
|
338
|
+
}
|
339
|
+
promises.push(promise);
|
340
|
+
}
|
341
|
+
resultArray.push(payload.value);
|
342
|
+
}
|
343
|
+
return new _RpcPayload(resultArray, "owned", stubs, promises);
|
344
|
+
}
|
345
|
+
// Create a payload from a value parsed off the wire using Evaluator.evaluate().
|
346
|
+
//
|
347
|
+
// A payload is constructed with a null value and the given stubs and promises arrays. The value
|
348
|
+
// is expected to be filled in by the evaluator, and the stubs and promises arrays are expected
|
349
|
+
// to be extended with stubs found during parsing. (This weird usage model is necessary so that
|
350
|
+
// if the root value turns out to be a promise, its `parent` in `promises` can be the payload
|
351
|
+
// object itself.)
|
352
|
+
//
|
353
|
+
// When done, the payload takes ownership of the final value and all the stubs within. It may
|
354
|
+
// modify the value in preparation for delivery, and may deliver the value directly to the app
|
355
|
+
// without copying.
|
356
|
+
static forEvaluate(stubs, promises) {
|
357
|
+
return new _RpcPayload(null, "owned", stubs, promises);
|
358
|
+
}
|
359
|
+
// Deep-copy the given value, including dup()ing all stubs.
|
360
|
+
//
|
361
|
+
// If `value` is a function, it should be bound to `oldParent` as its `this`.
|
362
|
+
//
|
363
|
+
// If deep-copying from a branch of some other RpcPayload, it must be provided, to make sure
|
364
|
+
// RpcTargets found within don't get duplicate stubs.
|
365
|
+
static deepCopyFrom(value, oldParent, owner) {
|
366
|
+
let result = new _RpcPayload(null, "owned", [], []);
|
367
|
+
result.value = result.deepCopy(
|
368
|
+
value,
|
369
|
+
oldParent,
|
370
|
+
"value",
|
371
|
+
result,
|
372
|
+
/*dupStubs=*/
|
373
|
+
true,
|
374
|
+
owner
|
375
|
+
);
|
376
|
+
return result;
|
161
377
|
}
|
378
|
+
// For `soruce === "return"` payloads only, this tracks any StubHooks created around RpcTargets
|
379
|
+
// found in the payload at the time that it is serialized (or deep-copied) for return, so that we
|
380
|
+
// can make sure they are not disposed before the pipeline ends.
|
381
|
+
//
|
382
|
+
// This is initialized on first use.
|
162
383
|
rpcTargets;
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
384
|
+
// Get the StubHook representing the given RpcTarget found inside this payload.
|
385
|
+
getHookForRpcTarget(target, parent, dupStubs = true) {
|
386
|
+
if (this.source === "params") {
|
387
|
+
return TargetStubHook.create(target, parent);
|
388
|
+
} else if (this.source === "return") {
|
389
|
+
let hook = this.rpcTargets?.get(target);
|
390
|
+
if (hook) {
|
391
|
+
if (dupStubs) {
|
392
|
+
return hook.dup();
|
393
|
+
} else {
|
394
|
+
this.rpcTargets?.delete(target);
|
395
|
+
return hook;
|
396
|
+
}
|
397
|
+
} else {
|
398
|
+
hook = TargetStubHook.create(target, parent);
|
399
|
+
if (dupStubs) {
|
400
|
+
if (!this.rpcTargets) {
|
401
|
+
this.rpcTargets = /* @__PURE__ */ new Map();
|
402
|
+
}
|
403
|
+
this.rpcTargets.set(target, hook);
|
404
|
+
return hook.dup();
|
405
|
+
} else {
|
406
|
+
return hook;
|
407
|
+
}
|
408
|
+
}
|
409
|
+
} else {
|
410
|
+
throw new Error("owned payload shouldn't contain raw RpcTargets");
|
411
|
+
}
|
170
412
|
}
|
171
|
-
deepCopy(
|
172
|
-
let
|
173
|
-
switch (
|
413
|
+
deepCopy(value, oldParent, property, parent, dupStubs, owner) {
|
414
|
+
let kind = typeForRpc(value);
|
415
|
+
switch (kind) {
|
174
416
|
case "unsupported":
|
175
|
-
return
|
417
|
+
return value;
|
176
418
|
case "primitive":
|
419
|
+
case "bigint":
|
177
420
|
case "date":
|
421
|
+
case "bytes":
|
178
422
|
case "error":
|
179
423
|
case "undefined":
|
180
|
-
return
|
424
|
+
return value;
|
181
425
|
case "array": {
|
182
|
-
let
|
183
|
-
|
184
|
-
|
426
|
+
let array = value;
|
427
|
+
let len = array.length;
|
428
|
+
let result = new Array(len);
|
429
|
+
for (let i = 0; i < len; i++) {
|
430
|
+
result[i] = this.deepCopy(array[i], array, i, result, dupStubs, owner);
|
431
|
+
}
|
432
|
+
return result;
|
185
433
|
}
|
186
434
|
case "object": {
|
187
|
-
let
|
188
|
-
|
189
|
-
|
435
|
+
let result = {};
|
436
|
+
let object = value;
|
437
|
+
for (let i in object) {
|
438
|
+
result[i] = this.deepCopy(object[i], object, i, result, dupStubs, owner);
|
439
|
+
}
|
440
|
+
return result;
|
190
441
|
}
|
191
442
|
case "stub":
|
192
443
|
case "rpc-promise": {
|
193
|
-
let
|
194
|
-
|
444
|
+
let stub = value;
|
445
|
+
let hook;
|
446
|
+
if (dupStubs) {
|
447
|
+
hook = unwrapStubAndDup(stub);
|
448
|
+
} else {
|
449
|
+
hook = unwrapStubTakingOwnership(stub);
|
450
|
+
}
|
451
|
+
if (stub instanceof RpcPromise) {
|
452
|
+
let promise = new RpcPromise(hook, []);
|
453
|
+
this.promises.push({ parent, property, promise });
|
454
|
+
return promise;
|
455
|
+
} else {
|
456
|
+
let newStub = new RpcStub(hook);
|
457
|
+
this.stubs.push(newStub);
|
458
|
+
return newStub;
|
459
|
+
}
|
195
460
|
}
|
196
461
|
case "function":
|
197
462
|
case "rpc-target": {
|
198
|
-
let
|
199
|
-
|
463
|
+
let target = value;
|
464
|
+
let stub;
|
465
|
+
if (owner) {
|
466
|
+
stub = new RpcStub(owner.getHookForRpcTarget(target, oldParent, dupStubs));
|
467
|
+
} else {
|
468
|
+
stub = new RpcStub(TargetStubHook.create(target, oldParent));
|
469
|
+
}
|
470
|
+
this.stubs.push(stub);
|
471
|
+
return stub;
|
472
|
+
}
|
473
|
+
case "rpc-thenable": {
|
474
|
+
let target = value;
|
475
|
+
let promise;
|
476
|
+
if (owner) {
|
477
|
+
promise = new RpcPromise(owner.getHookForRpcTarget(target, oldParent, dupStubs), []);
|
478
|
+
} else {
|
479
|
+
promise = new RpcPromise(TargetStubHook.create(target, oldParent), []);
|
480
|
+
}
|
481
|
+
this.promises.push({ parent, property, promise });
|
482
|
+
return promise;
|
200
483
|
}
|
201
484
|
default:
|
202
485
|
throw new Error("unreachable");
|
203
486
|
}
|
204
487
|
}
|
488
|
+
// Ensures that if the value originally came from an unowned source, we have replaced it with a
|
489
|
+
// deep copy.
|
205
490
|
ensureDeepCopied() {
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
}
|
491
|
+
if (this.source !== "owned") {
|
492
|
+
let dupStubs = this.source === "params";
|
493
|
+
this.stubs = [];
|
494
|
+
this.promises = [];
|
495
|
+
try {
|
496
|
+
this.value = this.deepCopy(this.value, void 0, "value", this, dupStubs, this);
|
497
|
+
} catch (err) {
|
498
|
+
this.stubs = void 0;
|
499
|
+
this.promises = void 0;
|
500
|
+
throw err;
|
501
|
+
}
|
502
|
+
this.source = "owned";
|
503
|
+
if (this.rpcTargets && this.rpcTargets.size > 0) {
|
504
|
+
throw new Error("Not all rpcTargets were accounted for in deep-copy?");
|
505
|
+
}
|
506
|
+
this.rpcTargets = void 0;
|
507
|
+
}
|
508
|
+
}
|
509
|
+
// Resolve all promises in this payload and then assign the final value into `parent[property]`.
|
510
|
+
deliverTo(parent, property, promises) {
|
511
|
+
this.ensureDeepCopied();
|
512
|
+
if (this.value instanceof RpcPromise) {
|
513
|
+
_RpcPayload.deliverRpcPromiseTo(this.value, parent, property, promises);
|
514
|
+
} else {
|
515
|
+
parent[property] = this.value;
|
516
|
+
for (let record of this.promises) {
|
517
|
+
_RpcPayload.deliverRpcPromiseTo(record.promise, record.parent, record.property, promises);
|
518
|
+
}
|
519
|
+
}
|
520
|
+
}
|
521
|
+
static deliverRpcPromiseTo(promise, parent, property, promises) {
|
522
|
+
let hook = unwrapStubNoProperties(promise);
|
523
|
+
if (!hook) {
|
524
|
+
throw new Error("property promises should have been resolved earlier");
|
525
|
+
}
|
526
|
+
let inner = hook.pull();
|
527
|
+
if (inner instanceof _RpcPayload) {
|
528
|
+
inner.deliverTo(parent, property, promises);
|
529
|
+
} else {
|
530
|
+
promises.push(inner.then((payload) => {
|
531
|
+
let subPromises = [];
|
532
|
+
payload.deliverTo(parent, property, subPromises);
|
533
|
+
if (subPromises.length > 0) {
|
534
|
+
return Promise.all(subPromises);
|
535
|
+
}
|
536
|
+
}));
|
537
|
+
}
|
223
538
|
}
|
224
|
-
|
539
|
+
// Call the given function with the payload as an argument. The call is made synchronously if
|
540
|
+
// possible, in order to maintain e-order. However, if any RpcPromises exist in the payload,
|
541
|
+
// they are awaited and substituted before calling the function. The result of the call is
|
542
|
+
// wrapped into another payload.
|
543
|
+
//
|
544
|
+
// The payload is automatically disposed after the call completes. The caller should not call
|
545
|
+
// dispose().
|
546
|
+
async deliverCall(func, thisArg) {
|
225
547
|
try {
|
226
|
-
let
|
227
|
-
this.deliverTo(this, "value",
|
228
|
-
|
229
|
-
|
548
|
+
let promises = [];
|
549
|
+
this.deliverTo(this, "value", promises);
|
550
|
+
if (promises.length > 0) {
|
551
|
+
await Promise.all(promises);
|
552
|
+
}
|
553
|
+
let result = Function.prototype.apply.call(func, thisArg, this.value);
|
554
|
+
if (result instanceof RpcPromise) {
|
555
|
+
return _RpcPayload.fromAppReturn(result);
|
556
|
+
} else {
|
557
|
+
return _RpcPayload.fromAppReturn(await result);
|
558
|
+
}
|
230
559
|
} finally {
|
231
560
|
this.dispose();
|
232
561
|
}
|
233
562
|
}
|
563
|
+
// Produce a promise for this payload for return to the application. Any RpcPromises in the
|
564
|
+
// payload are awaited and substituted with their results first.
|
565
|
+
//
|
566
|
+
// The returned object will have a disposer which disposes the payload. The caller should not
|
567
|
+
// separately dispose it.
|
234
568
|
async deliverResolve() {
|
235
569
|
try {
|
236
|
-
let
|
237
|
-
this.deliverTo(this, "value",
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
570
|
+
let promises = [];
|
571
|
+
this.deliverTo(this, "value", promises);
|
572
|
+
if (promises.length > 0) {
|
573
|
+
await Promise.all(promises);
|
574
|
+
}
|
575
|
+
let result = this.value;
|
576
|
+
if (result instanceof Object) {
|
577
|
+
if (!(Symbol.dispose in result)) {
|
578
|
+
Object.defineProperty(result, Symbol.dispose, {
|
579
|
+
// NOTE: Using `this.dispose.bind(this)` here causes Playwright's build of
|
580
|
+
// Chromium 140.0.7339.16 to fail when the object is assigned to a `using` variable,
|
581
|
+
// with the error:
|
582
|
+
// TypeError: Symbol(Symbol.dispose) is not a function
|
583
|
+
// I cannot reproduce this problem in Chrome 140.0.7339.127 nor in Node or workerd,
|
584
|
+
// so maybe it was a short-lived V8 bug or something. To be safe, though, we use
|
585
|
+
// `() => this.dispose()`, which seems to always work.
|
586
|
+
value: () => this.dispose(),
|
587
|
+
writable: true,
|
588
|
+
enumerable: false,
|
589
|
+
configurable: true
|
590
|
+
});
|
591
|
+
}
|
592
|
+
}
|
593
|
+
return result;
|
594
|
+
} catch (err) {
|
595
|
+
this.dispose();
|
596
|
+
throw err;
|
242
597
|
}
|
243
598
|
}
|
244
599
|
dispose() {
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
600
|
+
if (this.source === "owned") {
|
601
|
+
this.stubs.forEach((stub) => stub[Symbol.dispose]());
|
602
|
+
this.promises.forEach((promise) => promise.promise[Symbol.dispose]());
|
603
|
+
} else if (this.source === "return") {
|
604
|
+
this.disposeImpl(this.value, void 0);
|
605
|
+
if (this.rpcTargets && this.rpcTargets.size > 0) {
|
606
|
+
throw new Error("Not all rpcTargets were accounted for in disposeImpl()?");
|
607
|
+
}
|
608
|
+
} else ;
|
609
|
+
this.source = "owned";
|
610
|
+
this.stubs = [];
|
611
|
+
this.promises = [];
|
612
|
+
}
|
613
|
+
// Recursive dispose, called only when `source` is "return".
|
614
|
+
disposeImpl(value, parent) {
|
615
|
+
let kind = typeForRpc(value);
|
616
|
+
switch (kind) {
|
250
617
|
case "unsupported":
|
251
618
|
case "primitive":
|
619
|
+
case "bigint":
|
620
|
+
case "bytes":
|
252
621
|
case "date":
|
253
622
|
case "error":
|
254
623
|
case "undefined":
|
255
624
|
return;
|
256
625
|
case "array": {
|
257
|
-
let
|
258
|
-
|
626
|
+
let array = value;
|
627
|
+
let len = array.length;
|
628
|
+
for (let i = 0; i < len; i++) {
|
629
|
+
this.disposeImpl(array[i], array);
|
630
|
+
}
|
259
631
|
return;
|
260
632
|
}
|
261
633
|
case "object": {
|
262
|
-
let
|
263
|
-
for (let
|
634
|
+
let object = value;
|
635
|
+
for (let i in object) {
|
636
|
+
this.disposeImpl(object[i], object);
|
637
|
+
}
|
264
638
|
return;
|
265
639
|
}
|
266
640
|
case "stub":
|
267
641
|
case "rpc-promise": {
|
268
|
-
let
|
269
|
-
|
642
|
+
let stub = value;
|
643
|
+
let hook = unwrapStubNoProperties(stub);
|
644
|
+
if (hook) {
|
645
|
+
hook.dispose();
|
646
|
+
}
|
270
647
|
return;
|
271
648
|
}
|
272
649
|
case "function":
|
273
650
|
case "rpc-target": {
|
274
|
-
let
|
275
|
-
this.
|
651
|
+
let target = value;
|
652
|
+
let hook = this.rpcTargets?.get(target);
|
653
|
+
if (hook) {
|
654
|
+
hook.dispose();
|
655
|
+
this.rpcTargets.delete(target);
|
656
|
+
} else {
|
657
|
+
disposeRpcTarget(target);
|
658
|
+
}
|
276
659
|
return;
|
277
660
|
}
|
661
|
+
case "rpc-thenable":
|
662
|
+
return;
|
278
663
|
default:
|
279
664
|
return;
|
280
665
|
}
|
281
666
|
}
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
{
|
286
|
-
|
287
|
-
|
667
|
+
// Ignore unhandled rejections in all promises in this payload -- that is, all promises that
|
668
|
+
// *would* be awaited if this payload were to be delivered. See the similarly-named method of
|
669
|
+
// StubHook for explanation.
|
670
|
+
ignoreUnhandledRejections() {
|
671
|
+
if (this.stubs) {
|
672
|
+
this.stubs.forEach((stub) => {
|
673
|
+
unwrapStubOrParent(stub).ignoreUnhandledRejections();
|
674
|
+
});
|
675
|
+
this.promises.forEach(
|
676
|
+
(promise) => unwrapStubOrParent(promise.promise).ignoreUnhandledRejections()
|
677
|
+
);
|
678
|
+
} else {
|
679
|
+
this.ignoreUnhandledRejectionsImpl(this.value);
|
680
|
+
}
|
288
681
|
}
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
682
|
+
ignoreUnhandledRejectionsImpl(value) {
|
683
|
+
let kind = typeForRpc(value);
|
684
|
+
switch (kind) {
|
685
|
+
case "unsupported":
|
686
|
+
case "primitive":
|
687
|
+
case "bigint":
|
688
|
+
case "bytes":
|
689
|
+
case "date":
|
690
|
+
case "error":
|
691
|
+
case "undefined":
|
692
|
+
case "function":
|
693
|
+
case "rpc-target":
|
694
|
+
return;
|
695
|
+
case "array": {
|
696
|
+
let array = value;
|
697
|
+
let len = array.length;
|
698
|
+
for (let i = 0; i < len; i++) {
|
699
|
+
this.ignoreUnhandledRejectionsImpl(array[i]);
|
700
|
+
}
|
701
|
+
return;
|
702
|
+
}
|
703
|
+
case "object": {
|
704
|
+
let object = value;
|
705
|
+
for (let i in object) {
|
706
|
+
this.ignoreUnhandledRejectionsImpl(object[i]);
|
707
|
+
}
|
708
|
+
return;
|
709
|
+
}
|
710
|
+
case "stub":
|
711
|
+
case "rpc-promise":
|
712
|
+
unwrapStubOrParent(value).ignoreUnhandledRejections();
|
713
|
+
return;
|
714
|
+
case "rpc-thenable":
|
715
|
+
value.then((_) => {
|
716
|
+
}, (_) => {
|
717
|
+
});
|
718
|
+
return;
|
719
|
+
default:
|
720
|
+
return;
|
721
|
+
}
|
722
|
+
}
|
723
|
+
};
|
724
|
+
function followPath(value, parent, path, owner) {
|
725
|
+
for (let i = 0; i < path.length; i++) {
|
726
|
+
parent = value;
|
727
|
+
let part = path[i];
|
728
|
+
if (part in Object.prototype) {
|
729
|
+
value = void 0;
|
730
|
+
continue;
|
731
|
+
}
|
732
|
+
let kind = typeForRpc(value);
|
733
|
+
switch (kind) {
|
297
734
|
case "object":
|
298
|
-
case "array":
|
299
735
|
case "function":
|
300
|
-
Object.hasOwn(
|
736
|
+
if (Object.hasOwn(value, part)) {
|
737
|
+
value = value[part];
|
738
|
+
} else {
|
739
|
+
value = void 0;
|
740
|
+
}
|
301
741
|
break;
|
302
|
-
case "
|
303
|
-
|
742
|
+
case "array":
|
743
|
+
if (Number.isInteger(part) && part >= 0) {
|
744
|
+
value = value[part];
|
745
|
+
} else {
|
746
|
+
value = void 0;
|
747
|
+
}
|
748
|
+
break;
|
749
|
+
case "rpc-target":
|
750
|
+
case "rpc-thenable": {
|
751
|
+
if (Object.hasOwn(value, part)) {
|
752
|
+
value = void 0;
|
753
|
+
} else {
|
754
|
+
value = value[part];
|
755
|
+
}
|
756
|
+
owner = null;
|
304
757
|
break;
|
305
758
|
}
|
306
759
|
case "stub":
|
307
760
|
case "rpc-promise": {
|
308
|
-
let { hook
|
309
|
-
return { hook
|
761
|
+
let { hook, pathIfPromise } = unwrapStubAndPath(value);
|
762
|
+
return { hook, remainingPath: pathIfPromise ? pathIfPromise.concat(path.slice(i)) : path.slice(i) };
|
310
763
|
}
|
311
764
|
case "primitive":
|
765
|
+
case "bigint":
|
766
|
+
case "bytes":
|
312
767
|
case "date":
|
313
768
|
case "error":
|
769
|
+
value = void 0;
|
770
|
+
break;
|
314
771
|
case "undefined":
|
315
|
-
|
772
|
+
value = value[part];
|
773
|
+
break;
|
316
774
|
case "unsupported": {
|
317
|
-
if (
|
318
|
-
|
319
|
-
|
320
|
-
|
775
|
+
if (i === 0) {
|
776
|
+
throw new TypeError(`RPC stub points at a non-serializable type.`);
|
777
|
+
} else {
|
778
|
+
let prefix = path.slice(0, i).join(".");
|
779
|
+
let remainder = path.slice(0, i).join(".");
|
780
|
+
throw new TypeError(
|
781
|
+
`'${prefix}' is not a serializable type, so property ${remainder} cannot be accessed.`
|
782
|
+
);
|
321
783
|
}
|
322
784
|
}
|
323
785
|
default:
|
324
786
|
throw new TypeError("unreachable");
|
325
787
|
}
|
326
788
|
}
|
327
|
-
|
328
|
-
}
|
329
|
-
|
330
|
-
constructor(e) {
|
331
|
-
super(), this.payload = e;
|
789
|
+
if (value instanceof RpcPromise) {
|
790
|
+
let { hook, pathIfPromise } = unwrapStubAndPath(value);
|
791
|
+
return { hook, remainingPath: pathIfPromise || [] };
|
332
792
|
}
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
793
|
+
return {
|
794
|
+
value,
|
795
|
+
parent,
|
796
|
+
owner
|
797
|
+
};
|
798
|
+
}
|
799
|
+
var ValueStubHook = class extends StubHook {
|
800
|
+
call(path, args) {
|
801
|
+
try {
|
802
|
+
let { value, owner } = this.getValue();
|
803
|
+
let followResult = followPath(value, void 0, path, owner);
|
804
|
+
if (followResult.hook) {
|
805
|
+
return followResult.hook.call(followResult.remainingPath, args);
|
806
|
+
}
|
807
|
+
if (typeof followResult.value != "function") {
|
808
|
+
throw new TypeError(`'${path.join(".")}' is not a function.`);
|
809
|
+
}
|
810
|
+
let promise = args.deliverCall(followResult.value, followResult.parent);
|
811
|
+
return new PromiseStubHook(promise.then((payload) => {
|
812
|
+
return new PayloadStubHook(payload);
|
813
|
+
}));
|
814
|
+
} catch (err) {
|
815
|
+
return new ErrorStubHook(err);
|
816
|
+
}
|
337
817
|
}
|
338
|
-
|
818
|
+
map(path, captures, instructions) {
|
339
819
|
try {
|
340
|
-
let
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
820
|
+
let followResult;
|
821
|
+
try {
|
822
|
+
let { value, owner } = this.getValue();
|
823
|
+
followResult = followPath(value, void 0, path, owner);
|
824
|
+
;
|
825
|
+
} catch (err) {
|
826
|
+
for (let cap of captures) {
|
827
|
+
cap.dispose();
|
828
|
+
}
|
829
|
+
throw err;
|
830
|
+
}
|
831
|
+
if (followResult.hook) {
|
832
|
+
return followResult.hook.map(followResult.remainingPath, captures, instructions);
|
833
|
+
}
|
834
|
+
return mapImpl.applyMap(
|
835
|
+
followResult.value,
|
836
|
+
followResult.parent,
|
837
|
+
followResult.owner,
|
838
|
+
captures,
|
839
|
+
instructions
|
840
|
+
);
|
841
|
+
} catch (err) {
|
842
|
+
return new ErrorStubHook(err);
|
347
843
|
}
|
348
844
|
}
|
349
|
-
get(
|
845
|
+
get(path) {
|
350
846
|
try {
|
351
|
-
let
|
352
|
-
|
353
|
-
|
354
|
-
|
847
|
+
let { value, owner } = this.getValue();
|
848
|
+
if (path.length === 0 && owner === null) {
|
849
|
+
throw new Error("Can't dup an RpcTarget stub as a promise.");
|
850
|
+
}
|
851
|
+
let followResult = followPath(value, void 0, path, owner);
|
852
|
+
if (followResult.hook) {
|
853
|
+
return followResult.hook.get(followResult.remainingPath);
|
854
|
+
}
|
855
|
+
return new PayloadStubHook(RpcPayload.deepCopyFrom(
|
856
|
+
followResult.value,
|
857
|
+
followResult.parent,
|
858
|
+
followResult.owner
|
859
|
+
));
|
860
|
+
} catch (err) {
|
861
|
+
return new ErrorStubHook(err);
|
355
862
|
}
|
356
863
|
}
|
864
|
+
};
|
865
|
+
var PayloadStubHook = class _PayloadStubHook extends ValueStubHook {
|
866
|
+
constructor(payload) {
|
867
|
+
super();
|
868
|
+
this.payload = payload;
|
869
|
+
}
|
870
|
+
payload;
|
871
|
+
// cleared when disposed
|
872
|
+
getPayload() {
|
873
|
+
if (this.payload) {
|
874
|
+
return this.payload;
|
875
|
+
} else {
|
876
|
+
throw new Error("Attempted to use an RPC StubHook after it was disposed.");
|
877
|
+
}
|
878
|
+
}
|
879
|
+
getValue() {
|
880
|
+
let payload = this.getPayload();
|
881
|
+
return { value: payload.value, owner: payload };
|
882
|
+
}
|
357
883
|
dup() {
|
358
|
-
let
|
359
|
-
return new
|
884
|
+
let thisPayload = this.getPayload();
|
885
|
+
return new _PayloadStubHook(RpcPayload.deepCopyFrom(
|
886
|
+
thisPayload.value,
|
887
|
+
void 0,
|
888
|
+
thisPayload
|
889
|
+
));
|
360
890
|
}
|
361
891
|
pull() {
|
362
892
|
return this.getPayload();
|
363
893
|
}
|
894
|
+
ignoreUnhandledRejections() {
|
895
|
+
if (this.payload) {
|
896
|
+
this.payload.ignoreUnhandledRejections();
|
897
|
+
}
|
898
|
+
}
|
364
899
|
dispose() {
|
365
|
-
|
900
|
+
if (this.payload) {
|
901
|
+
this.payload.dispose();
|
902
|
+
this.payload = void 0;
|
903
|
+
}
|
366
904
|
}
|
367
|
-
onBroken(
|
368
|
-
|
905
|
+
onBroken(callback) {
|
906
|
+
if (this.payload) {
|
907
|
+
if (this.payload.value instanceof RpcStub) {
|
908
|
+
this.payload.value.onRpcBroken(callback);
|
909
|
+
}
|
910
|
+
}
|
369
911
|
}
|
370
912
|
};
|
371
|
-
|
372
|
-
|
373
|
-
|
913
|
+
function disposeRpcTarget(target) {
|
914
|
+
if (Symbol.dispose in target) {
|
915
|
+
try {
|
916
|
+
target[Symbol.dispose]();
|
917
|
+
} catch (err) {
|
918
|
+
Promise.reject(err);
|
919
|
+
}
|
374
920
|
}
|
375
|
-
|
376
|
-
|
921
|
+
}
|
922
|
+
var TargetStubHook = class _TargetStubHook extends ValueStubHook {
|
923
|
+
// Constructs a TargetStubHook that is not duplicated from an existing hook.
|
924
|
+
//
|
925
|
+
// If `value` is a function, `parent` is bound as its "this".
|
926
|
+
static create(value, parent) {
|
927
|
+
if (typeof value !== "function") {
|
928
|
+
parent = void 0;
|
929
|
+
}
|
930
|
+
return new _TargetStubHook(value, parent);
|
931
|
+
}
|
932
|
+
constructor(target, parent, dupFrom) {
|
933
|
+
super();
|
934
|
+
this.target = target;
|
935
|
+
this.parent = parent;
|
936
|
+
if (dupFrom) {
|
937
|
+
if (dupFrom.refcount) {
|
938
|
+
this.refcount = dupFrom.refcount;
|
939
|
+
++this.refcount.count;
|
940
|
+
}
|
941
|
+
} else if (Symbol.dispose in target) {
|
942
|
+
this.refcount = { count: 1 };
|
943
|
+
}
|
377
944
|
}
|
378
945
|
target;
|
946
|
+
// cleared when disposed
|
379
947
|
parent;
|
948
|
+
// `this` parameter when calling `target`
|
380
949
|
refcount;
|
950
|
+
// undefined if not needed (because target has no disposer)
|
381
951
|
getTarget() {
|
382
|
-
if (this.target)
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
try {
|
387
|
-
let r = this.getTarget(), o = H(r, this.parent, e, null);
|
388
|
-
if (o.hook) return o.hook.call(o.remainingPath, t);
|
389
|
-
if (typeof o.value != "function") throw new TypeError(`'${e.join(".")}' is not a function.`);
|
390
|
-
let n = t.deliverCall(o.value, o.parent);
|
391
|
-
return new j(n.then((i) => new w(i)));
|
392
|
-
} catch (r) {
|
393
|
-
return new f(r);
|
952
|
+
if (this.target) {
|
953
|
+
return this.target;
|
954
|
+
} else {
|
955
|
+
throw new Error("Attempted to use an RPC StubHook after it was disposed.");
|
394
956
|
}
|
395
957
|
}
|
396
|
-
|
397
|
-
|
398
|
-
if (e.length == 0) throw new Error("Can't dup an RpcTarget stub as a promise.");
|
399
|
-
let t = this.getTarget(), r = H(t, this.parent, e, null);
|
400
|
-
return r.hook ? r.hook.get(r.remainingPath) : new w(b.deepCopyFrom(r.value, r.parent, r.owner));
|
401
|
-
} catch (t) {
|
402
|
-
return new f(t);
|
403
|
-
}
|
958
|
+
getValue() {
|
959
|
+
return { value: this.getTarget(), owner: null };
|
404
960
|
}
|
405
961
|
dup() {
|
406
|
-
return new
|
962
|
+
return new _TargetStubHook(this.getTarget(), this.parent, this);
|
407
963
|
}
|
408
964
|
pull() {
|
409
|
-
|
965
|
+
let target = this.getTarget();
|
966
|
+
if ("then" in target) {
|
967
|
+
return Promise.resolve(target).then((resolution) => {
|
968
|
+
return RpcPayload.fromAppReturn(resolution);
|
969
|
+
});
|
970
|
+
} else {
|
971
|
+
return Promise.reject(new Error("Tried to resolve a non-promise stub."));
|
972
|
+
}
|
973
|
+
}
|
974
|
+
ignoreUnhandledRejections() {
|
410
975
|
}
|
411
976
|
dispose() {
|
412
977
|
if (this.target) {
|
413
|
-
if (this.refcount
|
414
|
-
this.
|
415
|
-
|
416
|
-
|
978
|
+
if (this.refcount) {
|
979
|
+
if (--this.refcount.count == 0) {
|
980
|
+
disposeRpcTarget(this.target);
|
981
|
+
}
|
417
982
|
}
|
418
983
|
this.target = void 0;
|
419
984
|
}
|
420
985
|
}
|
421
|
-
onBroken(
|
986
|
+
onBroken(callback) {
|
422
987
|
}
|
423
988
|
};
|
424
|
-
var
|
989
|
+
var PromiseStubHook = class _PromiseStubHook extends StubHook {
|
425
990
|
promise;
|
426
991
|
resolution;
|
427
|
-
constructor(
|
428
|
-
super()
|
992
|
+
constructor(promise) {
|
993
|
+
super();
|
994
|
+
this.promise = promise.then((res) => {
|
995
|
+
this.resolution = res;
|
996
|
+
return res;
|
997
|
+
});
|
429
998
|
}
|
430
|
-
call(
|
431
|
-
|
999
|
+
call(path, args) {
|
1000
|
+
args.ensureDeepCopied();
|
1001
|
+
return new _PromiseStubHook(this.promise.then((hook) => hook.call(path, args)));
|
432
1002
|
}
|
433
|
-
|
434
|
-
return new
|
1003
|
+
map(path, captures, instructions) {
|
1004
|
+
return new _PromiseStubHook(this.promise.then(
|
1005
|
+
(hook) => hook.map(path, captures, instructions),
|
1006
|
+
(err) => {
|
1007
|
+
for (let cap of captures) {
|
1008
|
+
cap.dispose();
|
1009
|
+
}
|
1010
|
+
throw err;
|
1011
|
+
}
|
1012
|
+
));
|
1013
|
+
}
|
1014
|
+
get(path) {
|
1015
|
+
return new _PromiseStubHook(this.promise.then((hook) => hook.get(path)));
|
435
1016
|
}
|
436
1017
|
dup() {
|
437
|
-
|
1018
|
+
if (this.resolution) {
|
1019
|
+
return this.resolution.dup();
|
1020
|
+
} else {
|
1021
|
+
return new _PromiseStubHook(this.promise.then((hook) => hook.dup()));
|
1022
|
+
}
|
438
1023
|
}
|
439
1024
|
pull() {
|
440
|
-
|
1025
|
+
if (this.resolution) {
|
1026
|
+
return this.resolution.pull();
|
1027
|
+
} else {
|
1028
|
+
return this.promise.then((hook) => hook.pull());
|
1029
|
+
}
|
1030
|
+
}
|
1031
|
+
ignoreUnhandledRejections() {
|
1032
|
+
if (this.resolution) {
|
1033
|
+
this.resolution.ignoreUnhandledRejections();
|
1034
|
+
} else {
|
1035
|
+
this.promise.then((res) => {
|
1036
|
+
res.ignoreUnhandledRejections();
|
1037
|
+
}, (err) => {
|
1038
|
+
});
|
1039
|
+
}
|
441
1040
|
}
|
442
1041
|
dispose() {
|
443
|
-
|
444
|
-
|
445
|
-
}
|
446
|
-
|
1042
|
+
if (this.resolution) {
|
1043
|
+
this.resolution.dispose();
|
1044
|
+
} else {
|
1045
|
+
this.promise.then((hook) => {
|
1046
|
+
hook.dispose();
|
1047
|
+
}, (err) => {
|
1048
|
+
});
|
1049
|
+
}
|
447
1050
|
}
|
448
|
-
onBroken(
|
449
|
-
|
450
|
-
|
451
|
-
}
|
1051
|
+
onBroken(callback) {
|
1052
|
+
if (this.resolution) {
|
1053
|
+
this.resolution.onBroken(callback);
|
1054
|
+
} else {
|
1055
|
+
this.promise.then((hook) => {
|
1056
|
+
hook.onBroken(callback);
|
1057
|
+
}, callback);
|
1058
|
+
}
|
452
1059
|
}
|
453
1060
|
};
|
454
|
-
var
|
455
|
-
exportStub(
|
1061
|
+
var NullExporter = class {
|
1062
|
+
exportStub(stub) {
|
456
1063
|
throw new Error("Cannot serialize RPC stubs without an RPC session.");
|
457
1064
|
}
|
458
|
-
exportPromise(
|
1065
|
+
exportPromise(stub) {
|
459
1066
|
throw new Error("Cannot serialize RPC stubs without an RPC session.");
|
460
1067
|
}
|
461
|
-
getImport(
|
1068
|
+
getImport(hook) {
|
1069
|
+
return void 0;
|
462
1070
|
}
|
463
|
-
unexport(
|
1071
|
+
unexport(ids) {
|
464
1072
|
}
|
465
|
-
onSendError(
|
1073
|
+
onSendError(error) {
|
466
1074
|
}
|
467
1075
|
};
|
468
|
-
var
|
469
|
-
var
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
1076
|
+
var NULL_EXPORTER = new NullExporter();
|
1077
|
+
var ERROR_TYPES = {
|
1078
|
+
Error,
|
1079
|
+
EvalError,
|
1080
|
+
RangeError,
|
1081
|
+
ReferenceError,
|
1082
|
+
SyntaxError,
|
1083
|
+
TypeError,
|
1084
|
+
URIError,
|
1085
|
+
AggregateError
|
1086
|
+
// TODO: DOMError? Others?
|
1087
|
+
};
|
1088
|
+
var Devaluator = class _Devaluator {
|
1089
|
+
constructor(exporter, source) {
|
1090
|
+
this.exporter = exporter;
|
1091
|
+
this.source = source;
|
1092
|
+
}
|
1093
|
+
// Devaluate the given value.
|
1094
|
+
// * value: The value to devaluate.
|
1095
|
+
// * parent: The value's parent object, which would be used as `this` if the value were called
|
1096
|
+
// as a function.
|
1097
|
+
// * exporter: Callbacks to the RPC session for exporting capabilities found in this message.
|
1098
|
+
// * source: The RpcPayload which contains the value, and therefore owns stubs within.
|
1099
|
+
//
|
1100
|
+
// Returns: The devaluated value, ready to be JSON-serialized.
|
1101
|
+
static devaluate(value, parent, exporter = NULL_EXPORTER, source) {
|
1102
|
+
let devaluator = new _Devaluator(exporter, source);
|
478
1103
|
try {
|
479
|
-
return
|
480
|
-
} catch (
|
481
|
-
if (
|
482
|
-
|
483
|
-
|
1104
|
+
return devaluator.devaluateImpl(value, parent, 0);
|
1105
|
+
} catch (err) {
|
1106
|
+
if (devaluator.exports) {
|
1107
|
+
try {
|
1108
|
+
exporter.unexport(devaluator.exports);
|
1109
|
+
} catch (err2) {
|
1110
|
+
}
|
484
1111
|
}
|
485
|
-
throw
|
1112
|
+
throw err;
|
486
1113
|
}
|
487
1114
|
}
|
488
1115
|
exports;
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
1116
|
+
devaluateImpl(value, parent, depth) {
|
1117
|
+
if (depth >= 64) {
|
1118
|
+
throw new Error(
|
1119
|
+
"Serialization exceeded maximum allowed depth. (Does the message contain cycles?)"
|
1120
|
+
);
|
1121
|
+
}
|
1122
|
+
let kind = typeForRpc(value);
|
1123
|
+
switch (kind) {
|
1124
|
+
case "unsupported": {
|
1125
|
+
let msg;
|
1126
|
+
try {
|
1127
|
+
msg = `Cannot serialize value: ${value}`;
|
1128
|
+
} catch (err) {
|
1129
|
+
msg = "Cannot serialize value: (couldn't stringify value)";
|
1130
|
+
}
|
1131
|
+
throw new TypeError(msg);
|
1132
|
+
}
|
496
1133
|
case "primitive":
|
497
|
-
return
|
1134
|
+
return value;
|
498
1135
|
case "object": {
|
499
|
-
let
|
500
|
-
|
501
|
-
|
1136
|
+
let object = value;
|
1137
|
+
let result = {};
|
1138
|
+
for (let key in object) {
|
1139
|
+
result[key] = this.devaluateImpl(object[key], object, depth + 1);
|
1140
|
+
}
|
1141
|
+
return result;
|
502
1142
|
}
|
503
1143
|
case "array": {
|
504
|
-
let
|
505
|
-
|
506
|
-
|
1144
|
+
let array = value;
|
1145
|
+
let len = array.length;
|
1146
|
+
let result = new Array(len);
|
1147
|
+
for (let i = 0; i < len; i++) {
|
1148
|
+
result[i] = this.devaluateImpl(array[i], array, depth + 1);
|
1149
|
+
}
|
1150
|
+
return [result];
|
507
1151
|
}
|
1152
|
+
case "bigint":
|
1153
|
+
return ["bigint", value.toString()];
|
508
1154
|
case "date":
|
509
|
-
return ["date",
|
1155
|
+
return ["date", value.getTime()];
|
1156
|
+
case "bytes": {
|
1157
|
+
let bytes = value;
|
1158
|
+
if (bytes.toBase64) {
|
1159
|
+
return ["bytes", bytes.toBase64({ omitPadding: true })];
|
1160
|
+
} else {
|
1161
|
+
return [
|
1162
|
+
"bytes",
|
1163
|
+
btoa(String.fromCharCode.apply(null, bytes).replace(/=*$/, ""))
|
1164
|
+
];
|
1165
|
+
}
|
1166
|
+
}
|
510
1167
|
case "error": {
|
511
|
-
let
|
512
|
-
|
513
|
-
|
514
|
-
|
1168
|
+
let e = value;
|
1169
|
+
let rewritten = this.exporter.onSendError(e);
|
1170
|
+
if (rewritten) {
|
1171
|
+
e = rewritten;
|
1172
|
+
}
|
1173
|
+
let result = ["error", e.name, e.message];
|
1174
|
+
if (rewritten && rewritten.stack) {
|
1175
|
+
result.push(rewritten.stack);
|
1176
|
+
}
|
1177
|
+
return result;
|
515
1178
|
}
|
516
1179
|
case "undefined":
|
517
1180
|
return ["undefined"];
|
518
1181
|
case "stub":
|
519
1182
|
case "rpc-promise": {
|
520
|
-
if (!this.source)
|
521
|
-
|
522
|
-
|
1183
|
+
if (!this.source) {
|
1184
|
+
throw new Error("Can't serialize RPC stubs in this context.");
|
1185
|
+
}
|
1186
|
+
let { hook, pathIfPromise } = unwrapStubAndPath(value);
|
1187
|
+
let importId = this.exporter.getImport(hook);
|
1188
|
+
if (importId !== void 0) {
|
1189
|
+
if (pathIfPromise) {
|
1190
|
+
if (pathIfPromise.length > 0) {
|
1191
|
+
return ["pipeline", importId, pathIfPromise];
|
1192
|
+
} else {
|
1193
|
+
return ["pipeline", importId];
|
1194
|
+
}
|
1195
|
+
} else {
|
1196
|
+
return ["import", importId];
|
1197
|
+
}
|
1198
|
+
}
|
1199
|
+
if (pathIfPromise) {
|
1200
|
+
hook = hook.get(pathIfPromise);
|
1201
|
+
} else {
|
1202
|
+
hook = hook.dup();
|
1203
|
+
}
|
1204
|
+
return this.devaluateHook(pathIfPromise ? "promise" : "export", hook);
|
523
1205
|
}
|
524
1206
|
case "function":
|
525
1207
|
case "rpc-target": {
|
526
|
-
if (!this.source)
|
527
|
-
|
528
|
-
|
1208
|
+
if (!this.source) {
|
1209
|
+
throw new Error("Can't serialize RPC stubs in this context.");
|
1210
|
+
}
|
1211
|
+
let hook = this.source.getHookForRpcTarget(value, parent);
|
1212
|
+
return this.devaluateHook("export", hook);
|
1213
|
+
}
|
1214
|
+
case "rpc-thenable": {
|
1215
|
+
if (!this.source) {
|
1216
|
+
throw new Error("Can't serialize RPC stubs in this context.");
|
1217
|
+
}
|
1218
|
+
let hook = this.source.getHookForRpcTarget(value, parent);
|
1219
|
+
return this.devaluateHook("promise", hook);
|
529
1220
|
}
|
530
1221
|
default:
|
531
1222
|
throw new Error("unreachable");
|
532
1223
|
}
|
533
1224
|
}
|
534
|
-
devaluateHook(
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
else if (t.length > 0) throw new Error("RPC system bug: Unexpected uncloned promise in from-app payload.");
|
540
|
-
let o = this.exporter.exportPromise(e);
|
541
|
-
return this.exports.push(o), ["promise", o];
|
542
|
-
} else {
|
543
|
-
this.takeOwnership || (e = e.dup());
|
544
|
-
let o = this.exporter.exportStub(e);
|
545
|
-
return this.exports.push(o), ["export", o];
|
546
|
-
}
|
1225
|
+
devaluateHook(type, hook) {
|
1226
|
+
if (!this.exports) this.exports = [];
|
1227
|
+
let exportId = type === "promise" ? this.exporter.exportPromise(hook) : this.exporter.exportStub(hook);
|
1228
|
+
this.exports.push(exportId);
|
1229
|
+
return [type, exportId];
|
547
1230
|
}
|
548
1231
|
};
|
549
|
-
var
|
550
|
-
importStub(
|
1232
|
+
var NullImporter = class {
|
1233
|
+
importStub(idx) {
|
551
1234
|
throw new Error("Cannot deserialize RPC stubs without an RPC session.");
|
552
1235
|
}
|
553
|
-
importPromise(
|
1236
|
+
importPromise(idx) {
|
554
1237
|
throw new Error("Cannot deserialize RPC stubs without an RPC session.");
|
555
1238
|
}
|
556
|
-
getExport(
|
1239
|
+
getExport(idx) {
|
1240
|
+
return void 0;
|
557
1241
|
}
|
558
1242
|
};
|
559
|
-
var
|
560
|
-
var
|
561
|
-
constructor(
|
562
|
-
this.importer =
|
1243
|
+
var NULL_IMPORTER = new NullImporter();
|
1244
|
+
var Evaluator = class _Evaluator {
|
1245
|
+
constructor(importer) {
|
1246
|
+
this.importer = importer;
|
563
1247
|
}
|
564
1248
|
stubs = [];
|
565
1249
|
promises = [];
|
566
|
-
evaluate(
|
567
|
-
let
|
1250
|
+
evaluate(value) {
|
1251
|
+
let payload = RpcPayload.forEvaluate(this.stubs, this.promises);
|
568
1252
|
try {
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
1253
|
+
payload.value = this.evaluateImpl(value, payload, "value");
|
1254
|
+
return payload;
|
1255
|
+
} catch (err) {
|
1256
|
+
payload.dispose();
|
1257
|
+
throw err;
|
1258
|
+
}
|
1259
|
+
}
|
1260
|
+
// Evaluate the value without destroying it.
|
1261
|
+
evaluateCopy(value) {
|
1262
|
+
return this.evaluate(structuredClone(value));
|
1263
|
+
}
|
1264
|
+
evaluateImpl(value, parent, property) {
|
1265
|
+
if (value instanceof Array) {
|
1266
|
+
if (value.length == 1 && value[0] instanceof Array) {
|
1267
|
+
let result = value[0];
|
1268
|
+
for (let i = 0; i < result.length; i++) {
|
1269
|
+
result[i] = this.evaluateImpl(result[i], result, i);
|
1270
|
+
}
|
1271
|
+
return result;
|
1272
|
+
} else switch (value[0]) {
|
1273
|
+
case "bigint":
|
1274
|
+
if (typeof value[1] == "string") {
|
1275
|
+
return BigInt(value[1]);
|
1276
|
+
}
|
1277
|
+
break;
|
581
1278
|
case "date":
|
582
|
-
if (typeof
|
1279
|
+
if (typeof value[1] == "number") {
|
1280
|
+
return new Date(value[1]);
|
1281
|
+
}
|
583
1282
|
break;
|
1283
|
+
case "bytes": {
|
1284
|
+
let b64 = Uint8Array;
|
1285
|
+
if (typeof value[1] == "string") {
|
1286
|
+
if (b64.fromBase64) {
|
1287
|
+
return b64.fromBase64(value[1]);
|
1288
|
+
} else {
|
1289
|
+
let bs = atob(value[1]);
|
1290
|
+
let len = bs.length;
|
1291
|
+
let bytes = new Uint8Array(len);
|
1292
|
+
for (let i = 0; i < len; i++) {
|
1293
|
+
bytes[i] = bs.charCodeAt(i);
|
1294
|
+
}
|
1295
|
+
return bytes;
|
1296
|
+
}
|
1297
|
+
}
|
1298
|
+
break;
|
1299
|
+
}
|
584
1300
|
case "error":
|
585
|
-
if (
|
586
|
-
let
|
587
|
-
|
1301
|
+
if (value.length >= 3 && typeof value[1] === "string" && typeof value[2] === "string") {
|
1302
|
+
let cls = ERROR_TYPES[value[1]] || Error;
|
1303
|
+
let result = new cls(value[2]);
|
1304
|
+
if (typeof value[3] === "string") {
|
1305
|
+
result.stack = value[3];
|
1306
|
+
}
|
1307
|
+
return result;
|
588
1308
|
}
|
589
1309
|
break;
|
590
1310
|
case "undefined":
|
591
|
-
if (
|
1311
|
+
if (value.length === 1) {
|
1312
|
+
return void 0;
|
1313
|
+
}
|
592
1314
|
break;
|
593
1315
|
case "import":
|
594
|
-
case "pipeline":
|
595
|
-
if (
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
1316
|
+
case "pipeline": {
|
1317
|
+
if (value.length < 2 || value.length > 4) {
|
1318
|
+
break;
|
1319
|
+
}
|
1320
|
+
if (typeof value[1] != "number") {
|
1321
|
+
break;
|
1322
|
+
}
|
1323
|
+
let hook = this.importer.getExport(value[1]);
|
1324
|
+
if (!hook) {
|
1325
|
+
throw new Error(`no such entry on exports table: ${value[1]}`);
|
1326
|
+
}
|
1327
|
+
let isPromise = value[0] == "pipeline";
|
1328
|
+
let addStub = (hook2) => {
|
1329
|
+
if (isPromise) {
|
1330
|
+
let promise = new RpcPromise(hook2, []);
|
1331
|
+
this.promises.push({ promise, parent, property });
|
1332
|
+
return promise;
|
602
1333
|
} else {
|
603
|
-
let
|
604
|
-
|
1334
|
+
let stub = new RpcPromise(hook2, []);
|
1335
|
+
this.stubs.push(stub);
|
1336
|
+
return stub;
|
605
1337
|
}
|
606
1338
|
};
|
607
|
-
if (
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
1339
|
+
if (value.length == 2) {
|
1340
|
+
if (isPromise) {
|
1341
|
+
return addStub(hook.get([]));
|
1342
|
+
} else {
|
1343
|
+
return addStub(hook.dup());
|
1344
|
+
}
|
1345
|
+
}
|
1346
|
+
let path = value[2];
|
1347
|
+
if (!(path instanceof Array)) {
|
1348
|
+
break;
|
1349
|
+
}
|
1350
|
+
if (!path.every(
|
1351
|
+
(part) => {
|
1352
|
+
return typeof part == "string" || typeof part == "number";
|
1353
|
+
}
|
1354
|
+
)) {
|
1355
|
+
break;
|
1356
|
+
}
|
1357
|
+
if (value.length == 3) {
|
1358
|
+
return addStub(hook.get(path));
|
1359
|
+
}
|
1360
|
+
let args = value[3];
|
1361
|
+
if (!(args instanceof Array)) {
|
1362
|
+
break;
|
1363
|
+
}
|
1364
|
+
let subEval = new _Evaluator(this.importer);
|
1365
|
+
args = subEval.evaluate([args]);
|
1366
|
+
return addStub(hook.call(path, args));
|
1367
|
+
}
|
1368
|
+
case "remap": {
|
1369
|
+
if (value.length !== 5 || typeof value[1] !== "number" || !(value[2] instanceof Array) || !(value[3] instanceof Array) || !(value[4] instanceof Array)) {
|
1370
|
+
break;
|
1371
|
+
}
|
1372
|
+
let hook = this.importer.getExport(value[1]);
|
1373
|
+
if (!hook) {
|
1374
|
+
throw new Error(`no such entry on exports table: ${value[1]}`);
|
1375
|
+
}
|
1376
|
+
let path = value[2];
|
1377
|
+
if (!path.every(
|
1378
|
+
(part) => {
|
1379
|
+
return typeof part == "string" || typeof part == "number";
|
1380
|
+
}
|
1381
|
+
)) {
|
1382
|
+
break;
|
1383
|
+
}
|
1384
|
+
let captures = value[3].map((cap) => {
|
1385
|
+
if (!(cap instanceof Array) || cap.length !== 2 || cap[0] !== "import" && cap[0] !== "export" || typeof cap[1] !== "number") {
|
1386
|
+
throw new TypeError(`unknown map capture: ${JSON.stringify(cap)}`);
|
1387
|
+
}
|
1388
|
+
if (cap[0] === "export") {
|
1389
|
+
return this.importer.importStub(cap[1]);
|
1390
|
+
} else {
|
1391
|
+
let exp = this.importer.getExport(cap[1]);
|
1392
|
+
if (!exp) {
|
1393
|
+
throw new Error(`no such entry on exports table: ${cap[1]}`);
|
1394
|
+
}
|
1395
|
+
return exp.dup();
|
1396
|
+
}
|
1397
|
+
});
|
1398
|
+
let instructions = value[4];
|
1399
|
+
let resultHook = hook.map(path, captures, instructions);
|
1400
|
+
let promise = new RpcPromise(resultHook, []);
|
1401
|
+
this.promises.push({ promise, parent, property });
|
1402
|
+
return promise;
|
1403
|
+
}
|
614
1404
|
case "export":
|
615
1405
|
case "promise":
|
616
|
-
if (typeof
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
1406
|
+
if (typeof value[1] == "number") {
|
1407
|
+
if (value[0] == "promise") {
|
1408
|
+
let hook = this.importer.importPromise(value[1]);
|
1409
|
+
let promise = new RpcPromise(hook, []);
|
1410
|
+
this.promises.push({ parent, property, promise });
|
1411
|
+
return promise;
|
1412
|
+
} else {
|
1413
|
+
let hook = this.importer.importStub(value[1]);
|
1414
|
+
let stub = new RpcStub(hook);
|
1415
|
+
this.stubs.push(stub);
|
1416
|
+
return stub;
|
1417
|
+
}
|
622
1418
|
}
|
623
1419
|
break;
|
624
1420
|
}
|
625
|
-
throw new TypeError(`unknown special value: ${JSON.stringify(
|
626
|
-
} else if (
|
627
|
-
let
|
628
|
-
for (let
|
629
|
-
|
630
|
-
|
1421
|
+
throw new TypeError(`unknown special value: ${JSON.stringify(value)}`);
|
1422
|
+
} else if (value instanceof Object) {
|
1423
|
+
let result = value;
|
1424
|
+
for (let key in result) {
|
1425
|
+
if (key in Object.prototype || key === "toJSON") {
|
1426
|
+
this.evaluateImpl(result[key], result, key);
|
1427
|
+
delete result[key];
|
1428
|
+
} else {
|
1429
|
+
result[key] = this.evaluateImpl(result[key], result, key);
|
1430
|
+
}
|
1431
|
+
}
|
1432
|
+
return result;
|
1433
|
+
} else {
|
1434
|
+
return value;
|
1435
|
+
}
|
631
1436
|
}
|
632
1437
|
};
|
633
|
-
var
|
634
|
-
constructor(
|
635
|
-
this.session =
|
636
|
-
this.importId =
|
637
|
-
|
1438
|
+
var ImportTableEntry = class {
|
1439
|
+
constructor(session, importId, pulling) {
|
1440
|
+
this.session = session;
|
1441
|
+
this.importId = importId;
|
1442
|
+
if (pulling) {
|
1443
|
+
this.activePull = Promise.withResolvers();
|
1444
|
+
}
|
638
1445
|
}
|
639
1446
|
localRefcount = 0;
|
640
1447
|
remoteRefcount = 1;
|
641
1448
|
activePull;
|
642
1449
|
resolution;
|
1450
|
+
// List of integer indexes into session.onBrokenCallbacks which are callbacks registered on
|
1451
|
+
// this import. Initialized on first use (so `undefined` is the same as an empty list).
|
643
1452
|
onBrokenRegistrations;
|
644
|
-
resolve(
|
1453
|
+
resolve(resolution) {
|
645
1454
|
if (this.localRefcount == 0) {
|
646
|
-
|
1455
|
+
resolution.dispose();
|
647
1456
|
return;
|
648
1457
|
}
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
1458
|
+
this.resolution = resolution;
|
1459
|
+
this.sendRelease();
|
1460
|
+
if (this.onBrokenRegistrations) {
|
1461
|
+
for (let i of this.onBrokenRegistrations) {
|
1462
|
+
let callback = this.session.onBrokenCallbacks[i];
|
1463
|
+
let endIndex = this.session.onBrokenCallbacks.length;
|
1464
|
+
resolution.onBroken(callback);
|
1465
|
+
if (this.session.onBrokenCallbacks[endIndex] === callback) {
|
1466
|
+
delete this.session.onBrokenCallbacks[endIndex];
|
1467
|
+
} else {
|
1468
|
+
delete this.session.onBrokenCallbacks[i];
|
1469
|
+
}
|
653
1470
|
}
|
654
1471
|
this.onBrokenRegistrations = void 0;
|
655
1472
|
}
|
656
|
-
|
1473
|
+
if (this.activePull) {
|
1474
|
+
this.activePull.resolve();
|
1475
|
+
this.activePull = void 0;
|
1476
|
+
}
|
657
1477
|
}
|
658
1478
|
async awaitResolution() {
|
659
|
-
|
1479
|
+
if (!this.activePull) {
|
1480
|
+
this.session.sendPull(this.importId);
|
1481
|
+
this.activePull = Promise.withResolvers();
|
1482
|
+
}
|
1483
|
+
await this.activePull.promise;
|
1484
|
+
return this.resolution.pull();
|
660
1485
|
}
|
661
1486
|
dispose() {
|
662
|
-
|
1487
|
+
if (this.resolution) {
|
1488
|
+
this.resolution.dispose();
|
1489
|
+
} else {
|
1490
|
+
this.abort(new Error("RPC was canceled because the RpcPromise was disposed."));
|
1491
|
+
this.sendRelease();
|
1492
|
+
}
|
663
1493
|
}
|
664
|
-
abort(
|
665
|
-
|
1494
|
+
abort(error) {
|
1495
|
+
if (!this.resolution) {
|
1496
|
+
this.resolution = new ErrorStubHook(error);
|
1497
|
+
if (this.activePull) {
|
1498
|
+
this.activePull.reject(error);
|
1499
|
+
this.activePull = void 0;
|
1500
|
+
}
|
1501
|
+
this.onBrokenRegistrations = void 0;
|
1502
|
+
}
|
666
1503
|
}
|
667
|
-
onBroken(
|
668
|
-
if (this.resolution)
|
669
|
-
|
670
|
-
|
671
|
-
|
1504
|
+
onBroken(callback) {
|
1505
|
+
if (this.resolution) {
|
1506
|
+
this.resolution.onBroken(callback);
|
1507
|
+
} else {
|
1508
|
+
let index = this.session.onBrokenCallbacks.length;
|
1509
|
+
this.session.onBrokenCallbacks.push(callback);
|
1510
|
+
if (!this.onBrokenRegistrations) this.onBrokenRegistrations = [];
|
1511
|
+
this.onBrokenRegistrations.push(index);
|
672
1512
|
}
|
673
1513
|
}
|
674
1514
|
sendRelease() {
|
675
|
-
this.remoteRefcount > 0
|
1515
|
+
if (this.remoteRefcount > 0) {
|
1516
|
+
this.session.sendRelease(this.importId, this.remoteRefcount);
|
1517
|
+
this.remoteRefcount = 0;
|
1518
|
+
}
|
676
1519
|
}
|
677
1520
|
};
|
678
|
-
var
|
679
|
-
|
1521
|
+
var RpcImportHook = class _RpcImportHook extends StubHook {
|
1522
|
+
// undefined when we're disposed
|
1523
|
+
// `pulling` is true if we already expect that this import is going to be resolved later, and
|
1524
|
+
// null if this import is not allowed to be pulled (i.e. it's a stub not a promise).
|
1525
|
+
constructor(isPromise, entry) {
|
680
1526
|
super();
|
681
|
-
this.isPromise =
|
682
|
-
++
|
1527
|
+
this.isPromise = isPromise;
|
1528
|
+
++entry.localRefcount;
|
1529
|
+
this.entry = entry;
|
683
1530
|
}
|
684
1531
|
entry;
|
685
|
-
collectPath(
|
1532
|
+
collectPath(path) {
|
686
1533
|
return this;
|
687
1534
|
}
|
688
1535
|
getEntry() {
|
689
|
-
if (this.entry)
|
690
|
-
|
1536
|
+
if (this.entry) {
|
1537
|
+
return this.entry;
|
1538
|
+
} else {
|
1539
|
+
throw new Error("This RpcImportHook was already disposed.");
|
1540
|
+
}
|
691
1541
|
}
|
692
|
-
|
693
|
-
|
694
|
-
|
1542
|
+
// -------------------------------------------------------------------------------------
|
1543
|
+
// implements StubHook
|
1544
|
+
call(path, args) {
|
1545
|
+
let entry = this.getEntry();
|
1546
|
+
if (entry.resolution) {
|
1547
|
+
return entry.resolution.call(path, args);
|
1548
|
+
} else {
|
1549
|
+
return entry.session.sendCall(entry.importId, path, args);
|
1550
|
+
}
|
695
1551
|
}
|
696
|
-
|
697
|
-
let
|
698
|
-
|
1552
|
+
map(path, captures, instructions) {
|
1553
|
+
let entry;
|
1554
|
+
try {
|
1555
|
+
entry = this.getEntry();
|
1556
|
+
} catch (err) {
|
1557
|
+
for (let cap of captures) {
|
1558
|
+
cap.dispose();
|
1559
|
+
}
|
1560
|
+
throw err;
|
1561
|
+
}
|
1562
|
+
if (entry.resolution) {
|
1563
|
+
return entry.resolution.map(path, captures, instructions);
|
1564
|
+
} else {
|
1565
|
+
return entry.session.sendMap(entry.importId, path, captures, instructions);
|
1566
|
+
}
|
1567
|
+
}
|
1568
|
+
get(path) {
|
1569
|
+
let entry = this.getEntry();
|
1570
|
+
if (entry.resolution) {
|
1571
|
+
return entry.resolution.get(path);
|
1572
|
+
} else {
|
1573
|
+
return entry.session.sendCall(entry.importId, path);
|
1574
|
+
}
|
699
1575
|
}
|
700
1576
|
dup() {
|
701
|
-
return new
|
1577
|
+
return new _RpcImportHook(false, this.getEntry());
|
702
1578
|
}
|
703
1579
|
pull() {
|
704
|
-
let
|
705
|
-
if (!this.isPromise)
|
706
|
-
|
1580
|
+
let entry = this.getEntry();
|
1581
|
+
if (!this.isPromise) {
|
1582
|
+
throw new Error("Can't pull this hook because it's not a promise hook.");
|
1583
|
+
}
|
1584
|
+
if (entry.resolution) {
|
1585
|
+
return entry.resolution.pull();
|
1586
|
+
}
|
1587
|
+
return entry.awaitResolution();
|
1588
|
+
}
|
1589
|
+
ignoreUnhandledRejections() {
|
707
1590
|
}
|
708
1591
|
dispose() {
|
709
|
-
let
|
710
|
-
this.entry = void 0
|
1592
|
+
let entry = this.entry;
|
1593
|
+
this.entry = void 0;
|
1594
|
+
if (entry) {
|
1595
|
+
if (--entry.localRefcount === 0) {
|
1596
|
+
entry.dispose();
|
1597
|
+
}
|
1598
|
+
}
|
711
1599
|
}
|
712
|
-
onBroken(
|
713
|
-
|
1600
|
+
onBroken(callback) {
|
1601
|
+
if (this.entry) {
|
1602
|
+
this.entry.onBroken(callback);
|
1603
|
+
}
|
714
1604
|
}
|
715
1605
|
};
|
716
|
-
var
|
1606
|
+
var RpcMainHook = class extends RpcImportHook {
|
717
1607
|
session;
|
718
|
-
constructor(
|
719
|
-
super(false,
|
1608
|
+
constructor(entry) {
|
1609
|
+
super(false, entry);
|
1610
|
+
this.session = entry.session;
|
720
1611
|
}
|
721
1612
|
dispose() {
|
722
1613
|
if (this.session) {
|
723
|
-
let
|
724
|
-
this.session = void 0
|
1614
|
+
let session = this.session;
|
1615
|
+
this.session = void 0;
|
1616
|
+
session.shutdown();
|
725
1617
|
}
|
726
1618
|
}
|
727
1619
|
};
|
728
|
-
var
|
729
|
-
constructor(
|
730
|
-
this.transport =
|
731
|
-
this.options =
|
732
|
-
this.exports.push({ hook:
|
733
|
-
|
734
|
-
|
1620
|
+
var RpcSessionImpl = class {
|
1621
|
+
constructor(transport, mainHook, options) {
|
1622
|
+
this.transport = transport;
|
1623
|
+
this.options = options;
|
1624
|
+
this.exports.push({ hook: mainHook, refcount: 1 });
|
1625
|
+
this.imports.push(new ImportTableEntry(this, 0, false));
|
1626
|
+
let rejectFunc;
|
1627
|
+
let abortPromise = new Promise((resolve, reject) => {
|
1628
|
+
rejectFunc = reject;
|
735
1629
|
});
|
736
|
-
this.cancelReadLoop =
|
1630
|
+
this.cancelReadLoop = rejectFunc;
|
1631
|
+
this.readLoop(abortPromise).catch((err) => this.abort(err));
|
737
1632
|
}
|
738
1633
|
exports = [];
|
739
1634
|
reverseExports = /* @__PURE__ */ new Map();
|
740
1635
|
imports = [];
|
741
1636
|
abortReason;
|
742
1637
|
cancelReadLoop;
|
1638
|
+
// We assign positive numbers to imports we initiate, and negative numbers to exports we
|
1639
|
+
// initiate. So the next import ID is just `imports.length`, but the next export ID needs
|
1640
|
+
// to be tracked explicitly.
|
743
1641
|
nextExportId = -1;
|
1642
|
+
// If set, call this when all incoming calls are complete.
|
744
1643
|
onBatchDone;
|
1644
|
+
// How many promises is our peer expecting us to resolve?
|
745
1645
|
pullCount = 0;
|
1646
|
+
// Sparse array of onBrokenCallback registrations. Items are strictly appended to the end but
|
1647
|
+
// may be deleted from the middle (hence leaving the array sparse).
|
746
1648
|
onBrokenCallbacks = [];
|
1649
|
+
// Should only be called once immediately after construction.
|
747
1650
|
getMainImport() {
|
748
|
-
return new
|
1651
|
+
return new RpcMainHook(this.imports[0]);
|
749
1652
|
}
|
750
1653
|
shutdown() {
|
751
1654
|
this.abort(new Error("RPC session was shut down by disposing the main stub"), false);
|
752
1655
|
}
|
753
|
-
exportStub(
|
1656
|
+
exportStub(hook) {
|
754
1657
|
if (this.abortReason) throw this.abortReason;
|
755
|
-
let
|
756
|
-
if (
|
757
|
-
|
758
|
-
|
759
|
-
|
1658
|
+
let existingExportId = this.reverseExports.get(hook);
|
1659
|
+
if (existingExportId !== void 0) {
|
1660
|
+
++this.exports[existingExportId].refcount;
|
1661
|
+
return existingExportId;
|
1662
|
+
} else {
|
1663
|
+
let exportId = this.nextExportId--;
|
1664
|
+
this.exports[exportId] = { hook, refcount: 1 };
|
1665
|
+
this.reverseExports.set(hook, exportId);
|
1666
|
+
return exportId;
|
760
1667
|
}
|
761
1668
|
}
|
762
|
-
exportPromise(
|
1669
|
+
exportPromise(hook) {
|
763
1670
|
if (this.abortReason) throw this.abortReason;
|
764
|
-
let
|
765
|
-
|
766
|
-
|
767
|
-
|
768
|
-
|
769
|
-
}
|
770
|
-
|
771
|
-
let
|
772
|
-
|
773
|
-
|
774
|
-
|
775
|
-
|
776
|
-
|
777
|
-
if (
|
778
|
-
|
779
|
-
|
780
|
-
|
781
|
-
|
782
|
-
|
783
|
-
|
784
|
-
|
1671
|
+
let exportId = this.nextExportId--;
|
1672
|
+
this.exports[exportId] = { hook, refcount: 1 };
|
1673
|
+
this.reverseExports.set(hook, exportId);
|
1674
|
+
this.ensureResolvingExport(exportId);
|
1675
|
+
return exportId;
|
1676
|
+
}
|
1677
|
+
unexport(ids) {
|
1678
|
+
for (let id of ids) {
|
1679
|
+
this.releaseExport(id, 1);
|
1680
|
+
}
|
1681
|
+
}
|
1682
|
+
releaseExport(exportId, refcount) {
|
1683
|
+
let entry = this.exports[exportId];
|
1684
|
+
if (!entry) {
|
1685
|
+
throw new Error(`no such export ID: ${exportId}`);
|
1686
|
+
}
|
1687
|
+
if (entry.refcount < refcount) {
|
1688
|
+
throw new Error(`refcount would go negative: ${entry.refcount} < ${refcount}`);
|
1689
|
+
}
|
1690
|
+
entry.refcount -= refcount;
|
1691
|
+
if (entry.refcount === 0) {
|
1692
|
+
delete this.exports[exportId];
|
1693
|
+
this.reverseExports.delete(entry.hook);
|
1694
|
+
entry.hook.dispose();
|
1695
|
+
}
|
1696
|
+
}
|
1697
|
+
onSendError(error) {
|
1698
|
+
if (this.options.onSendError) {
|
1699
|
+
return this.options.onSendError(error);
|
1700
|
+
}
|
1701
|
+
}
|
1702
|
+
ensureResolvingExport(exportId) {
|
1703
|
+
let exp = this.exports[exportId];
|
1704
|
+
if (!exp) {
|
1705
|
+
throw new Error(`no such export ID: ${exportId}`);
|
1706
|
+
}
|
1707
|
+
if (!exp.pull) {
|
1708
|
+
let resolve = async () => {
|
1709
|
+
let hook = exp.hook;
|
785
1710
|
for (; ; ) {
|
786
|
-
let
|
787
|
-
if (
|
788
|
-
let { hook:
|
789
|
-
if (
|
790
|
-
|
791
|
-
|
1711
|
+
let payload = await hook.pull();
|
1712
|
+
if (payload.value instanceof RpcStub) {
|
1713
|
+
let { hook: inner, pathIfPromise } = unwrapStubAndPath(payload.value);
|
1714
|
+
if (pathIfPromise && pathIfPromise.length == 0) {
|
1715
|
+
if (this.getImport(hook) === void 0) {
|
1716
|
+
hook = inner;
|
1717
|
+
continue;
|
1718
|
+
}
|
792
1719
|
}
|
793
1720
|
}
|
794
|
-
return
|
1721
|
+
return payload;
|
795
1722
|
}
|
796
1723
|
};
|
797
|
-
++this.pullCount
|
798
|
-
|
799
|
-
|
800
|
-
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
this.send(["reject",
|
805
|
-
}
|
806
|
-
|
1724
|
+
++this.pullCount;
|
1725
|
+
exp.pull = resolve().then(
|
1726
|
+
(payload) => {
|
1727
|
+
let value = Devaluator.devaluate(payload.value, void 0, this, payload);
|
1728
|
+
this.send(["resolve", exportId, value]);
|
1729
|
+
},
|
1730
|
+
(error) => {
|
1731
|
+
this.send(["reject", exportId, Devaluator.devaluate(error, void 0, this)]);
|
1732
|
+
}
|
1733
|
+
).catch(
|
1734
|
+
(error) => {
|
1735
|
+
try {
|
1736
|
+
this.send(["reject", exportId, Devaluator.devaluate(error, void 0, this)]);
|
1737
|
+
} catch (error2) {
|
1738
|
+
this.abort(error2);
|
1739
|
+
}
|
1740
|
+
}
|
1741
|
+
).finally(() => {
|
1742
|
+
if (--this.pullCount === 0) {
|
1743
|
+
if (this.onBatchDone) {
|
1744
|
+
this.onBatchDone.resolve();
|
1745
|
+
}
|
807
1746
|
}
|
808
|
-
}).finally(() => {
|
809
|
-
--this.pullCount === 0 && this.onBatchDone && this.onBatchDone.resolve();
|
810
1747
|
});
|
811
1748
|
}
|
812
1749
|
}
|
813
|
-
getImport(
|
814
|
-
if (
|
1750
|
+
getImport(hook) {
|
1751
|
+
if (hook instanceof RpcImportHook && hook.entry && hook.entry.session === this) {
|
1752
|
+
return hook.entry.importId;
|
1753
|
+
} else {
|
1754
|
+
return void 0;
|
1755
|
+
}
|
815
1756
|
}
|
816
|
-
importStub(
|
1757
|
+
importStub(idx) {
|
817
1758
|
if (this.abortReason) throw this.abortReason;
|
818
|
-
let
|
819
|
-
|
1759
|
+
let entry = this.imports[idx];
|
1760
|
+
if (!entry) {
|
1761
|
+
entry = new ImportTableEntry(this, idx, false);
|
1762
|
+
this.imports[idx] = entry;
|
1763
|
+
}
|
1764
|
+
return new RpcImportHook(
|
1765
|
+
/*isPromise=*/
|
1766
|
+
false,
|
1767
|
+
entry
|
1768
|
+
);
|
820
1769
|
}
|
821
|
-
importPromise(
|
1770
|
+
importPromise(idx) {
|
822
1771
|
if (this.abortReason) throw this.abortReason;
|
823
|
-
if (this.imports[
|
824
|
-
|
825
|
-
|
1772
|
+
if (this.imports[idx]) {
|
1773
|
+
return new ErrorStubHook(new Error(
|
1774
|
+
"Bug in RPC system: The peer sent a promise reusing an existing export ID."
|
1775
|
+
));
|
1776
|
+
}
|
1777
|
+
let entry = new ImportTableEntry(this, idx, true);
|
1778
|
+
this.imports[idx] = entry;
|
1779
|
+
return new RpcImportHook(
|
1780
|
+
/*isPromise=*/
|
1781
|
+
true,
|
1782
|
+
entry
|
1783
|
+
);
|
826
1784
|
}
|
827
|
-
getExport(
|
828
|
-
return this.exports[
|
1785
|
+
getExport(idx) {
|
1786
|
+
return this.exports[idx]?.hook;
|
829
1787
|
}
|
830
|
-
send(
|
831
|
-
if (this.abortReason !== void 0)
|
832
|
-
|
1788
|
+
send(msg) {
|
1789
|
+
if (this.abortReason !== void 0) {
|
1790
|
+
return;
|
1791
|
+
}
|
1792
|
+
let msgText;
|
833
1793
|
try {
|
834
|
-
|
835
|
-
} catch (
|
836
|
-
|
1794
|
+
msgText = JSON.stringify(msg);
|
1795
|
+
} catch (err) {
|
1796
|
+
try {
|
1797
|
+
this.abort(err);
|
1798
|
+
} catch (err2) {
|
1799
|
+
}
|
1800
|
+
throw err;
|
837
1801
|
}
|
838
|
-
this.transport.send(
|
1802
|
+
this.transport.send(msgText).catch((err) => this.abort(err, false));
|
839
1803
|
}
|
840
|
-
sendCall(
|
1804
|
+
sendCall(id, path, args) {
|
841
1805
|
if (this.abortReason) throw this.abortReason;
|
842
|
-
let
|
843
|
-
if (
|
844
|
-
let
|
845
|
-
|
1806
|
+
let value = ["pipeline", id, path];
|
1807
|
+
if (args) {
|
1808
|
+
let devalue = Devaluator.devaluate(args.value, void 0, this, args);
|
1809
|
+
value.push(devalue[0]);
|
846
1810
|
}
|
847
|
-
this.send(["push",
|
848
|
-
let
|
849
|
-
|
1811
|
+
this.send(["push", value]);
|
1812
|
+
let entry = new ImportTableEntry(this, this.imports.length, false);
|
1813
|
+
this.imports.push(entry);
|
1814
|
+
return new RpcImportHook(
|
1815
|
+
/*isPromise=*/
|
1816
|
+
true,
|
1817
|
+
entry
|
1818
|
+
);
|
1819
|
+
}
|
1820
|
+
sendMap(id, path, captures, instructions) {
|
1821
|
+
if (this.abortReason) {
|
1822
|
+
for (let cap of captures) {
|
1823
|
+
cap.dispose();
|
1824
|
+
}
|
1825
|
+
throw this.abortReason;
|
1826
|
+
}
|
1827
|
+
let devaluedCaptures = captures.map((hook) => {
|
1828
|
+
let importId = this.getImport(hook);
|
1829
|
+
if (importId !== void 0) {
|
1830
|
+
return ["import", importId];
|
1831
|
+
} else {
|
1832
|
+
return ["export", this.exportStub(hook)];
|
1833
|
+
}
|
1834
|
+
});
|
1835
|
+
let value = ["remap", id, path, devaluedCaptures, instructions];
|
1836
|
+
this.send(["push", value]);
|
1837
|
+
let entry = new ImportTableEntry(this, this.imports.length, false);
|
1838
|
+
this.imports.push(entry);
|
1839
|
+
return new RpcImportHook(
|
1840
|
+
/*isPromise=*/
|
1841
|
+
true,
|
1842
|
+
entry
|
1843
|
+
);
|
850
1844
|
}
|
851
|
-
sendPull(
|
1845
|
+
sendPull(id) {
|
852
1846
|
if (this.abortReason) throw this.abortReason;
|
853
|
-
this.send(["pull",
|
1847
|
+
this.send(["pull", id]);
|
854
1848
|
}
|
855
|
-
sendRelease(
|
856
|
-
|
1849
|
+
sendRelease(id, remoteRefcount) {
|
1850
|
+
if (this.abortReason) return;
|
1851
|
+
this.send(["release", id, remoteRefcount]);
|
1852
|
+
delete this.imports[id];
|
857
1853
|
}
|
858
|
-
abort(
|
859
|
-
if (this.abortReason
|
860
|
-
|
861
|
-
|
862
|
-
|
1854
|
+
abort(error, trySendAbortMessage = true) {
|
1855
|
+
if (this.abortReason !== void 0) return;
|
1856
|
+
this.cancelReadLoop(error);
|
1857
|
+
if (trySendAbortMessage) {
|
1858
|
+
try {
|
1859
|
+
this.transport.send(JSON.stringify(["abort", Devaluator.devaluate(error, void 0, this)])).catch((err) => {
|
1860
|
+
});
|
1861
|
+
} catch (err) {
|
863
1862
|
}
|
864
|
-
|
865
|
-
|
866
|
-
|
867
|
-
|
1863
|
+
}
|
1864
|
+
if (error === void 0) {
|
1865
|
+
error = "undefined";
|
1866
|
+
}
|
1867
|
+
this.abortReason = error;
|
1868
|
+
if (this.onBatchDone) {
|
1869
|
+
this.onBatchDone.reject(error);
|
1870
|
+
}
|
1871
|
+
if (this.transport.abort) {
|
1872
|
+
try {
|
1873
|
+
this.transport.abort(error);
|
1874
|
+
} catch (err) {
|
1875
|
+
Promise.resolve(err);
|
868
1876
|
}
|
869
|
-
|
870
|
-
|
871
|
-
|
872
|
-
|
1877
|
+
}
|
1878
|
+
for (let i in this.onBrokenCallbacks) {
|
1879
|
+
try {
|
1880
|
+
this.onBrokenCallbacks[i](error);
|
1881
|
+
} catch (err) {
|
1882
|
+
Promise.resolve(err);
|
873
1883
|
}
|
874
|
-
|
875
|
-
|
1884
|
+
}
|
1885
|
+
for (let i in this.imports) {
|
1886
|
+
this.imports[i].abort(error);
|
1887
|
+
}
|
1888
|
+
for (let i in this.exports) {
|
1889
|
+
this.exports[i].hook.dispose();
|
876
1890
|
}
|
877
1891
|
}
|
878
|
-
async readLoop(
|
879
|
-
|
880
|
-
let
|
1892
|
+
async readLoop(abortPromise) {
|
1893
|
+
while (!this.abortReason) {
|
1894
|
+
let msg = JSON.parse(await Promise.race([this.transport.receive(), abortPromise]));
|
881
1895
|
if (this.abortReason) break;
|
882
|
-
if (
|
883
|
-
|
884
|
-
|
885
|
-
|
886
|
-
|
887
|
-
|
1896
|
+
if (msg instanceof Array) {
|
1897
|
+
switch (msg[0]) {
|
1898
|
+
case "push":
|
1899
|
+
if (msg.length > 1) {
|
1900
|
+
let payload = new Evaluator(this).evaluate(msg[1]);
|
1901
|
+
let hook = new PayloadStubHook(payload);
|
1902
|
+
hook.ignoreUnhandledRejections();
|
1903
|
+
this.exports.push({ hook, refcount: 1 });
|
1904
|
+
continue;
|
1905
|
+
}
|
1906
|
+
break;
|
1907
|
+
case "pull": {
|
1908
|
+
let exportId = msg[1];
|
1909
|
+
if (typeof exportId == "number") {
|
1910
|
+
this.ensureResolvingExport(exportId);
|
1911
|
+
continue;
|
1912
|
+
}
|
1913
|
+
break;
|
888
1914
|
}
|
889
|
-
|
890
|
-
|
891
|
-
|
892
|
-
|
893
|
-
|
894
|
-
|
1915
|
+
case "resolve":
|
1916
|
+
// ["resolve", ExportId, Expression]
|
1917
|
+
case "reject": {
|
1918
|
+
let importId = msg[1];
|
1919
|
+
if (typeof importId == "number" && msg.length > 2) {
|
1920
|
+
let imp = this.imports[importId];
|
1921
|
+
if (imp) {
|
1922
|
+
if (msg[0] == "resolve") {
|
1923
|
+
imp.resolve(new PayloadStubHook(new Evaluator(this).evaluate(msg[2])));
|
1924
|
+
} else {
|
1925
|
+
let payload = new Evaluator(this).evaluate(msg[2]);
|
1926
|
+
payload.dispose();
|
1927
|
+
imp.resolve(new ErrorStubHook(payload.value));
|
1928
|
+
}
|
1929
|
+
} else {
|
1930
|
+
if (msg[0] == "resolve") {
|
1931
|
+
new Evaluator(this).evaluate(msg[2]).dispose();
|
1932
|
+
}
|
1933
|
+
}
|
1934
|
+
continue;
|
1935
|
+
}
|
1936
|
+
break;
|
895
1937
|
}
|
896
|
-
|
897
|
-
|
898
|
-
|
899
|
-
|
900
|
-
|
901
|
-
|
902
|
-
let o = this.imports[r];
|
903
|
-
if (o) if (t[0] == "resolve") o.resolve(new w(new g(this).evaluate(t[2])));
|
904
|
-
else {
|
905
|
-
let n = new g(this).evaluate(t[2]);
|
906
|
-
n.dispose(), o.resolve(new f(n.value));
|
1938
|
+
case "release": {
|
1939
|
+
let exportId = msg[1];
|
1940
|
+
let refcount = msg[2];
|
1941
|
+
if (typeof exportId == "number" && typeof refcount == "number") {
|
1942
|
+
this.releaseExport(exportId, refcount);
|
1943
|
+
continue;
|
907
1944
|
}
|
908
|
-
|
909
|
-
continue;
|
1945
|
+
break;
|
910
1946
|
}
|
911
|
-
|
912
|
-
|
913
|
-
|
914
|
-
|
915
|
-
|
916
|
-
this.releaseExport(r, o);
|
917
|
-
continue;
|
1947
|
+
case "abort": {
|
1948
|
+
let payload = new Evaluator(this).evaluate(msg[1]);
|
1949
|
+
payload.dispose();
|
1950
|
+
this.abort(payload, false);
|
1951
|
+
break;
|
918
1952
|
}
|
919
|
-
break;
|
920
|
-
}
|
921
|
-
case "abort": {
|
922
|
-
let r = new g(this).evaluate(t[1]);
|
923
|
-
r.dispose(), this.abort(r, false);
|
924
|
-
break;
|
925
1953
|
}
|
926
1954
|
}
|
927
|
-
throw new Error(`bad RPC message: ${JSON.stringify(
|
1955
|
+
throw new Error(`bad RPC message: ${JSON.stringify(msg)}`);
|
928
1956
|
}
|
929
1957
|
}
|
930
1958
|
async drain() {
|
931
|
-
if (this.abortReason)
|
1959
|
+
if (this.abortReason) {
|
1960
|
+
throw this.abortReason;
|
1961
|
+
}
|
932
1962
|
if (this.pullCount > 0) {
|
933
|
-
let { promise
|
934
|
-
this.onBatchDone = { resolve
|
1963
|
+
let { promise, resolve, reject } = Promise.withResolvers();
|
1964
|
+
this.onBatchDone = { resolve, reject };
|
1965
|
+
await promise;
|
935
1966
|
}
|
936
1967
|
}
|
937
1968
|
getStats() {
|
938
|
-
let
|
939
|
-
for (let
|
940
|
-
|
941
|
-
|
1969
|
+
let result = { imports: 0, exports: 0 };
|
1970
|
+
for (let i in this.imports) {
|
1971
|
+
++result.imports;
|
1972
|
+
}
|
1973
|
+
for (let i in this.exports) {
|
1974
|
+
++result.exports;
|
1975
|
+
}
|
1976
|
+
return result;
|
942
1977
|
}
|
943
1978
|
};
|
944
|
-
var
|
945
|
-
#
|
946
|
-
#
|
947
|
-
constructor(
|
948
|
-
let
|
949
|
-
|
1979
|
+
var RpcSession = class {
|
1980
|
+
#session;
|
1981
|
+
#mainStub;
|
1982
|
+
constructor(transport, localMain, options = {}) {
|
1983
|
+
let mainHook;
|
1984
|
+
if (localMain) {
|
1985
|
+
mainHook = new PayloadStubHook(RpcPayload.fromAppReturn(localMain));
|
1986
|
+
} else {
|
1987
|
+
mainHook = new ErrorStubHook(new Error("This connection has no main object."));
|
1988
|
+
}
|
1989
|
+
this.#session = new RpcSessionImpl(transport, mainHook, options);
|
1990
|
+
this.#mainStub = new RpcStub(this.#session.getMainImport());
|
950
1991
|
}
|
951
1992
|
getRemoteMain() {
|
952
|
-
return this.#
|
1993
|
+
return this.#mainStub;
|
953
1994
|
}
|
954
1995
|
getStats() {
|
955
|
-
return this.#
|
1996
|
+
return this.#session.getStats();
|
956
1997
|
}
|
957
1998
|
drain() {
|
958
|
-
return this.#
|
1999
|
+
return this.#session.drain();
|
959
2000
|
}
|
960
2001
|
};
|
961
|
-
function
|
962
|
-
typeof
|
963
|
-
|
964
|
-
|
2002
|
+
function newWebSocketRpcSession(webSocket, localMain, options) {
|
2003
|
+
if (typeof webSocket === "string") {
|
2004
|
+
webSocket = new WebSocket(webSocket);
|
2005
|
+
}
|
2006
|
+
let transport = new WebSocketTransport(webSocket);
|
2007
|
+
let rpc = new RpcSession(transport, localMain, options);
|
2008
|
+
return rpc.getRemoteMain();
|
965
2009
|
}
|
966
|
-
function
|
967
|
-
if (
|
968
|
-
|
969
|
-
|
2010
|
+
function newWorkersWebSocketRpcResponse(request, localMain, options) {
|
2011
|
+
if (request.headers.get("Upgrade")?.toLowerCase() !== "websocket") {
|
2012
|
+
return new Response("This endpoint only accepts WebSocket requests.", { status: 400 });
|
2013
|
+
}
|
2014
|
+
let pair = new WebSocketPair();
|
2015
|
+
let server = pair[0];
|
2016
|
+
server.accept();
|
2017
|
+
newWebSocketRpcSession(server, localMain, options);
|
2018
|
+
return new Response(null, {
|
2019
|
+
status: 101,
|
2020
|
+
webSocket: pair[1]
|
2021
|
+
});
|
970
2022
|
}
|
971
|
-
var
|
972
|
-
constructor(
|
973
|
-
this.#
|
974
|
-
|
975
|
-
|
976
|
-
|
977
|
-
|
978
|
-
|
979
|
-
|
980
|
-
|
981
|
-
|
982
|
-
|
983
|
-
|
984
|
-
|
985
|
-
|
2023
|
+
var WebSocketTransport = class {
|
2024
|
+
constructor(webSocket) {
|
2025
|
+
this.#webSocket = webSocket;
|
2026
|
+
if (webSocket.readyState === WebSocket.CONNECTING) {
|
2027
|
+
this.#sendQueue = [];
|
2028
|
+
webSocket.addEventListener("open", (event) => {
|
2029
|
+
try {
|
2030
|
+
for (let message of this.#sendQueue) {
|
2031
|
+
webSocket.send(message);
|
2032
|
+
}
|
2033
|
+
} catch (err) {
|
2034
|
+
this.#receivedError(err);
|
2035
|
+
}
|
2036
|
+
this.#sendQueue = void 0;
|
2037
|
+
});
|
2038
|
+
}
|
2039
|
+
webSocket.addEventListener("message", (event) => {
|
2040
|
+
if (this.#error) ;
|
2041
|
+
else if (typeof event.data === "string") {
|
2042
|
+
if (this.#receiveResolver) {
|
2043
|
+
this.#receiveResolver(event.data);
|
2044
|
+
this.#receiveResolver = void 0;
|
2045
|
+
this.#receiveRejecter = void 0;
|
2046
|
+
} else {
|
2047
|
+
this.#receiveQueue.push(event.data);
|
2048
|
+
}
|
2049
|
+
} else {
|
2050
|
+
this.#receivedError(new TypeError("Received non-string message from WebSocket."));
|
2051
|
+
}
|
2052
|
+
});
|
2053
|
+
webSocket.addEventListener("close", (event) => {
|
2054
|
+
this.#receivedError(new Error(`Peer closed WebSocket: ${event.code} ${event.reason}`));
|
2055
|
+
});
|
2056
|
+
webSocket.addEventListener("error", (event) => {
|
2057
|
+
this.#receivedError(new Error(`WebSocket connection failed.`));
|
986
2058
|
});
|
987
2059
|
}
|
988
|
-
#
|
989
|
-
#
|
990
|
-
|
991
|
-
#
|
992
|
-
#
|
993
|
-
#
|
994
|
-
|
995
|
-
|
2060
|
+
#webSocket;
|
2061
|
+
#sendQueue;
|
2062
|
+
// only if not opened yet
|
2063
|
+
#receiveResolver;
|
2064
|
+
#receiveRejecter;
|
2065
|
+
#receiveQueue = [];
|
2066
|
+
#error;
|
2067
|
+
async send(message) {
|
2068
|
+
if (this.#sendQueue === void 0) {
|
2069
|
+
this.#webSocket.send(message);
|
2070
|
+
} else {
|
2071
|
+
this.#sendQueue.push(message);
|
2072
|
+
}
|
996
2073
|
}
|
997
2074
|
async receive() {
|
998
|
-
if (this.#
|
999
|
-
|
1000
|
-
|
1001
|
-
|
1002
|
-
}
|
2075
|
+
if (this.#receiveQueue.length > 0) {
|
2076
|
+
return this.#receiveQueue.shift();
|
2077
|
+
} else if (this.#error) {
|
2078
|
+
throw this.#error;
|
2079
|
+
} else {
|
2080
|
+
return new Promise((resolve, reject) => {
|
2081
|
+
this.#receiveResolver = resolve;
|
2082
|
+
this.#receiveRejecter = reject;
|
2083
|
+
});
|
2084
|
+
}
|
1003
2085
|
}
|
1004
|
-
abort(
|
1005
|
-
let
|
1006
|
-
|
2086
|
+
abort(reason) {
|
2087
|
+
let message;
|
2088
|
+
if (reason instanceof Error) {
|
2089
|
+
message = reason.message;
|
2090
|
+
} else {
|
2091
|
+
message = `${reason}`;
|
2092
|
+
}
|
2093
|
+
this.#webSocket.close(3e3, message);
|
2094
|
+
if (!this.#error) {
|
2095
|
+
this.#error = reason;
|
2096
|
+
}
|
1007
2097
|
}
|
1008
|
-
#
|
1009
|
-
|
2098
|
+
#receivedError(reason) {
|
2099
|
+
if (!this.#error) {
|
2100
|
+
this.#error = reason;
|
2101
|
+
if (this.#receiveRejecter) {
|
2102
|
+
this.#receiveRejecter(reason);
|
2103
|
+
this.#receiveResolver = void 0;
|
2104
|
+
this.#receiveRejecter = void 0;
|
2105
|
+
}
|
2106
|
+
}
|
1010
2107
|
}
|
1011
2108
|
};
|
1012
|
-
var
|
1013
|
-
constructor(
|
1014
|
-
this.#
|
2109
|
+
var BatchServerTransport = class {
|
2110
|
+
constructor(batch) {
|
2111
|
+
this.#batchToReceive = batch;
|
1015
2112
|
}
|
1016
|
-
#
|
1017
|
-
#
|
1018
|
-
#
|
1019
|
-
async send(
|
1020
|
-
this.#
|
2113
|
+
#batchToSend = [];
|
2114
|
+
#batchToReceive;
|
2115
|
+
#allReceived = Promise.withResolvers();
|
2116
|
+
async send(message) {
|
2117
|
+
this.#batchToSend.push(message);
|
1021
2118
|
}
|
1022
2119
|
async receive() {
|
1023
|
-
let
|
1024
|
-
|
1025
|
-
|
2120
|
+
let msg = this.#batchToReceive.shift();
|
2121
|
+
if (msg !== void 0) {
|
2122
|
+
return msg;
|
2123
|
+
} else {
|
2124
|
+
this.#allReceived.resolve();
|
2125
|
+
return new Promise((r) => {
|
2126
|
+
});
|
2127
|
+
}
|
1026
2128
|
}
|
1027
|
-
abort(
|
1028
|
-
this.#
|
2129
|
+
abort(reason) {
|
2130
|
+
this.#allReceived.reject(reason);
|
1029
2131
|
}
|
1030
2132
|
whenAllReceived() {
|
1031
|
-
return this.#
|
2133
|
+
return this.#allReceived.promise;
|
1032
2134
|
}
|
1033
2135
|
getResponseBody() {
|
1034
|
-
return this.#
|
1035
|
-
`);
|
2136
|
+
return this.#batchToSend.join("\n");
|
1036
2137
|
}
|
1037
2138
|
};
|
1038
|
-
async function
|
1039
|
-
if (
|
1040
|
-
|
1041
|
-
|
1042
|
-
|
2139
|
+
async function newHttpBatchRpcResponse(request, localMain, options) {
|
2140
|
+
if (request.method !== "POST") {
|
2141
|
+
return new Response("This endpoint only accepts POST requests.", { status: 405 });
|
2142
|
+
}
|
2143
|
+
let body = await request.text();
|
2144
|
+
let batch = body === "" ? [] : body.split("\n");
|
2145
|
+
let transport = new BatchServerTransport(batch);
|
2146
|
+
let rpc = new RpcSession(transport, localMain, options);
|
2147
|
+
await transport.whenAllReceived();
|
2148
|
+
await rpc.drain();
|
2149
|
+
return new Response(transport.getResponseBody());
|
1043
2150
|
}
|
1044
|
-
|
1045
|
-
|
2151
|
+
var currentMapBuilder;
|
2152
|
+
var MapBuilder = class {
|
2153
|
+
context;
|
2154
|
+
captureMap = /* @__PURE__ */ new Map();
|
2155
|
+
instructions = [];
|
2156
|
+
constructor(subject, path) {
|
2157
|
+
if (currentMapBuilder) {
|
2158
|
+
this.context = {
|
2159
|
+
parent: currentMapBuilder,
|
2160
|
+
captures: [],
|
2161
|
+
subject: currentMapBuilder.capture(subject),
|
2162
|
+
path
|
2163
|
+
};
|
2164
|
+
} else {
|
2165
|
+
this.context = {
|
2166
|
+
parent: void 0,
|
2167
|
+
captures: [],
|
2168
|
+
subject,
|
2169
|
+
path
|
2170
|
+
};
|
2171
|
+
}
|
2172
|
+
currentMapBuilder = this;
|
2173
|
+
}
|
2174
|
+
unregister() {
|
2175
|
+
currentMapBuilder = this.context.parent;
|
2176
|
+
}
|
2177
|
+
makeInput() {
|
2178
|
+
return new MapVariableHook(this, 0);
|
2179
|
+
}
|
2180
|
+
makeOutput(result) {
|
2181
|
+
let devalued;
|
2182
|
+
try {
|
2183
|
+
devalued = Devaluator.devaluate(result.value, void 0, this, result);
|
2184
|
+
} finally {
|
2185
|
+
result.dispose();
|
2186
|
+
}
|
2187
|
+
this.instructions.push(devalued);
|
2188
|
+
if (this.context.parent) {
|
2189
|
+
this.context.parent.instructions.push(
|
2190
|
+
[
|
2191
|
+
"remap",
|
2192
|
+
this.context.subject,
|
2193
|
+
this.context.path,
|
2194
|
+
this.context.captures.map((cap) => ["import", cap]),
|
2195
|
+
this.instructions
|
2196
|
+
]
|
2197
|
+
);
|
2198
|
+
return new MapVariableHook(this.context.parent, this.context.parent.instructions.length);
|
2199
|
+
} else {
|
2200
|
+
return this.context.subject.map(this.context.path, this.context.captures, this.instructions);
|
2201
|
+
}
|
2202
|
+
}
|
2203
|
+
pushCall(hook, path, params) {
|
2204
|
+
let devalued = Devaluator.devaluate(params.value, void 0, this, params);
|
2205
|
+
devalued = devalued[0];
|
2206
|
+
let subject = this.capture(hook.dup());
|
2207
|
+
this.instructions.push(["pipeline", subject, path, devalued]);
|
2208
|
+
return new MapVariableHook(this, this.instructions.length);
|
2209
|
+
}
|
2210
|
+
pushGet(hook, path) {
|
2211
|
+
let subject = this.capture(hook.dup());
|
2212
|
+
this.instructions.push(["pipeline", subject, path]);
|
2213
|
+
return new MapVariableHook(this, this.instructions.length);
|
2214
|
+
}
|
2215
|
+
capture(hook) {
|
2216
|
+
if (hook instanceof MapVariableHook && hook.mapper === this) {
|
2217
|
+
return hook.idx;
|
2218
|
+
}
|
2219
|
+
let result = this.captureMap.get(hook);
|
2220
|
+
if (result === void 0) {
|
2221
|
+
if (this.context.parent) {
|
2222
|
+
let parentIdx = this.context.parent.capture(hook);
|
2223
|
+
this.context.captures.push(parentIdx);
|
2224
|
+
} else {
|
2225
|
+
this.context.captures.push(hook);
|
2226
|
+
}
|
2227
|
+
result = -this.context.captures.length;
|
2228
|
+
this.captureMap.set(hook, result);
|
2229
|
+
}
|
2230
|
+
return result;
|
2231
|
+
}
|
2232
|
+
// ---------------------------------------------------------------------------
|
2233
|
+
// implements Exporter
|
2234
|
+
exportStub(hook) {
|
2235
|
+
throw new Error(
|
2236
|
+
"Can't construct an RpcTarget or RPC callback inside a mapper function. Try creating a new RpcStub outside the callback first, then using it inside the callback."
|
2237
|
+
);
|
2238
|
+
}
|
2239
|
+
exportPromise(hook) {
|
2240
|
+
return this.exportStub(hook);
|
2241
|
+
}
|
2242
|
+
getImport(hook) {
|
2243
|
+
return this.capture(hook);
|
2244
|
+
}
|
2245
|
+
unexport(ids) {
|
2246
|
+
}
|
2247
|
+
onSendError(error) {
|
2248
|
+
}
|
2249
|
+
};
|
2250
|
+
mapImpl.sendMap = (hook, path, func) => {
|
2251
|
+
let builder = new MapBuilder(hook, path);
|
2252
|
+
let result;
|
2253
|
+
try {
|
2254
|
+
result = RpcPayload.fromAppReturn(withCallInterceptor(builder.pushCall.bind(builder), () => {
|
2255
|
+
return func(new RpcPromise(builder.makeInput(), []));
|
2256
|
+
}));
|
2257
|
+
} finally {
|
2258
|
+
builder.unregister();
|
2259
|
+
}
|
2260
|
+
if (result instanceof Promise) {
|
2261
|
+
result.catch((err) => {
|
2262
|
+
});
|
2263
|
+
throw new Error("RPC map() callbacks cannot be async.");
|
2264
|
+
}
|
2265
|
+
return new RpcPromise(builder.makeOutput(result), []);
|
2266
|
+
};
|
2267
|
+
function throwMapperBuilderUseError() {
|
2268
|
+
throw new Error(
|
2269
|
+
"Attempted to use an abstract placeholder from a mapper function. Please make sure your map function has no side effects."
|
2270
|
+
);
|
2271
|
+
}
|
2272
|
+
var MapVariableHook = class extends StubHook {
|
2273
|
+
constructor(mapper, idx) {
|
2274
|
+
super();
|
2275
|
+
this.mapper = mapper;
|
2276
|
+
this.idx = idx;
|
2277
|
+
}
|
2278
|
+
// We don't have anything we actually need to dispose, so dup() can just return the same hook.
|
2279
|
+
dup() {
|
2280
|
+
return this;
|
2281
|
+
}
|
2282
|
+
dispose() {
|
2283
|
+
}
|
2284
|
+
get(path) {
|
2285
|
+
if (path.length == 0) {
|
2286
|
+
return this;
|
2287
|
+
} else if (currentMapBuilder) {
|
2288
|
+
return currentMapBuilder.pushGet(this, path);
|
2289
|
+
} else {
|
2290
|
+
throwMapperBuilderUseError();
|
2291
|
+
}
|
2292
|
+
}
|
2293
|
+
// Other methods should never be called.
|
2294
|
+
call(path, args) {
|
2295
|
+
throwMapperBuilderUseError();
|
2296
|
+
}
|
2297
|
+
map(path, captures, instructions) {
|
2298
|
+
throwMapperBuilderUseError();
|
2299
|
+
}
|
2300
|
+
pull() {
|
2301
|
+
throwMapperBuilderUseError();
|
2302
|
+
}
|
2303
|
+
ignoreUnhandledRejections() {
|
2304
|
+
}
|
2305
|
+
onBroken(callback) {
|
2306
|
+
throwMapperBuilderUseError();
|
2307
|
+
}
|
2308
|
+
};
|
2309
|
+
var MapApplicator = class {
|
2310
|
+
constructor(captures, input) {
|
2311
|
+
this.captures = captures;
|
2312
|
+
this.variables = [input];
|
2313
|
+
}
|
2314
|
+
variables;
|
2315
|
+
dispose() {
|
2316
|
+
for (let variable of this.variables) {
|
2317
|
+
variable.dispose();
|
2318
|
+
}
|
2319
|
+
}
|
2320
|
+
apply(instructions) {
|
2321
|
+
try {
|
2322
|
+
if (instructions.length < 1) {
|
2323
|
+
throw new Error("Invalid empty mapper function.");
|
2324
|
+
}
|
2325
|
+
for (let instruction of instructions.slice(0, -1)) {
|
2326
|
+
let payload = new Evaluator(this).evaluateCopy(instruction);
|
2327
|
+
if (payload.value instanceof RpcStub) {
|
2328
|
+
let hook = unwrapStubNoProperties(payload.value);
|
2329
|
+
if (hook) {
|
2330
|
+
this.variables.push(hook);
|
2331
|
+
continue;
|
2332
|
+
}
|
2333
|
+
}
|
2334
|
+
this.variables.push(new PayloadStubHook(payload));
|
2335
|
+
}
|
2336
|
+
return new Evaluator(this).evaluateCopy(instructions[instructions.length - 1]);
|
2337
|
+
} finally {
|
2338
|
+
for (let variable of this.variables) {
|
2339
|
+
variable.dispose();
|
2340
|
+
}
|
2341
|
+
}
|
2342
|
+
}
|
2343
|
+
importStub(idx) {
|
2344
|
+
throw new Error("A mapper function cannot refer to exports.");
|
2345
|
+
}
|
2346
|
+
importPromise(idx) {
|
2347
|
+
return this.importStub(idx);
|
2348
|
+
}
|
2349
|
+
getExport(idx) {
|
2350
|
+
if (idx < 0) {
|
2351
|
+
return this.captures[-idx - 1];
|
2352
|
+
} else {
|
2353
|
+
return this.variables[idx];
|
2354
|
+
}
|
2355
|
+
}
|
2356
|
+
};
|
2357
|
+
function applyMapToElement(input, parent, owner, captures, instructions) {
|
2358
|
+
let inputHook = new PayloadStubHook(RpcPayload.deepCopyFrom(input, parent, owner));
|
2359
|
+
let mapper = new MapApplicator(captures, inputHook);
|
2360
|
+
try {
|
2361
|
+
return mapper.apply(instructions);
|
2362
|
+
} finally {
|
2363
|
+
mapper.dispose();
|
2364
|
+
}
|
2365
|
+
}
|
2366
|
+
mapImpl.applyMap = (input, parent, owner, captures, instructions) => {
|
2367
|
+
try {
|
2368
|
+
let result;
|
2369
|
+
if (input instanceof RpcPromise) {
|
2370
|
+
throw new Error("applyMap() can't be called on RpcPromise");
|
2371
|
+
} else if (input instanceof Array) {
|
2372
|
+
let payloads = [];
|
2373
|
+
try {
|
2374
|
+
for (let elem of input) {
|
2375
|
+
payloads.push(applyMapToElement(elem, input, owner, captures, instructions));
|
2376
|
+
}
|
2377
|
+
} catch (err) {
|
2378
|
+
for (let payload of payloads) {
|
2379
|
+
payload.dispose();
|
2380
|
+
}
|
2381
|
+
throw err;
|
2382
|
+
}
|
2383
|
+
result = RpcPayload.fromArray(payloads);
|
2384
|
+
} else if (input === null || input === void 0) {
|
2385
|
+
result = RpcPayload.fromAppReturn(input);
|
2386
|
+
} else {
|
2387
|
+
result = applyMapToElement(input, parent, owner, captures, instructions);
|
2388
|
+
}
|
2389
|
+
return new PayloadStubHook(result);
|
2390
|
+
} finally {
|
2391
|
+
for (let cap of captures) {
|
2392
|
+
cap.dispose();
|
2393
|
+
}
|
2394
|
+
}
|
2395
|
+
};
|
2396
|
+
async function newWorkersRpcResponse(request, localMain) {
|
2397
|
+
if (request.method === "POST") {
|
2398
|
+
let response = await newHttpBatchRpcResponse(request, localMain);
|
2399
|
+
response.headers.set("Access-Control-Allow-Origin", "*");
|
2400
|
+
return response;
|
2401
|
+
} else if (request.headers.get("Upgrade")?.toLowerCase() === "websocket") {
|
2402
|
+
return newWorkersWebSocketRpcResponse(request, localMain);
|
2403
|
+
} else {
|
2404
|
+
return new Response("This endpoint only accepts POST or WebSocket requests.", { status: 400 });
|
2405
|
+
}
|
1046
2406
|
}
|
1047
2407
|
|
1048
2408
|
// templates/remoteBindings/ProxyServerWorker.ts
|
@@ -1104,7 +2464,7 @@ var ProxyServerWorker_default = {
|
|
1104
2464
|
async fetch(request, env) {
|
1105
2465
|
try {
|
1106
2466
|
if (isJSRPCBinding(request)) {
|
1107
|
-
return
|
2467
|
+
return newWorkersRpcResponse(
|
1108
2468
|
request,
|
1109
2469
|
getExposedJSRPCBinding(request, env)
|
1110
2470
|
);
|