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.
Files changed (111) hide show
  1. package/dist/penpal.cjs +953 -0
  2. package/dist/penpal.cjs.map +1 -0
  3. package/dist/penpal.d.cts +234 -0
  4. package/dist/penpal.d.ts +234 -0
  5. package/dist/penpal.js +890 -1033
  6. package/dist/penpal.js.map +1 -0
  7. package/dist/penpal.min.js +1 -1
  8. package/dist/penpal.min.js.map +1 -1
  9. package/dist/penpal.mjs +943 -0
  10. package/dist/penpal.mjs.map +1 -0
  11. package/package.json +13 -21
  12. package/cjs/CallOptions.d.ts +0 -10
  13. package/cjs/CallOptions.js +0 -16
  14. package/cjs/ErrorCodeObj.d.ts +0 -9
  15. package/cjs/ErrorCodeObj.js +0 -14
  16. package/cjs/PenpalBugError.d.ts +0 -8
  17. package/cjs/PenpalBugError.js +0 -12
  18. package/cjs/PenpalError.d.ts +0 -6
  19. package/cjs/PenpalError.js +0 -11
  20. package/cjs/Reply.d.ts +0 -9
  21. package/cjs/Reply.js +0 -16
  22. package/cjs/backwardCompatibility.d.ts +0 -56
  23. package/cjs/backwardCompatibility.js +0 -134
  24. package/cjs/connect.d.ts +0 -33
  25. package/cjs/connect.js +0 -78
  26. package/cjs/connectCallHandler.d.ts +0 -8
  27. package/cjs/connectCallHandler.js +0 -90
  28. package/cjs/connectRemoteProxy.d.ts +0 -12
  29. package/cjs/connectRemoteProxy.js +0 -139
  30. package/cjs/debug.d.ts +0 -3
  31. package/cjs/debug.js +0 -8
  32. package/cjs/errorSerialization.d.ts +0 -9
  33. package/cjs/errorSerialization.js +0 -26
  34. package/cjs/generateId.d.ts +0 -8
  35. package/cjs/generateId.js +0 -11
  36. package/cjs/getPromiseWithResolvers.d.ts +0 -6
  37. package/cjs/getPromiseWithResolvers.js +0 -19
  38. package/cjs/guards.d.ts +0 -10
  39. package/cjs/guards.js +0 -40
  40. package/cjs/index.d.ts +0 -12
  41. package/cjs/index.js +0 -21
  42. package/cjs/indexForBundle.d.ts +0 -31
  43. package/cjs/indexForBundle.js +0 -22
  44. package/cjs/messengers/Messenger.d.ts +0 -14
  45. package/cjs/messengers/Messenger.js +0 -2
  46. package/cjs/messengers/PortMessenger.d.ts +0 -21
  47. package/cjs/messengers/PortMessenger.js +0 -47
  48. package/cjs/messengers/WindowMessenger.d.ts +0 -29
  49. package/cjs/messengers/WindowMessenger.js +0 -178
  50. package/cjs/messengers/WorkerMessenger.d.ts +0 -23
  51. package/cjs/messengers/WorkerMessenger.js +0 -86
  52. package/cjs/methodSerialization.d.ts +0 -22
  53. package/cjs/methodSerialization.js +0 -48
  54. package/cjs/namespace.d.ts +0 -2
  55. package/cjs/namespace.js +0 -3
  56. package/cjs/once.d.ts +0 -2
  57. package/cjs/once.js +0 -15
  58. package/cjs/shakeHands.d.ts +0 -76
  59. package/cjs/shakeHands.js +0 -190
  60. package/cjs/types.d.ts +0 -89
  61. package/cjs/types.js +0 -2
  62. package/lib/CallOptions.d.ts +0 -10
  63. package/lib/CallOptions.js +0 -14
  64. package/lib/ErrorCodeObj.d.ts +0 -9
  65. package/lib/ErrorCodeObj.js +0 -12
  66. package/lib/PenpalBugError.d.ts +0 -8
  67. package/lib/PenpalBugError.js +0 -10
  68. package/lib/PenpalError.d.ts +0 -6
  69. package/lib/PenpalError.js +0 -9
  70. package/lib/Reply.d.ts +0 -9
  71. package/lib/Reply.js +0 -14
  72. package/lib/backwardCompatibility.d.ts +0 -56
  73. package/lib/backwardCompatibility.js +0 -128
  74. package/lib/connect.d.ts +0 -33
  75. package/lib/connect.js +0 -76
  76. package/lib/connectCallHandler.d.ts +0 -8
  77. package/lib/connectCallHandler.js +0 -88
  78. package/lib/connectRemoteProxy.d.ts +0 -12
  79. package/lib/connectRemoteProxy.js +0 -137
  80. package/lib/debug.d.ts +0 -3
  81. package/lib/debug.js +0 -6
  82. package/lib/errorSerialization.d.ts +0 -9
  83. package/lib/errorSerialization.js +0 -21
  84. package/lib/generateId.d.ts +0 -8
  85. package/lib/generateId.js +0 -9
  86. package/lib/getPromiseWithResolvers.d.ts +0 -6
  87. package/lib/getPromiseWithResolvers.js +0 -17
  88. package/lib/guards.d.ts +0 -10
  89. package/lib/guards.js +0 -28
  90. package/lib/index.d.ts +0 -12
  91. package/lib/index.js +0 -9
  92. package/lib/indexForBundle.d.ts +0 -31
  93. package/lib/indexForBundle.js +0 -20
  94. package/lib/messengers/Messenger.d.ts +0 -14
  95. package/lib/messengers/Messenger.js +0 -1
  96. package/lib/messengers/PortMessenger.d.ts +0 -21
  97. package/lib/messengers/PortMessenger.js +0 -45
  98. package/lib/messengers/WindowMessenger.d.ts +0 -29
  99. package/lib/messengers/WindowMessenger.js +0 -176
  100. package/lib/messengers/WorkerMessenger.d.ts +0 -23
  101. package/lib/messengers/WorkerMessenger.js +0 -84
  102. package/lib/methodSerialization.d.ts +0 -22
  103. package/lib/methodSerialization.js +0 -42
  104. package/lib/namespace.d.ts +0 -2
  105. package/lib/namespace.js +0 -1
  106. package/lib/once.d.ts +0 -2
  107. package/lib/once.js +0 -13
  108. package/lib/shakeHands.d.ts +0 -76
  109. package/lib/shakeHands.js +0 -188
  110. package/lib/types.d.ts +0 -89
  111. package/lib/types.js +0 -1
