first commit

This commit is contained in:
2026-03-10 16:18:05 +00:00
commit 11f9c069b5
31635 changed files with 3187747 additions and 0 deletions

View File

@@ -0,0 +1,73 @@
import { WebSocketBackingStore } from './WebSocketBackingStore';
import { type WebSocketMessageEvent } from './WebSocketWithReconnect';
import type { ConnectionInfo, DevToolsPluginClientOptions, HandshakeMessageParams } from './devtools.types';
export interface EventSubscription {
remove(): void;
}
/**
* This client is for the Expo DevTools Plugins to communicate between the app and the DevTools webpage hosted in a browser.
* All the code should be both compatible with browsers and React Native.
*/
export declare abstract class DevToolsPluginClient {
readonly connectionInfo: ConnectionInfo;
private readonly options?;
private listeners;
private static defaultWSStore;
private readonly wsStore;
protected isClosed: boolean;
protected retries: number;
private readonly messageFramePacker;
constructor(connectionInfo: ConnectionInfo, options?: DevToolsPluginClientOptions | undefined);
/**
* Initialize the connection.
* @hidden
*/
initAsync(): Promise<void>;
/**
* Close the connection.
*/
closeAsync(): Promise<void>;
/**
* Send a message to the other end of DevTools.
* @param method A method name.
* @param params any extra payload.
*/
sendMessage(method: string, params: any): void;
/**
* Subscribe to a message from the other end of DevTools.
* @param method Subscribe to a message with a method name.
* @param listener Listener to be called when a message is received.
*/
addMessageListener(method: string, listener: (params: any) => void): EventSubscription;
/**
* Subscribe to a message from the other end of DevTools just once.
* @param method Subscribe to a message with a method name.
* @param listener Listener to be called when a message is received.
*/
addMessageListenerOnce(method: string, listener: (params: any) => void): void;
/**
* Internal handshake message sender.
* @hidden
*/
protected sendHandshakeMessage(params: HandshakeMessageParams): void;
/**
* Internal handshake message listener.
* @hidden
*/
protected addHandskakeMessageListener(listener: (params: HandshakeMessageParams) => void): EventSubscription;
/**
* Returns whether the client is connected to the server.
*/
isConnected(): boolean;
/**
* The method to create the WebSocket connection.
*/
protected connectAsync(): Promise<WebSocket>;
protected handleMessage: (event: WebSocketMessageEvent) => Promise<void>;
/**
* Get the WebSocket backing store. Exposed for testing.
* @hidden
*/
getWebSocketBackingStore(): WebSocketBackingStore;
}
//# sourceMappingURL=DevToolsPluginClient.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"DevToolsPluginClient.d.ts","sourceRoot":"","sources":["../src/DevToolsPluginClient.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAGL,KAAK,qBAAqB,EAC3B,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EACV,cAAc,EACd,2BAA2B,EAC3B,sBAAsB,EACvB,MAAM,kBAAkB,CAAC;AAS1B,MAAM,WAAW,iBAAiB;IAChC,MAAM,IAAI,IAAI,CAAC;CAChB;AAED;;;GAGG;AACH,8BAAsB,oBAAoB;aAYtB,cAAc,EAAE,cAAc;IAC9C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC;IAZ3B,OAAO,CAAC,SAAS,CAAyD;IAE1E,OAAO,CAAC,MAAM,CAAC,cAAc,CAAsD;IACnF,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA8D;IAEtF,SAAS,CAAC,QAAQ,UAAS;IAC3B,SAAS,CAAC,OAAO,SAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CACR;gBAGT,cAAc,EAAE,cAAc,EAC7B,OAAO,CAAC,EAAE,2BAA2B,YAAA;IAMxD;;;OAGG;IACU,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAQvC;;OAEG;IACU,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAWxC;;;;OAIG;IACI,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG;IAmB9C;;;;OAIG;IACI,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,IAAI,GAAG,iBAAiB;IAU7F;;;;OAIG;IACI,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,IAAI,GAAG,IAAI;IAQpF;;;OAGG;IACH,SAAS,CAAC,oBAAoB,CAAC,MAAM,EAAE,sBAAsB;IAQ7D;;;OAGG;IACH,SAAS,CAAC,2BAA2B,CACnC,QAAQ,EAAE,CAAC,MAAM,EAAE,sBAAsB,KAAK,IAAI,GACjD,iBAAiB;IA2BpB;;OAEG;IACI,WAAW,IAAI,OAAO;IAI7B;;OAEG;IACH,SAAS,CAAC,YAAY,IAAI,OAAO,CAAC,SAAS,CAAC;IA+B5C,SAAS,CAAC,aAAa,GAAU,OAAO,qBAAqB,mBA6B3D;IAEF;;;OAGG;IACI,wBAAwB,IAAI,qBAAqB;CAGzD"}

View File

@@ -0,0 +1,213 @@
import { MessageFramePacker } from './MessageFramePacker';
import { WebSocketBackingStore } from './WebSocketBackingStore';
import { WebSocketWithReconnect, } from './WebSocketWithReconnect';
import * as logger from './logger';
import { blobToArrayBufferAsync } from './utils/blobUtils';
/**
* This client is for the Expo DevTools Plugins to communicate between the app and the DevTools webpage hosted in a browser.
* All the code should be both compatible with browsers and React Native.
*/
export class DevToolsPluginClient {
connectionInfo;
options;
listeners;
static defaultWSStore = new WebSocketBackingStore();
wsStore = DevToolsPluginClient.defaultWSStore;
isClosed = false;
retries = 0;
messageFramePacker = new MessageFramePacker();
constructor(connectionInfo, options) {
this.connectionInfo = connectionInfo;
this.options = options;
this.wsStore = connectionInfo.wsStore || DevToolsPluginClient.defaultWSStore;
this.listeners = Object.create(null);
}
/**
* Initialize the connection.
* @hidden
*/
async initAsync() {
if (this.wsStore.ws == null) {
this.wsStore.ws = await this.connectAsync();
}
this.wsStore.refCount += 1;
this.wsStore.ws.addEventListener('message', this.handleMessage);
}
/**
* Close the connection.
*/
async closeAsync() {
this.isClosed = true;
this.wsStore.ws?.removeEventListener('message', this.handleMessage);
this.wsStore.refCount -= 1;
if (this.wsStore.refCount < 1) {
this.wsStore.ws?.close();
this.wsStore.ws = null;
}
this.listeners = Object.create(null);
}
/**
* Send a message to the other end of DevTools.
* @param method A method name.
* @param params any extra payload.
*/
sendMessage(method, params) {
if (this.wsStore.ws?.readyState === WebSocket.CLOSED) {
logger.warn('Unable to send message in a disconnected state.');
return;
}
const messageKey = {
pluginName: this.connectionInfo.pluginName,
method,
};
const packedData = this.messageFramePacker.pack({ messageKey, payload: params });
if (!(packedData instanceof Promise)) {
this.wsStore.ws?.send(packedData);
return;
}
packedData.then((data) => {
this.wsStore.ws?.send(data);
});
}
/**
* Subscribe to a message from the other end of DevTools.
* @param method Subscribe to a message with a method name.
* @param listener Listener to be called when a message is received.
*/
addMessageListener(method, listener) {
const listenersForMethod = this.listeners[method] || (this.listeners[method] = new Set());
listenersForMethod.add(listener);
return {
remove: () => {
this.listeners[method]?.delete(listener);
},
};
}
/**
* Subscribe to a message from the other end of DevTools just once.
* @param method Subscribe to a message with a method name.
* @param listener Listener to be called when a message is received.
*/
addMessageListenerOnce(method, listener) {
const wrappedListenerOnce = (params) => {
listener(params);
this.listeners[method]?.delete(wrappedListenerOnce);
};
this.addMessageListener(method, wrappedListenerOnce);
}
/**
* Internal handshake message sender.
* @hidden
*/
sendHandshakeMessage(params) {
if (this.wsStore.ws?.readyState === WebSocket.CLOSED) {
logger.warn('Unable to send message in a disconnected state.');
return;
}
this.wsStore.ws?.send(JSON.stringify({ ...params, __isHandshakeMessages: true }));
}
/**
* Internal handshake message listener.
* @hidden
*/
addHandskakeMessageListener(listener) {
const messageListener = (event) => {
if (typeof event.data !== 'string') {
// binary data is not coming from the handshake messages.
return;
}
const data = JSON.parse(event.data);
if (!data.__isHandshakeMessages) {
return;
}
delete data.__isHandshakeMessages;
const params = data;
if (params.pluginName && params.pluginName !== this.connectionInfo.pluginName) {
return;
}
listener(params);
};
this.wsStore.ws?.addEventListener('message', messageListener);
return {
remove: () => {
this.wsStore.ws?.removeEventListener('message', messageListener);
},
};
}
/**
* Returns whether the client is connected to the server.
*/
isConnected() {
return this.wsStore.ws?.readyState === WebSocket.OPEN;
}
/**
* The method to create the WebSocket connection.
*/
connectAsync() {
return new Promise((resolve, reject) => {
const endpoint = 'expo-dev-plugins/broadcast';
const protocol = this.connectionInfo.useWss ? 'wss' : 'ws';
const ws = new WebSocketWithReconnect(`${protocol}://${this.connectionInfo.devServer}/${endpoint}`, {
binaryType: this.options?.websocketBinaryType,
onError: (e) => {
if (e instanceof Error) {
console.warn(`Error happened from the WebSocket connection: ${e.message}\n${e.stack}`);
}
else {
console.warn(`Error happened from the WebSocket connection: ${JSON.stringify(e)}`);
}
},
});
ws.addEventListener('open', () => {
resolve(ws);
});
ws.addEventListener('error', (e) => {
reject(e);
});
ws.addEventListener('close', (e) => {
logger.info('WebSocket closed', e.code, e.reason);
});
});
}
handleMessage = async (event) => {
let data;
if (typeof event.data === 'string') {
data = event.data;
}
else if (event.data instanceof ArrayBuffer) {
data = event.data;
}
else if (ArrayBuffer.isView(event.data)) {
data = event.data.buffer;
}
else if (event.data instanceof Blob) {
data = await blobToArrayBufferAsync(event.data);
}
else {
logger.warn('Unsupported received data type in handleMessageImpl');
return;
}
const { messageKey, payload, ...rest } = this.messageFramePacker.unpack(data);
// @ts-expect-error: `__isHandshakeMessages` is a private field that is not part of the MessageFramePacker type.
if (rest?.__isHandshakeMessages === true) {
return;
}
if (messageKey.pluginName && messageKey.pluginName !== this.connectionInfo.pluginName) {
return;
}
const listenersForMethod = this.listeners[messageKey.method];
if (listenersForMethod) {
for (const listener of listenersForMethod) {
listener(payload);
}
}
};
/**
* Get the WebSocket backing store. Exposed for testing.
* @hidden
*/
getWebSocketBackingStore() {
return this.wsStore;
}
}
//# sourceMappingURL=DevToolsPluginClient.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,16 @@
import type { DevToolsPluginClient } from './DevToolsPluginClient';
import type { ConnectionInfo, DevToolsPluginClientOptions } from './devtools.types';
/**
* Factory of DevToolsPluginClient based on sender types.
* @hidden
*/
export declare function createDevToolsPluginClient(connectionInfo: ConnectionInfo, options?: DevToolsPluginClientOptions): Promise<DevToolsPluginClient>;
/**
* Public API to get the DevToolsPluginClient instance.
*/
export declare function getDevToolsPluginClientAsync(pluginName: string, options?: DevToolsPluginClientOptions): Promise<DevToolsPluginClient>;
/**
* Internal testing API to cleanup all DevToolsPluginClient instances.
*/
export declare function cleanupDevToolsPluginInstances(): void;
//# sourceMappingURL=DevToolsPluginClientFactory.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"DevToolsPluginClientFactory.d.ts","sourceRoot":"","sources":["../src/DevToolsPluginClientFactory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAGnE,OAAO,KAAK,EAAE,cAAc,EAAE,2BAA2B,EAAE,MAAM,kBAAkB,CAAC;AAKpF;;;GAGG;AACH,wBAAsB,0BAA0B,CAC9C,cAAc,EAAE,cAAc,EAC9B,OAAO,CAAC,EAAE,2BAA2B,GACpC,OAAO,CAAC,oBAAoB,CAAC,CAS/B;AAED;;GAEG;AACH,wBAAsB,4BAA4B,CAChD,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,2BAA2B,GACpC,OAAO,CAAC,oBAAoB,CAAC,CAyB/B;AAED;;GAEG;AACH,wBAAgB,8BAA8B,SAU7C"}

