dev testing

This commit is contained in:
2026-03-23 15:29:13 -04:00
parent 28dae0dc60
commit d772b7ec9c
5664 changed files with 863006 additions and 73 deletions

View File

@@ -0,0 +1,198 @@
/**
* @license
* Copyright 2017 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { RepoInfo } from '../core/RepoInfo';
import { PacketReceiver } from './polling/PacketReceiver';
import { Transport } from './Transport';
export declare const FIREBASE_LONGPOLL_START_PARAM = "start";
export declare const FIREBASE_LONGPOLL_CLOSE_COMMAND = "close";
export declare const FIREBASE_LONGPOLL_COMMAND_CB_NAME = "pLPCommand";
export declare const FIREBASE_LONGPOLL_DATA_CB_NAME = "pRTLPCB";
export declare const FIREBASE_LONGPOLL_ID_PARAM = "id";
export declare const FIREBASE_LONGPOLL_PW_PARAM = "pw";
export declare const FIREBASE_LONGPOLL_SERIAL_PARAM = "ser";
export declare const FIREBASE_LONGPOLL_CALLBACK_ID_PARAM = "cb";
export declare const FIREBASE_LONGPOLL_SEGMENT_NUM_PARAM = "seg";
export declare const FIREBASE_LONGPOLL_SEGMENTS_IN_PACKET = "ts";
export declare const FIREBASE_LONGPOLL_DATA_PARAM = "d";
export declare const FIREBASE_LONGPOLL_DISCONN_FRAME_PARAM = "disconn";
export declare const FIREBASE_LONGPOLL_DISCONN_FRAME_REQUEST_PARAM = "dframe";
/**
* This class manages a single long-polling connection.
*/
export declare class BrowserPollConnection implements Transport {
connId: string;
repoInfo: RepoInfo;
private applicationId?;
private appCheckToken?;
private authToken?;
transportSessionId?: string;
lastSessionId?: string;
bytesSent: number;
bytesReceived: number;
urlFn: (params: object) => string;
scriptTagHolder: FirebaseIFrameScriptHolder;
myDisconnFrame: HTMLIFrameElement;
curSegmentNum: number;
myPacketOrderer: PacketReceiver;
id: string;
password: string;
private log_;
private stats_;
private everConnected_;
private isClosed_;
private connectTimeoutTimer_;
private onDisconnect_;
/**
* @param connId An identifier for this connection, used for logging
* @param repoInfo The info for the endpoint to send data to.
* @param applicationId The Firebase App ID for this project.
* @param appCheckToken The AppCheck token for this client.
* @param authToken The AuthToken to use for this connection.
* @param transportSessionId Optional transportSessionid if we are
* reconnecting for an existing transport session
* @param lastSessionId Optional lastSessionId if the PersistentConnection has
* already created a connection previously
*/
constructor(connId: string, repoInfo: RepoInfo, applicationId?: string, appCheckToken?: string, authToken?: string, transportSessionId?: string, lastSessionId?: string);
/**
* @param onMessage - Callback when messages arrive
* @param onDisconnect - Callback with connection lost.
*/
open(onMessage: (msg: {}) => void, onDisconnect: (a?: boolean) => void): void;
/**
* Call this when a handshake has completed successfully and we want to consider the connection established
*/
start(): void;
static forceAllow_: boolean;
/**
* Forces long polling to be considered as a potential transport
*/
static forceAllow(): void;
static forceDisallow_: boolean;
/**
* Forces longpolling to not be considered as a potential transport
*/
static forceDisallow(): void;
static isAvailable(): boolean;
/**
* No-op for polling
*/
markConnectionHealthy(): void;
/**
* Stops polling and cleans up the iframe
*/
private shutdown_;
/**
* Triggered when this transport is closed
*/
private onClosed_;
/**
* External-facing close handler. RealTime has requested we shut down. Kill our connection and tell the server
* that we've left.
*/
close(): void;
/**
* Send the JSON object down to the server. It will need to be stringified, base64 encoded, and then
* broken into chunks (since URLs have a small maximum length).
* @param data - The JSON data to transmit.
*/
send(data: {}): void;
/**
* This is how we notify the server that we're leaving.
* We aren't able to send requests with DHTML on a window close event, but we can
* trigger XHR requests in some browsers (everything but Opera basically).
*/
addDisconnectPingFrame(id: string, pw: string): void;
/**
* Used to track the bytes received by this client
*/
private incrementIncomingBytes_;
}
export interface IFrameElement extends HTMLIFrameElement {
doc: Document;
}
/*********************************************************************************************
* A wrapper around an iframe that is used as a long-polling script holder.
*********************************************************************************************/
export declare class FirebaseIFrameScriptHolder {
onDisconnect: () => void;
urlFn: (a: object) => string;
outstandingRequests: Set<number>;
pendingSegs: Array<{
seg: number;
ts: number;
d: unknown;
}>;
currentSerial: number;
sendNewPolls: boolean;
uniqueCallbackIdentifier: number;
myIFrame: IFrameElement;
alive: boolean;
myID: string;
myPW: string;
commandCB: (command: string, ...args: unknown[]) => void;
onMessageCB: (...args: unknown[]) => void;
/**
* @param commandCB - The callback to be called when control commands are received from the server.
* @param onMessageCB - The callback to be triggered when responses arrive from the server.
* @param onDisconnect - The callback to be triggered when this tag holder is closed
* @param urlFn - A function that provides the URL of the endpoint to send data to.
*/
constructor(commandCB: (command: string, ...args: unknown[]) => void, onMessageCB: (...args: unknown[]) => void, onDisconnect: () => void, urlFn: (a: object) => string);
/**
* Each browser has its own funny way to handle iframes. Here we mush them all together into one object that I can
* actually use.
*/
private static createIFrame_;
/**
* Cancel all outstanding queries and remove the frame.
*/
close(): void;
/**
* Actually start the long-polling session by adding the first script tag(s) to the iframe.
* @param id - The ID of this connection
* @param pw - The password for this connection
*/
startLongPoll(id: string, pw: string): void;
/**
* This is called any time someone might want a script tag to be added. It adds a script tag when there aren't
* too many outstanding requests and we are still alive.
*
* If there are outstanding packet segments to send, it sends one. If there aren't, it sends a long-poll anyways if
* needed.
*/
private newRequest_;
/**
* Queue a packet for transmission to the server.
* @param segnum - A sequential id for this packet segment used for reassembly
* @param totalsegs - The total number of segments in this packet
* @param data - The data for this segment.
*/
enqueueSegment(segnum: number, totalsegs: number, data: unknown): void;
/**
* Add a script tag for a regular long-poll request.
* @param url - The URL of the script tag.
* @param serial - The serial number of the request.
*/
private addLongPollTag_;
/**
* Add an arbitrary script tag to the iframe.
* @param url - The URL for the script tag source.
* @param loadCB - A callback to be triggered once the script has loaded.
*/
addTag(url: string, loadCB: () => void): void;
}

