Skip to content

fix: pong response & chunked upload #42

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

Merged
merged 10 commits into from
Jan 29, 2025
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Appwrite React Native SDK

![License](https://img.shields.io/github/license/appwrite/sdk-for-react-native.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
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": "react-native-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": "0.5.0",
"version": "0.7.0",
"license": "BSD-3-Clause",
"main": "dist/cjs/sdk.js",
"exports": {
Expand Down
32 changes: 29 additions & 3 deletions src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ type Headers = {
}

type RealtimeResponse = {
type: 'error' | 'event' | 'connected' | 'response';
data: RealtimeResponseAuthenticated | RealtimeResponseConnected | RealtimeResponseError | RealtimeResponseEvent<unknown>;
type: 'error' | 'event' | 'connected' | 'response' | 'pong';
data: RealtimeResponseAuthenticated | RealtimeResponseConnected | RealtimeResponseError | RealtimeResponseEvent<unknown> | undefined;
}

type RealtimeRequest = {
Expand Down Expand Up @@ -49,7 +49,17 @@ type RealtimeRequestAuthenticate = {

type Realtime = {
socket?: WebSocket;

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

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

url?: string;
lastMessage?: RealtimeResponse;
channels: Set<string>;
Expand All @@ -63,6 +73,7 @@ type Realtime = {
getTimeout: () => number;
connect: () => void;
createSocket: () => void;
createHeartbeat: () => void;
cleanUp: (channels: string[]) => void;
onMessage: (event: MessageEvent) => void;
}
Expand Down Expand Up @@ -103,7 +114,7 @@ class Client {
'x-sdk-name': 'React Native',
'x-sdk-platform': 'client',
'x-sdk-language': 'reactnative',
'x-sdk-version': '0.5.0',
'x-sdk-version': '0.7.0',
'X-Appwrite-Response-Format': '1.6.0',
};

Expand Down Expand Up @@ -212,6 +223,7 @@ class Client {
private realtime: Realtime = {
socket: undefined,
timeout: undefined,
heartbeat: undefined,
url: '',
channels: new Set(),
subscriptions: new Map(),
Expand All @@ -237,6 +249,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 @@ -275,6 +298,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 @@ -315,6 +339,8 @@ class Client {
})
}
break;
case 'pong':
break; // Handle pong response if needed
case 'error':
throw message.data;
default:
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 @@ -839,11 +839,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 @@ -867,7 +867,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 @@ -1195,5 +1195,9 @@ export namespace Models {
* The target identifier.
*/
identifier: string;
/**
* Is the target expired.
*/
expired: boolean;
}
}
39 changes: 25 additions & 14 deletions src/services/account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ export class Account extends Service {
}

/**
* List Identities
* List identities
*
* Get the list of identities for the currently logged in user.
*
Expand Down Expand Up @@ -253,7 +253,7 @@ export class Account extends Service {
}

/**
* Create Authenticator
* Create authenticator
*
* Add an authenticator app to be used as an MFA factor. Verify the
* authenticator using the [verify
Expand All @@ -279,7 +279,7 @@ export class Account extends Service {
}

/**
* Verify Authenticator
* Verify authenticator
*
* Verify an authenticator app after adding it using the [add
* authenticator](/docs/references/cloud/client-web/account#createMfaAuthenticator)
Expand Down Expand Up @@ -313,7 +313,7 @@ export class Account extends Service {
}

/**
* Delete Authenticator
* Delete authenticator
*
* Delete an authenticator for a user by ID.
*
Expand All @@ -336,7 +336,7 @@ export class Account extends Service {
}

/**
* 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)
Expand Down Expand Up @@ -365,7 +365,7 @@ export class Account extends Service {
}

/**
* 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
Expand All @@ -378,7 +378,7 @@ export class Account extends Service {
* @throws {AppwriteException}
* @returns {Promise}
*/
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 All @@ -405,7 +405,7 @@ export class Account extends Service {
}

/**
* List Factors
* List factors
*
* List the factors available on the account to be used as a MFA challange.
*
Expand All @@ -423,7 +423,7 @@ export class Account extends Service {
}

/**
* 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
Expand All @@ -444,7 +444,7 @@ export class Account extends Service {
}

/**
* Create MFA Recovery Codes
* Create MFA recovery codes
*
* Generate recovery codes as backup for MFA flow. It's recommended to
* generate and show then immediately after user successfully adds their
Expand All @@ -466,7 +466,7 @@ export class Account extends Service {
}

/**
* 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
Expand Down Expand Up @@ -1104,6 +1104,11 @@ export class Account extends Service {
/**
* 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 @@ -1144,6 +1149,11 @@ export class Account extends Service {
/**
* Update push target
*
* Update the currently logged in user's push notification target. You can
* modify the target'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 @@ -1175,6 +1185,9 @@ export class Account extends Service {
/**
* 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 @@ -1255,9 +1268,7 @@ export class Account extends Service {
* [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'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.
* address is valid for 1 hour.
*
* A user is limited to 10 active sessions at a time by default. [Learn more
* about session
Expand Down
2 changes: 1 addition & 1 deletion src/services/locale.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export class Locale extends Service {
}

/**
* List Locale Codes
* List locale codes
*
* List of all locale codes in [ISO
* 639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes).
Expand Down
12 changes: 5 additions & 7 deletions src/services/storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,12 +122,10 @@ export class Storage extends Service {

let offset = 0;
let response = undefined;
if(fileId != 'unique()') {
try {
response = await this.client.call('GET', new URL(this.client.config.endpoint + apiPath + '/' + fileId), apiHeaders);
offset = response.chunksUploaded * Service.CHUNK_SIZE;
} catch(e) {
}
try {
response = await this.client.call('GET', new URL(this.client.config.endpoint + apiPath + '/' + fileId), apiHeaders);
offset = response.chunksUploaded * Service.CHUNK_SIZE;
} catch(e) {
}

let timestamp = new Date().getTime();
Expand Down Expand Up @@ -237,7 +235,7 @@ export class Storage extends Service {
}

/**
* Delete File
* Delete file
*
* Delete a file by its unique ID. Only users with write permissions have
* access to delete this resource.
Expand Down
6 changes: 4 additions & 2 deletions src/services/teams.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,8 @@ export class Teams extends Service {
* List team memberships
*
* Use this endpoint to list a team's members using the team's ID. All team
* members have read access to this endpoint.
* members have read access to this endpoint. Hide sensitive attributes from
* the response by toggling membership privacy in the Console.
*
* @param {string} teamId
* @param {string[]} queries
Expand Down Expand Up @@ -279,7 +280,8 @@ export class Teams extends Service {
* Get team membership
*
* Get a team member by the membership unique id. All team members have read
* access for this resource.
* access for this resource. Hide sensitive attributes from the response by
* toggling membership privacy in the Console.
*
* @param {string} teamId
* @param {string} membershipId
Expand Down