penpal 7.0.3 → 7.0.4
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/dist/penpal.cjs +953 -0
- package/dist/penpal.cjs.map +1 -0
- package/dist/penpal.d.cts +234 -0
- package/dist/penpal.d.ts +234 -0
- package/dist/penpal.js +890 -1033
- package/dist/penpal.js.map +1 -0
- package/dist/penpal.min.js +1 -1
- package/dist/penpal.min.js.map +1 -1
- package/dist/penpal.mjs +943 -0
- package/dist/penpal.mjs.map +1 -0
- package/package.json +13 -21
- package/cjs/CallOptions.d.ts +0 -10
- package/cjs/CallOptions.js +0 -16
- package/cjs/ErrorCodeObj.d.ts +0 -9
- package/cjs/ErrorCodeObj.js +0 -14
- package/cjs/PenpalBugError.d.ts +0 -8
- package/cjs/PenpalBugError.js +0 -12
- package/cjs/PenpalError.d.ts +0 -6
- package/cjs/PenpalError.js +0 -11
- package/cjs/Reply.d.ts +0 -9
- package/cjs/Reply.js +0 -16
- package/cjs/backwardCompatibility.d.ts +0 -56
- package/cjs/backwardCompatibility.js +0 -134
- package/cjs/connect.d.ts +0 -33
- package/cjs/connect.js +0 -78
- package/cjs/connectCallHandler.d.ts +0 -8
- package/cjs/connectCallHandler.js +0 -90
- package/cjs/connectRemoteProxy.d.ts +0 -12
- package/cjs/connectRemoteProxy.js +0 -139
- package/cjs/debug.d.ts +0 -3
- package/cjs/debug.js +0 -8
- package/cjs/errorSerialization.d.ts +0 -9
- package/cjs/errorSerialization.js +0 -26
- package/cjs/generateId.d.ts +0 -8
- package/cjs/generateId.js +0 -11
- package/cjs/getPromiseWithResolvers.d.ts +0 -6
- package/cjs/getPromiseWithResolvers.js +0 -19
- package/cjs/guards.d.ts +0 -10
- package/cjs/guards.js +0 -40
- package/cjs/index.d.ts +0 -12
- package/cjs/index.js +0 -21
- package/cjs/indexForBundle.d.ts +0 -31
- package/cjs/indexForBundle.js +0 -22
- package/cjs/messengers/Messenger.d.ts +0 -14
- package/cjs/messengers/Messenger.js +0 -2
- package/cjs/messengers/PortMessenger.d.ts +0 -21
- package/cjs/messengers/PortMessenger.js +0 -47
- package/cjs/messengers/WindowMessenger.d.ts +0 -29
- package/cjs/messengers/WindowMessenger.js +0 -178
- package/cjs/messengers/WorkerMessenger.d.ts +0 -23
- package/cjs/messengers/WorkerMessenger.js +0 -86
- package/cjs/methodSerialization.d.ts +0 -22
- package/cjs/methodSerialization.js +0 -48
- package/cjs/namespace.d.ts +0 -2
- package/cjs/namespace.js +0 -3
- package/cjs/once.d.ts +0 -2
- package/cjs/once.js +0 -15
- package/cjs/shakeHands.d.ts +0 -76
- package/cjs/shakeHands.js +0 -190
- package/cjs/types.d.ts +0 -89
- package/cjs/types.js +0 -2
- package/lib/CallOptions.d.ts +0 -10
- package/lib/CallOptions.js +0 -14
- package/lib/ErrorCodeObj.d.ts +0 -9
- package/lib/ErrorCodeObj.js +0 -12
- package/lib/PenpalBugError.d.ts +0 -8
- package/lib/PenpalBugError.js +0 -10
- package/lib/PenpalError.d.ts +0 -6
- package/lib/PenpalError.js +0 -9
- package/lib/Reply.d.ts +0 -9
- package/lib/Reply.js +0 -14
- package/lib/backwardCompatibility.d.ts +0 -56
- package/lib/backwardCompatibility.js +0 -128
- package/lib/connect.d.ts +0 -33
- package/lib/connect.js +0 -76
- package/lib/connectCallHandler.d.ts +0 -8
- package/lib/connectCallHandler.js +0 -88
- package/lib/connectRemoteProxy.d.ts +0 -12
- package/lib/connectRemoteProxy.js +0 -137
- package/lib/debug.d.ts +0 -3
- package/lib/debug.js +0 -6
- package/lib/errorSerialization.d.ts +0 -9
- package/lib/errorSerialization.js +0 -21
- package/lib/generateId.d.ts +0 -8
- package/lib/generateId.js +0 -9
- package/lib/getPromiseWithResolvers.d.ts +0 -6
- package/lib/getPromiseWithResolvers.js +0 -17
- package/lib/guards.d.ts +0 -10
- package/lib/guards.js +0 -28
- package/lib/index.d.ts +0 -12
- package/lib/index.js +0 -9
- package/lib/indexForBundle.d.ts +0 -31
- package/lib/indexForBundle.js +0 -20
- package/lib/messengers/Messenger.d.ts +0 -14
- package/lib/messengers/Messenger.js +0 -1
- package/lib/messengers/PortMessenger.d.ts +0 -21
- package/lib/messengers/PortMessenger.js +0 -45
- package/lib/messengers/WindowMessenger.d.ts +0 -29
- package/lib/messengers/WindowMessenger.js +0 -176
- package/lib/messengers/WorkerMessenger.d.ts +0 -23
- package/lib/messengers/WorkerMessenger.js +0 -84
- package/lib/methodSerialization.d.ts +0 -22
- package/lib/methodSerialization.js +0 -42
- package/lib/namespace.d.ts +0 -2
- package/lib/namespace.js +0 -1
- package/lib/once.d.ts +0 -2
- package/lib/once.js +0 -13
- package/lib/shakeHands.d.ts +0 -76
- package/lib/shakeHands.js +0 -188
- package/lib/types.d.ts +0 -89
- package/lib/types.js +0 -1
package/cjs/shakeHands.js
DELETED
|
@@ -1,190 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const PenpalError_js_1 = require("./PenpalError.js");
|
|
4
|
-
const connectCallHandler_js_1 = require("./connectCallHandler.js");
|
|
5
|
-
const connectRemoteProxy_js_1 = require("./connectRemoteProxy.js");
|
|
6
|
-
const guards_js_1 = require("./guards.js");
|
|
7
|
-
const getPromiseWithResolvers_js_1 = require("./getPromiseWithResolvers.js");
|
|
8
|
-
const methodSerialization_js_1 = require("./methodSerialization.js");
|
|
9
|
-
const generateId_js_1 = require("./generateId.js");
|
|
10
|
-
const backwardCompatibility_js_1 = require("./backwardCompatibility.js");
|
|
11
|
-
const namespace_js_1 = require("./namespace.js");
|
|
12
|
-
/**
|
|
13
|
-
* Attempts to establish communication with the remote via a handshake protocol.
|
|
14
|
-
* The handshake protocol fulfills a few requirements:
|
|
15
|
-
*
|
|
16
|
-
* 1. One participant in the handshake may not be available when the other
|
|
17
|
-
* participant starts the handshake. For example, a document inside an iframe
|
|
18
|
-
* may not be loaded when the parent window starts a handshake.
|
|
19
|
-
* 2. While #1 could be solved by having the consumer of Penpal specify which
|
|
20
|
-
* participant should initiate the handshake, we'd rather avoid this
|
|
21
|
-
* unnecessary cognitive load.
|
|
22
|
-
* 3. While #1 could be solved by having the consumer of Penpal specify which
|
|
23
|
-
* participant is the "parent" or "child" and then having Penpal assume
|
|
24
|
-
* the child should initiate the handshake, we'd rather avoid parent-child
|
|
25
|
-
* terminology since Penpal can support communication between two
|
|
26
|
-
* participants where neither would be considered a parent nor child. It may
|
|
27
|
-
* also be too presumptive that the child should always initiate the
|
|
28
|
-
* handshake.
|
|
29
|
-
* 4. For robustness, each participant must know that the other participant is
|
|
30
|
-
* receiving its messages for the handshake to be considered complete.
|
|
31
|
-
* 5. The handshake should support a participant attempting to
|
|
32
|
-
* re-establish the connection. This can occur, for example, if an end user
|
|
33
|
-
* were to right-click within an iframe and click reload.
|
|
34
|
-
* 6. The handshake should allow a Messenger to easily attach something to
|
|
35
|
-
* a handshake message from one participant to the other unidirectionally
|
|
36
|
-
* (rather than from both participants to each other).
|
|
37
|
-
* This is important when a participant needs to be in charge of, for
|
|
38
|
-
* example, creating a MessageChannel and sending one MessagePort from the
|
|
39
|
-
* MessagePort pair to the other participant. If both participants attempted
|
|
40
|
-
* to do this it could lead to confusion.
|
|
41
|
-
* 7. The handshake ideally shouldn't require sending handshake messages on an
|
|
42
|
-
* interval (retrying until the other participant is ready to receive them).
|
|
43
|
-
* Intervals can increase compute resources if the interval is too short
|
|
44
|
-
* or increase latency if the interval is too long. While we could make this
|
|
45
|
-
* configurable, it's additional mental load for the consumer. Additionally,
|
|
46
|
-
* setInterval and setTimeout are not available within some contexts
|
|
47
|
-
* (like AudioWorklet), where a consumer may like to use Penpal.
|
|
48
|
-
*
|
|
49
|
-
* To accomplish these requirements, the handshake protocol is as follows:
|
|
50
|
-
* 1. Each participant generates a random participant ID.
|
|
51
|
-
* 2. As soon as possible, each participant sends a SYN message containing its
|
|
52
|
-
* participant ID to the other participant.
|
|
53
|
-
* 3. When the SYN messages were sent, one of the participants may not have
|
|
54
|
-
* been ready to receive the SYN message from the other. At least one
|
|
55
|
-
* of the participants was ready, however, and should have received a SYN
|
|
56
|
-
* message from the other participant. Each participant that did receive
|
|
57
|
-
* a SYN message knows for sure that the other participant is now ready
|
|
58
|
-
* to receive a SYN message, so it will send another SYN message in case
|
|
59
|
-
* the other participant did not receive the first SYN message. This
|
|
60
|
-
* ultimately results in each participant sending two SYN messages.
|
|
61
|
-
* 4. Each participant now should have received at least one SYN message from
|
|
62
|
-
* the other participant. Each participant compares their own ID with the
|
|
63
|
-
* other participant's ID. Whichever participant has the higher ID
|
|
64
|
-
* (using a simple string comparison) is considered the handshake leader
|
|
65
|
-
* and will send an ACK1 message to the other participant.
|
|
66
|
-
* 5. At this point, the handshake leader does not know whether the other
|
|
67
|
-
* participant is actually receiving messages. The participant receiving
|
|
68
|
-
* the ACK1 message will respond with an ACK2, informing the handshake
|
|
69
|
-
* leader that it is indeed receiving messages.
|
|
70
|
-
* 6. At this point, both participants know the other is receiving messages
|
|
71
|
-
* and the handshake is complete.
|
|
72
|
-
*/
|
|
73
|
-
const shakeHands = ({ messenger, methods, timeout, channel, log, }) => {
|
|
74
|
-
const participantId = (0, generateId_js_1.default)();
|
|
75
|
-
let remoteParticipantId;
|
|
76
|
-
const destroyHandlers = [];
|
|
77
|
-
let isComplete = false;
|
|
78
|
-
const methodPaths = (0, methodSerialization_js_1.extractMethodPathsFromMethods)(methods);
|
|
79
|
-
const { promise, resolve, reject } = (0, getPromiseWithResolvers_js_1.default)();
|
|
80
|
-
const timeoutId = timeout !== undefined
|
|
81
|
-
? setTimeout(() => {
|
|
82
|
-
reject(new PenpalError_js_1.default('CONNECTION_TIMEOUT', `Connection timed out after ${timeout}ms`));
|
|
83
|
-
}, timeout)
|
|
84
|
-
: undefined;
|
|
85
|
-
const destroy = () => {
|
|
86
|
-
for (const destroyHandler of destroyHandlers) {
|
|
87
|
-
destroyHandler();
|
|
88
|
-
}
|
|
89
|
-
};
|
|
90
|
-
const connectCallHandlerAndMethodProxies = () => {
|
|
91
|
-
if (isComplete) {
|
|
92
|
-
// If we get here, it means the remote is attempting to re-connect. While
|
|
93
|
-
// that's supported, we don't need to run the rest of this function again.
|
|
94
|
-
return;
|
|
95
|
-
}
|
|
96
|
-
destroyHandlers.push((0, connectCallHandler_js_1.default)(messenger, methods, channel, log));
|
|
97
|
-
const { remoteProxy, destroy: destroyMethodProxies } = (0, connectRemoteProxy_js_1.default)(messenger, channel, log);
|
|
98
|
-
destroyHandlers.push(destroyMethodProxies);
|
|
99
|
-
clearTimeout(timeoutId);
|
|
100
|
-
isComplete = true;
|
|
101
|
-
resolve({
|
|
102
|
-
remoteProxy,
|
|
103
|
-
destroy: destroy,
|
|
104
|
-
});
|
|
105
|
-
};
|
|
106
|
-
const sendSynMessage = () => {
|
|
107
|
-
const synMessage = {
|
|
108
|
-
namespace: namespace_js_1.default,
|
|
109
|
-
type: 'SYN',
|
|
110
|
-
channel,
|
|
111
|
-
participantId: participantId,
|
|
112
|
-
};
|
|
113
|
-
log?.(`Sending handshake SYN`, synMessage);
|
|
114
|
-
try {
|
|
115
|
-
messenger.sendMessage(synMessage);
|
|
116
|
-
}
|
|
117
|
-
catch (error) {
|
|
118
|
-
reject(new PenpalError_js_1.default('TRANSMISSION_FAILED', error.message));
|
|
119
|
-
}
|
|
120
|
-
};
|
|
121
|
-
const handleSynMessage = (message) => {
|
|
122
|
-
log?.(`Received handshake SYN`, message);
|
|
123
|
-
if (message.participantId === remoteParticipantId &&
|
|
124
|
-
// TODO: Used for backward-compatibility. Remove in next major version.
|
|
125
|
-
remoteParticipantId !== backwardCompatibility_js_1.DEPRECATED_PENPAL_PARTICIPANT_ID) {
|
|
126
|
-
return;
|
|
127
|
-
}
|
|
128
|
-
remoteParticipantId = message.participantId;
|
|
129
|
-
// We send another SYN message in case the other participant was not ready
|
|
130
|
-
// when we sent the first SYN message.
|
|
131
|
-
sendSynMessage();
|
|
132
|
-
const isHandshakeLeader = participantId > remoteParticipantId ||
|
|
133
|
-
// TODO: Used for backward-compatibility. Remove in next major version.
|
|
134
|
-
remoteParticipantId === backwardCompatibility_js_1.DEPRECATED_PENPAL_PARTICIPANT_ID;
|
|
135
|
-
if (!isHandshakeLeader) {
|
|
136
|
-
return;
|
|
137
|
-
}
|
|
138
|
-
const ack1Message = {
|
|
139
|
-
namespace: namespace_js_1.default,
|
|
140
|
-
channel,
|
|
141
|
-
type: 'ACK1',
|
|
142
|
-
methodPaths,
|
|
143
|
-
};
|
|
144
|
-
log?.(`Sending handshake ACK1`, ack1Message);
|
|
145
|
-
try {
|
|
146
|
-
messenger.sendMessage(ack1Message);
|
|
147
|
-
}
|
|
148
|
-
catch (error) {
|
|
149
|
-
reject(new PenpalError_js_1.default('TRANSMISSION_FAILED', error.message));
|
|
150
|
-
return;
|
|
151
|
-
}
|
|
152
|
-
};
|
|
153
|
-
const handleAck1Message = (message) => {
|
|
154
|
-
log?.(`Received handshake ACK1`, message);
|
|
155
|
-
const ack2Message = {
|
|
156
|
-
namespace: namespace_js_1.default,
|
|
157
|
-
channel,
|
|
158
|
-
type: 'ACK2',
|
|
159
|
-
};
|
|
160
|
-
log?.(`Sending handshake ACK2`, ack2Message);
|
|
161
|
-
try {
|
|
162
|
-
messenger.sendMessage(ack2Message);
|
|
163
|
-
}
|
|
164
|
-
catch (error) {
|
|
165
|
-
reject(new PenpalError_js_1.default('TRANSMISSION_FAILED', error.message));
|
|
166
|
-
return;
|
|
167
|
-
}
|
|
168
|
-
connectCallHandlerAndMethodProxies();
|
|
169
|
-
};
|
|
170
|
-
const handleAck2Message = (message) => {
|
|
171
|
-
log?.(`Received handshake ACK2`, message);
|
|
172
|
-
connectCallHandlerAndMethodProxies();
|
|
173
|
-
};
|
|
174
|
-
const handleMessage = (message) => {
|
|
175
|
-
if ((0, guards_js_1.isSynMessage)(message)) {
|
|
176
|
-
handleSynMessage(message);
|
|
177
|
-
}
|
|
178
|
-
if ((0, guards_js_1.isAck1Message)(message)) {
|
|
179
|
-
handleAck1Message(message);
|
|
180
|
-
}
|
|
181
|
-
if ((0, guards_js_1.isAck2Message)(message)) {
|
|
182
|
-
handleAck2Message(message);
|
|
183
|
-
}
|
|
184
|
-
};
|
|
185
|
-
messenger.addMessageHandler(handleMessage);
|
|
186
|
-
destroyHandlers.push(() => messenger.removeMessageHandler(handleMessage));
|
|
187
|
-
sendSynMessage();
|
|
188
|
-
return promise;
|
|
189
|
-
};
|
|
190
|
-
exports.default = shakeHands;
|
package/cjs/types.d.ts
DELETED
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
import CallOptions from './CallOptions.js';
|
|
2
|
-
import Reply from './Reply.js';
|
|
3
|
-
import namespace from './namespace.js';
|
|
4
|
-
import ErrorCodeObj from './ErrorCodeObj.js';
|
|
5
|
-
type ExtractValueFromReply<R> = R extends Reply ? Awaited<R['value']> : R;
|
|
6
|
-
/**
|
|
7
|
-
* An object representing methods exposed by the remote but that can be called
|
|
8
|
-
* locally.
|
|
9
|
-
*/
|
|
10
|
-
export type RemoteProxy<TMethods extends Methods = Methods> = {
|
|
11
|
-
[K in keyof TMethods]: TMethods[K] extends (...args: infer A) => infer R ? (...args: [...A, CallOptions?]) => Promise<ExtractValueFromReply<Awaited<R>>> : TMethods[K] extends Methods ? RemoteProxy<TMethods[K]> : never;
|
|
12
|
-
};
|
|
13
|
-
/**
|
|
14
|
-
* An object representing the connection as a result of calling connect().
|
|
15
|
-
*/
|
|
16
|
-
export type Connection<TMethods extends Methods = Methods> = {
|
|
17
|
-
/**
|
|
18
|
-
* A promise which will be resolved once the connection has been established.
|
|
19
|
-
*/
|
|
20
|
-
promise: Promise<RemoteProxy<TMethods>>;
|
|
21
|
-
/**
|
|
22
|
-
* A method that, when called, will disconnect any communication.
|
|
23
|
-
* You may call this even before a connection has been established.
|
|
24
|
-
*/
|
|
25
|
-
destroy: () => void;
|
|
26
|
-
};
|
|
27
|
-
/**
|
|
28
|
-
* Methods to expose to the remote window. May contain nested objects
|
|
29
|
-
* with methods as well.
|
|
30
|
-
*/
|
|
31
|
-
export type Methods = {
|
|
32
|
-
[index: string]: Methods | Function;
|
|
33
|
-
};
|
|
34
|
-
/**
|
|
35
|
-
* An array of path segments (object property keys) to use to find a method
|
|
36
|
-
* within a Methods object. We avoid using a period-delimited string because
|
|
37
|
-
* property names can have periods in them which could cause issues.
|
|
38
|
-
*/
|
|
39
|
-
export type MethodPath = string[];
|
|
40
|
-
export type ErrorCode = typeof ErrorCodeObj[keyof typeof ErrorCodeObj];
|
|
41
|
-
export type SerializedError = {
|
|
42
|
-
name: string;
|
|
43
|
-
message: string;
|
|
44
|
-
stack?: string;
|
|
45
|
-
penpalCode?: ErrorCode;
|
|
46
|
-
};
|
|
47
|
-
type MessageBase = {
|
|
48
|
-
namespace: typeof namespace;
|
|
49
|
-
channel: string | undefined;
|
|
50
|
-
};
|
|
51
|
-
export type SynMessage = MessageBase & {
|
|
52
|
-
type: 'SYN';
|
|
53
|
-
participantId: string;
|
|
54
|
-
};
|
|
55
|
-
export type Ack1Message = MessageBase & {
|
|
56
|
-
type: 'ACK1';
|
|
57
|
-
methodPaths: MethodPath[];
|
|
58
|
-
};
|
|
59
|
-
export type Ack2Message = MessageBase & {
|
|
60
|
-
type: 'ACK2';
|
|
61
|
-
};
|
|
62
|
-
export type CallMessage = MessageBase & {
|
|
63
|
-
type: 'CALL';
|
|
64
|
-
id: string;
|
|
65
|
-
methodPath: MethodPath;
|
|
66
|
-
args: unknown[];
|
|
67
|
-
};
|
|
68
|
-
export type ReplyMessage = MessageBase & {
|
|
69
|
-
type: 'REPLY';
|
|
70
|
-
callId: string;
|
|
71
|
-
} & ({
|
|
72
|
-
value: unknown;
|
|
73
|
-
isError?: false;
|
|
74
|
-
isSerializedErrorInstance?: false;
|
|
75
|
-
} | {
|
|
76
|
-
value: unknown;
|
|
77
|
-
isError: true;
|
|
78
|
-
isSerializedErrorInstance?: false;
|
|
79
|
-
} | {
|
|
80
|
-
value: SerializedError;
|
|
81
|
-
isError: true;
|
|
82
|
-
isSerializedErrorInstance: true;
|
|
83
|
-
});
|
|
84
|
-
export type DestroyMessage = MessageBase & {
|
|
85
|
-
type: 'DESTROY';
|
|
86
|
-
};
|
|
87
|
-
export type Message = SynMessage | Ack1Message | Ack2Message | CallMessage | ReplyMessage | DestroyMessage;
|
|
88
|
-
export type Log = (...args: unknown[]) => void;
|
|
89
|
-
export {};
|
package/cjs/types.js
DELETED
package/lib/CallOptions.d.ts
DELETED
package/lib/CallOptions.js
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
const brand = Symbol('CallOptions');
|
|
2
|
-
class CallOptions {
|
|
3
|
-
transferables;
|
|
4
|
-
timeout;
|
|
5
|
-
// Allows TypeScript to distinguish between an actual instance of this
|
|
6
|
-
// class versus an object that looks structurally similar.
|
|
7
|
-
// eslint-disable-next-line no-unused-private-class-members
|
|
8
|
-
#brand = brand;
|
|
9
|
-
constructor(options) {
|
|
10
|
-
this.transferables = options?.transferables;
|
|
11
|
-
this.timeout = options?.timeout;
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
export default CallOptions;
|
package/lib/ErrorCodeObj.d.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
declare const ErrorCodeObj: {
|
|
2
|
-
readonly ConnectionDestroyed: "CONNECTION_DESTROYED";
|
|
3
|
-
readonly ConnectionTimeout: "CONNECTION_TIMEOUT";
|
|
4
|
-
readonly InvalidArgument: "INVALID_ARGUMENT";
|
|
5
|
-
readonly MethodCallTimeout: "METHOD_CALL_TIMEOUT";
|
|
6
|
-
readonly MethodNotFound: "METHOD_NOT_FOUND";
|
|
7
|
-
readonly TransmissionFailed: "TRANSMISSION_FAILED";
|
|
8
|
-
};
|
|
9
|
-
export default ErrorCodeObj;
|
package/lib/ErrorCodeObj.js
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
// Not intended to be used internally. Can be useful externally
|
|
2
|
-
// in projects not using TypeScript. It has the `Obj` suffix to disambiguate
|
|
3
|
-
// it from the ErrorCode string union.
|
|
4
|
-
const ErrorCodeObj = {
|
|
5
|
-
ConnectionDestroyed: 'CONNECTION_DESTROYED',
|
|
6
|
-
ConnectionTimeout: 'CONNECTION_TIMEOUT',
|
|
7
|
-
InvalidArgument: 'INVALID_ARGUMENT',
|
|
8
|
-
MethodCallTimeout: 'METHOD_CALL_TIMEOUT',
|
|
9
|
-
MethodNotFound: 'METHOD_NOT_FOUND',
|
|
10
|
-
TransmissionFailed: 'TRANSMISSION_FAILED',
|
|
11
|
-
};
|
|
12
|
-
export default ErrorCodeObj;
|
package/lib/PenpalBugError.d.ts
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Error class that is thrown when we've reached a situation that we believe to
|
|
3
|
-
* be a bug in Penpal and not anything the consumer has done.
|
|
4
|
-
*/
|
|
5
|
-
declare class PenpalBugError extends Error {
|
|
6
|
-
constructor(message: string);
|
|
7
|
-
}
|
|
8
|
-
export default PenpalBugError;
|
package/lib/PenpalBugError.js
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Error class that is thrown when we've reached a situation that we believe to
|
|
3
|
-
* be a bug in Penpal and not anything the consumer has done.
|
|
4
|
-
*/
|
|
5
|
-
class PenpalBugError extends Error {
|
|
6
|
-
constructor(message) {
|
|
7
|
-
super(`You've hit a bug in Penpal. Please file an issue with the following information: ${message}`);
|
|
8
|
-
}
|
|
9
|
-
}
|
|
10
|
-
export default PenpalBugError;
|
package/lib/PenpalError.d.ts
DELETED
package/lib/PenpalError.js
DELETED
package/lib/Reply.d.ts
DELETED
package/lib/Reply.js
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
const brand = Symbol('Reply');
|
|
2
|
-
class Reply {
|
|
3
|
-
value;
|
|
4
|
-
transferables;
|
|
5
|
-
// Allows TypeScript to distinguish between an actual instance of this
|
|
6
|
-
// class versus an object that looks structurally similar.
|
|
7
|
-
// eslint-disable-next-line no-unused-private-class-members
|
|
8
|
-
#brand = brand;
|
|
9
|
-
constructor(value, options) {
|
|
10
|
-
this.value = value;
|
|
11
|
-
this.transferables = options?.transferables;
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
export default Reply;
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import { Message } from './types.js';
|
|
2
|
-
export declare const DEPRECATED_PENPAL_PARTICIPANT_ID = "deprecated-penpal";
|
|
3
|
-
declare enum DeprecatedMessageType {
|
|
4
|
-
Call = "call",
|
|
5
|
-
Reply = "reply",
|
|
6
|
-
Syn = "syn",
|
|
7
|
-
SynAck = "synAck",
|
|
8
|
-
Ack = "ack"
|
|
9
|
-
}
|
|
10
|
-
declare enum DeprecatedResolution {
|
|
11
|
-
Fulfilled = "fulfilled",
|
|
12
|
-
Rejected = "rejected"
|
|
13
|
-
}
|
|
14
|
-
type DeprecatedSynMessage = {
|
|
15
|
-
penpal: DeprecatedMessageType.Syn;
|
|
16
|
-
};
|
|
17
|
-
type DeprecatedSynAckMessage = {
|
|
18
|
-
penpal: DeprecatedMessageType.SynAck;
|
|
19
|
-
methodNames: string[];
|
|
20
|
-
};
|
|
21
|
-
type DeprecatedAckMessage = {
|
|
22
|
-
penpal: DeprecatedMessageType.Ack;
|
|
23
|
-
methodNames: string[];
|
|
24
|
-
};
|
|
25
|
-
type DeprecatedCallMessage = {
|
|
26
|
-
penpal: DeprecatedMessageType.Call;
|
|
27
|
-
id: number;
|
|
28
|
-
methodName: string;
|
|
29
|
-
args: unknown[];
|
|
30
|
-
};
|
|
31
|
-
type DeprecatedSerializedError = {
|
|
32
|
-
name: string;
|
|
33
|
-
message: string;
|
|
34
|
-
stack?: string;
|
|
35
|
-
};
|
|
36
|
-
type DeprecatedReplyMessage = {
|
|
37
|
-
penpal: DeprecatedMessageType.Reply;
|
|
38
|
-
id: number;
|
|
39
|
-
} & ({
|
|
40
|
-
resolution: DeprecatedResolution.Fulfilled;
|
|
41
|
-
returnValue: unknown;
|
|
42
|
-
returnValueIsError?: false;
|
|
43
|
-
} | {
|
|
44
|
-
resolution: DeprecatedResolution.Rejected;
|
|
45
|
-
returnValue: unknown;
|
|
46
|
-
returnValueIsError?: false;
|
|
47
|
-
} | {
|
|
48
|
-
resolution: DeprecatedResolution.Rejected;
|
|
49
|
-
returnValue: DeprecatedSerializedError;
|
|
50
|
-
returnValueIsError: true;
|
|
51
|
-
});
|
|
52
|
-
export type DeprecatedMessage = DeprecatedSynMessage | DeprecatedSynAckMessage | DeprecatedAckMessage | DeprecatedCallMessage | DeprecatedReplyMessage;
|
|
53
|
-
export declare const isDeprecatedMessage: (data: unknown) => data is DeprecatedMessage;
|
|
54
|
-
export declare const upgradeMessage: (message: DeprecatedMessage) => Message;
|
|
55
|
-
export declare const downgradeMessage: (message: Message) => DeprecatedMessage;
|
|
56
|
-
export {};
|
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
import namespace from './namespace.js';
|
|
2
|
-
import { isCallMessage, isReplyMessage, isAck1Message, isObject, } from './guards.js';
|
|
3
|
-
import PenpalBugError from './PenpalBugError.js';
|
|
4
|
-
export const DEPRECATED_PENPAL_PARTICIPANT_ID = 'deprecated-penpal';
|
|
5
|
-
// TODO: This file is used for backward-compatibility. Remove in next major version.
|
|
6
|
-
var DeprecatedMessageType;
|
|
7
|
-
(function (DeprecatedMessageType) {
|
|
8
|
-
DeprecatedMessageType["Call"] = "call";
|
|
9
|
-
DeprecatedMessageType["Reply"] = "reply";
|
|
10
|
-
DeprecatedMessageType["Syn"] = "syn";
|
|
11
|
-
DeprecatedMessageType["SynAck"] = "synAck";
|
|
12
|
-
DeprecatedMessageType["Ack"] = "ack";
|
|
13
|
-
})(DeprecatedMessageType || (DeprecatedMessageType = {}));
|
|
14
|
-
var DeprecatedResolution;
|
|
15
|
-
(function (DeprecatedResolution) {
|
|
16
|
-
DeprecatedResolution["Fulfilled"] = "fulfilled";
|
|
17
|
-
DeprecatedResolution["Rejected"] = "rejected";
|
|
18
|
-
})(DeprecatedResolution || (DeprecatedResolution = {}));
|
|
19
|
-
export const isDeprecatedMessage = (data) => {
|
|
20
|
-
return isObject(data) && 'penpal' in data;
|
|
21
|
-
};
|
|
22
|
-
const upgradeMethodPath = (methodPath) => methodPath.split('.');
|
|
23
|
-
const downgradeMethodPath = (methodPath) => methodPath.join('.');
|
|
24
|
-
const getUnexpectedMessageError = (message) => {
|
|
25
|
-
return new PenpalBugError(`Unexpected message to translate: ${JSON.stringify(message)}`);
|
|
26
|
-
};
|
|
27
|
-
export const upgradeMessage = (message) => {
|
|
28
|
-
if (message.penpal === DeprecatedMessageType.Syn) {
|
|
29
|
-
return {
|
|
30
|
-
namespace,
|
|
31
|
-
channel: undefined,
|
|
32
|
-
type: 'SYN',
|
|
33
|
-
participantId: DEPRECATED_PENPAL_PARTICIPANT_ID,
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
if (message.penpal === DeprecatedMessageType.Ack) {
|
|
37
|
-
return {
|
|
38
|
-
namespace,
|
|
39
|
-
channel: undefined,
|
|
40
|
-
type: 'ACK2',
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
if (message.penpal === DeprecatedMessageType.Call) {
|
|
44
|
-
return {
|
|
45
|
-
namespace,
|
|
46
|
-
channel: undefined,
|
|
47
|
-
type: 'CALL',
|
|
48
|
-
// Actually converting the ID to a string would break communication.
|
|
49
|
-
id: message.id,
|
|
50
|
-
methodPath: upgradeMethodPath(message.methodName),
|
|
51
|
-
args: message.args,
|
|
52
|
-
};
|
|
53
|
-
}
|
|
54
|
-
if (message.penpal === DeprecatedMessageType.Reply) {
|
|
55
|
-
if (message.resolution === DeprecatedResolution.Fulfilled) {
|
|
56
|
-
return {
|
|
57
|
-
namespace,
|
|
58
|
-
channel: undefined,
|
|
59
|
-
type: 'REPLY',
|
|
60
|
-
// Actually converting the ID to a string would break communication.
|
|
61
|
-
callId: message.id,
|
|
62
|
-
value: message.returnValue,
|
|
63
|
-
};
|
|
64
|
-
}
|
|
65
|
-
else {
|
|
66
|
-
return {
|
|
67
|
-
namespace,
|
|
68
|
-
channel: undefined,
|
|
69
|
-
type: 'REPLY',
|
|
70
|
-
// Actually converting the ID to a string would break communication.
|
|
71
|
-
callId: message.id,
|
|
72
|
-
isError: true,
|
|
73
|
-
...(message.returnValueIsError
|
|
74
|
-
? {
|
|
75
|
-
value: message.returnValue,
|
|
76
|
-
isSerializedErrorInstance: true,
|
|
77
|
-
}
|
|
78
|
-
: {
|
|
79
|
-
value: message.returnValue,
|
|
80
|
-
}),
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
throw getUnexpectedMessageError(message);
|
|
85
|
-
};
|
|
86
|
-
export const downgradeMessage = (message) => {
|
|
87
|
-
if (isAck1Message(message)) {
|
|
88
|
-
return {
|
|
89
|
-
penpal: DeprecatedMessageType.SynAck,
|
|
90
|
-
methodNames: message.methodPaths.map(downgradeMethodPath),
|
|
91
|
-
};
|
|
92
|
-
}
|
|
93
|
-
if (isCallMessage(message)) {
|
|
94
|
-
return {
|
|
95
|
-
penpal: DeprecatedMessageType.Call,
|
|
96
|
-
// Actually converting the ID to a number would break communication.
|
|
97
|
-
id: message.id,
|
|
98
|
-
methodName: downgradeMethodPath(message.methodPath),
|
|
99
|
-
args: message.args,
|
|
100
|
-
};
|
|
101
|
-
}
|
|
102
|
-
if (isReplyMessage(message)) {
|
|
103
|
-
if (message.isError) {
|
|
104
|
-
return {
|
|
105
|
-
penpal: DeprecatedMessageType.Reply,
|
|
106
|
-
// Actually converting the ID to a number would break communication.
|
|
107
|
-
id: message.callId,
|
|
108
|
-
resolution: DeprecatedResolution.Rejected,
|
|
109
|
-
...(message.isSerializedErrorInstance
|
|
110
|
-
? {
|
|
111
|
-
returnValue: message.value,
|
|
112
|
-
returnValueIsError: true,
|
|
113
|
-
}
|
|
114
|
-
: { returnValue: message.value }),
|
|
115
|
-
};
|
|
116
|
-
}
|
|
117
|
-
else {
|
|
118
|
-
return {
|
|
119
|
-
penpal: DeprecatedMessageType.Reply,
|
|
120
|
-
// Actually converting the ID to a number would break communication.
|
|
121
|
-
id: message.callId,
|
|
122
|
-
resolution: DeprecatedResolution.Fulfilled,
|
|
123
|
-
returnValue: message.value,
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
throw getUnexpectedMessageError(message);
|
|
128
|
-
};
|
package/lib/connect.d.ts
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { Connection, Log, Methods } from './types.js';
|
|
2
|
-
import Messenger from './messengers/Messenger.js';
|
|
3
|
-
type Options = {
|
|
4
|
-
/**
|
|
5
|
-
* Messenger in charge of handling communication with the remote.
|
|
6
|
-
*/
|
|
7
|
-
messenger: Messenger;
|
|
8
|
-
/**
|
|
9
|
-
* Methods that may be called by the remote.
|
|
10
|
-
*/
|
|
11
|
-
methods?: Methods;
|
|
12
|
-
/**
|
|
13
|
-
* The amount of time, in milliseconds, Penpal should wait
|
|
14
|
-
* for a connection to be established before rejecting the connection promise.
|
|
15
|
-
*/
|
|
16
|
-
timeout?: number;
|
|
17
|
-
/**
|
|
18
|
-
* A string identifier that disambiguates communication when establishing
|
|
19
|
-
* multiple, parallel connections between two participants (e.g., two windows,
|
|
20
|
-
* a window and a worker).
|
|
21
|
-
*/
|
|
22
|
-
channel?: string;
|
|
23
|
-
/**
|
|
24
|
-
* A function for logging debug messages. Debug messages will only be
|
|
25
|
-
* logged when this is defined.
|
|
26
|
-
*/
|
|
27
|
-
log?: Log;
|
|
28
|
-
};
|
|
29
|
-
/**
|
|
30
|
-
* Attempts to establish communication with the remote.
|
|
31
|
-
*/
|
|
32
|
-
declare const connect: <TMethods extends Methods>({ messenger, methods, timeout, channel, log, }: Options) => Connection<TMethods>;
|
|
33
|
-
export default connect;
|