Skip to content

Commit 8038b49

Browse files
committed
add back getPubSub to database
1 parent 4e601b3 commit 8038b49

File tree

10 files changed

+146
-80
lines changed

10 files changed

+146
-80
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@sqlitecloud/drivers",
3-
"version": "1.0.359",
3+
"version": "1.0.360",
44
"description": "SQLiteCloud drivers for Typescript/Javascript in edge, web and node clients",
55
"main": "./lib/index.js",
66
"types": "./lib/index.d.ts",

src/drivers/database.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { ErrorCallback, ResultsCallback, RowCallback, RowsCallback } from './typ
1515
import EventEmitter from 'eventemitter3'
1616
import { isBrowser } from './utilities'
1717
import { Statement } from './statement'
18+
import { PubSub } from './pubsub'
1819

1920
// Uses eventemitter3 instead of node events for browser compatibility
2021
// https://github.com/primus/eventemitter3
@@ -478,4 +479,23 @@ export class Database extends EventEmitter {
478479
})
479480
})
480481
}
482+
/**
483+
* PubSub class provides a Pub/Sub real-time updates and notifications system to
484+
* allow multiple applications to communicate with each other asynchronously.
485+
* It allows applications to subscribe to tables and receive notifications whenever
486+
* data changes in the database table. It also enables sending messages to anyone
487+
* subscribed to a specific channel.
488+
* @returns {PubSub} A PubSub object
489+
*/
490+
public async getPubSub(): Promise<PubSub> {
491+
return new Promise((resolve, reject) => {
492+
this.getConnection((error, connection) => {
493+
if (error || !connection) {
494+
reject(error)
495+
} else {
496+
resolve(new PubSub(connection))
497+
}
498+
})
499+
})
500+
}
481501
}

src/packages/SQLiteCloudClient.ts

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,18 @@
11
import { Database } from '../drivers/database'
22
import { Fetch, fetchWithAuth } from './utils/fetch'
33
import { PubSubClient } from './pubsub/PubSubClient'
4-
import { WebliteClient } from './weblite/SQLiteCloudWebliteClient'
4+
import { WebliteClient } from './weblite/WebliteClient'
55
import { StorageClient } from './storage/StorageClient'
66
import { SQLiteCloudCommand, SQLiteCloudError } from '../drivers/types'
77
import { cleanConnectionString, getDefaultDatabase } from './utils'
8-
9-
interface SQLiteCloudClientConfig {
10-
connectionString: string
11-
fetch?: Fetch
12-
}
8+
import { FunctionsClient } from './_functions/FunctionsClient'
9+
import { SQLiteCloudClientConfig } from './types'
1310

1411
export class SQLiteCloudClient {
1512
protected connectionString: string
1613
protected fetch: Fetch
14+
protected globalHeaders: Record<string, string>
15+
protected _defaultDb: string
1716
protected _db: Database
1817

1918
constructor(config: SQLiteCloudClientConfig | string) {
@@ -23,25 +22,30 @@ export class SQLiteCloudClient {
2322
}
2423
let connectionString: string
2524
let customFetch: Fetch | undefined
25+
let globalHeaders: Record<string, string> = {}
2626

2727
if (typeof config === 'string') {
2828
connectionString = cleanConnectionString(config)
29+
globalHeaders = {}
2930
} else {
3031
connectionString = config.connectionString
31-
customFetch = config.fetch
32+
customFetch = config.global?.fetch
33+
globalHeaders = config.global?.headers ?? {}
3234
}
33-
35+
3436
this.connectionString = connectionString
3537
this.fetch = fetchWithAuth(this.connectionString, customFetch)
36-
this.defaultDb = getDefaultDatabase(this.connectionString) ?? ''
38+
this.globalHeaders = globalHeaders
39+
this._defaultDb = getDefaultDatabase(this.connectionString) ?? ''
3740
this._db = new Database(this.connectionString)
41+
3842
} catch (error) {
3943
throw new SQLiteCloudError('failed to initialize SQLiteCloudClient')
4044
}
4145
}
4246