View File

@@ -0,0 +1,102 @@
/**
* @license
* Copyright 2017 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { RepoInfo } from '../core/RepoInfo';
/**
* Creates a new real-time connection to the server using whichever method works
* best in the current browser.
*/
export declare class Connection {
id: string;
private repoInfo_;
private applicationId_;
private appCheckToken_;
private authToken_;
private onMessage_;
private onReady_;
private onDisconnect_;
private onKill_;
lastSessionId?: string;
connectionCount: number;
pendingDataMessages: unknown[];
sessionId: string;
private conn_;
private healthyTimeout_;
private isHealthy_;
private log_;
private primaryResponsesRequired_;
private rx_;
private secondaryConn_;
private secondaryResponsesRequired_;
private state_;
private transportManager_;
private tx_;
/**
* @param id - an id for this connection
* @param repoInfo_ - the info for the endpoint to connect to
* @param applicationId_ - the Firebase App ID for this project
* @param appCheckToken_ - The App Check Token for this device.
* @param authToken_ - The auth token for this session.
* @param onMessage_ - the callback to be triggered when a server-push message arrives
* @param onReady_ - the callback to be triggered when this connection is ready to send messages.
* @param onDisconnect_ - the callback to be triggered when a connection was lost
* @param onKill_ - the callback to be triggered when this connection has permanently shut down.
* @param lastSessionId - last session id in persistent connection. is used to clean up old session in real-time server
*/
constructor(id: string, repoInfo_: RepoInfo, applicationId_: string | undefined, appCheckToken_: string | undefined, authToken_: string | undefined, onMessage_: (a: {}) => void, onReady_: (a: number, b: string) => void, onDisconnect_: () => void, onKill_: (a: string) => void, lastSessionId?: string);
/**
* Starts a connection attempt
*/
private start_;
private nextTransportId_;
private disconnReceiver_;
private connReceiver_;
/**
* @param dataMsg - An arbitrary data message to be sent to the server
*/
sendRequest(dataMsg: object): void;
tryCleanupConnection(): void;
private onSecondaryControl_;
private onSecondaryMessageReceived_;
private upgradeIfSecondaryHealthy_;
private proceedWithUpgrade_;
private onPrimaryMessageReceived_;
private onDataMessage_;
private onPrimaryResponse_;
private onControl_;
/**
* @param handshake - The handshake data returned from the server
*/
private onHandshake_;
private tryStartUpgrade_;
private startUpgrade_;
private onReset_;
private onConnectionEstablished_;
private sendPingOnPrimaryIfNecessary_;
private onSecondaryConnectionLost_;
/**
* @param everConnected - Whether or not the connection ever reached a server. Used to determine if
* we should flush the host cache
*/
private onConnectionLost_;
private onConnectionShutdown_;
private sendData_;
/**
* Cleans up this connection, calling the appropriate callbacks
*/
close(): void;
private closeConnections_;
}