View File

@@ -0,0 +1,60 @@
import { DevToolsPluginClientImplApp } from './DevToolsPluginClientImplApp';
import { DevToolsPluginClientImplBrowser } from './DevToolsPluginClientImplBrowser';
import { getConnectionInfo } from './getConnectionInfo';
const instanceMap = {};
/**
* Factory of DevToolsPluginClient based on sender types.
* @hidden
*/
export async function createDevToolsPluginClient(connectionInfo, options) {
let client;
if (connectionInfo.sender === 'app') {
client = new DevToolsPluginClientImplApp(connectionInfo, options);
}
else {
client = new DevToolsPluginClientImplBrowser(connectionInfo, options);
}
await client.initAsync();
return client;
}
/**
* Public API to get the DevToolsPluginClient instance.
*/
export async function getDevToolsPluginClientAsync(pluginName, options) {
const connectionInfo = getConnectionInfo();
let instance = instanceMap[pluginName];
if (instance != null) {
if (instance instanceof Promise) {
return instance;
}
if (instance.isConnected() === false ||
instance.connectionInfo.devServer !== connectionInfo.devServer) {
await instance.closeAsync();
delete instanceMap[pluginName];
instance = null;
}
}
if (instance == null) {
const instancePromise = createDevToolsPluginClient({ ...connectionInfo, pluginName }, options);
instanceMap[pluginName] = instancePromise;
instance = await instancePromise;
instanceMap[pluginName] = instance;
}
return instance;
}
/**
* Internal testing API to cleanup all DevToolsPluginClient instances.
*/
export function cleanupDevToolsPluginInstances() {
for (const pluginName of Object.keys(instanceMap)) {
const instance = instanceMap[pluginName];
delete instanceMap[pluginName];
if (instance instanceof Promise) {
instance.then((instance) => instance.closeAsync());
}
else {
instance.closeAsync();
}
}
}
//# sourceMappingURL=DevToolsPluginClientFactory.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"DevToolsPluginClientFactory.js","sourceRoot":"","sources":["../src/DevToolsPluginClientFactory.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,2BAA2B,EAAE,MAAM,+BAA+B,CAAC;AAC5E,OAAO,EAAE,+BAA+B,EAAE,MAAM,mCAAmC,CAAC;AAEpF,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAExD,MAAM,WAAW,GAAyE,EAAE,CAAC;AAE7F;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAC9C,cAA8B,EAC9B,OAAqC;IAErC,IAAI,MAA4B,CAAC;IACjC,IAAI,cAAc,CAAC,MAAM,KAAK,KAAK,EAAE,CAAC;QACpC,MAAM,GAAG,IAAI,2BAA2B,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;IACpE,CAAC;SAAM,CAAC;QACN,MAAM,GAAG,IAAI,+BAA+B,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;IACxE,CAAC;IACD,MAAM,MAAM,CAAC,SAAS,EAAE,CAAC;IACzB,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,4BAA4B,CAChD,UAAkB,EAClB,OAAqC;IAErC,MAAM,cAAc,GAAG,iBAAiB,EAAE,CAAC;IAE3C,IAAI,QAAQ,GACV,WAAW,CAAC,UAAU,CAAC,CAAC;IAC1B,IAAI,QAAQ,IAAI,IAAI,EAAE,CAAC;QACrB,IAAI,QAAQ,YAAY,OAAO,EAAE,CAAC;YAChC,OAAO,QAAQ,CAAC;QAClB,CAAC;QACD,IACE,QAAQ,CAAC,WAAW,EAAE,KAAK,KAAK;YAChC,QAAQ,CAAC,cAAc,CAAC,SAAS,KAAK,cAAc,CAAC,SAAS,EAC9D,CAAC;YACD,MAAM,QAAQ,CAAC,UAAU,EAAE,CAAC;YAC5B,OAAO,WAAW,CAAC,UAAU,CAAC,CAAC;YAC/B,QAAQ,GAAG,IAAI,CAAC;QAClB,CAAC;IACH,CAAC;IACD,IAAI,QAAQ,IAAI,IAAI,EAAE,CAAC;QACrB,MAAM,eAAe,GAAG,0BAA0B,CAAC,EAAE,GAAG,cAAc,EAAE,UAAU,EAAE,EAAE,OAAO,CAAC,CAAC;QAC/F,WAAW,CAAC,UAAU,CAAC,GAAG,eAAe,CAAC;QAC1C,QAAQ,GAAG,MAAM,eAAe,CAAC;QACjC,WAAW,CAAC,UAAU,CAAC,GAAG,QAAQ,CAAC;IACrC,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,8BAA8B;IAC5C,KAAK,MAAM,UAAU,IAAI,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;QAClD,MAAM,QAAQ,GAAG,WAAW,CAAC,UAAU,CAAC,CAAC;QACzC,OAAO,WAAW,CAAC,UAAU,CAAC,CAAC;QAC/B,IAAI,QAAQ,YAAY,OAAO,EAAE,CAAC;YAChC,QAAQ,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;QACrD,CAAC;aAAM,CAAC;YACN,QAAQ,CAAC,UAAU,EAAE,CAAC;QACxB,CAAC;IACH,CAAC;AACH,CAAC","sourcesContent":["import type { DevToolsPluginClient } from './DevToolsPluginClient';\nimport { DevToolsPluginClientImplApp } from './DevToolsPluginClientImplApp';\nimport { DevToolsPluginClientImplBrowser } from './DevToolsPluginClientImplBrowser';\nimport type { ConnectionInfo, DevToolsPluginClientOptions } from './devtools.types';\nimport { getConnectionInfo } from './getConnectionInfo';\n\nconst instanceMap: Record<string, DevToolsPluginClient | Promise<DevToolsPluginClient>> = {};\n\n/**\n * Factory of DevToolsPluginClient based on sender types.\n * @hidden\n */\nexport async function createDevToolsPluginClient(\n connectionInfo: ConnectionInfo,\n options?: DevToolsPluginClientOptions\n): Promise<DevToolsPluginClient> {\n let client: DevToolsPluginClient;\n if (connectionInfo.sender === 'app') {\n client = new DevToolsPluginClientImplApp(connectionInfo, options);\n } else {\n client = new DevToolsPluginClientImplBrowser(connectionInfo, options);\n }\n await client.initAsync();\n return client;\n}\n\n/**\n * Public API to get the DevToolsPluginClient instance.\n */\nexport async function getDevToolsPluginClientAsync(\n pluginName: string,\n options?: DevToolsPluginClientOptions\n): Promise<DevToolsPluginClient> {\n const connectionInfo = getConnectionInfo();\n\n let instance: DevToolsPluginClient | Promise<DevToolsPluginClient> | null =\n instanceMap[pluginName];\n if (instance != null) {\n if (instance instanceof Promise) {\n return instance;\n }\n if (\n instance.isConnected() === false ||\n instance.connectionInfo.devServer !== connectionInfo.devServer\n ) {\n await instance.closeAsync();\n delete instanceMap[pluginName];\n instance = null;\n }\n }\n if (instance == null) {\n const instancePromise = createDevToolsPluginClient({ ...connectionInfo, pluginName }, options);\n instanceMap[pluginName] = instancePromise;\n instance = await instancePromise;\n instanceMap[pluginName] = instance;\n }\n return instance;\n}\n\n/**\n * Internal testing API to cleanup all DevToolsPluginClient instances.\n */\nexport function cleanupDevToolsPluginInstances() {\n for (const pluginName of Object.keys(instanceMap)) {\n const instance = instanceMap[pluginName];\n delete instanceMap[pluginName];\n if (instance instanceof Promise) {\n instance.then((instance) => instance.closeAsync());\n } else {\n instance.closeAsync();\n }\n }\n}\n"]}

View File

@@ -0,0 +1,15 @@
import { DevToolsPluginClient } from './DevToolsPluginClient';
/**
* The DevToolsPluginClient for the app -> browser communication.
*/
export declare class DevToolsPluginClientImplApp extends DevToolsPluginClient {
private browserClientMap;
/**
* Initialize the connection.
* @hidden
*/
initAsync(): Promise<void>;
private addHandshakeHandler;
private terminateBrowserClient;
}
//# sourceMappingURL=DevToolsPluginClientImplApp.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"DevToolsPluginClientImplApp.d.ts","sourceRoot":"","sources":["../src/DevToolsPluginClientImplApp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAG9D;;GAEG;AACH,qBAAa,2BAA4B,SAAQ,oBAAoB;IAEnE,OAAO,CAAC,gBAAgB,CAA8B;IAEtD;;;OAGG;IACY,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAKzC,OAAO,CAAC,mBAAmB;IA4B3B,OAAO,CAAC,sBAAsB;CAQ/B"}