4347
async sql(sql: TemplateStringsArray | string | SQLiteCloudCommand, ...values: any[]) {
44-
this.db.exec(`USE DATABASE ${this.defaultDb}`)
48+
this.db.exec(`USE DATABASE ${this._defaultDb}`)
4549
try {
4650
const result = await this.db.sql(sql, ...values)
4751
return { data: result, error: null }
@@ -59,20 +63,32 @@ export class SQLiteCloudClient {
5963
}
6064

6165
get weblite() {
62-
return new WebliteClient(this.connectionString, { customFetch: this.fetch })
66+
return new WebliteClient(this.connectionString, {
67+
customFetch: this.fetch,
68+
headers: this.globalHeaders
69+
})
6370
}
6471

6572
get files() {
66-
return new StorageClient(this.connectionString, { customFetch: this.fetch })
73+
return new StorageClient(this.connectionString, {
74+
customFetch: this.fetch,
75+
headers: this.globalHeaders
76+
})
6777
}
6878

6979
get functions() {
70-
// return new SQLiteCloudFunctionsClient(this.connectionString, this.fetch)
71-
return null
80+
return new FunctionsClient(this.connectionString, {
81+
customFetch: this.fetch,
82+
headers: this.globalHeaders
83+
})
7284
}
7385

7486
set defaultDb(dbName: string) {
75-
this.defaultDb = dbName
87+
this._defaultDb = dbName
88+
}
89+
90+
get defaultDb() {
91+
return this._defaultDb
7692
}
7793
}
7894

src/packages/functions/FunctionsClient.ts renamed to src/packages/_functions/FunctionsClient.ts

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -41,39 +41,38 @@ export class FunctionsClient {
4141
}
4242

4343
async invoke(functionId: string, options: FunctionInvokeOptions) {
44-
const { headers, args } = options
4544
let body;
4645
let _headers: Record<string, string> = {}
47-
if (args &&
48-
((headers && !Object.prototype.hasOwnProperty.call(headers, 'Content-Type')) || !headers)
46+
if (options.args &&
47+
((options.headers && !Object.prototype.hasOwnProperty.call(options.headers, 'Content-Type')) || !options.headers)
4948
) {
5049
if (
51-
(typeof Blob !== 'undefined' && args instanceof Blob) ||
52-
args instanceof ArrayBuffer
50+
(typeof Blob !== 'undefined' && options.args instanceof Blob) ||
51+
options.args instanceof ArrayBuffer
5352
) {
5453
// will work for File as File inherits Blob
5554
// also works for ArrayBuffer as it is the same underlying structure as a Blob
5655
_headers['Content-Type'] = 'application/octet-stream'
57-
body = args
58-
} else if (typeof args === 'string') {
56+
body = options.args
57+
} else if (typeof options.args === 'string') {
5958
// plain string
6059
_headers['Content-Type'] = 'text/plain'
61-
body = args
62-
} else if (typeof FormData !== 'undefined' && args instanceof FormData) {
60+
body = options.args
61+
} else if (typeof FormData !== 'undefined' && options.args instanceof FormData) {
6362
_headers['Content-Type'] = 'multipart/form-data'
64-
body = args
63+
body = options.args
6564
} else {
6665
// default, assume this is JSON
6766
_headers['Content-Type'] = 'application/json'
68-
body = JSON.stringify(args)
67+
body = JSON.stringify(options.args)
6968
}
7069
}
7170

7271
try {
7372
const response = await this.fetch(`${this.url}/${functionId}`, {
7473
method: 'POST',
75-
body: JSON.stringify(args),
76-
headers: { ..._headers, ...this.headers, ...headers }
74+
body: JSON.stringify(options.args),
75+
headers: { ..._headers, ...this.headers, ...options.headers }
7776
})
7877

7978
if (!response.ok) {
File renamed without changes.

src/packages/storage/StorageClient.ts

Lines changed: 2 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2,41 +2,9 @@ import { DEFAULT_HEADERS } from "../../drivers/constants"
22
import { SQLiteCloudError } from "../../drivers/types"
33
import { getAPIUrl } from "../utils"
44
import { Fetch, fetchWithAuth } from "../utils/fetch"
5+
import { Storage } from "../types"
56

67
// TODO: add consistent return types
7-
8-
9-
/**
10-
* StorageResponse
11-
* @param data - The data returned from the operation.
12-
* @param error - The error that occurred.
13-
*/
14-
interface StorageResponse {
15-
data: any
16-
error: any
17-
}
18-
19-
/**
20-
* Storage
21-
* @param createBucket - Create a bucket.
22-
* @param getBucket - Get a bucket.
23-
* @param deleteBucket - Delete a bucket.
24-
* @param listBuckets - List all buckets.
25-
* @param upload - Upload a file.
26-
* @param download - Download a file.
27-
* @param remove - Remove a file.
28-
* @param list - List all files in a bucket.
29-
*/
30-
interface Storage {
31-
createBucket(bucket: string): Promise<StorageResponse>
32-
getBucket(bucket: string): Promise<StorageResponse>
33-
deleteBucket(bucket: string): Promise<StorageResponse>
34-
listBuckets(): Promise<StorageResponse>
35-
upload(bucket: string, pathname: string, file: File | Buffer | Blob | string, options: { headers?: Record<string, string> }): Promise<StorageResponse>
36-
download(bucket: string, pathname: string): Promise<StorageResponse>
37-
remove(bucket: string, pathName: string): Promise<StorageResponse>
38-
list(bucket: string): Promise<StorageResponse>
39-
}
408
export class StorageClient implements Storage {
419
protected filesUrl: string
4210
protected webliteSQLUrl: string
@@ -187,7 +155,7 @@ export class StorageClient implements Storage {
187155
}
188156
}
189157

190-
async list(bucket: string) {
158+
async listBucketContents(bucket: string) {
191159
const sql = `USE DATABASE files.sqlite; SELECT * FROM files WHERE bucket = '${bucket}'`
192160
try {
193161
const response = await this.fetch(this.webliteSQLUrl, {

src/packages/test/storage.test.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { expect } from '@jest/globals'
2+
import { StorageClient } from '../storage/StorageClient'
3+
import { CHINOOK_DATABASE_URL } from '../../../test/shared'
4+
5+
6+
const storage = new StorageClient(CHINOOK_DATABASE_URL)
7+
8+
describe('StorageClient', () => {
9+
it('should be able to create a bucket', async () => {
10+
expect(storage).toBeDefined()
11+
12+
const bucket = await storage.createBucket('test-bucket')
13+
14+
expect(bucket).toBeDefined()
15+
})
16+
})
17+
18+

src/packages/test/utils.ts

Whitespace-only changes.

src/packages/types/index.d.ts

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import { Fetch } from '../utils/fetch'
2+
3+
4+
export interface SQLiteCloudClientConfig {
5+
connectionString: string
6+
global?: {
7+
fetch?: Fetch
8+
headers?: Record<string, string>
9+
}
10+
}
11+
12+
export interface WebliteResponse {
13+
data: any, // TODO: type this
14+
error: SQLiteCloudError | null
15+
}
16+
export interface Weblite {
17+
upload(dbName: string, file: File | Buffer | Blob | string, opts: UploadOptions): Promise<WebliteResponse>
18+
download(dbName: string): Promise<WebliteResponse>
19+
delete(dbName: string): Promise<WebliteResponse>
20+
listDatabases(): Promise<WebliteResponse>
21+
create(dbName: string): Promise<WebliteResponse>
22+
}
23+
24+
25+
/**
26+
* StorageResponse
27+
* @param data - The data returned from the operation.
28+
* @param error - The error that occurred.
29+
*/
30+
interface StorageResponse {
31+
data: any
32+
error: any
33+
}
34+
35+
/**
36+
* Storage
37+
* @param createBucket - Create a bucket.
38+
* @param getBucket - Get a bucket.
39+
* @param deleteBucket - Delete a bucket.
40+
* @param listBuckets - List all buckets.
41+
* @param upload - Upload a file.
42+
* @param download - Download a file.
43+
* @param remove - Remove a file.
44+
* @param list - List all files in a bucket.
45+
*/
46+
interface Storage {
47+
createBucket(bucket: string): Promise<StorageResponse>
48+
getBucket(bucket: string): Promise<StorageResponse>
49+
deleteBucket(bucket: string): Promise<StorageResponse>
50+
listBuckets(): Promise<StorageResponse>
51+
upload(bucket: string, pathname: string, file: File | Buffer | Blob | string, options: { headers?: Record<string, string> }): Promise<StorageResponse>
52+
download(bucket: string, pathname: string): Promise<StorageResponse>
53+
remove(bucket: string, pathName: string): Promise<StorageResponse>
54+
listBucketContents(bucket: string): Promise<StorageResponse>
55+
}

src/packages/weblite/SQLiteCloudWebliteClient.ts renamed to src/packages/weblite/WebliteClient.ts

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,7 @@ import { SQLiteCloudError, UploadOptions } from '../../drivers/types'
22
import { Fetch, fetchWithAuth } from '../utils/fetch'
33
import { DEFAULT_HEADERS } from '../../drivers/constants'
44
import { getAPIUrl } from '../utils'
5-
6-
interface WebliteResponse {
7-
data: any, // TODO: type this
8-
error: SQLiteCloudError | null
9-
}
10-
interface Weblite {
11-
upload(dbName: string, file: File | Buffer | Blob | string, opts: UploadOptions): Promise<WebliteResponse>
12-
download(dbName: string): Promise<WebliteResponse>
13-
delete(dbName: string): Promise<WebliteResponse>
14-
listDatabases(): Promise<WebliteResponse>
15-
create(dbName: string): Promise<WebliteResponse>
16-
}
5+
import { Weblite } from '../types'
176

187
export class WebliteClient implements Weblite {
198
protected webliteUrl: string
@@ -25,11 +14,13 @@ export class WebliteClient implements Weblite {
2514
options: {
2615
customFetch?: Fetch,
2716
headers?: Record<string, string>
28-
} = {}
17+
} = {
18+
headers: {}
19+
}
2920
) {
3021
this.webliteUrl = getAPIUrl(connectionString, 'weblite')
3122
this.fetch = options?.customFetch || fetchWithAuth(connectionString)
32-
this.headers = options.headers ? { ...DEFAULT_HEADERS, ...options.headers } : { ...DEFAULT_HEADERS }
23+
this.headers = { ...DEFAULT_HEADERS, ...options.headers }
3324
}
3425

3526
async upload(
@@ -39,7 +30,6 @@ export class WebliteClient implements Weblite {
3930
) {
4031
const url = `${this.webliteUrl}/${dbName}`
4132
let body: File | Buffer | Blob | string
42-
let headers = {}
4333
if (file instanceof File) {
4434
body = file
4535

@@ -52,9 +42,9 @@ export class WebliteClient implements Weblite {
5242
body = new Blob([file])
5343
}
5444

55-
headers = {
45+
const headers = {
5646
...(opts.headers ?? {}),
57-
...headers,
47+
...this.headers,
5848
...DEFAULT_HEADERS,
5949
}
6050

0 commit comments

Comments
 (0)