View File

@@ -0,0 +1,27 @@
/**
* @license
* Copyright 2017 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export declare const PROTOCOL_VERSION = "5";
export declare const VERSION_PARAM = "v";
export declare const TRANSPORT_SESSION_PARAM = "s";
export declare const REFERER_PARAM = "r";
export declare const FORGE_REF = "f";
export declare const FORGE_DOMAIN_RE: RegExp;
export declare const LAST_SESSION_PARAM = "ls";
export declare const APPLICATION_ID_PARAM = "p";
export declare const APP_CHECK_TOKEN_PARAM = "ac";
export declare const WEBSOCKET = "websocket";
export declare const LONG_POLLING = "long_polling";

View File

@@ -0,0 +1,58 @@
/**
* @license
* Copyright 2017 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { RepoInfo } from '../core/RepoInfo';
export interface TransportConstructor {
new (connId: string, repoInfo: RepoInfo, applicationId?: string, appCheckToken?: string, authToken?: string, transportSessionId?: string, lastSessionId?: string): Transport;
isAvailable: () => boolean;
responsesRequiredToBeHealthy?: number;
healthyTimeout?: number;
}
export declare abstract class Transport {
/**
* Bytes received since connection started.
*/
abstract bytesReceived: number;
/**
* Bytes sent since connection started.
*/
abstract bytesSent: number;
/**
* An identifier for this connection, used for logging
*/
abstract connId: string;
/**
* @param connId - An identifier for this connection, used for logging
* @param repoInfo - The info for the endpoint to send data to.
* @param transportSessionId - Optional transportSessionId if this is connecting to an existing transport session
* @param lastSessionId - Optional lastSessionId if there was a previous connection
* @interface
*/
constructor(connId: string, repoInfo: RepoInfo, transportSessionId?: string, lastSessionId?: string);
/**
* @param onMessage - Callback when messages arrive
* @param onDisconnect - Callback with connection lost.
*/
abstract open(onMessage: (a: {}) => void, onDisconnect: (a?: boolean) => void): void;
abstract start(): void;
abstract close(): void;
/**
* @param data - The JSON data to transmit
*/
abstract send(data: {}): void;
abstract markConnectionHealthy(): void;
abstract markConnectionHealthy(): void;
}

View File

@@ -0,0 +1,50 @@
/**
* @license
* Copyright 2017 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { RepoInfo } from '../core/RepoInfo';
import { BrowserPollConnection } from './BrowserPollConnection';
import { TransportConstructor } from './Transport';
import { WebSocketConnection } from './WebSocketConnection';
/**
* Currently simplistic, this class manages what transport a Connection should use at various stages of its
* lifecycle.
*
* It starts with longpolling in a browser, and httppolling on node. It then upgrades to websockets if
* they are available.
*/
export declare class TransportManager {
private transports_;
static globalTransportInitialized_: boolean;
static get ALL_TRANSPORTS(): (typeof BrowserPollConnection | typeof WebSocketConnection)[];
/**
* Returns whether transport has been selected to ensure WebSocketConnection or BrowserPollConnection are not called after
* TransportManager has already set up transports_
*/
static get IS_TRANSPORT_INITIALIZED(): boolean;
/**
* @param repoInfo - Metadata around the namespace we're connecting to
*/
constructor(repoInfo: RepoInfo);
private initTransports_;
/**
* @returns The constructor for the initial transport to use
*/
initialTransport(): TransportConstructor;
/**
* @returns The constructor for the next transport, or null
*/
upgradeTransport(): TransportConstructor | null;
}