View File

@@ -0,0 +1,47 @@
import { DevToolsPluginClient } from './DevToolsPluginClient';
import * as logger from './logger';
/**
* The DevToolsPluginClient for the app -> browser communication.
*/
export class DevToolsPluginClientImplApp extends DevToolsPluginClient {
// Map of pluginName -> browserClientId
browserClientMap = {};
/**
* Initialize the connection.
* @hidden
*/
async initAsync() {
await super.initAsync();
this.addHandshakeHandler();
}
addHandshakeHandler() {
this.addHandskakeMessageListener((params) => {
if (params.method === 'handshake') {
const { pluginName, protocolVersion } = params;
// [0] Check protocol version
if (protocolVersion !== this.connectionInfo.protocolVersion) {
// Use console.warn than logger because we want to show the warning even logging is disabled.
console.warn(`Received an incompatible devtools plugin handshake message - pluginName[${pluginName}]`);
this.terminateBrowserClient(pluginName, params.browserClientId);
return;
}
// [1] Terminate duplicated browser clients for the same plugin
const previousBrowserClientId = this.browserClientMap[pluginName];
if (previousBrowserClientId != null && previousBrowserClientId !== params.browserClientId) {
logger.info(`Terminate the previous browser client connection - previousBrowserClientId[${previousBrowserClientId}]`);
this.terminateBrowserClient(pluginName, previousBrowserClientId);
}
this.browserClientMap[pluginName] = params.browserClientId;
}
});
}
terminateBrowserClient(pluginName, browserClientId) {
this.sendHandshakeMessage({
protocolVersion: this.connectionInfo.protocolVersion,
method: 'terminateBrowserClient',
browserClientId,
pluginName,
});
}
}
//# sourceMappingURL=DevToolsPluginClientImplApp.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"DevToolsPluginClientImplApp.js","sourceRoot":"","sources":["../src/DevToolsPluginClientImplApp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,KAAK,MAAM,MAAM,UAAU,CAAC;AAEnC;;GAEG;AACH,MAAM,OAAO,2BAA4B,SAAQ,oBAAoB;IACnE,uCAAuC;IAC/B,gBAAgB,GAA2B,EAAE,CAAC;IAEtD;;;OAGG;IACM,KAAK,CAAC,SAAS;QACtB,MAAM,KAAK,CAAC,SAAS,EAAE,CAAC;QACxB,IAAI,CAAC,mBAAmB,EAAE,CAAC;IAC7B,CAAC;IAEO,mBAAmB;QACzB,IAAI,CAAC,2BAA2B,CAAC,CAAC,MAAM,EAAE,EAAE;YAC1C,IAAI,MAAM,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;gBAClC,MAAM,EAAE,UAAU,EAAE,eAAe,EAAE,GAAG,MAAM,CAAC;gBAE/C,6BAA6B;gBAC7B,IAAI,eAAe,KAAK,IAAI,CAAC,cAAc,CAAC,eAAe,EAAE,CAAC;oBAC5D,6FAA6F;oBAC7F,OAAO,CAAC,IAAI,CACV,2EAA2E,UAAU,GAAG,CACzF,CAAC;oBACF,IAAI,CAAC,sBAAsB,CAAC,UAAU,EAAE,MAAM,CAAC,eAAe,CAAC,CAAC;oBAChE,OAAO;gBACT,CAAC;gBAED,+DAA+D;gBAC/D,MAAM,uBAAuB,GAAG,IAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC;gBAClE,IAAI,uBAAuB,IAAI,IAAI,IAAI,uBAAuB,KAAK,MAAM,CAAC,eAAe,EAAE,CAAC;oBAC1F,MAAM,CAAC,IAAI,CACT,8EAA8E,uBAAuB,GAAG,CACzG,CAAC;oBACF,IAAI,CAAC,sBAAsB,CAAC,UAAU,EAAE,uBAAuB,CAAC,CAAC;gBACnE,CAAC;gBACD,IAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC,GAAG,MAAM,CAAC,eAAe,CAAC;YAC7D,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,sBAAsB,CAAC,UAAkB,EAAE,eAAuB;QACxE,IAAI,CAAC,oBAAoB,CAAC;YACxB,eAAe,EAAE,IAAI,CAAC,cAAc,CAAC,eAAe;YACpD,MAAM,EAAE,wBAAwB;YAChC,eAAe;YACf,UAAU;SACX,CAAC,CAAC;IACL,CAAC;CACF","sourcesContent":["import { DevToolsPluginClient } from './DevToolsPluginClient';\nimport * as logger from './logger';\n\n/**\n * The DevToolsPluginClient for the app -> browser communication.\n */\nexport class DevToolsPluginClientImplApp extends DevToolsPluginClient {\n // Map of pluginName -> browserClientId\n private browserClientMap: Record<string, string> = {};\n\n /**\n * Initialize the connection.\n * @hidden\n */\n override async initAsync(): Promise<void> {\n await super.initAsync();\n this.addHandshakeHandler();\n }\n\n private addHandshakeHandler() {\n this.addHandskakeMessageListener((params) => {\n if (params.method === 'handshake') {\n const { pluginName, protocolVersion } = params;\n\n // [0] Check protocol version\n if (protocolVersion !== this.connectionInfo.protocolVersion) {\n // Use console.warn than logger because we want to show the warning even logging is disabled.\n console.warn(\n `Received an incompatible devtools plugin handshake message - pluginName[${pluginName}]`\n );\n this.terminateBrowserClient(pluginName, params.browserClientId);\n return;\n }\n\n // [1] Terminate duplicated browser clients for the same plugin\n const previousBrowserClientId = this.browserClientMap[pluginName];\n if (previousBrowserClientId != null && previousBrowserClientId !== params.browserClientId) {\n logger.info(\n `Terminate the previous browser client connection - previousBrowserClientId[${previousBrowserClientId}]`\n );\n this.terminateBrowserClient(pluginName, previousBrowserClientId);\n }\n this.browserClientMap[pluginName] = params.browserClientId;\n }\n });\n }\n\n private terminateBrowserClient(pluginName: string, browserClientId: string) {\n this.sendHandshakeMessage({\n protocolVersion: this.connectionInfo.protocolVersion,\n method: 'terminateBrowserClient',\n browserClientId,\n pluginName,\n });\n }\n}\n"]}

View File

@@ -0,0 +1,14 @@
import { DevToolsPluginClient } from './DevToolsPluginClient';
/**
* The DevToolsPluginClient for the browser -> app communication.
*/
export declare class DevToolsPluginClientImplBrowser extends DevToolsPluginClient {
private browserClientId;
/**
* Initialize the connection.
* @hidden
*/
initAsync(): Promise<void>;
private startHandshake;
}
//# sourceMappingURL=DevToolsPluginClientImplBrowser.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"DevToolsPluginClientImplBrowser.d.ts","sourceRoot":"","sources":["../src/DevToolsPluginClientImplBrowser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAG9D;;GAEG;AACH,qBAAa,+BAAgC,SAAQ,oBAAoB;IACvE,OAAO,CAAC,eAAe,CAAiC;IAExD;;;OAGG;IACY,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAKzC,OAAO,CAAC,cAAc;CAmBvB"}

View File

@@ -0,0 +1,32 @@
import { DevToolsPluginClient } from './DevToolsPluginClient';
import * as logger from './logger';
/**
* The DevToolsPluginClient for the browser -> app communication.
*/
export class DevToolsPluginClientImplBrowser extends DevToolsPluginClient {
browserClientId = Date.now().toString();
/**
* Initialize the connection.
* @hidden
*/
async initAsync() {
await super.initAsync();
this.startHandshake();
}
startHandshake() {
this.addHandskakeMessageListener((params) => {
if (params.method === 'terminateBrowserClient' &&
this.browserClientId === params.browserClientId) {
logger.info('Received terminateBrowserClient messages and terminate the current connection');
this.closeAsync();
}
});
this.sendHandshakeMessage({
protocolVersion: this.connectionInfo.protocolVersion,
pluginName: this.connectionInfo.pluginName,
method: 'handshake',
browserClientId: this.browserClientId,
});
}
}
//# sourceMappingURL=DevToolsPluginClientImplBrowser.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"DevToolsPluginClientImplBrowser.js","sourceRoot":"","sources":["../src/DevToolsPluginClientImplBrowser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,KAAK,MAAM,MAAM,UAAU,CAAC;AAEnC;;GAEG;AACH,MAAM,OAAO,+BAAgC,SAAQ,oBAAoB;IAC/D,eAAe,GAAW,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC;IAExD;;;OAGG;IACM,KAAK,CAAC,SAAS;QACtB,MAAM,KAAK,CAAC,SAAS,EAAE,CAAC;QACxB,IAAI,CAAC,cAAc,EAAE,CAAC;IACxB,CAAC;IAEO,cAAc;QACpB,IAAI,CAAC,2BAA2B,CAAC,CAAC,MAAM,EAAE,EAAE;YAC1C,IACE,MAAM,CAAC,MAAM,KAAK,wBAAwB;gBAC1C,IAAI,CAAC,eAAe,KAAK,MAAM,CAAC,eAAe,EAC/C,CAAC;gBACD,MAAM,CAAC,IAAI,CACT,+EAA+E,CAChF,CAAC;gBACF,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,CAAC;QACH,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,oBAAoB,CAAC;YACxB,eAAe,EAAE,IAAI,CAAC,cAAc,CAAC,eAAe;YACpD,UAAU,EAAE,IAAI,CAAC,cAAc,CAAC,UAAU;YAC1C,MAAM,EAAE,WAAW;YACnB,eAAe,EAAE,IAAI,CAAC,eAAe;SACtC,CAAC,CAAC;IACL,CAAC;CACF","sourcesContent":["import { DevToolsPluginClient } from './DevToolsPluginClient';\nimport * as logger from './logger';\n\n/**\n * The DevToolsPluginClient for the browser -> app communication.\n */\nexport class DevToolsPluginClientImplBrowser extends DevToolsPluginClient {\n private browserClientId: string = Date.now().toString();\n\n /**\n * Initialize the connection.\n * @hidden\n */\n override async initAsync(): Promise<void> {\n await super.initAsync();\n this.startHandshake();\n }\n\n private startHandshake() {\n this.addHandskakeMessageListener((params) => {\n if (\n params.method === 'terminateBrowserClient' &&\n this.browserClientId === params.browserClientId\n ) {\n logger.info(\n 'Received terminateBrowserClient messages and terminate the current connection'\n );\n this.closeAsync();\n }\n });\n this.sendHandshakeMessage({\n protocolVersion: this.connectionInfo.protocolVersion,\n pluginName: this.connectionInfo.pluginName,\n method: 'handshake',\n browserClientId: this.browserClientId,\n });\n }\n}\n"]}

