Skip to content

Commit 64f53b2

Browse files
committed
Moving supabase/supabase-js to its own repository
0 parents  commit 64f53b2

File tree

15 files changed

+1263
-0
lines changed

15 files changed

+1263
-0
lines changed

LICENSE.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# MIT License
2+
3+
Copyright (c) 2020 Supabase
4+
5+
Permission is hereby granted, free of charge, to any person obtaining
6+
a copy of this software and associated documentation files (the
7+
"Software"), to deal in the Software without restriction, including
8+
without limitation the rights to use, copy, modify, merge, publish,
9+
distribute, sublicense, and/or sell copies of the Software, and to
10+
permit persons to whom the Software is furnished to do so, subject to
11+
the following conditions:
12+
13+
The above copyright notice and this permission notice shall be
14+
included in all copies or substantial portions of the Software.
15+
16+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Makefile

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
REPO_DIR=$(shell pwd)
2+
3+
help:
4+
@echo "\nDOCKER\n"
5+
@echo "make start # start backend "
6+
@echo "make remove # remove backend "
7+
@echo "make rebuild # rebuild backend - loses any changes to the database"
8+
@echo "make pull # pull all the latest docker images"
9+
10+
#########################
11+
# Docker
12+
#########################
13+
14+
15+
start:
16+
docker-compose up
17+
18+
remove:
19+
docker-compose down --remove-orphans
20+
21+
rebuild:
22+
docker-compose down --remove-orphans
23+
docker-compose build
24+
docker-compose up --force-recreate
25+
26+
pull:
27+
docker-compose pull

README.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Supabase JS
2+
3+
## Commands
4+
- `npm run clean` - Remove `lib/` directory
5+
- `npm test` - Run tests with linting and coverage results.
6+
- `npm run test:integration` - Run the integration tests without docker (requires you to run the docker container separately)
7+
- `npm run test:integration:full` - Run the integration tests (requires docker to be running)
8+
- `npm test:only` - Run tests without linting or coverage.
9+
- `npm test:watch` - You can even re-run tests on file changes!
10+
- `npm test:prod` - Run tests with minified code.
11+
- `npm run test:examples` - Test written examples on pure JS for better understanding module usage.
12+
- `npm run lint` - Run ESlint with airbnb-config
13+
- `npm run cover` - Get coverage report for your code.
14+
- `npm run build` - Babel will transpile ES6 => ES5 and minify the code.
15+
- `npm run prepublish` - Hook for npm. Do all the checks before publishing your module.
16+
17+
18+
## Publishing
19+
20+
Bump the semver.
21+
22+
```sh
23+
npm publish --access=public
24+
```

docker-compose.yml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
version: '3'
2+
3+
services:
4+
supabase:
5+
image: supabase/supabase-dev:0.1.9
6+
ports:
7+
- "8000:8000"
8+
environment:
9+
DB_HOST: db
10+
DB_NAME: postgres
11+
DB_USER: postgres
12+
DB_PASSWORD: postgres
13+
DB_PORT: 5432
14+
DB_SCHEMA: public, personal
15+
depends_on:
16+
- db
17+
db:
18+
image: postgres:12
19+
ports:
20+
- "6543:5432"
21+
volumes:
22+
- ./test/db:/docker-entrypoint-initdb.d/
23+
command:
24+
- "postgres"
25+
- "-c"
26+
- "wal_level=logical"
27+
environment:
28+
POSTGRES_DB: postgres
29+
POSTGRES_USER: postgres
30+
POSTGRES_PASSWORD: postgres
31+
POSTGRES_PORT: 5432

package.json

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
{
2+
"name": "@supabase/supabase-js",
3+
"version": "0.34.0",
4+
"description": "Supabase Realtime API",
5+
"main": "./lib/index.js",
6+
"scripts": {
7+
"clean": "rimraf lib",
8+
"test": "mocha -r @babel/register -r babel-polyfill test/unit/**/*.js",
9+
"test:integration": "mocha -r @babel/register -r babel-polyfill test/integration/**/*.js",
10+
"test:integration:full": "docker-compose up -d && sleep 10 && mocha -r @babel/register -r babel-polyfill test/integration/**/*.js ; docker-compose down --remove-orphans",
11+
"test:prod": "cross-env BABEL_ENV=production npm run test",
12+
"test:watch": "npm test -- --watch",
13+
"test:examples": "node examples/",
14+
"cover": "nyc --check-coverage && npm test",
15+
"build": "BABEL_ENV=production babel src --out-dir lib",
16+
"prepublish": "npm run clean && npm run build",
17+
"deploy:minor": "npm version minor && npm publish --access=public",
18+
"deploy:patch": "npm version patch && npm publish --access=public"
19+
},
20+
"files": [
21+
"lib",
22+
"src"
23+
],
24+
"repository": "https://github.com/supabase/supabase",
25+
"keywords": [
26+
"supabase",
27+
"realtime",
28+
"postgrest",
29+
"javascript"
30+
],
31+
"author": "Supabase",
32+
"license": "MIT",
33+
"bugs": {
34+
"url": "https://github.com/supabase/supabase/issues"
35+
},
36+
"homepage": "https://supabase.io",
37+
"devDependencies": {
38+
"@babel/cli": "^7.8.3",
39+
"@babel/core": "^7.8.3",
40+
"@babel/preset-env": "^7.8.3",
41+
"@babel/register": "^7.8.3",
42+
"babel-plugin-add-module-exports": "^1.0.0",
43+
"babel-polyfill": "^6.26.0",
44+
"babel-preset-minify": "^0.5.1",
45+
"chai": "^4.1.2",
46+
"cross-env": "^7.0.2",
47+
"jest-websocket-mock": "^2.0.1",
48+
"mocha": "^7.1.0",
49+
"nyc": "^15.0.0",
50+
"rimraf": "^3.0.2"
51+
},
52+
"dependencies": {
53+
"@supabase/doctest-js": "^0.1.0",
54+
"@supabase/postgrest-js": "^0.16.1",
55+
"@supabase/realtime-js": "^0.9.0",
56+
"superagent": "^5.2.1"
57+
}
58+
}

