Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: pong response & chunked upload #118

Merged
merged 12 commits into from
Jan 29, 2025
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Copyright (c) 2024 Appwrite (https://appwrite.io) and individual contributors.
Copyright (c) 2025 Appwrite (https://appwrite.io) and individual contributors.
All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Appwrite Web SDK

![License](https://img.shields.io/github/license/appwrite/sdk-for-web.svg?style=flat-square)
![Version](https://img.shields.io/badge/api%20version-1.6.0-blue.svg?style=flat-square)
![Version](https://img.shields.io/badge/api%20version-1.6.1-blue.svg?style=flat-square)
[![Build Status](https://img.shields.io/travis/com/appwrite/sdk-generator?style=flat-square)](https://travis-ci.com/appwrite/sdk-generator)
[![Twitter Account](https://img.shields.io/twitter/follow/appwrite?color=00acee&label=twitter&style=flat-square)](https://twitter.com/appwrite)
[![Discord](https://img.shields.io/discord/564160730845151244?label=discord&style=flat-square)](https://appwrite.io/discord)
Expand Down Expand Up @@ -33,7 +33,7 @@ import { Client, Account } from "appwrite";
To install with a CDN (content delivery network) add the following scripts to the bottom of your <body> tag, but before you use any Appwrite services:

```html
<script src="https://cdn.jsdelivr.net/npm/appwrite@16.0.2"></script>
<script src="https://cdn.jsdelivr.net/npm/appwrite@16.1.1"></script>
```


Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "appwrite",
"homepage": "https://appwrite.io/support",
"description": "Appwrite is an open-source self-hosted backend server that abstract and simplify complex and repetitive development tasks behind a very simple REST API",
"version": "16.0.2",
"version": "16.1.1",
"license": "BSD-3-Clause",
"main": "dist/cjs/sdk.js",
"exports": {
Expand Down
43 changes: 37 additions & 6 deletions src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@ type Headers = {
*/
type RealtimeResponse = {
/**
* Type of the response: 'error', 'event', 'connected', or 'response'.
* Type of the response: 'error', 'event', 'connected', 'response' or 'pong'.
*/
type: 'error' | 'event' | 'connected' | 'response';
type: 'error' | 'event' | 'connected' | 'response' | 'pong';

/**
* Data associated with the response based on the response type.
*/
data: RealtimeResponseAuthenticated | RealtimeResponseConnected | RealtimeResponseError | RealtimeResponseEvent<unknown>;
data: RealtimeResponseAuthenticated | RealtimeResponseConnected | RealtimeResponseError | RealtimeResponseEvent<unknown> | undefined;
}

/**
Expand Down Expand Up @@ -129,6 +129,8 @@ type RealtimeRequestAuthenticate = {
session: string;
}

type TimeoutHandle = ReturnType<typeof setTimeout> | number;

/**
* Realtime interface representing the structure of a realtime communication object.
*/
Expand All @@ -139,9 +141,14 @@ type Realtime = {
socket?: WebSocket;

/**
* Timeout duration for communication operations.
* Timeout for reconnect operations.
*/
timeout?: number;
timeout?: TimeoutHandle;

/**
* Heartbeat interval for the realtime connection.
*/
heartbeat?: TimeoutHandle;

/**
* URL for establishing the WebSocket connection.
Expand Down Expand Up @@ -196,6 +203,11 @@ type Realtime = {
*/
createSocket: () => void;

/**
* Function to create a new heartbeat interval.
*/
createHeartbeat: () => void;

/**
* Function to clean up resources associated with specified channels.
*
Expand Down Expand Up @@ -303,7 +315,7 @@ class Client {
'x-sdk-name': 'Web',
'x-sdk-platform': 'client',
'x-sdk-language': 'web',
'x-sdk-version': '16.0.2',
'x-sdk-version': '16.1.1',
'X-Appwrite-Response-Format': '1.6.0',
};

Expand Down Expand Up @@ -394,6 +406,7 @@ class Client {
private realtime: Realtime = {
socket: undefined,
timeout: undefined,
heartbeat: undefined,
url: '',
channels: new Set(),
subscriptions: new Map(),
Expand All @@ -419,6 +432,17 @@ class Client {
return 60_000;
}
},
createHeartbeat: () => {
if (this.realtime.heartbeat) {
clearTimeout(this.realtime.heartbeat);
}

this.realtime.heartbeat = window?.setInterval(() => {
this.realtime.socket?.send(JSON.stringify({
type: 'ping'
}));
}, 20_000);
},
createSocket: () => {
if (this.realtime.channels.size < 1) {
this.realtime.reconnect = false;
Expand Down Expand Up @@ -452,6 +476,7 @@ class Client {
this.realtime.socket.addEventListener('message', this.realtime.onMessage);
this.realtime.socket.addEventListener('open', _event => {
this.realtime.reconnectAttempts = 0;
this.realtime.createHeartbeat();
});
this.realtime.socket.addEventListener('close', event => {
if (
Expand Down Expand Up @@ -506,6 +531,8 @@ class Client {
})
}
break;
case 'pong':
break; // Handle pong response if needed
case 'error':
throw message.data;
default:
Expand Down Expand Up @@ -669,6 +696,10 @@ class Client {
return response;
}

async ping(): Promise<string> {
return this.call('GET', new URL(this.config.endpoint + '/ping'));
}

async call(method: string, url: URL, headers: Headers = {}, params: Payload = {}, responseType = 'json'): Promise<any> {
const { uri, options } = this.prepareRequest(method, url, headers, params);

Expand Down
2 changes: 2 additions & 0 deletions src/enums/image-format.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,6 @@ export enum ImageFormat {
Gif = 'gif',
Png = 'png',
Webp = 'webp',
Heic = 'heic',
Avif = 'avif',
}
10 changes: 7 additions & 3 deletions src/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -842,11 +842,11 @@ export namespace Models {
*/
userId: string;
/**
* User name.
* User name. Hide this attribute by toggling membership privacy in the Console.
*/
userName: string;
/**
* User email address.
* User email address. Hide this attribute by toggling membership privacy in the Console.
*/
userEmail: string;
/**
Expand All @@ -870,7 +870,7 @@ export namespace Models {
*/
confirm: boolean;
/**
* Multi factor authentication status, true if the user has MFA enabled or false otherwise.
* Multi factor authentication status, true if the user has MFA enabled or false otherwise. Hide this attribute by toggling membership privacy in the Console.
*/
mfa: boolean;
/**
Expand Down Expand Up @@ -1198,5 +1198,9 @@ export namespace Models {
* The target identifier.
*/
identifier: string;
/**
* Is the target expired.
*/
expired: boolean;
}
}
29 changes: 16 additions & 13 deletions src/services/account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ This endpoint can also be used to convert an anonymous account to a normal one,
);
}
/**
* List Identities
* List identities
*
* Get the list of identities for the currently logged in user.
*
Expand Down Expand Up @@ -273,7 +273,7 @@ This endpoint can also be used to convert an anonymous account to a normal one,
);
}
/**
* Create Authenticator
* Create authenticator
*
* Add an authenticator app to be used as an MFA factor. Verify the authenticator using the [verify authenticator](/docs/references/cloud/client-web/account#updateMfaAuthenticator) method.
*
Expand Down Expand Up @@ -302,7 +302,7 @@ This endpoint can also be used to convert an anonymous account to a normal one,
);
}
/**
* Verify Authenticator
* Verify authenticator
*
* Verify an authenticator app after adding it using the [add authenticator](/docs/references/cloud/client-web/account#createMfaAuthenticator) method.
*
Expand Down Expand Up @@ -338,7 +338,7 @@ This endpoint can also be used to convert an anonymous account to a normal one,
);
}
/**
* Delete Authenticator
* Delete authenticator
*
* Delete an authenticator for a user by ID.
*
Expand Down Expand Up @@ -367,7 +367,7 @@ This endpoint can also be used to convert an anonymous account to a normal one,
);
}
/**
* Create MFA Challenge
* Create MFA challenge
*
* Begin the process of MFA verification after sign-in. Finish the flow with [updateMfaChallenge](/docs/references/cloud/client-web/account#updateMfaChallenge) method.
*
Expand Down Expand Up @@ -399,16 +399,16 @@ This endpoint can also be used to convert an anonymous account to a normal one,
);
}
/**
* Create MFA Challenge (confirmation)
* Create MFA challenge (confirmation)
*
* Complete the MFA challenge by providing the one-time password. Finish the process of MFA verification by providing the one-time password. To begin the flow, use [createMfaChallenge](/docs/references/cloud/client-web/account#createMfaChallenge) method.
*
* @param {string} challengeId
* @param {string} otp
* @throws {AppwriteException}
* @returns {Promise<{}>}
* @returns {Promise<Models.Session>}
*/
async updateMfaChallenge(challengeId: string, otp: string): Promise<{}> {
async updateMfaChallenge(challengeId: string, otp: string): Promise<Models.Session> {
if (typeof challengeId === 'undefined') {
throw new AppwriteException('Missing required parameter: "challengeId"');
}
Expand Down Expand Up @@ -438,7 +438,7 @@ This endpoint can also be used to convert an anonymous account to a normal one,
);
}
/**
* List Factors
* List factors
*
* List the factors available on the account to be used as a MFA challange.
*
Expand All @@ -463,7 +463,7 @@ This endpoint can also be used to convert an anonymous account to a normal one,
);
}
/**
* Get MFA Recovery Codes
* Get MFA recovery codes
*
* Get recovery codes that can be used as backup for MFA flow. Before getting codes, they must be generated using [createMfaRecoveryCodes](/docs/references/cloud/client-web/account#createMfaRecoveryCodes) method. An OTP challenge is required to read recovery codes.
*
Expand All @@ -488,7 +488,7 @@ This endpoint can also be used to convert an anonymous account to a normal one,
);
}
/**
* Create MFA Recovery Codes
* Create MFA recovery codes
*
* Generate recovery codes as backup for MFA flow. It&#039;s recommended to generate and show then immediately after user successfully adds their authehticator. Recovery codes can be used as a MFA verification type in [createMfaChallenge](/docs/references/cloud/client-web/account#createMfaChallenge) method.
*
Expand All @@ -513,7 +513,7 @@ This endpoint can also be used to convert an anonymous account to a normal one,
);
}
/**
* Regenerate MFA Recovery Codes
* Regenerate MFA recovery codes
*
* Regenerate recovery codes that can be used as backup for MFA flow. Before regenerating codes, they must be first generated using [createMfaRecoveryCodes](/docs/references/cloud/client-web/account#createMfaRecoveryCodes) method. An OTP challenge is required to regenreate recovery codes.
*
Expand Down Expand Up @@ -1186,6 +1186,7 @@ A user is limited to 10 active sessions at a time by default. [Learn more about
/**
* Create push target
*
* Use this endpoint to register a device for push notifications. Provide a target ID (custom or generated using ID.unique()), a device identifier (usually a device token), and optionally specify which provider should send notifications to this target. The target is automatically linked to the current session and includes device information like brand and model.
*
* @param {string} targetId
* @param {string} identifier
Expand Down Expand Up @@ -1228,6 +1229,7 @@ A user is limited to 10 active sessions at a time by default. [Learn more about
/**
* Update push target
*
* Update the currently logged in user&#039;s push notification target. You can modify the target&#039;s identifier (device token) and provider ID (token, email, phone etc.). The target must exist and belong to the current user. If you change the provider ID, notifications will be sent through the new messaging provider instead.
*
* @param {string} targetId
* @param {string} identifier
Expand Down Expand Up @@ -1263,6 +1265,7 @@ A user is limited to 10 active sessions at a time by default. [Learn more about
/**
* Delete push target
*
* Delete a push notification target for the currently logged in user. After deletion, the device will no longer receive push notifications. The target must exist and belong to the current user.
*
* @param {string} targetId
* @throws {AppwriteException}
Expand Down Expand Up @@ -1336,7 +1339,7 @@ A user is limited to 10 active sessions at a time by default. [Learn more about
/**
* Create magic URL token
*
* Sends the user an email with a secret key for creating a session. If the provided user ID has not been registered, a new user will be created. When the user clicks the link in the email, the user is redirected back to the URL you provided with the secret key and userId values attached to the URL query string. Use the query string parameters to submit a request to the [POST /v1/account/sessions/token](https://appwrite.io/docs/references/cloud/client-web/account#createSession) endpoint to complete the login process. The link sent to the user&#039;s email address is valid for 1 hour. If you are on a mobile device you can leave the URL parameter empty, so that the login completion will be handled by your Appwrite instance by default.
* Sends the user an email with a secret key for creating a session. If the provided user ID has not been registered, a new user will be created. When the user clicks the link in the email, the user is redirected back to the URL you provided with the secret key and userId values attached to the URL query string. Use the query string parameters to submit a request to the [POST /v1/account/sessions/token](https://appwrite.io/docs/references/cloud/client-web/account#createSession) endpoint to complete the login process. The link sent to the user&#039;s email address is valid for 1 hour.

A user is limited to 10 active sessions at a time by default. [Learn more about session limits](https://appwrite.io/docs/authentication-security#limits).

Expand Down
Loading