View File

@@ -0,0 +1,50 @@
/**
* A message frame packer that serializes a messageKey and a payload into either a JSON string
* (fast path) or a binary format (for complex payloads).
*
* Fast Path (JSON.stringify/JSON.parse):
* - For simple payloads (e.g., strings, numbers, null, undefined, or plain objects), the packer
* uses `JSON.stringify` for serialization and `JSON.parse` for deserialization, ensuring
* optimal performance.
*
* Binary Format:
* - For more complex payloads (e.g., Uint8Array, ArrayBuffer, Blob), the packer uses a binary
* format with the following structure:
*
* +------------------+-------------------+----------------------------+--------------------------+
* | 4 bytes (Uint32) | Variable length | 1 byte (Uint8) | Variable length |
* | MessageKeyLength | MessageKey (JSON) | PayloadTypeIndicator (enum)| Payload (binary data) |
* +------------------+-------------------+----------------------------+--------------------------+
*
* 1. MessageKeyLength (4 bytes):
* - A 4-byte unsigned integer indicating the length of the MessageKey JSON string.
*
* 2. MessageKey (Variable length):
* - The JSON string representing the message key, encoded as UTF-8.
*
* 3. PayloadTypeIndicator (1 byte):
* - A single byte enum value representing the type of the payload (e.g., Uint8Array, String,
* Object, ArrayBuffer, Blob).
*
* 4. Payload (Variable length):
* - The actual payload data, which can vary in type and length depending on the PayloadType.
*/
type MessageKeyTypeBase = string | object;
type PayloadType = Uint8Array | string | number | null | undefined | object | ArrayBuffer | Blob;
interface MessageFrame<T extends MessageKeyTypeBase> {
messageKey: T;
payload?: PayloadType;
}
export declare class MessageFramePacker<T extends MessageKeyTypeBase> {
private textEncoder;
private textDecoder;
pack({ messageKey, payload }: MessageFrame<T>): string | Uint8Array | Promise<Uint8Array>;
unpack(packedData: string | ArrayBuffer): MessageFrame<T>;
private isFastPathPayload;
private payloadToUint8Array;
private packImpl;
private deserializePayload;
private static getPayloadTypeIndicator;
}
export {};
//# sourceMappingURL=MessageFramePacker.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"MessageFramePacker.d.ts","sourceRoot":"","sources":["../src/MessageFramePacker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAIH,KAAK,kBAAkB,GAAG,MAAM,GAAG,MAAM,CAAC;AAC1C,KAAK,WAAW,GAAG,UAAU,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,WAAW,GAAG,IAAI,CAAC;AAajG,UAAU,YAAY,CAAC,CAAC,SAAS,kBAAkB;IACjD,UAAU,EAAE,CAAC,CAAC;IACd,OAAO,CAAC,EAAE,WAAW,CAAC;CACvB;AAED,qBAAa,kBAAkB,CAAC,CAAC,SAAS,kBAAkB;IAC1D,OAAO,CAAC,WAAW,CAAqB;IACxC,OAAO,CAAC,WAAW,CAAqB;IAEjC,IAAI,CAAC,EAAE,UAAU,EAAE,OAAO,EAAE,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,MAAM,GAAG,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;IA2BzF,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,WAAW,GAAG,YAAY,CAAC,CAAC,CAAC;IA0BhE,OAAO,CAAC,iBAAiB;IAczB,OAAO,CAAC,mBAAmB;IAuB3B,OAAO,CAAC,QAAQ;IA8BhB,OAAO,CAAC,kBAAkB;IAoC1B,OAAO,CAAC,MAAM,CAAC,uBAAuB;CAqBvC"}

211
node_modules/@expo/devtools/build/MessageFramePacker.js generated vendored Normal file
View File

@@ -0,0 +1,211 @@
/**
* A message frame packer that serializes a messageKey and a payload into either a JSON string
* (fast path) or a binary format (for complex payloads).
*
* Fast Path (JSON.stringify/JSON.parse):
* - For simple payloads (e.g., strings, numbers, null, undefined, or plain objects), the packer
* uses `JSON.stringify` for serialization and `JSON.parse` for deserialization, ensuring
* optimal performance.
*
* Binary Format:
* - For more complex payloads (e.g., Uint8Array, ArrayBuffer, Blob), the packer uses a binary
* format with the following structure:
*
* +------------------+-------------------+----------------------------+--------------------------+
* | 4 bytes (Uint32) | Variable length | 1 byte (Uint8) | Variable length |
* | MessageKeyLength | MessageKey (JSON) | PayloadTypeIndicator (enum)| Payload (binary data) |
* +------------------+-------------------+----------------------------+--------------------------+
*
* 1. MessageKeyLength (4 bytes):
* - A 4-byte unsigned integer indicating the length of the MessageKey JSON string.
*
* 2. MessageKey (Variable length):
* - The JSON string representing the message key, encoded as UTF-8.
*
* 3. PayloadTypeIndicator (1 byte):
* - A single byte enum value representing the type of the payload (e.g., Uint8Array, String,
* Object, ArrayBuffer, Blob).
*
* 4. Payload (Variable length):
* - The actual payload data, which can vary in type and length depending on the PayloadType.
*/
import { blobToArrayBufferAsync } from './utils/blobUtils';
var PayloadTypeIndicator;
(function (PayloadTypeIndicator) {
PayloadTypeIndicator[PayloadTypeIndicator["Uint8Array"] = 1] = "Uint8Array";
PayloadTypeIndicator[PayloadTypeIndicator["String"] = 2] = "String";
PayloadTypeIndicator[PayloadTypeIndicator["Number"] = 3] = "Number";
PayloadTypeIndicator[PayloadTypeIndicator["Null"] = 4] = "Null";
PayloadTypeIndicator[PayloadTypeIndicator["Undefined"] = 5] = "Undefined";
PayloadTypeIndicator[PayloadTypeIndicator["Object"] = 6] = "Object";
PayloadTypeIndicator[PayloadTypeIndicator["ArrayBuffer"] = 7] = "ArrayBuffer";
PayloadTypeIndicator[PayloadTypeIndicator["Blob"] = 8] = "Blob";
})(PayloadTypeIndicator || (PayloadTypeIndicator = {}));
export class MessageFramePacker {
textEncoder = new TextEncoder();
textDecoder = new TextDecoder();
pack({ messageKey, payload }) {
// Fast path to pack as string given `JSON.stringify` is fast.
if (this.isFastPathPayload(payload)) {
return JSON.stringify({ messageKey, payload });
}
// Slowest path for Blob returns a promise.
if (payload instanceof Blob) {
return new Promise(async (resolve, reject) => {
try {
const arrayBuffer = await blobToArrayBufferAsync(payload);
resolve(this.packImpl({ messageKey, payload: new Uint8Array(arrayBuffer) }, PayloadTypeIndicator.Blob));
}
catch (error) {
reject(error);
}
});
}
// Slow path for other types returns a Uint8Array.
return this.packImpl({ messageKey, payload }, undefined);
}
unpack(packedData) {
// Fast path to unpack as string given `JSON.parse` is fast.
if (typeof packedData === 'string') {
return JSON.parse(packedData);
}
// [0] messageKeyLength (4 bytes)
const messageKeyLengthView = new DataView(packedData, 0, 4);
const messageKeyLength = messageKeyLengthView.getUint32(0, false);
// [1] messageKey (variable length)
const messageKeyBytes = packedData.slice(4, 4 + messageKeyLength);
const messageKeyString = this.textDecoder.decode(messageKeyBytes);
const messageKey = JSON.parse(messageKeyString);
// [2] payloadTypeIndicator (1 byte)
const payloadTypeView = new DataView(packedData, 4 + messageKeyLength, 1);
const payloadType = payloadTypeView.getUint8(0);
// [3] payload (variable length)
const payloadBinary = packedData.slice(4 + messageKeyLength + 1);
const payload = this.deserializePayload(payloadBinary, payloadType);
return { messageKey, payload };
}
isFastPathPayload(payload) {
if (payload == null) {
return true;
}
const payloadType = typeof payload;
if (payloadType === 'string' || payloadType === 'number') {
return true;
}
if (payloadType === 'object' && payload.constructor === Object) {
return true;
}
return false;
}
payloadToUint8Array(payload) {
if (payload instanceof Uint8Array) {
return payload;
}
else if (typeof payload === 'string') {
return this.textEncoder.encode(payload);
}
else if (typeof payload === 'number') {
const buffer = new ArrayBuffer(8);
const view = new DataView(buffer);
view.setFloat64(0, payload, false);
return new Uint8Array(buffer);
}
else if (payload === null) {
return new Uint8Array(0);
}
else if (payload === undefined) {
return new Uint8Array(0);
}
else if (payload instanceof ArrayBuffer) {
return new Uint8Array(payload);
}
else if (payload instanceof Blob) {
throw new Error('Blob is not supported in this callsite.');
}
else {
return this.textEncoder.encode(JSON.stringify(payload));
}
}
packImpl({ messageKey, payload }, payloadType) {
const messageKeyString = JSON.stringify(messageKey);
const messageKeyBytes = this.textEncoder.encode(messageKeyString);
const messageKeyLength = messageKeyBytes.length;
const payloadBinary = this.payloadToUint8Array(payload);
const totalLength = 4 + messageKeyLength + 1 + payloadBinary.byteLength;
const buffer = new ArrayBuffer(totalLength);
const packedArray = new Uint8Array(buffer);
// [0] messageKeyLength (4 bytes)
const messageKeyLengthView = new DataView(buffer, 0, 4);
messageKeyLengthView.setUint32(0, messageKeyLength, false);
// [1] messageKey (variable length)
packedArray.set(messageKeyBytes, 4);
// [2] payloadTypeIndicator (1 byte)
const payloadTypeView = new DataView(buffer, 4 + messageKeyLength, 1);
payloadTypeView.setUint8(0, payloadType ?? MessageFramePacker.getPayloadTypeIndicator(payload));
// [3] payload (variable length)
packedArray.set(payloadBinary, 4 + messageKeyLength + 1);
return packedArray;
}
deserializePayload(payloadBinary, payloadTypeIndicator) {
switch (payloadTypeIndicator) {
case PayloadTypeIndicator.Uint8Array: {
return new Uint8Array(payloadBinary);
}
case PayloadTypeIndicator.String: {
return this.textDecoder.decode(payloadBinary);
}
case PayloadTypeIndicator.Number: {
const view = new DataView(payloadBinary);
return view.getFloat64(0, false);
}
case PayloadTypeIndicator.Null: {
return null;
}
case PayloadTypeIndicator.Undefined: {
return undefined;
}
case PayloadTypeIndicator.Object: {
const jsonString = this.textDecoder.decode(payloadBinary);
return JSON.parse(jsonString);
}
case PayloadTypeIndicator.ArrayBuffer: {
return payloadBinary;
}
case PayloadTypeIndicator.Blob: {
return new Blob([payloadBinary]);
}
default:
throw new Error('Unsupported payload type');
}
}
static getPayloadTypeIndicator(payload) {
if (payload instanceof Uint8Array) {
return PayloadTypeIndicator.Uint8Array;
}
else if (typeof payload === 'string') {
return PayloadTypeIndicator.String;
}
else if (typeof payload === 'number') {
return PayloadTypeIndicator.Number;
}
else if (payload === null) {
return PayloadTypeIndicator.Null;
}
else if (payload === undefined) {
return PayloadTypeIndicator.Undefined;
}
else if (payload instanceof ArrayBuffer) {
return PayloadTypeIndicator.ArrayBuffer;
}
else if (payload instanceof Blob) {
return PayloadTypeIndicator.Blob;
}
else if (typeof payload === 'object') {
return PayloadTypeIndicator.Object;
}
else {
throw new Error('Unsupported payload type');
}
}
}
//# sourceMappingURL=MessageFramePacker.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,7 @@
/**
* A transport protocol version between the app and the webui.
* It shows a warning in handshaking stage if the version is different between the app and the webui.
* The value should be increased when the protocol is changed.
*/
export declare const PROTOCOL_VERSION = 1;
//# sourceMappingURL=ProtocolVersion.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"ProtocolVersion.d.ts","sourceRoot":"","sources":["../src/ProtocolVersion.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,IAAI,CAAC"}