package/lib/connect.js DELETED
@@ -1,76 +0,0 @@
1
- import PenpalError from './PenpalError.js';
2
- import shakeHands from './shakeHands.js';
3
- import { isDestroyMessage, isMessage } from './guards.js';
4
- import once from './once.js';
5
- import namespace from './namespace.js';
6
- const usedMessengers = new WeakSet();
7
- /**
8
- * Attempts to establish communication with the remote.
9
- */
10
- const connect = ({ messenger, methods = {}, timeout, channel, log, }) => {
11
- if (!messenger) {
12
- throw new PenpalError('INVALID_ARGUMENT', 'messenger must be defined');
13
- }
14
- if (usedMessengers.has(messenger)) {
15
- throw new PenpalError('INVALID_ARGUMENT', 'A messenger can only be used for a single connection');
16
- }
17
- usedMessengers.add(messenger);
18
- const connectionDestroyedHandlers = [messenger.destroy];
19
- const destroyConnection = once((notifyOtherParticipant) => {
20
- if (notifyOtherParticipant) {
21
- const destroyMessage = {
22
- namespace,
23
- channel,
24
- type: 'DESTROY',
25
- };
26
- try {
27
- messenger.sendMessage(destroyMessage);
28
- }
29
- catch (_) {
30
- // We do our best to notify the other participant of the connection, but
31
- // if there's an error in doing so (e.g., maybe the handshake hasn't
32
- // completed and a messenger can't send the message), it's probably not
33
- // worth bothering the consumer with an error.
34
- }
35
- }
36
- for (const connectionDestroyedHandler of connectionDestroyedHandlers) {
37
- connectionDestroyedHandler();
38
- }
39
- log?.('Connection destroyed');
40
- });
41
- const validateReceivedMessage = (data) => {
42
- return isMessage(data) && data.channel === channel;
43
- };
44
- const promise = (async () => {
45
- try {
46
- messenger.initialize({ log, validateReceivedMessage });
47
- messenger.addMessageHandler((message) => {
48
- if (isDestroyMessage(message)) {
49
- destroyConnection(false);
50
- }
51
- });
52
- const { remoteProxy, destroy } = await shakeHands({
53
- messenger,
54
- methods,
55
- timeout,
56
- channel,
57
- log,
58
- });
59
- connectionDestroyedHandlers.push(destroy);
60
- return remoteProxy;
61
- }
62
- catch (error) {
63
- destroyConnection(true);
64
- throw error;
65
- }
66
- })();
67
- return {
68
- promise,
69
- // Why we don't reject the connection promise when consumer calls destroy():
70
- // https://github.com/Aaronius/penpal/issues/51
71
- destroy: () => {
72
- destroyConnection(true);
73
- },
74
- };
75
- };
76
- export default connect;
@@ -1,8 +0,0 @@
1
- import { Methods, Log } from './types.js';
2
- import Messenger from './messengers/Messenger.js';
3
- /**
4
- * Listens for "call" messages from the remote, executes the corresponding method,
5
- * and responds with the return value or error.
6
- */
7
- declare const connectCallHandler: (messenger: Messenger, methods: Methods, channel: string | undefined, log: Log | undefined) => () => void;
8
- export default connectCallHandler;
@@ -1,88 +0,0 @@
1
- import { serializeError } from './errorSerialization.js';
2
- import Reply from './Reply.js';
3
- import PenpalError from './PenpalError.js';
4
- import { formatMethodPath, getMethodAtMethodPath, } from './methodSerialization.js';
5
- import { isCallMessage } from './guards.js';
6
- import namespace from './namespace.js';
7
- const createErrorReplyMessage = (channel, callId, error) => ({
8
- namespace,
9
- channel,
10
- type: 'REPLY',
11
- callId,
12
- isError: true,
13
- ...(error instanceof Error
14
- ? { value: serializeError(error), isSerializedErrorInstance: true }
15
- : { value: error }),
16
- });
17
- /**
18
- * Listens for "call" messages from the remote, executes the corresponding method,
19
- * and responds with the return value or error.
20
- */
21
- const connectCallHandler = (messenger, methods, channel, log) => {
22
- let isDestroyed = false;
23
- const handleMessage = async (message) => {
24
- if (isDestroyed) {
25
- // It's possible to throw an error here, but it would only be catchable
26
- // using window.onerror since we're in an asynchronously-called function.
27
- // There is no method call the consumer is making that they could wrap in
28
- // a try-catch. Even if the consumer were to catch the error somehow,
29
- // the value of doing so is questionable.
30
- return;
31
- }
32
- if (!isCallMessage(message)) {
33
- return;
34
- }
35
- log?.(`Received ${formatMethodPath(message.methodPath)}() call`, message);
36
- const { methodPath, args, id: callId } = message;
37
- let replyMessage;
38
- let transferables;
39
- try {
40
- const method = getMethodAtMethodPath(methodPath, methods);
41
- if (!method) {
42
- throw new PenpalError('METHOD_NOT_FOUND', `Method \`${formatMethodPath(methodPath)}\` is not found.`);
43
- }
44
- let value = await method(...args);
45
- if (value instanceof Reply) {
46
- transferables = value.transferables;
47
- value = await value.value;
48
- }
49
- replyMessage = {
50
- namespace,
51
- channel,
52
- type: 'REPLY',
53
- callId,
54
- value,
55
- };
56
- }
57
- catch (error) {
58
- replyMessage = createErrorReplyMessage(channel, callId, error);
59
- }
60
- // Although we checked this at the beginning of the function, we need to
61
- // check it again because we've made async calls, and the connection may
62
- // have been destroyed in the meantime.
63
- if (isDestroyed) {
64
- return;
65
- }
66
- try {
67
- log?.(`Sending ${formatMethodPath(methodPath)}() reply`, replyMessage);
68
- messenger.sendMessage(replyMessage, transferables);
69
- }
70
- catch (error) {
71
- // If a consumer attempts to send an object that's not
72
- // cloneable (e.g., window), we want to ensure the receiver's promise
73
- // gets rejected.
74
- if (error.name === 'DataCloneError') {
75
- replyMessage = createErrorReplyMessage(channel, callId, error);
76
- log?.(`Sending ${formatMethodPath(methodPath)}() reply`, replyMessage);
77
- messenger.sendMessage(replyMessage);
78
- }
79
- throw error;
80
- }
81
- };
82
- messenger.addMessageHandler(handleMessage);
83
- return () => {
84
- isDestroyed = true;
85
- messenger.removeMessageHandler(handleMessage);
86
- };
87
- };
88
- export default connectCallHandler;
@@ -1,12 +0,0 @@
1
- import { RemoteProxy, Methods, Log } from './types.js';
2
- import Messenger from './messengers/Messenger.js';
3
- /**
4
- * Creates a proxy. When methods are called on the proxy, a "call" message will
5
- * be sent to the remote, the remote's corresponding method will be
6
- * executed, and the method's return value will be returned via a message.
7
- */
8
- declare const connectRemoteProxy: <TMethods extends Methods>(messenger: Messenger, channel: string | undefined, log: Log | undefined) => {
9
- remoteProxy: RemoteProxy<TMethods>;
10
- destroy: () => void;
11
- };
12
- export default connectRemoteProxy;
@@ -1,137 +0,0 @@
1
- import generateId from './generateId.js';
2
- import { deserializeError } from './errorSerialization.js';
3
- import { formatMethodPath } from './methodSerialization.js';
4
- import CallOptions from './CallOptions.js';
5
- import PenpalError from './PenpalError.js';
6
- import { isReplyMessage } from './guards.js';
7
- import namespace from './namespace.js';
8
- const methodsToTreatAsNative = new Set(['apply', 'call', 'bind']);
9
- const createRemoteProxy = (callback, log, path = []) => {
10
- return new Proxy(path.length
11
- ? () => {
12
- // Intentionally empty
13
- }
14
- : Object.create(null), {
15
- get(target, prop) {
16
- // If a promise is resolved with this proxy object, the JavaScript
17
- // runtime will look for a `then` property on this object to determine
18
- // if it should be treated as a promise (to support promise chaining).
19
- // If we don't return undefined here, the JavaScript runtime will treat
20
- // this object as a promise and attempt to call `then`, which will
21
- // then send a call message to the remote. This is not what we want.
22
- if (prop === 'then') {
23
- return;
24
- }
25
- // Because we're using a proxy and because Penpal supports developers
26
- // exposing nested methods, we have a predicament. If a developer
27
- // calls, for example, remote.auth.apply(), are they
28
- // attempting to call a nested apply() method that a developer has
29
- // explicitly exposed from the remote? Could they instead be attempting
30
- // to call Function.prototype.apply() on the remote.auth() method?
31
- // Without the remote telling the local Penpal which methods the
32
- // developer has exposed, it has no way of knowing (and the main reason
33
- // we use a proxy is so that Penpal doesn't have to communicate which
34
- // methods are exposed). So, we treat certain methods as native methods
35
- // and return the native method rather than a proxy. The downside of
36
- // this is that if a developer has explicitly exposed a nested method
37
- // with the same name as one of these native method names, the developer
38
- // will be unable to call the exposed remote method because they will
39
- // be calling the method on the Function prototype instead.
40
- if (path.length && methodsToTreatAsNative.has(prop)) {
41
- return Reflect.get(target, prop);
42
- }
43
- return createRemoteProxy(callback, log, [...path, prop]);
44
- },
45
- apply(target, _thisArg, args) {
46
- return callback(path, args);
47
- },
48
- });
49
- };
50
- const getDestroyedConnectionMethodCallError = (methodPath) => {
51
- return new PenpalError('CONNECTION_DESTROYED', `Method call ${formatMethodPath(methodPath)}() failed due to destroyed connection`);
52
- };
53
- /**
54
- * Creates a proxy. When methods are called on the proxy, a "call" message will
55
- * be sent to the remote, the remote's corresponding method will be
56
- * executed, and the method's return value will be returned via a message.
57
- */
58
- const connectRemoteProxy = (messenger, channel, log) => {
59
- let isDestroyed = false;
60
- const replyHandlers = new Map();
61
- const handleMessage = (message) => {
62
- if (!isReplyMessage(message)) {
63
- return;
64
- }
65
- const { callId, value, isError, isSerializedErrorInstance } = message;
66
- const replyHandler = replyHandlers.get(callId);
67
- if (!replyHandler) {
68
- return;
69
- }
70
- replyHandlers.delete(callId);
71
- log?.(`Received ${formatMethodPath(replyHandler.methodPath)}() call`, message);
72
- if (isError) {
73
- replyHandler.reject(isSerializedErrorInstance ? deserializeError(value) : value);
74
- }
75
- else {
76
- replyHandler.resolve(value);
77
- }
78
- };
79
- messenger.addMessageHandler(handleMessage);
80
- const remoteProxy = createRemoteProxy((methodPath, args) => {
81
- if (isDestroyed) {
82
- throw getDestroyedConnectionMethodCallError(methodPath);
83
- }
84
- const callId = generateId();
85
- const lastArg = args[args.length - 1];
86
- const lastArgIsOptions = lastArg instanceof CallOptions;
87
- const { timeout, transferables } = lastArgIsOptions ? lastArg : {};
88
- const argsWithoutOptions = lastArgIsOptions ? args.slice(0, -1) : args;
89
- return new Promise((resolve, reject) => {
90
- // We reference `window.setTimeout` instead of just `setTimeout`
91
- // so that the TypeScript engine doesn't
92
- // get confused when running tests. Something within
93
- // Karma + @rollup/plugin-typescript leaks node types into source
94
- // files when running tests. Node's setTimeout has a return type of
95
- // Timeout rather than number, resulting in a build error when
96
- // running tests if we don't disambiguate the browser setTimeout
97
- // from node's setTimeout. There may be a better way to configure
98
- // Karma + Rollup + Typescript to avoid node type leakage.
99
- const timeoutId = timeout !== undefined
100
- ? window.setTimeout(() => {
101
- replyHandlers.delete(callId);
102
- reject(new PenpalError('METHOD_CALL_TIMEOUT', `Method call ${formatMethodPath(methodPath)}() timed out after ${timeout}ms`));
103
- }, timeout)
104
- : undefined;
105
- replyHandlers.set(callId, { methodPath, resolve, reject, timeoutId });
106
- try {
107
- const callMessage = {
108
- namespace,
109
- channel,
110
- type: 'CALL',
111
- id: callId,
112
- methodPath,
113
- args: argsWithoutOptions,
114
- };
115
- log?.(`Sending ${formatMethodPath(methodPath)}() call`, callMessage);
116
- messenger.sendMessage(callMessage, transferables);
117
- }
118
- catch (error) {
119
- reject(new PenpalError('TRANSMISSION_FAILED', error.message));
120
- }
121
- });
122
- }, log);
123
- const destroy = () => {
124
- isDestroyed = true;
125
- messenger.removeMessageHandler(handleMessage);
126
- for (const { methodPath, reject, timeoutId } of replyHandlers.values()) {
127
- clearTimeout(timeoutId);
128
- reject(getDestroyedConnectionMethodCallError(methodPath));
129
- }
130
- replyHandlers.clear();
131
- };
132
- return {
133
- remoteProxy,
134
- destroy,
135
- };
136
- };
137
- export default connectRemoteProxy;
package/lib/debug.d.ts DELETED
@@ -1,3 +0,0 @@
1
- import { Log } from './types.js';
2
- declare const debug: (prefix?: string) => Log;
3
- export default debug;
package/lib/debug.js DELETED
@@ -1,6 +0,0 @@
1
- const debug = (prefix) => {
2
- return (...args) => {
3
- console.log(`✍️ %c${prefix}%c`, 'font-weight: bold;', '', ...args);
4
- };
5
- };
6
- export default debug;
@@ -1,9 +0,0 @@
1
- import { SerializedError } from './types.js';
2
- /**
3
- * Converts an error object into a plain object.
4
- */
5
- export declare const serializeError: (error: Error) => SerializedError;
6
- /**
7
- * Converts a plain object into an error object.
8
- */
9
- export declare const deserializeError: ({ name, message, stack, penpalCode, }: SerializedError) => Error;
@@ -1,21 +0,0 @@
1
- import PenpalError from './PenpalError.js';
2
- /**
3
- * Converts an error object into a plain object.
4
- */
5
- export const serializeError = (error) => ({
6
- name: error.name,
7
- message: error.message,
8
- stack: error.stack,
9
- penpalCode: error instanceof PenpalError ? error.code : undefined,
10
- });
11
- /**
12
- * Converts a plain object into an error object.
13
- */
14
- export const deserializeError = ({ name, message, stack, penpalCode, }) => {
15
- const deserializedError = penpalCode
16
- ? new PenpalError(penpalCode, message)
17
- : new Error(message);
18
- deserializedError.name = name;
19
- deserializedError.stack = stack;
20
- return deserializedError;
21
- };
@@ -1,8 +0,0 @@
1
- /**
2
- * @return A unique ID
3
- */
4
- declare const _default: {
5
- (): `${string}-${string}-${string}-${string}-${string}`;
6
- (): `${string}-${string}-${string}-${string}-${string}`;
7
- };
8
- export default _default;
package/lib/generateId.js DELETED
@@ -1,9 +0,0 @@
1
- /**
2
- * @return A unique ID
3
- */
4
- // crypto.randomUUID is not available in insecure contexts.
5
- export default crypto.randomUUID?.bind(crypto) ??
6
- (() => new Array(4)
7
- .fill(0)
8
- .map(() => Math.floor(Math.random() * Number.MAX_SAFE_INTEGER).toString(16))
9
- .join('-'));
@@ -1,6 +0,0 @@
1
- declare const getPromiseWithResolvers: <ResolvedValueType, RejectedValueType>() => {
2
- promise: Promise<ResolvedValueType>;
3
- resolve: (value: ResolvedValueType) => void;
4
- reject: (error: RejectedValueType) => void;
5
- };
6
- export default getPromiseWithResolvers;
@@ -1,17 +0,0 @@
1
- // Just use the native Promise.withResolvers() once it gains a bit more
2
- // adoption. Safari was the last major browser to support it, which happened
3
- // on March 5, 2024 in Safari 17.4.
4
- const getPromiseWithResolvers = () => {
5
- let resolve;
6
- let reject;
7
- const promise = new Promise((res, rej) => {
8
- resolve = res;
9
- reject = rej;
10
- });
11
- return {
12
- promise,
13
- resolve: resolve,
14
- reject: reject,
15
- };
16
- };
17
- export default getPromiseWithResolvers;
package/lib/guards.d.ts DELETED
@@ -1,10 +0,0 @@
1
- import { Ack2Message, CallMessage, Message, ReplyMessage, Ack1Message, SynMessage, DestroyMessage } from './types.js';
2
- export declare const isObject: (value: unknown) => value is Record<string | number | symbol, unknown>;
3
- export declare const isFunction: (value: unknown) => value is Function;
4
- export declare const isMessage: (data: unknown) => data is Message;
5
- export declare const isSynMessage: (message: Message) => message is SynMessage;
6
- export declare const isAck1Message: (message: Message) => message is Ack1Message;
7
- export declare const isAck2Message: (message: Message) => message is Ack2Message;
8
- export declare const isCallMessage: (message: Message) => message is CallMessage;
9
- export declare const isReplyMessage: (message: Message) => message is ReplyMessage;
10
- export declare const isDestroyMessage: (message: Message) => message is DestroyMessage;
package/lib/guards.js DELETED
@@ -1,28 +0,0 @@
1
- import namespace from './namespace.js';
2
- export const isObject = (value) => {
3
- return typeof value === 'object' && value !== null;
4
- };
5
- export const isFunction = (value) => {
6
- return typeof value === 'function';
7
- };
8
- export const isMessage = (data) => {
9
- return isObject(data) && data.namespace === namespace;
10
- };
11
- export const isSynMessage = (message) => {
12
- return message.type === 'SYN';
13
- };
14
- export const isAck1Message = (message) => {
15
- return message.type === 'ACK1';
16
- };
17
- export const isAck2Message = (message) => {
18
- return message.type === 'ACK2';
19
- };
20
- export const isCallMessage = (message) => {
21
- return message.type === 'CALL';
22
- };
23
- export const isReplyMessage = (message) => {
24
- return message.type === 'REPLY';
25
- };
26
- export const isDestroyMessage = (message) => {
27
- return message.type === 'DESTROY';
28
- };
package/lib/index.d.ts DELETED
@@ -1,12 +0,0 @@
1
- export { default as connect } from './connect.js';
2
- export { default as WindowMessenger } from './messengers/WindowMessenger.js';
3
- export { default as WorkerMessenger } from './messengers/WorkerMessenger.js';
4
- export { default as PortMessenger } from './messengers/PortMessenger.js';
5
- export { default as CallOptions } from './CallOptions.js';
6
- export { default as Reply } from './Reply.js';
7
- export { default as PenpalError } from './PenpalError.js';
8
- export { default as ErrorCode } from './ErrorCodeObj.js';
9
- export { default as debug } from './debug.js';
10
- export { Connection, RemoteProxy, Methods } from './types.js';
11
- export { default as Messenger, InitializeMessengerOptions, MessageHandler, } from './messengers/Messenger.js';
12
- export { Log, Message, SynMessage, Ack1Message, Ack2Message, CallMessage, ReplyMessage, DestroyMessage, } from './types.js';
package/lib/index.js DELETED
@@ -1,9 +0,0 @@
1
- export { default as connect } from './connect.js';
2
- export { default as WindowMessenger } from './messengers/WindowMessenger.js';
3
- export { default as WorkerMessenger } from './messengers/WorkerMessenger.js';
4
- export { default as PortMessenger } from './messengers/PortMessenger.js';
5
- export { default as CallOptions } from './CallOptions.js';
6
- export { default as Reply } from './Reply.js';
7
- export { default as PenpalError } from './PenpalError.js';
8
- export { default as ErrorCode } from './ErrorCodeObj.js';
9
- export { default as debug } from './debug.js';
@@ -1,31 +0,0 @@
1
- import WindowMessenger from './messengers/WindowMessenger.js';
2
- import WorkerMessenger from './messengers/WorkerMessenger.js';
3
- import PortMessenger from './messengers/PortMessenger.js';
4
- import CallOptions from './CallOptions.js';
5
- import Reply from './Reply.js';
6
- import PenpalError from './PenpalError.js';
7
- declare const _default: {
8
- connect: <TMethods extends import("./types.js").Methods>({ messenger, methods, timeout, channel, log, }: {
9
- messenger: import("./index.js").Messenger;
10
- methods?: import("./types.js").Methods;
11
- timeout?: number;
12
- channel?: string;
13
- log?: import("./types.js").Log;
14
- }) => import("./types.js").Connection<TMethods>;
15
- WindowMessenger: typeof WindowMessenger;
16
- WorkerMessenger: typeof WorkerMessenger;
17
- PortMessenger: typeof PortMessenger;
18
- CallOptions: typeof CallOptions;
19
- Reply: typeof Reply;
20
- PenpalError: typeof PenpalError;
21
- debug: (prefix?: string) => import("./types.js").Log;
22
- ErrorCode: {
23
- readonly ConnectionDestroyed: "CONNECTION_DESTROYED";
24
- readonly ConnectionTimeout: "CONNECTION_TIMEOUT";
25
- readonly InvalidArgument: "INVALID_ARGUMENT";
26
- readonly MethodCallTimeout: "METHOD_CALL_TIMEOUT";
27
- readonly MethodNotFound: "METHOD_NOT_FOUND";
28
- readonly TransmissionFailed: "TRANSMISSION_FAILED";
29
- };
30
- };
31
- export default _default;
@@ -1,20 +0,0 @@
1
- import connect from './connect.js';
2
- import WindowMessenger from './messengers/WindowMessenger.js';
3
- import WorkerMessenger from './messengers/WorkerMessenger.js';
4
- import PortMessenger from './messengers/PortMessenger.js';
5
- import CallOptions from './CallOptions.js';
6
- import Reply from './Reply.js';
7
- import PenpalError from './PenpalError.js';
8
- import ErrorCode from './ErrorCodeObj.js';
9
- import debug from './debug.js';
10
- export default {
11
- connect,
12
- WindowMessenger,
13
- WorkerMessenger,
14
- PortMessenger,
15
- CallOptions,
16
- Reply,
17
- PenpalError,
18
- debug,
19
- ErrorCode,
20
- };
@@ -1,14 +0,0 @@
1
- import { Message, Log } from '../types.js';
2
- export type MessageHandler = (message: Message) => void;
3
- export type InitializeMessengerOptions = {
4
- log?: Log;
5
- validateReceivedMessage: (data: unknown) => data is Message;
6
- };
7
- interface Messenger {
8
- sendMessage: (message: Message, transferables?: Transferable[]) => void;
9
- addMessageHandler: (callback: MessageHandler) => void;
10
- removeMessageHandler: (callback: MessageHandler) => void;
11
- initialize: (options: InitializeMessengerOptions) => void;
12
- destroy: () => void;
13
- }
14
- export default Messenger;
@@ -1 +0,0 @@
1
- export {};
@@ -1,21 +0,0 @@
1
- import { Message } from '../types.js';
2
- import Messenger, { InitializeMessengerOptions, MessageHandler } from './Messenger.js';
3
- type Options = {
4
- /**
5
- * The port used to communicate to the other port of the port pair.
6
- */
7
- port: MessagePort;
8
- };
9
- /**
10
- * Handles the details of communicating on a MessagePort.
11
- */
12
- declare class PortMessenger implements Messenger {
13
- #private;
14
- constructor({ port }: Options);
15
- initialize: ({ validateReceivedMessage }: InitializeMessengerOptions) => void;
16
- sendMessage: (message: Message, transferables?: Transferable[]) => void;
17
- addMessageHandler: (callback: MessageHandler) => void;
18
- removeMessageHandler: (callback: MessageHandler) => void;
19
- destroy: () => void;
20
- }
21
- export default PortMessenger;
@@ -1,45 +0,0 @@
1
- import PenpalError from '../PenpalError.js';
2
- /**
3
- * Handles the details of communicating on a MessagePort.
4
- */
5
- class PortMessenger {
6
- #port;
7
- #validateReceivedMessage;
8
- #messageCallbacks = new Set();
9
- constructor({ port }) {
10
- if (!port) {
11
- throw new PenpalError('INVALID_ARGUMENT', 'port must be defined');
12
- }
13
- this.#port = port;
14
- }
15
- initialize = ({ validateReceivedMessage }) => {
16
- this.#validateReceivedMessage = validateReceivedMessage;
17
- this.#port.addEventListener('message', this.#handleMessage);
18
- this.#port.start();
19
- };
20
- sendMessage = (message, transferables) => {
21
- this.#port?.postMessage(message, {
22
- transfer: transferables,
23
- });
24
- };
25
- addMessageHandler = (callback) => {
26
- this.#messageCallbacks.add(callback);
27
- };
28
- removeMessageHandler = (callback) => {
29
- this.#messageCallbacks.delete(callback);
30
- };
31
- destroy = () => {
32
- this.#port.removeEventListener('message', this.#handleMessage);
33
- this.#port.close();
34
- this.#messageCallbacks.clear();
35
- };
36
- #handleMessage = ({ data }) => {
37
- if (!this.#validateReceivedMessage?.(data)) {
38
- return;
39
- }
40
- for (const callback of this.#messageCallbacks) {
41
- callback(data);
42
- }
43
- };
44
- }
45
- export default PortMessenger;
@@ -1,29 +0,0 @@
1
- import { Message } from '../types.js';
2
- import Messenger, { InitializeMessengerOptions, MessageHandler } from './Messenger.js';
3
- type Options = {
4
- /**
5
- * The window with which the current window will communicate.
6
- */
7
- remoteWindow: Window;
8
- /**
9
- * An array of strings or regular expressions defining to which origins
10
- * communication will be allowed. If not provided, communication will be
11
- * restricted to the origin of the current page. You may specify an allowed
12
- * origin of `*` to not restrict communication, but beware the risks of
13
- * doing so.
14
- */
15
- allowedOrigins?: (string | RegExp)[];
16
- };
17
- /**
18
- * Handles the details of communicating with a child window.
19
- */
20
- declare class WindowMessenger implements Messenger {
21
- #private;
22
- constructor({ remoteWindow, allowedOrigins }: Options);
23
- initialize: ({ log, validateReceivedMessage, }: InitializeMessengerOptions) => void;
24
- sendMessage: (message: Message, transferables?: Transferable[]) => void;
25
- addMessageHandler: (callback: MessageHandler) => void;
26
- removeMessageHandler: (callback: MessageHandler) => void;
27
- destroy: () => void;
28
- }
29
- export default WindowMessenger;