Skip to content

Commit ca3344c

Browse files
committed
feat: realtime heartbeat
1 parent 9423ee9 commit ca3344c

File tree

18 files changed

+539
-594
lines changed

18 files changed

+539
-594
lines changed

docs/examples/functions/create-execution.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ const functions = new Functions(client);
88

99
const result = await functions.createExecution(
1010
'<FUNCTION_ID>', // functionId
11-
Payload.fromJson({ x: "y" }), // body (optional)
11+
'<BODY>', // body (optional)
1212
false, // async (optional)
1313
'<PATH>', // path (optional)
1414
ExecutionMethod.GET, // method (optional)

docs/examples/storage/create-file.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ const storage = new Storage(client);
99
const result = await storage.createFile(
1010
'<BUCKET_ID>', // bucketId
1111
'<FILE_ID>', // fileId
12-
Payload.fromFile(document.getElementById('uploader').files[0]), // file
12+
document.getElementById('uploader').files[0], // file
1313
["read("any")"] // permissions (optional)
1414
);
1515

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
},
2727
"devDependencies": {
2828
"@rollup/plugin-typescript": "8.3.2",
29+
"playwright": "1.15.0",
2930
"rollup": "2.75.4",
3031
"serve-handler": "6.1.0",
3132
"tslib": "2.4.0",

src/client.ts

Lines changed: 32 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
import { Models } from './models';
2-
import { Payload } from './payload';
3-
import { MultipartParser } from './multipart';
42

53
/**
64
* Payload type representing a key-value pair with string keys and any values.
75
*/
8-
type Params = {
6+
type Payload = {
97
[key: string]: any;
108
}
119

@@ -576,7 +574,7 @@ class Client {
576574
}
577575
}
578576

579-
async prepareRequest(method: string, url: URL, headers: Headers = {}, params: Params = {}): Promise<{ uri: string, options: RequestInit }> {
577+
prepareRequest(method: string, url: URL, headers: Headers = {}, params: Payload = {}): { uri: string, options: RequestInit } {
580578
method = method.toUpperCase();
581579

582580
headers = Object.assign({}, this.headers, headers);
@@ -607,63 +605,56 @@ class Client {
607605
case 'multipart/form-data':
608606
const formData = new FormData();
609607

610-
for (const [name, value] of Object.entries(params)) {
611-
if (value instanceof Payload) {
612-
if (value.filename) {
613-
formData.append(name, await value.toFile(), value.filename);
614-
} else {
615-
formData.append(name, await value.toString());
616-
}
608+
for (const [key, value] of Object.entries(params)) {
609+
if (value instanceof File) {
610+
formData.append(key, value, value.name);
617611
} else if (Array.isArray(value)) {
618612
for (const nestedValue of value) {
619-
formData.append(`${name}[]`, nestedValue);
613+
formData.append(`${key}[]`, nestedValue);
620614
}
621615
} else {
622-
formData.append(name, value);
616+
formData.append(key, value);
623617
}
624618
}
625-
619+
626620
options.body = formData;
627621
delete headers['content-type'];
628-
headers['accept'] = 'multipart/form-data';
629622
break;
630623
}
631624
}
632625

633626
return { uri: url.toString(), options };
634627
}
635628

636-
async chunkedUpload(method: string, url: URL, headers: Headers = {}, params: Params = {}, onProgress: (progress: UploadProgress) => void) {
637-
const entry = Object.entries(params).find(([_key, value]) => value instanceof Payload);
638-
if (!entry) {
639-
throw new Error('No payload found in params');
640-
}
629+
async chunkedUpload(method: string, url: URL, headers: Headers = {}, originalPayload: Payload = {}, onProgress: (progress: UploadProgress) => void) {
630+
const file = Object.values(originalPayload).find((value) => value instanceof File);
641631

642-
const [paramName, payload] = entry as [string, Payload];
643-
644-
if (payload.size <= Client.CHUNK_SIZE) {
645-
return await this.call(method, url, headers, params);
632+
if (file.size <= Client.CHUNK_SIZE) {
633+
return await this.call(method, url, headers, originalPayload);
646634
}
647635

648636
let start = 0;
649637
let response = null;
650638

651-
while (start < payload.size) {
652-
const end = Math.min(start + Client.CHUNK_SIZE, payload.size);
639+
while (start < file.size) {
640+
let end = start + Client.CHUNK_SIZE; // Prepare end for the next chunk
641+
if (end >= file.size) {
642+
end = file.size; // Adjust for the last chunk to include the last byte
643+
}
653644

654-
headers['content-range'] = `bytes ${start}-${end-1}/${payload.size}`;
645+
headers['content-range'] = `bytes ${start}-${end-1}/${file.size}`;
646+
const chunk = file.slice(start, end);
655647

656-
const buffer = await payload.toBinary(start, end - start);
657-
params[paramName] = Payload.fromBinary(buffer, payload.filename);
648+
let payload = { ...originalPayload, file: new File([chunk], file.name)};
658649

659-
response = await this.call(method, url, headers, params);
650+
response = await this.call(method, url, headers, payload);
660651

661652
if (onProgress && typeof onProgress === 'function') {
662653
onProgress({
663654
$id: response.$id,
664-
progress: Math.round((end / payload.size) * 100),
655+
progress: Math.round((end / file.size) * 100),
665656
sizeUploaded: end,
666-
chunksTotal: Math.ceil(payload.size / Client.CHUNK_SIZE),
657+
chunksTotal: Math.ceil(file.size / Client.CHUNK_SIZE),
667658
chunksUploaded: Math.ceil(end / Client.CHUNK_SIZE)
668659
});
669660
}
@@ -678,8 +669,12 @@ class Client {
678669
return response;
679670
}
680671

681-
async call(method: string, url: URL, headers: Headers = {}, params: Params = {}, responseType = 'json'): Promise<any> {
682-
const { uri, options } = await this.prepareRequest(method, url, headers, params);
672+
async ping(): Promise<string> {
673+
return this.call('GET', new URL(this.config.endpoint + '/ping'));
674+
}
675+
676+
async call(method: string, url: URL, headers: Headers = {}, params: Payload = {}, responseType = 'json'): Promise<any> {
677+
const { uri, options } = this.prepareRequest(method, url, headers, params);
683678

684679
let data: any = null;
685680

@@ -692,12 +687,6 @@ class Client {
692687

693688
if (response.headers.get('content-type')?.includes('application/json')) {
694689
data = await response.json();
695-
696-
} else if (response.headers.get('content-type')?.includes('multipart/form-data')) {
697-
const buffer = await response.arrayBuffer();
698-
const multipart = new MultipartParser(buffer, response.headers.get('content-type')!);
699-
data = multipart.toObject();
700-
701690
} else if (responseType === 'arrayBuffer') {
702691
data = await response.arrayBuffer();
703692
} else {
@@ -720,8 +709,8 @@ class Client {
720709
return data;
721710
}
722711

723-
static flatten(data: Params, prefix = ''): Params {
724-
let output: Params = {};
712+
static flatten(data: Payload, prefix = ''): Payload {
713+
let output: Payload = {};
725714

726715
for (const [key, value] of Object.entries(data)) {
727716
let finalKey = prefix ? prefix + '[' + key +']' : key;
@@ -738,6 +727,6 @@ class Client {
738727

739728
export { Client, AppwriteException };
740729
export { Query } from './query';
741-
export type { Models, Params, UploadProgress };
730+
export type { Models, Payload, UploadProgress };
742731
export type { RealtimeResponseEvent };
743732
export type { QueryTypes, QueryTypesList } from './query';

src/index.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,8 @@ export { Locale } from './services/locale';
1515
export { Messaging } from './services/messaging';
1616
export { Storage } from './services/storage';
1717
export { Teams } from './services/teams';
18-
export type { Models, RealtimeResponseEvent, UploadProgress } from './client';
18+
export type { Models, Payload, RealtimeResponseEvent, UploadProgress } from './client';
1919
export type { QueryTypes, QueryTypesList } from './query';
20-
export { Payload } from './payload';
2120
export { Permission } from './permission';
2221
export { Role } from './role';
2322
export { ID } from './id';

src/models.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import type { Payload } from './payload';
2-
31
/**
42
* Appwrite Models
53
*/
@@ -931,7 +929,7 @@ export namespace Models {
931929
/**
932930
* HTTP response body. This will return empty unless execution is created as synchronous.
933931
*/
934-
responseBody: Payload;
932+
responseBody: string;
935933
/**
936934
* HTTP response headers as a key-value object. This will return only whitelisted headers. All headers are returned if execution is created as synchronous.
937935
*/

src/multipart.ts

Lines changed: 0 additions & 119 deletions
This file was deleted.

src/payload.ts

Lines changed: 0 additions & 48 deletions
This file was deleted.

0 commit comments

Comments
 (0)