7
node_modules/@expo/devtools/build/ProtocolVersion.js generated vendored Normal file
View File

@@ -0,0 +1,7 @@
/**
* A transport protocol version between the app and the webui.
* It shows a warning in handshaking stage if the version is different between the app and the webui.
* The value should be increased when the protocol is changed.
*/
export const PROTOCOL_VERSION = 1;
//# sourceMappingURL=ProtocolVersion.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"ProtocolVersion.js","sourceRoot":"","sources":["../src/ProtocolVersion.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC","sourcesContent":["/**\n * A transport protocol version between the app and the webui.\n * It shows a warning in handshaking stage if the version is different between the app and the webui.\n * The value should be increased when the protocol is changed.\n */\nexport const PROTOCOL_VERSION = 1;\n"]}

View File

@@ -0,0 +1,10 @@
/**
* The backing store for the WebSocket connection and reference count.
* This is used for connection multiplexing.
*/
export declare class WebSocketBackingStore {
ws: WebSocket | null;
refCount: number;
constructor(ws?: WebSocket | null, refCount?: number);
}
//# sourceMappingURL=WebSocketBackingStore.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"WebSocketBackingStore.d.ts","sourceRoot":"","sources":["../src/WebSocketBackingStore.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,qBAAa,qBAAqB;IAEvB,EAAE,EAAE,SAAS,GAAG,IAAI;IACpB,QAAQ,EAAE,MAAM;gBADhB,EAAE,GAAE,SAAS,GAAG,IAAW,EAC3B,QAAQ,GAAE,MAAU;CAE9B"}

View File

@@ -0,0 +1,13 @@
/**
* The backing store for the WebSocket connection and reference count.
* This is used for connection multiplexing.
*/
export class WebSocketBackingStore {
ws;
refCount;
constructor(ws = null, refCount = 0) {
this.ws = ws;
this.refCount = refCount;
}
}
//# sourceMappingURL=WebSocketBackingStore.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"WebSocketBackingStore.js","sourceRoot":"","sources":["../src/WebSocketBackingStore.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,OAAO,qBAAqB;IAEvB;IACA;IAFT,YACS,KAAuB,IAAI,EAC3B,WAAmB,CAAC;QADpB,OAAE,GAAF,EAAE,CAAyB;QAC3B,aAAQ,GAAR,QAAQ,CAAY;IAC1B,CAAC;CACL","sourcesContent":["/**\n * The backing store for the WebSocket connection and reference count.\n * This is used for connection multiplexing.\n */\nexport class WebSocketBackingStore {\n constructor(\n public ws: WebSocket | null = null,\n public refCount: number = 0\n ) {}\n}\n"]}

View File

@@ -0,0 +1,92 @@
import type { DevToolsPluginClientOptions } from './devtools.types';
export interface WebSocketCloseEvent extends Event {
code?: number;
reason?: string;
message?: string;
}
export interface WebSocketErrorEvent extends Event {
message?: string;
}
export interface WebSocketMessageEvent extends Event {
data: string | ArrayBufferLike | Blob | ArrayBufferView;
}
export interface Options {
/**
* Reconnect interval in milliseconds.
* @default 1500
*/
retriesInterval?: number;
/**
* The maximum number of retries.
* @default 200
*/
maxRetries?: number;
/**
* The timeout in milliseconds for the WebSocket connecting.
*/
connectTimeout?: number;
/**
* The error handler.
* @default throwing an error
*/
onError?: (error: Error) => void;
/**
* The callback to be called when the WebSocket is reconnected.
* @default no-op
*/
onReconnect?: (reason: string) => void;
/**
* The [`binaryType`](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/binaryType).
*/
binaryType?: DevToolsPluginClientOptions['websocketBinaryType'];
}
export declare class WebSocketWithReconnect implements WebSocket {
readonly url: string;
private readonly retriesInterval;
private readonly maxRetries;
private readonly connectTimeout;
private readonly onError;
private readonly onReconnect;
private ws;
private retries;
private connectTimeoutHandle;
private isClosed;
private sendQueue;
private lastCloseEvent;
private eventListeners;
private readonly wsBinaryType?;
constructor(url: string, options?: Options);
close(code?: number, reason?: string): void;
addEventListener(event: 'message', listener: (event: WebSocketMessageEvent) => void): void;
addEventListener(event: 'open', listener: () => void): void;
addEventListener(event: 'error', listener: (event: WebSocketErrorEvent) => void): void;
addEventListener(event: 'close', listener: (event: WebSocketCloseEvent) => void): void;
removeEventListener(event: string, listener: (event: any) => void): void;
private connect;
send(data: string | ArrayBufferView | Blob | ArrayBufferLike): void;
private emitEvent;
private handleOpen;
private handleMessage;
private handleError;
private handleClose;
private handleConnectTimeout;
private clearConnectTimeoutIfNeeded;
private reconnectIfNeeded;
private wsClose;
get readyState(): number;
readonly CONNECTING = 0;
readonly OPEN = 1;
readonly CLOSING = 2;
readonly CLOSED = 3;
get binaryType(): BinaryType;
get bufferedAmount(): number;
get extensions(): string;
get protocol(): string;
ping(): void;
dispatchEvent(event: Event): boolean;
set onclose(_value: ((e: WebSocketCloseEvent) => any) | null);
set onerror(_value: ((e: Event) => any) | null);
set onmessage(_value: ((e: WebSocketMessageEvent) => any) | null);
set onopen(_value: (() => any) | null);
}
//# sourceMappingURL=WebSocketWithReconnect.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"WebSocketWithReconnect.d.ts","sourceRoot":"","sources":["../src/WebSocketWithReconnect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,kBAAkB,CAAC;AAEpE,MAAM,WAAW,mBAAoB,SAAQ,KAAK;IAChD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AACD,MAAM,WAAW,mBAAoB,SAAQ,KAAK;IAEhD,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AACD,MAAM,WAAW,qBAAsB,SAAQ,KAAK;IAClD,IAAI,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,GAAG,eAAe,CAAC;CACzD;AAED,MAAM,WAAW,OAAO;IACtB;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;;OAGG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IAEjC;;;OAGG;IACH,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAEvC;;OAEG;IACH,UAAU,CAAC,EAAE,2BAA2B,CAAC,qBAAqB,CAAC,CAAC;CACjE;AAUD,qBAAa,sBAAuB,YAAW,SAAS;aAkBpC,GAAG,EAAE,MAAM;IAjB7B,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAyB;IACjD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA2B;IAEvD,OAAO,CAAC,EAAE,CAA0B;IACpC,OAAO,CAAC,OAAO,CAAK;IACpB,OAAO,CAAC,oBAAoB,CAA8C;IAC1E,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,SAAS,CAA6D;IAC9E,OAAO,CAAC,cAAc,CAAqE;IAC3F,OAAO,CAAC,cAAc,CAAyB;IAE/C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAwB;gBAGpC,GAAG,EAAE,MAAM,EAC3B,OAAO,CAAC,EAAE,OAAO;IAiBZ,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM;IAqBpC,gBAAgB,CAAC,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,qBAAqB,KAAK,IAAI,GAAG,IAAI;IAC1F,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,IAAI,GAAG,IAAI;IAC3D,gBAAgB,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,mBAAmB,KAAK,IAAI,GAAG,IAAI;IACtF,gBAAgB,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,mBAAmB,KAAK,IAAI,GAAG,IAAI;IAMtF,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI;IAMxE,OAAO,CAAC,OAAO;IAiBR,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,GAAG,eAAe,GAAG,IAAI;IAqB1E,OAAO,CAAC,SAAS;IAajB,OAAO,CAAC,UAAU,CAUhB;IAEF,OAAO,CAAC,aAAa,CAEnB;IAEF,OAAO,CAAC,WAAW,CAIjB;IAEF,OAAO,CAAC,WAAW,CAQjB;IAEF,OAAO,CAAC,oBAAoB,CAE1B;IAEF,OAAO,CAAC,2BAA2B;IAOnC,OAAO,CAAC,iBAAiB;IAsBzB,OAAO,CAAC,OAAO;IAgBf,IAAW,UAAU,WAWpB;IAMD,SAAgB,UAAU,KAAK;IAC/B,SAAgB,IAAI,KAAK;IACzB,SAAgB,OAAO,KAAK;IAC5B,SAAgB,MAAM,KAAK;IAE3B,IAAW,UAAU,eAEpB;IAED,IAAW,cAAc,WAExB;IAED,IAAW,UAAU,WAEpB;IAED,IAAW,QAAQ,WAElB;IAEM,IAAI,IAAI,IAAI;IAKZ,aAAa,CAAC,KAAK,EAAE,KAAK;IAQjC,IAAW,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,mBAAmB,KAAK,GAAG,CAAC,GAAG,IAAI,EAElE;IAED,IAAW,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,KAAK,GAAG,CAAC,GAAG,IAAI,EAEpD;IAED,IAAW,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,qBAAqB,KAAK,GAAG,CAAC,GAAG,IAAI,EAEtE;IAED,IAAW,MAAM,CAAC,MAAM,EAAE,CAAC,MAAM,GAAG,CAAC,GAAG,IAAI,EAE3C;CAGF"}

