-
Notifications
You must be signed in to change notification settings - Fork 221
/
Copy pathcaptp.js
90 lines (88 loc) · 2.48 KB
/
captp.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
// @ts-check
import { E, makeCapTP } from '@endo/captp';
import { Far } from '@endo/marshal';
export const getCapTPHandler = (send, getLocalBootstrap, fallback) => {
let lastEpoch = 0;
const chans = new Map();
const doFallback = async (method, ...args) => {
if (!fallback) {
return false;
}
return E(fallback)[method](...args);
};
const handler = Far('capTpHandler', {
onOpen(obj, meta) {
const { channelHandle, origin = 'unknown' } = meta || {};
lastEpoch += 1;
const epoch = lastEpoch;
console.debug(`Starting CapTP#${epoch}`, meta);
const sendObj = o => {
send(o, [channelHandle]);
};
const {
dispatch,
abort,
getBootstrap: getRemoteBootstrap,
} = makeCapTP(
origin,
sendObj,
async o => getLocalBootstrap(getRemoteBootstrap(), meta, o),
{
// Disambiguate in case we receive messages from different
// connections.
epoch,
onReject(err) {
// Be quieter for sanity's sake.
console.log('CapTP', origin, 'exception:', err);
},
},
);
chans.set(channelHandle, {
dispatch,
abort,
});
doFallback('onOpen', obj, meta).catch(e => {
console.error(`Error in fallback onOpen`, e);
});
},
onClose(obj, meta) {
console.debug(`Finishing CapTP`, meta);
const chan = chans.get(meta.channelHandle);
if (chan) {
const { abort } = chan;
abort();
}
chans.delete(meta.channelHandle);
doFallback('onClose', obj, meta).catch(e => {
console.error(`Error in fallback onClose`, e);
});
},
onError(obj, meta) {
console.debug(`Error in CapTP`, meta, obj.error);
const chan = chans.get(meta.channelHandle);
if (chan) {
const { abort } = chan;
abort(obj.error);
}
doFallback('onError', obj, meta).catch(e => {
console.error(`Error in fallback onError`, e);
});
},
async onMessage(obj, meta) {
console.debug('processing inbound', obj);
const chan = chans.get(meta.channelHandle);
if (chan) {
const { dispatch } = chan;
if (dispatch(obj)) {
return true;
}
}
const done = await doFallback('onMessage', obj, meta);
if (!done) {
console.error(`Could not find handler ${obj.type}`, obj, meta);
}
return done;
},
});
return harden(handler);
};