View File

@@ -0,0 +1,127 @@
/**
* @license
* Copyright 2017 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { RepoInfo } from '../core/RepoInfo';
import { Transport } from './Transport';
export declare function setWebSocketImpl(impl: any): void;
/**
* Create a new websocket connection with the given callbacks.
*/
export declare class WebSocketConnection implements Transport {
connId: string;
private applicationId?;
private appCheckToken?;
private authToken?;
keepaliveTimer: number | null;
frames: string[] | null;
totalFrames: number;
bytesSent: number;
bytesReceived: number;
connURL: string;
onDisconnect: (a?: boolean) => void;
onMessage: (msg: {}) => void;
mySock: WebSocket | null;
private log_;
private stats_;
private everConnected_;
private isClosed_;
private nodeAdmin;
/**
* @param connId identifier for this transport
* @param repoInfo The info for the websocket endpoint.
* @param applicationId The Firebase App ID for this project.
* @param appCheckToken The App Check Token for this client.
* @param authToken The Auth Token for this client.
* @param transportSessionId Optional transportSessionId if this is connecting
* to an existing transport session
* @param lastSessionId Optional lastSessionId if there was a previous
* connection
*/
constructor(connId: string, repoInfo: RepoInfo, applicationId?: string, appCheckToken?: string, authToken?: string, transportSessionId?: string, lastSessionId?: string);
/**
* @param repoInfo - The info for the websocket endpoint.
* @param transportSessionId - Optional transportSessionId if this is connecting to an existing transport
* session
* @param lastSessionId - Optional lastSessionId if there was a previous connection
* @returns connection url
*/
private static connectionURL_;
/**
* @param onMessage - Callback when messages arrive
* @param onDisconnect - Callback with connection lost.
*/
open(onMessage: (msg: {}) => void, onDisconnect: (a?: boolean) => void): void;
/**
* No-op for websockets, we don't need to do anything once the connection is confirmed as open
*/
start(): void;
static forceDisallow_: boolean;
static forceDisallow(): void;
static isAvailable(): boolean;
/**
* Number of response before we consider the connection "healthy."
*/
static responsesRequiredToBeHealthy: number;
/**
* Time to wait for the connection te become healthy before giving up.
*/
static healthyTimeout: number;
/**
* Returns true if we previously failed to connect with this transport.
*/
static previouslyFailed(): boolean;
markConnectionHealthy(): void;
private appendFrame_;
/**
* @param frameCount - The number of frames we are expecting from the server
*/
private handleNewFrameCount_;
/**
* Attempts to parse a frame count out of some text. If it can't, assumes a value of 1
* @returns Any remaining data to be process, or null if there is none
*/
private extractFrameCount_;
/**
* Process a websocket frame that has arrived from the server.
* @param mess - The frame data
*/
handleIncomingFrame(mess: {
[k: string]: unknown;
}): void;
/**
* Send a message to the server
* @param data - The JSON object to transmit
*/
send(data: {}): void;
private shutdown_;
private onClosed_;
/**
* External-facing close handler.
* Close the websocket and kill the connection.
*/
close(): void;
/**
* Kill the current keepalive timer and start a new one, to ensure that it always fires N seconds after
* the last activity.
*/
resetKeepAlive(): void;
/**
* Send a string over the websocket.
*
* @param str - String to send.
*/
private sendString_;
}

View File

@@ -0,0 +1,38 @@
/**
* @license
* Copyright 2017 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* This class ensures the packets from the server arrive in order
* This class takes data from the server and ensures it gets passed into the callbacks in order.
*/
export declare class PacketReceiver {
private onMessage_;
pendingResponses: unknown[];
currentResponseNum: number;
closeAfterResponse: number;
onClose: (() => void) | null;
/**
* @param onMessage_
*/
constructor(onMessage_: (a: {}) => void);
closeAfter(responseNum: number, callback: () => void): void;
/**
* Each message from the server comes with a response number, and an array of data. The responseNumber
* allows us to ensure that we process them in the right order, since we can't be guaranteed that all
* browsers will respond in the same order as the requests we sent
*/
handleResponse(requestNum: number, data: unknown[]): void;
}