View File

@@ -0,0 +1,216 @@
export class WebSocketWithReconnect {
url;
retriesInterval;
maxRetries;
connectTimeout;
onError;
onReconnect;
ws = null;
retries = 0;
connectTimeoutHandle = null;
isClosed = false;
sendQueue = [];
lastCloseEvent = null;
eventListeners;
wsBinaryType;
constructor(url, options) {
this.url = url;
this.retriesInterval = options?.retriesInterval ?? 1500;
this.maxRetries = options?.maxRetries ?? 200;
this.connectTimeout = options?.connectTimeout ?? 5000;
this.onError =
options?.onError ??
((error) => {
throw error;
});
this.onReconnect = options?.onReconnect ?? (() => { });
this.wsBinaryType = options?.binaryType;
this.eventListeners = Object.create(null);
this.connect();
}
close(code, reason) {
this.clearConnectTimeoutIfNeeded();
this.emitEvent('close', (this.lastCloseEvent ?? {
code: code ?? 1000,
reason: reason ?? 'Explicit closing',
message: 'Explicit closing',
}));
this.lastCloseEvent = null;
this.isClosed = true;
this.eventListeners = Object.create(null);
this.sendQueue = [];
if (this.ws != null) {
const ws = this.ws;
this.ws = null;
this.wsClose(ws);
}
}
addEventListener(event, listener) {
const listeners = this.eventListeners[event] || (this.eventListeners[event] = new Set());
listeners.add(listener);
}
removeEventListener(event, listener) {
this.eventListeners[event]?.delete(listener);
}
//#region Internals
connect() {
if (this.ws != null) {
return;
}
this.connectTimeoutHandle = setTimeout(this.handleConnectTimeout, this.connectTimeout);
this.ws = new WebSocket(this.url.toString());
if (this.wsBinaryType != null) {
this.ws.binaryType = this.wsBinaryType;
}
this.ws.addEventListener('message', this.handleMessage);
this.ws.addEventListener('open', this.handleOpen);
// @ts-ignore TypeScript expects (e: Event) => any, but we want (e: WebSocketErrorEvent) => any
this.ws.addEventListener('error', this.handleError);
this.ws.addEventListener('close', this.handleClose);
}
send(data) {
if (this.isClosed) {
this.onError(new Error('Unable to send data: WebSocket is closed'));
return;
}
if (this.retries >= this.maxRetries) {
this.onError(new Error(`Unable to send data: Exceeded max retries - retries[${this.retries}]`));
return;
}
const ws = this.ws;
if (ws != null && ws.readyState === WebSocket.OPEN) {
ws.send(data);
}
else {
this.sendQueue.push(data);
}
}
emitEvent(event, payload) {
const listeners = this.eventListeners[event];
if (listeners) {
for (const listener of listeners) {
listener(payload);
}
}
}
handleOpen = () => {
this.clearConnectTimeoutIfNeeded();
this.lastCloseEvent = null;
this.emitEvent('open');
const sendQueue = this.sendQueue;
this.sendQueue = [];
for (const data of sendQueue) {
this.send(data);
}
};
handleMessage = (event) => {
this.emitEvent('message', event);
};
handleError = (event) => {
this.clearConnectTimeoutIfNeeded();
this.emitEvent('error', event);
this.reconnectIfNeeded(`WebSocket error - ${event.message}`);
};
handleClose = (event) => {
this.clearConnectTimeoutIfNeeded();
this.lastCloseEvent = {
code: event.code,
reason: event.reason,
message: event.message,
};
this.reconnectIfNeeded(`WebSocket closed - code[${event.code}] reason[${event.reason}]`);
};
handleConnectTimeout = () => {
this.reconnectIfNeeded('Timeout from connecting to the WebSocket');
};
clearConnectTimeoutIfNeeded() {
if (this.connectTimeoutHandle != null) {
clearTimeout(this.connectTimeoutHandle);
this.connectTimeoutHandle = null;
}
}
reconnectIfNeeded(reason) {
if (this.ws != null) {
this.wsClose(this.ws);
this.ws = null;
}
if (this.isClosed) {
return;
}
if (this.retries >= this.maxRetries) {
this.onError(new Error('Exceeded max retries'));
this.close();
return;
}
setTimeout(() => {
this.retries += 1;
this.connect();
this.onReconnect(reason);
}, this.retriesInterval);
}
wsClose(ws) {
try {
ws.removeEventListener('message', this.handleMessage);
ws.removeEventListener('open', this.handleOpen);
ws.removeEventListener('close', this.handleClose);
// WebSocket throws errors if we don't handle the error event.
// Specifically when closing a ws in CONNECTING readyState,
// WebSocket will have `WebSocket was closed before the connection was established` error.
// We won't like to have the exception, so set a noop error handler.
ws.onerror = () => { };
ws.close();
}
catch { }
}
get readyState() {
// Only return closed if the WebSocket is explicitly closed or exceeds max retries.
if (this.isClosed) {
return WebSocket.CLOSED;
}
const readyState = this.ws?.readyState;
if (readyState === WebSocket.CLOSED) {
return WebSocket.CONNECTING;
}
return readyState ?? WebSocket.CONNECTING;
}
//#endregion
//#region WebSocket API proxy
CONNECTING = 0;
OPEN = 1;
CLOSING = 2;
CLOSED = 3;
get binaryType() {
return this.ws?.binaryType ?? 'blob';
}
get bufferedAmount() {
return this.ws?.bufferedAmount ?? 0;
}
get extensions() {
return this.ws?.extensions ?? '';
}
get protocol() {
return this.ws?.protocol ?? '';
}
ping() {
// @ts-ignore react-native WebSocket has the ping method
return this.ws?.ping();
}
dispatchEvent(event) {
return this.ws?.dispatchEvent(event) ?? false;
}
//#endregion
//#regions Unsupported legacy properties
set onclose(_value) {
throw new Error('Unsupported legacy property, use addEventListener instead');
}
set onerror(_value) {
throw new Error('Unsupported legacy property, use addEventListener instead');
}
set onmessage(_value) {
throw new Error('Unsupported legacy property, use addEventListener instead');
}
set onopen(_value) {
throw new Error('Unsupported legacy property, use addEventListener instead');
}
}
//# sourceMappingURL=WebSocketWithReconnect.js.map

File diff suppressed because one or more lines are too long

46
node_modules/@expo/devtools/build/devtools.types.d.ts generated vendored Normal file
View File

@@ -0,0 +1,46 @@
import type { WebSocketBackingStore } from './WebSocketBackingStore';
/**
* The connection info for devtools plugins client.
*/
export interface ConnectionInfo {
/** Indicates the sender towards the devtools plugin. */
sender: 'app' | 'browser';
/** Dev server address. */
devServer: string;
/** The plugin name. */
pluginName: string;
/**
* The backing store for the WebSocket connection. Exposed for testing.
* If not provided, the default singleton instance will be used.
* @hidden
*/
wsStore?: WebSocketBackingStore;
/**
* The transport protocol version between the app and the webui.
*/
protocolVersion: number;
/**
* Whether to use WSS for the WebSocket connection.
*/
useWss: boolean;
}
/**
* Options for the devtools plugin client.
*/
export interface DevToolsPluginClientOptions {
/**
* The underlying WebSocket [`binaryType`](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/binaryType).
*/
websocketBinaryType?: 'arraybuffer' | 'blob';
}
/**
* The handshake messages for the devtools plugin client.
* @hidden
*/
export interface HandshakeMessageParams {
protocolVersion: number;
pluginName: string;
method: 'handshake' | 'terminateBrowserClient';
browserClientId: string;
}
//# sourceMappingURL=devtools.types.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"devtools.types.d.ts","sourceRoot":"","sources":["../src/devtools.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAErE;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,wDAAwD;IACxD,MAAM,EACF,KAAK,GACL,SAAS,CAAC;IAEd,0BAA0B;IAC1B,SAAS,EAAE,MAAM,CAAC;IAElB,uBAAuB;IACvB,UAAU,EAAE,MAAM,CAAC;IAEnB;;;;OAIG;IACH,OAAO,CAAC,EAAE,qBAAqB,CAAC;IAEhC;;OAEG;IACH,eAAe,EAAE,MAAM,CAAC;IAExB;;OAEG;IACH,MAAM,EAAE,OAAO,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,2BAA2B;IAC1C;;OAEG;IACH,mBAAmB,CAAC,EAAE,aAAa,GAAG,MAAM,CAAC;CAC9C;AAED;;;GAGG;AACH,MAAM,WAAW,sBAAsB;IACrC,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,WAAW,GAAG,wBAAwB,CAAC;IAC/C,eAAe,EAAE,MAAM,CAAC;CACzB"}

2
node_modules/@expo/devtools/build/devtools.types.js generated vendored Normal file
View File