src/Realtime.js

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
import { Socket } from '@supabase/realtime-js'
2+
import * as ChangeMapper from './utils/ChangeMapper'
3+
4+
class Realtime {
5+
constructor(
6+
tableName,
7+
realtimeUrl,
8+
schema,
9+
apikey,
10+
uuid,
11+
eventType,
12+
callbackFunction,
13+
queryFilters
14+
) {
15+
this.tableName = tableName
16+
this.realtimeUrl = realtimeUrl
17+
this.schema = schema
18+
this.apikey = apikey
19+
this.uuid = uuid
20+
21+
this.socket = null
22+
this.channel = null
23+
this.listeners = {}
24+
25+
this.queryFilters = queryFilters
26+
27+
this.on(eventType, callbackFunction)
28+
}
29+
30+
/**
31+
* REALTIME FUNCTIONALITY
32+
*/
33+
34+
createListener() {
35+
let socketUrl = `${this.realtimeUrl}`
36+
37+
var filterString = ''
38+
this.queryFilters.forEach((queryFilter) => {
39+
switch (queryFilter.filter) {
40+
case 'filter':
41+
// temporary solution
42+
// this is the only thing we are supporting at the moment
43+
if (queryFilter.operator === 'eq') {
44+
// right now, the string is replaced instead of being stacked
45+
// the server does not support multiple eq. statements
46+
// as such, we will only process the very last eq. statement provided
47+
filterString = `:${queryFilter.columnName}=${queryFilter.operator}.${queryFilter.criteria}`
48+
}
49+
break
50+
default:
51+
break
52+
}
53+
})
54+
55+
let channel =
56+
this.tableName == '*'
57+
? 'realtime:*'
58+
: `realtime:${this.schema}:${this.tableName}${filterString}`
59+
this.socket = new Socket(socketUrl, { params: { apikey: this.apikey } })
60+
this.channel = this.socket.channel(channel)
61+
62+
this.socket.onOpen(() => {
63+
console.debug(`${this.realtimeUrl}: REALTIME CONNECTED`)
64+
})
65+
this.socket.onClose(() => {
66+
console.debug(`${this.realtimeUrl}: REALTIME DISCONNECTED`)
67+
})
68+
}
69+
70+
on(eventType, callbackFunction) {
71+
if (this.socket == null) this.createListener()
72+
73+
this.channel.on(eventType, (payload) => {
74+
let payloadEnriched = {
75+
schema: payload.schema,
76+
table: payload.table,
77+
commit_timestamp: payload.commit_timestamp,
78+
}
79+
let newData = {}
80+
let oldData = {}
81+
let oldDataEnriched = {}
82+
83+
switch (payload.type) {
84+
case 'INSERT':
85+
newData = ChangeMapper.convertChangeData(payload.columns, payload.record)
86+
payloadEnriched.eventType = 'INSERT'
87+
payloadEnriched.new = newData
88+
89+
break
90+
91+
case 'UPDATE':
92+
oldData = ChangeMapper.convertChangeData(payload.columns, payload.old_record)
93+
newData = ChangeMapper.convertChangeData(payload.columns, payload.record)
94+
95+
Object.keys(oldData).forEach((key) => {
96+
if (oldData[key] != null) oldDataEnriched[key] = oldData[key]
97+
})
98+
99+
payloadEnriched.eventType = 'UPDATE'
100+
payloadEnriched.old = oldDataEnriched
101+
payloadEnriched.new = newData
102+
103+
break
104+
105+
case 'DELETE':
106+
oldData = ChangeMapper.convertChangeData(payload.columns, payload.old_record)
107+
108+
Object.keys(oldData).forEach((key) => {
109+
if (oldData[key] != null) oldDataEnriched[key] = oldData[key]
110+
})
111+
112+
payloadEnriched.eventType = 'DELETE'
113+
payloadEnriched.old = oldDataEnriched
114+
115+
break
116+
117+
default:
118+
break
119+
}
120+
121+
callbackFunction(payloadEnriched)
122+
})
123+
124+
this.listeners[eventType] = callbackFunction
125+
return this
126+
}
127+
128+
subscribe() {
129+
if (this.socket == null) this.createListener()
130+
131+
this.socket.connect()
132+
133+
if (this.channel.state !== 'joined') {
134+
this.channel
135+
.join()
136+
.receive('ok', (resp) =>
137+
console.debug(`${this.realtimeUrl}: Joined Realtime successfully `, resp)
138+
)
139+
.receive('error', (resp) => console.debug(`${this.realtimeUrl}: Unable to join `, resp))
140+
.receive('timeout', () =>
141+
console.debug(`${this.realtimeUrl}: Network timeout. Still waiting...`)
142+
)
143+
}
144+
145+
return this
146+
}
147+
148+
unsubscribe() {
149+
if (this.socket) this.socket.disconnect()
150+
151+
return this
152+
}
153+
}
154+
155+
export default Realtime

0 commit comments

Comments
 (0)