@@ -0,0 +1,2 @@
export {};
//# sourceMappingURL=devtools.types.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"devtools.types.js","sourceRoot":"","sources":["../src/devtools.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { WebSocketBackingStore } from './WebSocketBackingStore';\n\n/**\n * The connection info for devtools plugins client.\n */\nexport interface ConnectionInfo {\n /** Indicates the sender towards the devtools plugin. */\n sender:\n | 'app' // client running in the app environment.\n | 'browser'; // client running in the browser environment.\n\n /** Dev server address. */\n devServer: string;\n\n /** The plugin name. */\n pluginName: string;\n\n /**\n * The backing store for the WebSocket connection. Exposed for testing.\n * If not provided, the default singleton instance will be used.\n * @hidden\n */\n wsStore?: WebSocketBackingStore;\n\n /**\n * The transport protocol version between the app and the webui.\n */\n protocolVersion: number;\n\n /**\n * Whether to use WSS for the WebSocket connection.\n */\n useWss: boolean;\n}\n\n/**\n * Options for the devtools plugin client.\n */\nexport interface DevToolsPluginClientOptions {\n /**\n * The underlying WebSocket [`binaryType`](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/binaryType).\n */\n websocketBinaryType?: 'arraybuffer' | 'blob';\n}\n\n/**\n * The handshake messages for the devtools plugin client.\n * @hidden\n */\nexport interface HandshakeMessageParams {\n protocolVersion: number;\n pluginName: string;\n method: 'handshake' | 'terminateBrowserClient';\n browserClientId: string;\n}\n"]}

View File

@@ -0,0 +1,6 @@
/**
* Get the dev server address.
*/
import type { ConnectionInfo } from './devtools.types';
export declare function getConnectionInfo(): Omit<ConnectionInfo, 'pluginName'>;
//# sourceMappingURL=getConnectionInfo.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"getConnectionInfo.d.ts","sourceRoot":"","sources":["../src/getConnectionInfo.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEvD,wBAAgB,iBAAiB,IAAI,IAAI,CAAC,cAAc,EAAE,YAAY,CAAC,CAStE"}

15
node_modules/@expo/devtools/build/getConnectionInfo.js generated vendored Normal file
View File

@@ -0,0 +1,15 @@
/**
* Get the dev server address.
*/
import { PROTOCOL_VERSION } from './ProtocolVersion';
export function getConnectionInfo() {
const devServerQuery = new URLSearchParams(window.location.search).get('devServer');
const host = window.location.origin.replace(/^https?:\/\//, '');
return {
protocolVersion: PROTOCOL_VERSION,
sender: 'browser',
devServer: devServerQuery || host,
useWss: window.location.protocol === 'https:',
};
}
//# sourceMappingURL=getConnectionInfo.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"getConnectionInfo.js","sourceRoot":"","sources":["../src/getConnectionInfo.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAGrD,MAAM,UAAU,iBAAiB;IAC/B,MAAM,cAAc,GAAG,IAAI,eAAe,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IACpF,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;IAChE,OAAO;QACL,eAAe,EAAE,gBAAgB;QACjC,MAAM,EAAE,SAAS;QACjB,SAAS,EAAE,cAAc,IAAI,IAAI;QACjC,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,QAAQ,KAAK,QAAQ;KAC9C,CAAC;AACJ,CAAC","sourcesContent":["/**\n * Get the dev server address.\n */\n\nimport { PROTOCOL_VERSION } from './ProtocolVersion';\nimport type { ConnectionInfo } from './devtools.types';\n\nexport function getConnectionInfo(): Omit<ConnectionInfo, 'pluginName'> {\n const devServerQuery = new URLSearchParams(window.location.search).get('devServer');\n const host = window.location.origin.replace(/^https?:\\/\\//, '');\n return {\n protocolVersion: PROTOCOL_VERSION,\n sender: 'browser',\n devServer: devServerQuery || host,\n useWss: window.location.protocol === 'https:',\n };\n}\n"]}

View File

@@ -0,0 +1,6 @@
/**
* Get the dev server address.
*/
import type { ConnectionInfo } from './devtools.types';
export declare function getConnectionInfo(): Omit<ConnectionInfo, 'pluginName'>;
//# sourceMappingURL=getConnectionInfo.native.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"getConnectionInfo.native.d.ts","sourceRoot":"","sources":["../src/getConnectionInfo.native.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEvD,wBAAgB,iBAAiB,IAAI,IAAI,CAAC,cAAc,EAAE,YAAY,CAAC,CAUtE"}

View File

@@ -0,0 +1,16 @@
/**
* Get the dev server address.
*/
import { PROTOCOL_VERSION } from './ProtocolVersion';
export function getConnectionInfo() {
const getDevServer = require('react-native/Libraries/Core/Devtools/getDevServer').default;
const devServerUrl = getDevServer().url;
const devServer = devServerUrl.replace(/^https?:\/\//, '').replace(/\/?$/, '');
return {
protocolVersion: PROTOCOL_VERSION,
sender: 'app',
devServer,
useWss: devServerUrl.startsWith('https://'),
};
}
//# sourceMappingURL=getConnectionInfo.native.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"getConnectionInfo.native.js","sourceRoot":"","sources":["../src/getConnectionInfo.native.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAGrD,MAAM,UAAU,iBAAiB;IAC/B,MAAM,YAAY,GAAG,OAAO,CAAC,mDAAmD,CAAC,CAAC,OAAO,CAAC;IAC1F,MAAM,YAAY,GAAG,YAAY,EAAE,CAAC,GAAG,CAAC;IACxC,MAAM,SAAS,GAAG,YAAY,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAW,CAAC;IACzF,OAAO;QACL,eAAe,EAAE,gBAAgB;QACjC,MAAM,EAAE,KAAK;QACb,SAAS;QACT,MAAM,EAAE,YAAY,CAAC,UAAU,CAAC,UAAU,CAAC;KAC5C,CAAC;AACJ,CAAC","sourcesContent":["/**\n * Get the dev server address.\n */\n\nimport { PROTOCOL_VERSION } from './ProtocolVersion';\nimport type { ConnectionInfo } from './devtools.types';\n\nexport function getConnectionInfo(): Omit<ConnectionInfo, 'pluginName'> {\n const getDevServer = require('react-native/Libraries/Core/Devtools/getDevServer').default;\n const devServerUrl = getDevServer().url;\n const devServer = devServerUrl.replace(/^https?:\\/\\//, '').replace(/\\/?$/, '') as string;\n return {\n protocolVersion: PROTOCOL_VERSION,\n sender: 'app',\n devServer,\n useWss: devServerUrl.startsWith('https://'),\n };\n}\n"]}

7
node_modules/@expo/devtools/build/hooks.d.ts generated vendored Normal file
View File

@@ -0,0 +1,7 @@
import { DevToolsPluginClient } from './DevToolsPluginClient';
import type { DevToolsPluginClientOptions } from './devtools.types';
/**
* A React hook to get the DevToolsPluginClient instance.
*/
export declare function useDevToolsPluginClient(pluginName: string, options?: DevToolsPluginClientOptions): DevToolsPluginClient | null;
//# sourceMappingURL=hooks.d.ts.map

1
node_modules/@expo/devtools/build/hooks.d.ts.map generated vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../src/hooks.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAE9D,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,kBAAkB,CAAC;AAEpE;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,2BAA2B,GACpC,oBAAoB,GAAG,IAAI,CAkC7B"}

37
node_modules/@expo/devtools/build/hooks.js generated vendored Normal file
View File

@@ -0,0 +1,37 @@
import { useState, useEffect } from 'react';
import { getDevToolsPluginClientAsync } from './DevToolsPluginClientFactory';
/**
* A React hook to get the DevToolsPluginClient instance.
*/
export function useDevToolsPluginClient(pluginName, options) {
const [client, setClient] = useState(null);
const [error, setError] = useState(null);
useEffect(() => {
async function setup() {
try {
const client = await getDevToolsPluginClientAsync(pluginName, options);
setClient(client);
}
catch (e) {
setError(new Error('Failed to setup client from useDevToolsPluginClient: ' + e.toString()));
}
}
async function teardown() {
try {
await client?.closeAsync();
}
catch (e) {
setError(new Error('Failed to teardown client from useDevToolsPluginClient: ' + e.toString()));
}
}
setup();
return () => {
teardown();
};
}, [pluginName]);
if (error != null) {
throw error;
}
return client;
}
//# sourceMappingURL=hooks.js.map

1
node_modules/@expo/devtools/build/hooks.js.map generated vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"hooks.js","sourceRoot":"","sources":["../src/hooks.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAG5C,OAAO,EAAE,4BAA4B,EAAE,MAAM,+BAA+B,CAAC;AAG7E;;GAEG;AACH,MAAM,UAAU,uBAAuB,CACrC,UAAkB,EAClB,OAAqC;IAErC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAA8B,IAAI,CAAC,CAAC;IACxE,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAe,IAAI,CAAC,CAAC;IAEvD,SAAS,CAAC,GAAG,EAAE;QACb,KAAK,UAAU,KAAK;YAClB,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,4BAA4B,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;gBACvE,SAAS,CAAC,MAAM,CAAC,CAAC;YACpB,CAAC;YAAC,OAAO,CAAM,EAAE,CAAC;gBAChB,QAAQ,CAAC,IAAI,KAAK,CAAC,uDAAuD,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;YAC9F,CAAC;QACH,CAAC;QAED,KAAK,UAAU,QAAQ;YACrB,IAAI,CAAC;gBACH,MAAM,MAAM,EAAE,UAAU,EAAE,CAAC;YAC7B,CAAC;YAAC,OAAO,CAAM,EAAE,CAAC;gBAChB,QAAQ,CACN,IAAI,KAAK,CAAC,0DAA0D,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,CACrF,CAAC;YACJ,CAAC;QACH,CAAC;QAED,KAAK,EAAE,CAAC;QACR,OAAO,GAAG,EAAE;YACV,QAAQ,EAAE,CAAC;QACb,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;IAEjB,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;QAClB,MAAM,KAAK,CAAC;IACd,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC","sourcesContent":["import { useState, useEffect } from 'react';\n\nimport { DevToolsPluginClient } from './DevToolsPluginClient';\nimport { getDevToolsPluginClientAsync } from './DevToolsPluginClientFactory';\nimport type { DevToolsPluginClientOptions } from './devtools.types';\n\n/**\n * A React hook to get the DevToolsPluginClient instance.\n */\nexport function useDevToolsPluginClient(\n pluginName: string,\n options?: DevToolsPluginClientOptions\n): DevToolsPluginClient | null {\n const [client, setClient] = useState<DevToolsPluginClient | null>(null);\n const [error, setError] = useState<Error | null>(null);\n\n useEffect(() => {\n async function setup() {\n try {\n const client = await getDevToolsPluginClientAsync(pluginName, options);\n setClient(client);\n } catch (e: any) {\n setError(new Error('Failed to setup client from useDevToolsPluginClient: ' + e.toString()));\n }\n }\n\n async function teardown() {\n try {\n await client?.closeAsync();\n } catch (e: any) {\n setError(\n new Error('Failed to teardown client from useDevToolsPluginClient: ' + e.toString())\n );\n }\n }\n\n setup();\n return () => {\n teardown();\n };\n }, [pluginName]);\n\n if (error != null) {\n throw error;\n }\n return client;\n}\n"]}

10
node_modules/@expo/devtools/build/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,10 @@
export * from './hooks';
export { setEnableLogging } from './logger';
export { getDevToolsPluginClientAsync } from './DevToolsPluginClientFactory';
export { DevToolsPluginClient } from './DevToolsPluginClient';
export type { EventSubscription } from './DevToolsPluginClient';
export type * from './devtools.types';
export { createDevToolsPluginClient as unstable_createDevToolsPluginClient } from './DevToolsPluginClientFactory';
export { WebSocketBackingStore as unstable_WebSocketBackingStore } from './WebSocketBackingStore';
export { getConnectionInfo as unstable_getConnectionInfo } from './getConnectionInfo';
//# sourceMappingURL=index.d.ts.map

1
node_modules/@expo/devtools/build/index.d.ts.map generated vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,4BAA4B,EAAE,MAAM,+BAA+B,CAAC;AAC7E,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAG9D,YAAY,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAChE,mBAAmB,kBAAkB,CAAC;AAGtC,OAAO,EAAE,0BAA0B,IAAI,mCAAmC,EAAE,MAAM,+BAA+B,CAAC;AAClH,OAAO,EAAE,qBAAqB,IAAI,8BAA8B,EAAE,MAAM,yBAAyB,CAAC;AAClG,OAAO,EAAE,iBAAiB,IAAI,0BAA0B,EAAE,MAAM,qBAAqB,CAAC"}

9
node_modules/@expo/devtools/build/index.js generated vendored Normal file
View File

@@ -0,0 +1,9 @@
export * from './hooks';
export { setEnableLogging } from './logger';
export { getDevToolsPluginClientAsync } from './DevToolsPluginClientFactory';
export { DevToolsPluginClient } from './DevToolsPluginClient';
// Unstable APIs exported for testing purposes.
export { createDevToolsPluginClient as unstable_createDevToolsPluginClient } from './DevToolsPluginClientFactory';
export { WebSocketBackingStore as unstable_WebSocketBackingStore } from './WebSocketBackingStore';
export { getConnectionInfo as unstable_getConnectionInfo } from './getConnectionInfo';
//# sourceMappingURL=index.js.map

1
node_modules/@expo/devtools/build/index.js.map generated vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,4BAA4B,EAAE,MAAM,+BAA+B,CAAC;AAC7E,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAM9D,+CAA+C;AAC/C,OAAO,EAAE,0BAA0B,IAAI,mCAAmC,EAAE,MAAM,+BAA+B,CAAC;AAClH,OAAO,EAAE,qBAAqB,IAAI,8BAA8B,EAAE,MAAM,yBAAyB,CAAC;AAClG,OAAO,EAAE,iBAAiB,IAAI,0BAA0B,EAAE,MAAM,qBAAqB,CAAC","sourcesContent":["export * from './hooks';\nexport { setEnableLogging } from './logger';\nexport { getDevToolsPluginClientAsync } from './DevToolsPluginClientFactory';\nexport { DevToolsPluginClient } from './DevToolsPluginClient';\n\n// Export the EventSubscription type if people need to use explicit type from `addMessageListener`\nexport type { EventSubscription } from './DevToolsPluginClient';\nexport type * from './devtools.types';\n\n// Unstable APIs exported for testing purposes.\nexport { createDevToolsPluginClient as unstable_createDevToolsPluginClient } from './DevToolsPluginClientFactory';\nexport { WebSocketBackingStore as unstable_WebSocketBackingStore } from './WebSocketBackingStore';\nexport { getConnectionInfo as unstable_getConnectionInfo } from './getConnectionInfo';\n"]}

6
node_modules/@expo/devtools/build/logger.d.ts generated vendored Normal file
View File

@@ -0,0 +1,6 @@
export declare function log(...params: Parameters<typeof console.log>): void;
export declare function debug(...params: Parameters<typeof console.debug>): void;
export declare function info(...params: Parameters<typeof console.info>): void;
export declare function warn(...params: Parameters<typeof console.info>): void;
export declare function setEnableLogging(enabled: boolean): void;
//# sourceMappingURL=logger.d.ts.map

1
node_modules/@expo/devtools/build/logger.d.ts.map generated vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAEA,wBAAgB,GAAG,CAAC,GAAG,MAAM,EAAE,UAAU,CAAC,OAAO,OAAO,CAAC,GAAG,CAAC,QAI5D;AAED,wBAAgB,KAAK,CAAC,GAAG,MAAM,EAAE,UAAU,CAAC,OAAO,OAAO,CAAC,KAAK,CAAC,QAIhE;AAED,wBAAgB,IAAI,CAAC,GAAG,MAAM,EAAE,UAAU,CAAC,OAAO,OAAO,CAAC,IAAI,CAAC,QAI9D;AAED,wBAAgB,IAAI,CAAC,GAAG,MAAM,EAAE,UAAU,CAAC,OAAO,OAAO,CAAC,IAAI,CAAC,QAI9D;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,QAEhD"}

25
node_modules/@expo/devtools/build/logger.js generated vendored Normal file
View File

@@ -0,0 +1,25 @@
let enableLogging = false;
export function log(...params) {
if (enableLogging) {
console.log(...params);
}
}
export function debug(...params) {
if (enableLogging) {
console.debug(...params);
}
}
export function info(...params) {
if (enableLogging) {
console.info(...params);
}
}
export function warn(...params) {
if (enableLogging) {
console.warn(...params);
}
}
export function setEnableLogging(enabled) {
enableLogging = enabled;
}
//# sourceMappingURL=logger.js.map

1
node_modules/@expo/devtools/build/logger.js.map generated vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA,IAAI,aAAa,GAAG,KAAK,CAAC;AAE1B,MAAM,UAAU,GAAG,CAAC,GAAG,MAAsC;IAC3D,IAAI,aAAa,EAAE,CAAC;QAClB,OAAO,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC;IACzB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,GAAG,MAAwC;IAC/D,IAAI,aAAa,EAAE,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,CAAC;IAC3B,CAAC;AACH,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,GAAG,MAAuC;IAC7D,IAAI,aAAa,EAAE,CAAC;QAClB,OAAO,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC;IAC1B,CAAC;AACH,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,GAAG,MAAuC;IAC7D,IAAI,aAAa,EAAE,CAAC;QAClB,OAAO,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC;IAC1B,CAAC;AACH,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,OAAgB;IAC/C,aAAa,GAAG,OAAO,CAAC;AAC1B,CAAC","sourcesContent":["let enableLogging = false;\n\nexport function log(...params: Parameters<typeof console.log>) {\n if (enableLogging) {\n console.log(...params);\n }\n}\n\nexport function debug(...params: Parameters<typeof console.debug>) {\n if (enableLogging) {\n console.debug(...params);\n }\n}\n\nexport function info(...params: Parameters<typeof console.info>) {\n if (enableLogging) {\n console.info(...params);\n }\n}\n\nexport function warn(...params: Parameters<typeof console.info>) {\n if (enableLogging) {\n console.warn(...params);\n }\n}\n\nexport function setEnableLogging(enabled: boolean) {\n enableLogging = enabled;\n}\n"]}

View File

@@ -0,0 +1,9 @@
/**
* Converts a Blob to an ArrayBuffer.
*/
export declare function blobToArrayBufferAsync(blob: Blob): Promise<ArrayBuffer>;
/**
* Converts a Blob to an ArrayBuffer using the FileReader API.
*/
export declare function legacyBlobToArrayBufferAsync(blob: Blob): Promise<ArrayBuffer>;
//# sourceMappingURL=blobUtils.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"blobUtils.d.ts","sourceRoot":"","sources":["../../src/utils/blobUtils.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,WAAW,CAAC,CAKvE;AAED;;GAEG;AACH,wBAAsB,4BAA4B,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,WAAW,CAAC,CASnF"}

23
node_modules/@expo/devtools/build/utils/blobUtils.js generated vendored Normal file
View File

@@ -0,0 +1,23 @@
/**
* Converts a Blob to an ArrayBuffer.
*/
export function blobToArrayBufferAsync(blob) {
if (typeof blob.arrayBuffer === 'function') {
return blob.arrayBuffer();
}
return legacyBlobToArrayBufferAsync(blob);
}
/**
* Converts a Blob to an ArrayBuffer using the FileReader API.
*/
export async function legacyBlobToArrayBufferAsync(blob) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => {
resolve(reader.result);
};
reader.onerror = reject;
reader.readAsArrayBuffer(blob);
});
}
//# sourceMappingURL=blobUtils.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"blobUtils.js","sourceRoot":"","sources":["../../src/utils/blobUtils.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,UAAU,sBAAsB,CAAC,IAAU;IAC/C,IAAI,OAAO,IAAI,CAAC,WAAW,KAAK,UAAU,EAAE,CAAC;QAC3C,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC;IAC5B,CAAC;IACD,OAAO,4BAA4B,CAAC,IAAI,CAAC,CAAC;AAC5C,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,4BAA4B,CAAC,IAAU;IAC3D,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;QAChC,MAAM,CAAC,MAAM,GAAG,GAAG,EAAE;YACnB,OAAO,CAAC,MAAM,CAAC,MAAqB,CAAC,CAAC;QACxC,CAAC,CAAC;QACF,MAAM,CAAC,OAAO,GAAG,MAAM,CAAC;QACxB,MAAM,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC,CAAC,CAAC;AACL,CAAC","sourcesContent":["/**\n * Converts a Blob to an ArrayBuffer.\n */\nexport function blobToArrayBufferAsync(blob: Blob): Promise<ArrayBuffer> {\n if (typeof blob.arrayBuffer === 'function') {\n return blob.arrayBuffer();\n }\n return legacyBlobToArrayBufferAsync(blob);\n}\n\n/**\n * Converts a Blob to an ArrayBuffer using the FileReader API.\n */\nexport async function legacyBlobToArrayBufferAsync(blob: Blob): Promise<ArrayBuffer> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = () => {\n resolve(reader.result as ArrayBuffer);\n };\n reader.onerror = reject;\n reader.readAsArrayBuffer(blob);\n });\n}\n"]}