Merge branch 'master' into feat/phone-docs

This commit is contained in:
Paul Copplestone committed 2021-07-28 21:59:07 +08:00
commit 285fea4149
59 files changed
+864 -206

No files matched your search

+13 -5
View File
@@ -2,17 +2,25 @@ REPO_DIR=$(shell pwd)
help:
@echo "\SCRIPTS\n"
@echo "make github.users # pull a list of all contributors"
@echo "make github.contributors # pull a list of all contributors"
@echo "make github.issues # pull a list of all issue creators"
@echo "make github.repos # pull a list of our repos"
@echo "make github.traction # get a history of stargazers for our individual repos"
github.users:
curl -sS https://api.github.com/repos/supabase/supabase/contributors \
| jq -r 'map_values({username: .login, avatar_url: .avatar_url}) \
github.contributors.%:
curl -sS https://api.github.com/repos/supabase/$*/contributors \
| jq -r 'map_values({ username: .login }) \
| unique \
| sort_by(.username)' \
> $(REPO_DIR)/web/src/data/contributors/contributors.json
> $(REPO_DIR)/web/src/data/contributors/$*.json
.PHONY: github.rcontributorsepos
github.contributors: \
github.contributors.supabase \
github.contributors.supabase-js \
github.contributors.supabase-py \
github.contributors.supabase-flutter \
github.contributors.supabase-dart
github.issues:
curl -sS https://api.github.com/repos/supabase/supabase/issues \
+1
View File
@@ -25,6 +25,7 @@ For full documentation, visit [supabase.io/docs](https://supabase.io/docs)
- [Community Forum](https://github.com/supabase/supabase/discussions). Best for: help with building, discussion about database best practices.
- [GitHub Issues](https://github.com/supabase/supabase/issues). Best for: bugs and errors you encounter using Supabase.
- [Email Support](https://supabase.io/docs/support#business-support). Best for: problems with your database or infrastructure.
- [Discord](https://discord.supabase.com). Best for: sharing you applications and hanging out with the community.
## Status
+1
View File
@@ -25,6 +25,7 @@ Para ver la documentación completa, visita [supabase.io/docs](https://supabase.
- [Foro de la comunidad](https://github.com/supabase/supabase/discussions). Mejor para: ayuda construyendo, discusiones acerca de las mejores practicas de base de datos.
- [GitHub Issues](https://github.com/supabase/supabase/issues). Mejor para: bugs y errores que te puedes encontrar utilizando Supabase.
- [Soporte por e-mail](https://supabase.io/docs/support#business-support). Mejor para: problemas con la base de datos o infraestructura.
- [Discord](https://discord.supabase.com). Mejor para: compartir tus aplicaciones y pasar el rato con la comunidad.
## Estatus
+1 -1
View File
@@ -138,7 +138,7 @@ values={[
```sh
1. Go to the "API" section.
2. Find "todos" in the "Tables an Views" section.
2. Find "todos" in the "Tables and Views" section.
3. Switch between the Javascript and the cURL docs using the tabs.
```
+2 -2
View File
@@ -128,7 +128,7 @@ returns smallint as $$
var num_affected = plv8.execute(
'udpate profiles set first_name = $1 where id = $2',
[id, first_name]
[first_name, id]
);
return num_affected;
@@ -155,4 +155,4 @@ $$ language plv8;
## Resources
- Official [`plv8` documentation](https://plv8.github.io/).
- [plv8 Github Repository](https://github.com/plv8/plv8).
- [plv8 Github Repository](https://github.com/plv8/plv8).
+1 -2
View File
@@ -17,7 +17,6 @@ Our CLI is still under heavy development, and is missing some features:
- You cannot yet deploy your local changes to your live project using the CLI. You will need to take a "dump" of your database schema
and run it on your live database.
- We have not yet added Storage to the local development suite.
- The self-hosted version of Supabase does not include a UI yet.
We are working on this in stages, starting with our [UI library](https://github.com/supabase/ui)
([more context](https://github.com/supabase/supabase/discussions/1001#discussioncomment-558696)).
@@ -33,7 +32,7 @@ In the meantime, here are some suggested tools for interacting with your Postgre
## Prerequisites
Our CLI makes heavy use of [Docker Compose](https://docs.docker.com/compose/install), so make sure it is installed and configured to
[run with elevated priveleges][https://docs.docker.com/engine/install/linux-postinstall/#manage-docker-as-a-non-root-user].
[run with elevated priveleges](https://docs.docker.com/engine/install/linux-postinstall/#manage-docker-as-a-non-root-user).
You will also need to install [NPM](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm).
+39 -13
View File
@@ -22,7 +22,7 @@ By the end of this guide you'll have an app which allows users to login and upda
<img height="500px" src="/img/supabase-flutter-demo.png" alt="Supabase User Management example" />
### Github
Whenever you get stuck at any point, take a look at [this repo](https://github.com/dshukertjr/flutter_supabase_quickstart).
Whenever you get stuck at any point, take a look at [this repo](https://github.com/supasquad/supabase-flutter-quickstart).
## Project set up
@@ -161,7 +161,7 @@ Then let's install the only additional dependency: [supabase-flutter](https://gi
Open the app and copy and paste the following inside `pubspec.yaml` under `dependencies`.
```yaml
supabase_flutter: ^0.0.4
supabase_flutter: ^0.0.6
```
Run `flutter pub get` to install the dependencies.
@@ -283,6 +283,26 @@ class AuthState<T extends StatefulWidget> extends SupabaseAuthState<T> {
}
```
### Set up AuthRequiredState
We might want to show certain pages to the users only if they are signed in.
For that we can create a handy `AuthRequiredState` class that we can inherit from for pages where the users need to be authenticated.
`AuthRequiredState` will inherit `SupabaseAuthRequiredState` which is provided by `supabase_flutter` package.
```dart title="lib/components/auth_required_state.dart"
import 'package:flutter/material.dart';
import 'package:supabase_flutter/supabase_flutter.dart';
class AuthRequiredState<T extends StatefulWidget>
extends SupabaseAuthRequiredState<T> {
@override
void onUnauthenticated() {
/// Users will be sent back to the LoginPage if they sign out.
Navigator.of(context).pushNamedAndRemoveUntil('/login', (route) => false);
}
}
```
Let's also create a constant file to make it easier to use Supabase client.
```dart title="lib/utils/constants.dart"
@@ -412,13 +432,14 @@ class _LoginPageState extends AuthState<LoginPage> {
### Set up Account page
After a user is signed in we can allow them to edit their profile details and manage their account.
Let's create a new component for that called `account_page.dart`.
Note that this page will also inherit `AuthState` as it will handle user sign out.
Let's create a new widget called `account_page.dart` for that.
Note that this page will inherit `AuthRequiredState` as user needs to be authenticated to view this page.
```dart title="lib/pages/account_page.dart"
import 'package:flutter/material.dart';
import 'package:supabase_flutter_guide/components/auth_state.dart';
import 'package:supabase_flutter_guide/components/auth_required_state.dart';
import 'package:supabase_flutter_guide/utils/constants.dart';
import 'package:supabase/supabase.dart';
class AccountPage extends StatefulWidget {
const AccountPage({Key? key}) : super(key: key);
@@ -427,20 +448,19 @@ class AccountPage extends StatefulWidget {
_AccountPageState createState() => _AccountPageState();
}
class _AccountPageState extends AuthState<AccountPage> {
class _AccountPageState extends AuthRequiredState<AccountPage> {
late final _usernameController = TextEditingController();
late final _websiteController = TextEditingController();
var _loading = false;
Future<void> _getProfile() async {
Future<void> _getProfile(String userId) async {
setState(() {
_loading = true;
});
final user = supabase.auth.user()!;
final response = await supabase
.from('profiles')
.select()
.eq('id', user.id)
.eq('id', userId)
.single()
.execute();
if (response.error != null && response.status != 406) {
@@ -496,9 +516,16 @@ class _AccountPageState extends AuthState<AccountPage> {
}
@override
void initState() {
_getProfile();
super.initState();
void onAuthenticated(Session session) {
final user = session.user;
if (user != null) {
_getProfile(user.id);
}
}
@override
void onUnauthenticated() {
Navigator.of(context).pushReplacementNamed('/login');
}
@override
@@ -538,7 +565,6 @@ class _AccountPageState extends AuthState<AccountPage> {
```
### Launch!
Now that we have all the components in place, let's update `lib/main.dart`:
+8 -28
View File
@@ -4,42 +4,22 @@ title: Contributing
description: Want to help?
---
import Sponsors from '../../src/components/Sponsors'
## How to contribute
Want to contribute? Why not jump into our GitHub repo and:
- [Sponsor Supabase](https://github.com/sponsors/supabase).
- [Answer Discussions](https://github.com/supabase/supabase/discussions).
- Submit an issue.
- Report a performance issue or a part of the documentation that you find confusing.
- Create a pull request.
- Try one of our products and give feedback.
- Translate this website.
- [Vote on a new client library](https://github.com/supabase/supabase/issues/5) for your favorite language.
- [Translate our Readme](https://github.com/supabase/supabase/issues/1341).
- Try our products and give feedback.
- Spread the word if you like what we are doing.
- Add your project or company to our showcase.
## Contributors
To add yourself as a contributor:
Open [this page](https://github.com/supabase/supabase/blob/master/web/docs/handbook/contributing.mdx) on GitHub and then click the pencil icon.
![Edit this page](/img/edit-contributors.png)
Enter your GitHub profile name and link on a new line.
![Add your Github handle](/img/add-contributor.png)
Enter a title for your pull request and click "Propose Changes":
![Submit PR](/img/propose-changes.png)
One of the Supabase maintainers will approve your PR in the next few hours.
<!-- Add your github handle below this line. Every name should be on a new line -->
[awalias](https://github.com/awalias).
[kiwicopple](https://github.com/kiwicopple).
[abhinav-TB](https://github.com/abhinav-TB).
[jacobfenger](https://github.com/jacobfenger).
<!-- Add your github above this line. Every name should be on a new line -->
## Sponsors
<Sponsors />
+83
View File
@@ -0,0 +1,83 @@
---
id: supasquad
title: SupaSquad
description: Supabase Advocate program
---
The SupaSquad is an official Supabase advocate program where community members help build and manage the Supabase community.
- Official recognition in the Supabase community.
- Direct connection to the Supabase team.
- Help steer the Supabase community.
![Supabase SupaSquad](/img/supabase-squad.png)
## Requirements
As a member of the Squad, you choose the approach where you'll provide the most value.
You can help in one of five ways:
### Maintainer
Help maintain Supabase repositories. This includes building client librararies, managing issues, and fixing bugs.
### Expert
Answer user questions on Github [Discussions](https://github.com/supabase/supabase/discussions), Discord, and various other social platforms.
### Advocate
Spread the word on social channels and help to answer Supabase-related questions in the broader community and social channels.
### Builder
Build Supabase examples, blog about them, and them add to the [SupaSquad GitHub Org](https://github.com/supasquad).
### Author
Write guest blog posts, create documentation, and help Supabase global expansion through translation.
### Moderator
Help us maintain the community guidelines in our GitHub and Community-led communities such as Discord, [Reddit](https://reddit.com/r/Supabase/),
[StackOverflow](https://stackoverflow.com/questions/tagged/supabase) etc.
## Benefits for SupaSquad members
- Access to a Supabase Discord channel providing direct communication with the team, Discord badges, and elevated privileges.
- Special AMA sessions with members of the Supabase team.
- Monthly DevRel committee call with industry-leading Developer Advocates (many of whom are [angel investors](https://supabase.io/blog/2021/03/25/angels-of-supabase)), where you can learn from the best.
- We'll help you build your audience by promoting content via the Supabase social channels.
- Featured profile on Supabase website.
- Early access to new features (and the opportunity to provide feedback to the team!).
- Free credits that you can use for Squad efforts.
- Direct access to members of the Supabase team for questions, suggestions, etc.
- Help shape the future of the program.
- Invited to the [SupaSquad GitHub Org](https://github.com/supasquad) to collaborate with the other squad members.
- Exclusive Supabase Team swag drops usually exclusively reserved to the Supabase core team.
## How to join
1. Apply to join the program using [this form](https://airtable.com/shr0FtLqLfhpuEya8).
2. We will start taking interviewing members from `1 September 2021`.
3. Entry is capped to 20 founding members so we can grow the community at a healthy pace and provide a great experience to all new users.
4. Membership is valid for one year, and can be renewed every year.
## FAQs
<details>
<summary><i>Why are you only admitting 20 new members?</i></summary>
The entire Supabase team is only 20 people, so as you can imagine adding another 20 people sounds like a lot to us! We wish we could admit everyone who wanted to join.
But we also want to make sure everyone who joins the Squad has an awesome experience. In the future we will probably expand the intake to include a monthly quota.
</details>
<details>
<summary><i>What is expected?</i></summary>
Mostly just enthusiasm. If you are interested in Open Source and want to get involved, the SupaSquad program is a great channel. You'll be given opportunities to contribute
to the community in whatever ways match your skillset.
</details>
<details>
<summary><i>What if I become too busy to contribute?</i></summary>
No worries! The program isn't a job. It's just an opportunity to build your skillset and audience within the Supabase ecosystem.
</details>
+1
View File
@@ -102,6 +102,7 @@ module.exports = {
},
prism: {
defaultLanguage: 'js',
additionalLanguages: ['dart'],
plugins: ['line-numbers', 'show-language'],
theme: require('@kiwicopple/prism-react-renderer/themes/vsDark'),
darkTheme: require('@kiwicopple/prism-react-renderer/themes/vsDark'),
+9 -3
View File
@@ -84,12 +84,12 @@ module.exports = {
collapsed: false,
items: [
'guides/examples',
'guides/with-angular',
'guides/with-flutter',
'guides/with-nextjs',
'guides/with-react',
'guides/with-svelte',
'guides/with-vue-3',
'guides/with-angular',
'guides/with-flutter',
'guides/self-hosting',
],
},
@@ -97,7 +97,13 @@ module.exports = {
type: 'category',
label: 'See Also',
collapsed: false,
items: ['handbook/contributing', 'company/terms', 'company/privacy', 'company/aup'],
items: [
'handbook/contributing',
'handbook/supasquad',
'company/terms',
'company/privacy',
'company/aup',
],
},
],
guides: [
+71
View File
@@ -0,0 +1,71 @@
import React from 'react'
import sponsors from '../data/sponsors.json'
export default function Sponsors() {
const tiers = [
{
tier_name: '$5,000 a month',
heading: 'Enterprise: $5,000 per month',
transactions: sponsors.filter((x) => (x.tier == '$5,000 a month')),
},
{
tier_name: '$2,500 a month',
heading: 'Agency: $2,500 per month',
transactions: sponsors.filter((x) => (x.tier == '$2,500 a month')),
},
{
tier_name: '$1,000 a month',
heading: 'Startup: $1,000 per month',
transactions: sponsors.filter((x) => (x.tier == '$1,000 a month')),
},
{
tier_name: '$49 a month',
heading: 'Evangelist: $49 per month',
transactions: sponsors.filter((x) => (x.tier == '$49 a month')),
},
{
tier_name: '$19 a month',
heading: 'Supporter: $19 per month',
transactions: sponsors.filter((x) => (x.tier == '$19 a month')),
},
{
tier_name: '$5 a month',
heading: 'Contributor: $5 per month',
transactions: sponsors.filter((x) => (x.tier == '$5 a month')),
},
]
return (
<div >
{tiers.map(
(t) =>
!!t.transactions.length && (
<>
<h4 className="">{t.heading}</h4>
<div className="row is-multiline" style={{ paddingLeft: 15 }}>
{t.transactions.map((x) => (
<div className="col col--3" key={x.sponsor}>
<a className="avatar" href={`https://github.com/${x.sponsor}`}>
<img
className="avatar__photo avatar__photo--sm"
src={`https://github.com/${x.sponsor}.png`}
/>
<div className="avatar__intro">
<h5 className="avatar__name" >{x.sponsor}</h5>
</div>
</a>
</div>
))}
</div>
<br />
</>
)
)}
</div>
)
}
+4 -94
View File
@@ -6,51 +6,19 @@ import maintainers from '../data/maintainers.json'
import GithubCard from '../components/GithubCard'
import { repos } from '../data/github'
import Sponsors from '../components/Sponsors'
export default function Oss() {
const [activePill, setActivePill] = React.useState('All')
const context = useDocusaurusContext()
const { siteConfig = {} } = context
const maintainerTags = maintainers
.reduce((acc, x) => acc.concat(x.tags), []) // get all tags
.filter((v, i, a) => a.indexOf(v) === i) // remove duplicates
.sort((a, b) => a.localeCompare(b)) // alphabetical
const maintainerPills = ['All'].concat(maintainerTags)
const tiers = [
{
tier_name: '$5,000 a month',
heading: 'Enterprise: $5,000 per month',
transactions: sponsors.filter((x) => (x.tier == '$5,000 a month')),
},
{
tier_name: '$2,500 a month',
heading: 'Agency: $2,500 per month',
transactions: sponsors.filter((x) => (x.tier == '$2,500 a month')),
},
{
tier_name: '$1,000 a month',
heading: 'Startup: $1,000 per month',
transactions: sponsors.filter((x) => (x.tier == '$1,000 a month')),
},
{
tier_name: '$49 a month',
heading: 'Evangelist: $49 per month',
transactions: sponsors.filter((x) => (x.tier == '$49 a month')),
},
{
tier_name: '$19 a month',
heading: 'Supporter: $19 per month',
transactions: sponsors.filter((x) => (x.tier == '$19 a month')),
},
{
tier_name: '$5 a month',
heading: 'Contributor: $5 per month',
transactions: sponsors.filter((x) => (x.tier == '$5 a month')),
},
]
return (
<Layout title={`${siteConfig.title}`} description={siteConfig.tagline}>
<section className={'section-lg'}>
@@ -71,30 +39,7 @@ export default function Oss() {
<section className={'section-lg'}>
<div className="container">
<h2 className="with-underline">Sponsors</h2>
{tiers.map(
(t) =>
!!t.transactions.length && (
<>
<h4 className="">{t.heading}</h4>
<div className="row is-multiline">
{t.transactions.map((x) => (
<div className="col col--3" key={x.sponsor}>
<a className="avatar" href={`https://github.com/${x.sponsor}`}>
<img
className="avatar__photo avatar__photo--sm"
src={`https://github.com/${x.sponsor}.png`}
/>
<div className="avatar__intro">
<h5 className="avatar__name">{x.sponsor}</h5>
</div>
</a>
</div>
))}
</div>
<br />
</>
)
)}
<Sponsors />
</div>
</section>
@@ -163,38 +108,3 @@ export default function Oss() {
</Layout>
)
}
function ContributorCard({ title, description, href, stars, handle }) {
return (
<a className={'card'} href={href} style={{ height: '100%' }}>
<div className="card__body">
<h4 style={styles.h4} style={{ margin: 0 }}>
{title.toUpperCase()}
</h4>
<small>{description}</small>
</div>
<hr style={styles.hr} />
<div style={styles.cardBase}>
<div>@{handle}</div>
<div>{stars} ★</div>
</div>
</a>
)
}
const styles = {
hr: {
margin: '15px 0 10px 0',
},
h3: {
margin: 0,
textTransform: 'capitalize',
},
cardBase: {
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-between',
padding: '0 15px 10px 15px',
fontSize: '0.8em',
},
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 86 KiB

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

@@ -35,7 +35,7 @@ One of the best things about building Supabase is the community. We're even luck
### Where?
Blog post coming soon. Follow our [Twitter](https://twitter.com/supabase) to get notified immediately.
Read the [blog post](/blog/2021/07/26/supabase-community-day).
## Tuesday 27 July: Storage v2
+37 -39
View File
@@ -8,46 +8,43 @@ authorURL: https://github.com/roryw10
image: epsilon3/og-epsilon3.jpg
thumb: epsilon3/cover-epsilon3.jpg
tags:
- launch-week
- case-study
date: '2021-07-26'
toc_depth: 2
---
Epsilon3 are a USA based Y-Combinator backed startup leveraging telemetry data to digitise paper based procedures for complex
testing and operations. Their product is rapidly becoming the OS for space projects and complex operations.
Epsilon3 is a USA-based Y Combinator startup. They digitize paper-based procedures in the space industry using telemetry data,
simplifying testing and operations. Their product is rapidly becoming the OS for space projects and complex operations.
Learn how the team at Epsilon3 use Supabase to help teams execute secure and reliable operations in an industry that
project spend runs into the billions.
Learn how the team at Epsilon3 uses Supabase to help teams execute secure and reliable operations in an industry where project
spend runs into the billions.
### Space Operations
Epsilon3 are modernising the industry by leveraging telemetry data to digitise paper procedures in space operations.
Their customers need to run testing and operational procedures in real time. Using Epsilon3's solution means people can
collaborate online as a team instead of being siloed and separated, an increasingly important requirement in a post-pandemic working world.
Epsilon3 are powering an industry where reliability is a must. In the space industry missions cost billions and need to run reliably.
Epsilon3's customers run testing and operational procedures in real-time. Epsilon3's solution allows online collaboration as a team,
instead of being siloed and separated which is an increasingly important requirement in a post-pandemic working world.
Epsilon3 is powering an industry where reliability is paramount. In the space industry, missions cost billions and need to run reliably.
![Epsilon3 digitize paper-based processes.](/new/images/blog/epsilon3/epsilon3-product.gif)
![Epsilon3 digitizes paper-based processes.](/new/images/blog/epsilon3/epsilon3-product.gif)
The stakes are high when working on projects where failure entails huge potential financial losses. Epsilon3's software saves
operators time and reduces errors to improve complex operations. Their customers are already using their software and successfully
sending satellites into space, and are about to use Epsilon3's software for an operational Rocket Launch. As a result, their
software reputation for improving the quality standard for complex operations has led to demand from other industries.
The team now have enquiries from clients in the robotics, logistics and medical equipment sectors who need a structured and standardised
way of running procedures and keeping audit trails.
Epsilon3's software saves operators time and reduces errors to improve complex operations. Their customers are using their software and
successfully sending satellites into space and are about to use Epsilon3's software for an operational Rocket Launch. As a result, their
reputation for improving the quality standard for complex operations has led to demand from other industries. The team is receiving
enquiries from clients in the robotics, logistics and medical equipment sectors who need a structured and standardized way of running
procedures and keeping audit trails.
**Moving fast in regulated markets**
## Moving fast in regulated markets
The team has a background in engineering from Northrop, Google, and SpaceX and understand the technical benefits Postgres offers as a
battle tested open-source relational database.
As a startup, Epsilon3 needs to move fast and scale. They require security, reliability, and performance.
Whilst the team know they want to use Postgres, they also understand setting up a scalable back-end takes time and must be maintained.
Realtime functionality is also a key for their customers so they can see how running procedures are progressing in real time.
The team has a background in engineering from Northrop, Google, and SpaceX and understands the technical benefits Postgres offers as a
battle-tested open-source relational database.
As a startup, Epsilon3 need to move fast AND scale. They require security, reliability, and performance.
Real-time functionality is also a key for their customers to see how running procedures are progressing as the changes occur.
The space industry is highly regulated adding complexity. For example, in the USA deployments must be in an ITAR-compliant way like AWS
GovCloud while customers in countries outside the USA may need to host their data within their own country.
This means that Epsilon3 must be able to offer flexible hosting options, including on premises deployment.
The space industry is highly regulated, adding complexity. For example, in the USA, deployments must be in an ITAR-compliant way
(for instance AWS GovCloud supports ITAR compliance) while customers in countries outside the USA may need to host their data within their own
country. These customer requirements mean Epsilon3 must be able to offer flexible hosting options, including on-premises deployment.
<Quote
img="aaron-epsilon3.png"
@@ -69,23 +66,24 @@ This means that Epsilon3 must be able to offer flexible hosting options, includi
</p>
</Quote>
**Supabase gives Postgres users Supa-powers**
### Supabase gives Postgres users Superpowers
The team implemented a self hosted Supabase setup. For a customer in production in the USA this means they can use AWS infrastructure with
the Supabase API powering an RDS Postgres instance. This gives the perfect balance of rapid development, reduced DevOps, and flexible hosting
options - crucial for their customers. As Supabase uniquely offers realtime for Postgres they are able to allow their customers to see updates
from running procedures. Supabase also offers well supported client libraries that make row level security easy to use, which is crucial for the
Epsilon3 team to deliver on their future roadmap. Finally all this is easy and fast for the team to set up, even when self hosting which means
the team can focus on what they do best - helping their customers run complex operations smoothly.
The team implemented a self-hosted Supabase setup. They use AWS with a self-hosted Supabase API powering an RDS Postgres instance.
This setup gives a balance of rapid development, reduced DevOps, and flexible hosting options. As Supabase uniquely offers real-time for
Postgres, it allows their customers to see updates from running procedures. Supabase offers well-supported client libraries that make
Postgres Row Level Security easy to use, which is a critical item on the Epsilon3 roadmap.
With this implementation Epsilon3 get all the benefits of Postgres plus the smooth developer experience and support that Supabase is known for,
without making compromises to meet compliance needs.
All this was easy for the team to set up, even with self-hosting, so the team was able to focus on what they do best&mdash;helping their customers
run complex operations smoothly. With this implementation, Epsilon3 gets all the benefits of Postgres, plus the smooth developer experience and
support that Supabase is known for, without compromising their compliance needs.
![Epsilon3 use Supabase for hosting their critical infrastructure.](/new/images/blog/epsilon3/supabase-epsilon3-architecture.png)
![Epsilon3 uses Supabase for hosting their critical infrastructure.](/new/images/blog/epsilon3/supabase-epsilon3-architecture.png)
### Self-hosted Supabase, a superpower
Self-hosting Supabase means the crew at Epsilon3 are able to move fast to revolutionise space operations securely and reliably in realtime
whilst staying compliant. The team are now seeing demand from other industries and are confident in their scaling capability because
they know it's just Postgres under the hood. Check out the Epsilon3 website to learn more about the team and their OS for space operations.
If you are interested in self-hosting Supabase then you can do XYZ action.
Self-hosting Supabase allows the crew at Epsilon3 to move fast. They are revolutionizing space operations securely and reliably in real-time whilst
staying compliant. The team is now seeing demand from other industries and is confident in their scaling capability because they know it's
just Postgres under the hood.
Check out the [Epsilon3 website](https://www.epsilon3.io/) to learn more about the team and their OS for space operations. If you are interested
in self-hosting Supabase then you can **contact us** to learn more.
@@ -0,0 +1,136 @@
---
title: 'Supabase Community Day'
description: Community Day
author: steve_chavez
author_url: https://github.com/steve-chavez
author_image_url: https://github.com/steve-chavez.png
authorURL: https://github.com/steve-chavez
thumb: launch-week-sql-day-1-community-day/launch-week-sql-day-1-community-day-thumb.jpg
image: launch-week-sql-day-1-community-day/launch-week-sql-day-1-community-day-og.jpg
tags:
- launch-week
date: '2021-07-26'
toc_depth: 2
---
Supabase has grown a lot [^1] since last [Launch Week](https://supabase.io/blog/2021/03/25/launch-week),
but it wouldn't be possible without some amazing open source tools.
Since we're shipping a few upgrades this week we feel it's only fair
to shine a spotlight on some tools and community efforts that make Supabase possible.
## PostgreSQL version 13.3
![Postgres version 13 released](/new/images/blog/launch-week-sql-day-1-community-day/launch-week-sql-day-1-community-day-postgres-upgrade.jpg)
PostgreSQL is a big part of Supabase, and it's also a huge inspiration - the speed that they ship, their community organization,
and their absolute dedication towards reliability. PostgreSQL 13.3 was released in June and (from today) every new Supabase project will
be on [PostgreSQL version 13.3](/blog/2021/07/26/supabase-postgres-13).
### Giving back
Supabase makes it easy to get started with Postgres, but we think you should try it even if you don't want to use Supabase. Here's a
few ways we make it easy to use PostgreSQL without Supabase:
- Supabase was the first company to put Postgres in the [Digital Ocean Marketplace](https://marketplace.digitalocean.com/apps/supabase-postgres).
Since then it's been installed over 1000 times (not by us!).
- We provide a Postgres image in the [AWS marketplace](https://aws.amazon.com/marketplace/pp/prodview-lk2pfa5nafecg).
- We're packaging the Marketplace version, [along with "Bundles"](/blog/2021/07/26/supabase-postgres-13#postgresql-bundles)
- We're developing a few extensions: [supautils](https://github.com/supabase/supautils), [pg_net](https://github.com/supabase/pg_net), and a couple more soon to be announced.
### Get involved
- Follow the official [PostgreSQL Twitter](https://twitter.com/PostgreSQL) account.
- Join the official [mailing lists](https://www.postgresql.org/community/).
## PostgREST version 8.0
![PostgREST version 8.0 released](/new/images/blog/launch-week-sql-day-1-community-day/launch-week-sql-day-1-community-day-postgrest.jpg)
This new PostgREST stable version comes with the improvements we've made to make it truly enterprise-grade. Due to our commitment with OSS,
all of our improvements are upstreamed, so you can fully use them on your own self-hosted projects.
### Highlights
**Improved Performance**: Due to Supabase's high throughput requirements, PostgREST 8.0 handles up to 50% more throughput on
GET requests, according to our benchmarks. We converted all SELECT queries to use prepared statements and reduced logging
verbosity to make this possible.
**Reduced downtime**: we need PostgREST to be more "set it and forget it", so reloading schema cache now has zero downtime.
**Dynamic Configuration**: we've made it easier to handle PostgREST configuration at scale (we manage thousands of PostgREST instances).
This new version includes the ability to use an in-database configuration that is reloadable through a `NOTIFY` command.
**Less admin burden**: PostgREST previously required the `pg_listen` utility to reload its schema cache. This is no longer needed.
The schema cache is reloadable with a simple `NOTIFY` command.
**Better diagnostic information**: in the rare cases where PostgREST fails, we want to find the exact root cause quickly.
For this we've improved its logging by adding logging levels and timestamps to all server errors.
**Simpler OpenAPI**: showing a complete OpenAPI output used to require a highly-privileged `anon` role. With the new `openapi-mode`,
this is no longer needed and `anon` can be kept with minimal privileges.
The community has made many more enhancements and bug fixes for the new version. See
[v8.0 CHANGELOG](https://github.com/PostgREST/postgrest/releases/tag/v8.0.0) for the full list.
### Get Started
Want to get started with PostgREST? The Supabase community has built a number of client libraries to make it simpler to use:
- Javascript: [postgrest-js](https://github.com/supabase/postgrest-js)
- Rust: [postgrest-rs](https://github.com/supabase/postgrest-rs)
- Go: [postgrest-go](https://github.com/supabase/postgrest-go)
- Python: [postgrest-py](https://github.com/supabase/postgrest-py)
- Dart: [postgrest-dart](https://github.com/supabase/postgrest-dart)
- C#: [postgrest-csharp](https://github.com/supabase/postgrest-csharp)
- Swift: [postgrest-swift](https://github.com/supabase/postgrest-swift)
- Ruby: [postgrest-rb](https://github.com/supabase/postgrest-rb)
- Kotlin: [postgrest-kt](https://github.com/supabase/postgrest-kt)
### Get involved
- Help with [PostgREST development](https://github.com/PostgREST/postgrest/blob/main/.github/CONTRIBUTING.md).
- Help with [PostgREST docs translations](https://github.com/PostgREST/postgrest-docs/issues/393).
- Follow the official [PostgREST Twitter](https://twitter.com/postgrest_org) account.
## Supabase Flutter/Dart (Beta release)
![Supabase Flutter Beta release](/new/images/blog/launch-week-sql-day-1-community-day/launch-week-sql-day-1-community-day-flutter-library.jpg)
While the Supabase team have been busy with the Javascript libraries, the community have been beavering away with Dart. They've even
[built fully-functional apps](https://www.producthunt.com/posts/spot-2d300f54-7a0a-4dbf-aee2-4a75311217cc) using Supabase Auth and Storage.
Today the Community are releasing both the Flutter and Dart libraries in Beta (with a bit of help from the Supabase team).
### Get started
- Check out the [Flutter Quickstart Guide](https://supabase.io/docs/guides/with-flutter)
- Check out the code:
- Supabase Flutter: [GitHub](https://github.com/supabase/supabase-flutter/) | [Release](https://pub.dev/packages/supabase_flutter)
- Supabase Dart: [GitHub](https://github.com/supabase/supabase-dart/) | [Release](https://pub.dev/packages/supabase)
### Get involved
- Help [write](https://supabase.io/docs/handbook/supasquad#author) the Flutter Docs.
- Help [maintain](https://supabase.io/docs/handbook/supasquad#maintainer) the [Flutter](https://github.com/supabase/supabase-flutter/)
and [Dart](https://github.com/supabase/supabase-dart/) libraries.
## Supabase Discord
![Supabase Discord](/new/images/blog/launch-week-sql-day-1-community-day/launch-week-sql-day-1-community-day-discord-server.jpg)
OK, OK, we get it - GitHub [Discussions](https://github.com/supabase/supabase/discussions) aren't enough for y'all. While we've been trying
to keep the conversation contained to our GitHub org, the community has been creating [subreddits](https://www.reddit.com/r/Supabase/),
StackOverflow [tags](https://stackoverflow.com/questions/tagged/supabase), and GitHub [topics](https://github.com/topics/supabase).
A few weeks ago one of the community created a Community-led Discord, and so the team figured we might as well join the fun.
We'll still be using Discussions for debugging, but if you're looking for a place to hang out with Supabase developers, Discord is where to find it.
### Get involved
Join the Supabase Community Discord: [discord.supabase.com](http://discord.supabase.com), say hi, and start building.
[^1]:
Supabase has been one of the fastest growing startups [on GitHub](https://github.com/supabase/supabase) for four consecutive quarters:
207% in [Q3](https://runacap.com/ross-index/q3-2020/) 2020; 1,373% in [Q4](https://runacap.com/ross-index/q4-2020/) 2020;
462% in [Q1](https://runacap.com/ross-index/q1-2021/) 2021; 1,653% in [Q2](https://runacap.com/ross-index/q2-2021/) 2021.
@@ -0,0 +1,122 @@
---
title: 'Supabase is now on Postgres 13.3'
description: From today, new Supabase projects will be on a version of Supabase Postgres that runs on Postgres 13.3.
author: angelico_de_los_reyes
author_url: https://github.com/dragarcia
author_image_url: https://github.com/dragarcia.png
authorURL: https://github.com/dragarcia
image: pg13/postgres-13-og.jpg
thumb: pg13/postgres-13-thumb.jpg
tags:
- launch-week
- database
date: '2021-07-26'
toc_depth: 2
---
From today, new Supabase projects will be on a version of [Supabase Postgres](https://github.com/supabase/postgres) that runs
on [Postgres 13.3](https://www.postgresql.org/about/news/postgresql-13-released-2077/). This won't be the only big change however in this version.
Here are a few other things that have changed under the hood.
## PostgreSQL version 13.3
We've jumped from PostgreSQL 12.0 to PostgreSQL [version 13.3](https://www.postgresql.org/docs/13/release-13-3.html), introducing
significant performance improvements and some great new functionality. Some changes include:
- native [UUID generation](https://www.postgresql.org/docs/13/functions-uuid.html) (!) using `gen_random_uuid`
- a new JSONB [datetime](https://www.postgresql.org/docs/13/functions-json.html) function
- vacuuming indexes in [parallel](https://www.postgresql.org/docs/13/sql-vacuum.html)
- [incremental sorting](https://www.postgresql.org/docs/13/using-explain.html#USING-EXPLAIN-BASICS)
- smaller [btree indexes](https://www.postgresql.org/docs/13/btree-implementation.html#BTREE-DEDUPLICATION)
- improvements to [extended statistics](https://www.postgresql.org/docs/13/planner-stats.html#PLANNER-STATS-EXTENDED)
## Supabase Versioning
Our [Postgres repo](https://github.com/supabase/postgres) has jumped from `0.15.0` to `13.3.0`. From now on, both major and minor versions of
Supabase Postgres will follow PostgreSQL. This makes it much easier to ascertain what version of PostgreSQL is installed. In the situation wherein
there are no updates to PostgreSQL in between releases, the patch version will be bumped up.
## Large System Extensions (LSE) enabled for ARM instances
<small>
*Disclaimer for self-hosting: This is not available for x86 instances. All instances on the
Supabase platform have this enabled by default.*
</small>
The recent wave of Graviton 2 instances from AWS introduces support for the Large System Extensions (LSE). This looks to greatly enhance
application performance through atomics, and
[improves locking and synchronisation performance across large systems](https://github.com/aws/aws-graviton-getting-started#building-for-graviton-and-graviton2).
### Preliminary Benchmarks
Below is a comparison between the ARM versions of Supabase Postgres `0.15.0` and `13.3.0`. Both are using `m6gd.8xlarge` instances
and follow the PostgreSQL configuration [here](https://www.percona.com/blog/2021/01/22/postgresql-on-arm-based-aws-ec2-instances-is-it-any-good/).
The following configuration of `pgbench` was used.
```bash hideCopy
pgbench -i -s 150
```
Running the benchmark with 2, 4, 8, 16, 64, and 128 clients:
```bash hideCopy
pgbench -P 5 -c {num_clients} -j {num_clients} -T 300 -M prepared postgres
```
![PostgreSQL 13.3 performance](/new/images/blog/pg13/postgres-13-performance.png)
## Ubuntu 20.04
We have taken the opportunity to upgrade new projects from Ubuntu 18.04 to Ubuntu 20.04. A switch to Ubuntu 20.04 guarantees that the underlying
OS of Supabase Postgres is supported by the Canonical team up until the year 2025 (2023 for Ubuntu 18.04).
## Built from source
Driven by the need to enable LSE, the underlying PostgreSQL in this version was built from the ground up instead of downloaded binaries.
Supabase Postgres can now be easily upgraded whenever a new major or minor version of PostgreSQL is released. When PostgreSQL 14 comes out,
expect Supabase Postgres 14 to quickly follow.
## New Extensions
### `pgRouting`
An extension of PostGIS, [`pgRouting`](https://pgrouting.org/) provides geospatial routing functionality.
More information can be found [here](https://docs.pgrouting.org/latest/en/index.html).
### `wal2json`
Converts WAL output into clean and organized JSON objects.
More information can be found [here](https://github.com/eulerto/wal2json).
## Enhanced security
To help combat brute force attacks, `fail2ban` has now been configured to protect direct connections to Postgres. This applies to both
ports `5432` (PostgreSQL) and `6543` (PgBouncer).
IPs get banned for 10 minutes after three failed attempts, and we'll continue to fine-tune and improve the protections applied to the
database servers based on evolving traffic patterns.
## PostgreSQL bundles
`[Coming Soon]`
Last but not the least, we're diversifying the images of Supabase Postgres available in the AWS and Digital Ocean Marketplaces.
Instead of a single option, we'll soon offer four configurations of PostgreSQL. Each bundle offers functionality for
common use-cases. For example, if you're using Postgres with Serverless functions, you might want to run the PgBouncer bundle. If you want an
HTTP API with your Postgres offering you might want to run the PostgREST bundle.
| `Name` | `PostgreSQL` | `PgBouncer` | `PostgREST` |
| ----------------------------------- | ------------ | ----------- | ----------- |
| Supabase Postgres | ✅ | | |
| Supabase Postgres: PgBouncer Bundle | ✅ | ✅ | |
| Supabase Postgres: PostgREST Bundle | ✅ | | ✅ |
| Supabase Postgres: Complete Bundle | ✅ | ✅ | ✅ |
Each offering will be available for both the `x86` and `arm` architectures.
## Try PostgreSQL 13
Try the new features of PostgreSQL 13.3 today by creating a [new project](https://app.supabase.io/) on Supabase.
@@ -0,0 +1,94 @@
---
title: 'Spot: a video sharing app built with Flutter'
description: Spot is a geolocation-based video-sharing app with some social networking features.
author: rory_wilding
author_url: https://github.com/roryw10
author_image_url: https://github.com/roryw10.png
authorURL: https://github.com/roryw10
image: spot/og-spot-flutter-supabase.jpg
thumb: spot/cover-spot-flutter-supabase.jpg
tags:
- case-study
date: '2021-07-27'
toc_depth: 2
---
Learn why Tyler decided Flutter and Supabase are the perfect tech-stack shipping innovative ideas fast.
[Tyler Shukert](https://twitter.com/dshukertjr) is an indie developer who has been building websites and applications for seven years.
Tyler is a Firebase & Flutter expert who recently discovered Supabase. After falling in love with Supabase,
Tyler decided to launch his latest app. [Spot](https://www.producthunt.com/posts/spot-2d300f54-7a0a-4dbf-aee2-4a75311217cc)
is a geolocation-based video-sharing app with some social networking features.
## NoSQL doesn't mean No Schema
Tyler loves how easy it is to create high-quality web and mobile applications with Firebase. For the past few years he has honed
his Flutter, Angular, and Firebase skills to quickly ship mobile and web apps. But the more his development expertise grew,
the more he understood the limitations of Firebase.
Before starting a project, Tyler is never sure if the project will grow. It could be an overnight success, or it might need to
pivot in a different direction. He finds this is particularly difficult with Firebase as he faces a denormalization dilemma.
Denormalization means combining the data into a single table to make data retrieval faster. Google promotes denormalization
as best practice for a snappier app experience. Denormalisation in Firebase takes work and requires additional development
time. For new projects, it is often unclear if they will reach a scale justifying the effort denormalization requires.
In relational databases like Postgres, data is normalized, meaning reduced data redundancy with maintained data integrity.
## Supabase + Flutter: a match made in heaven
When Tyler discovered Supabase on Twitter, he was intrigued by the promise of Postgres with Firebase-like features.
He wanted the benefits of SQL and Relational schemas, and decided to build an app to test Supabase.
Tyler had been thinking about building Spot, a mobile app for sharing geo-based video content. When he previously planned Spot,
he felt like hacking around Firebase would be too much effort. After researching the PostGIS extension for geospatial data,
he realized Supabase was the perfect fit. As an avid Flutter fan, Supabase's Dart library was a bonus.
Tyler loves the open-source nature of Supabase and immediately began contributing to the Dart library to enable functionality that he needed.
Tyler decided that Spot would be perfect to showcase the power of Supabase and Flutter. Since he's active in the open-source community,
he decided to open-source the whole project, making Spot one of the most interesting Supabase examples.
![Spot screenshots.](/new/images/blog/spot/spot-screenshots.jpg)
## Comparing Firebase to Supabase
Although Spot seems like simple, it has a lot of complicated components. Implementing social "Likes" requires `count` functionality,
which is notoriously tricky in Firebase. In Supabase, because it's just Postgres under the hood, `count` is implemented
using a simple SQL `count` query.
Supabase has Row-Level Security, which Tyler uses as a filter - something he can't do with Firebase.
Spot uses Supabase Storage for managing large video files. Firebase Storage [has a reputation](https://stackoverflow.com/questions/43851742/firebase-storage-very-slow-compared-to-firebase-hosting) for slowness until it is public, which was a privacy concern for Tyler. With Supabase Storage, this wasn't an issue - storage is performant and secure.
The Firebase API pricing model makes it is difficult to predict pricing upfront for new projects. With Supabase,
Tyler doesn't need to worry about how many API calls his project makes.
Supabase gives Spot speed, performance, and predictable pricing.
As of today, Tyler has around 3000 installs for Spot and is getting ready to add new functionality. He is confident Supabase,
Postgres, and his data structure will enable future development.
<Quote
img="tyler-spot.jpg"
caption="Tyler Shukert, creator of Spot."
>
<p>
As soon as I saw Supabase I knew it was the perfect technology to use alongside Flutter to build apps faster than ever.
For apps like Spot where we handle user submitted files, it is very easy to manage them securely.
</p>
<p>
Supabaseを最初発見した時にこれとFlutterを組み合わせれば今まで以上に爆速でアプリ開発ができるだろうと思いました。
Spotのようにユーザーがファイルを投稿するアプリの場合でもセキュアに取り扱うのが簡単で本当に助かります。
</p>
</Quote>
## Spot is Open Source
With Supabase, Tyler can use Flutter to build a performant app quickly at a low cost. Tyler is now a massive fan of the Supabase
experience and has even joined the SupaSquad.
You can download and install spot for [iOS](https://apps.apple.com/us/app/spot-videos/id1564675926?utm_source=supabase&utm_campaign=static)
and [Android](https://play.google.com/store/apps/details?id=app.spotvideo&utm_source=supabase&utm_campaign=static)
to see just how snappy his setup is.
Tyler has fully open-sourced his example - you can [clone the repo](https://github.com/dshukertjr/spot)
and use it as the basis of your next big idea.
+169
View File
@@ -0,0 +1,169 @@
---
title: 'Supabase Storage now in Beta'
description: Supabase Storage moves into Beta.
author: inian
image: launch-week-sql-day-2/supabase-storage-beta-og.jpg
thumb: launch-week-sql-day-2/supabase-storage-beta.jpg
tags:
- storage
- launch-week
date: '2021-07-27'
toc_depth: 2
---
At Supabase, one of our core values is [Kaizen](https://en.wikipedia.org/wiki/Kaizen) - continuous improvement. And that's exactly what we've been doing with Storage since it [launched](https://supabase.io/blog/2021/03/30/supabase-storage) three months ago. Today, we are launching the Sequel to Storage Alpha (I bet you didn't see that coming): Storage Beta!
## Streaming Media
We've added support for streaming audio and video files.
Clients can use the `Content-Range` HTTP header to request specific parts of a file from a server. This allows them to intelligently download the parts of the video that a user is viewing, without buffering irrelevant sections of the media file. Supabase Storage now supports this header, making it easier to host and watch [nyan cat videos](https://www.youtube.com/watch?v=SkgTxQm9DWM) all day long.
<video width="99%" autoPlay="autoplay" muted playsInline controls={true}>
<source
src="/new/videos/blog/launch-week-storage-2/nyan-cat.mp4"
type="video/mp4"
muted
playsInline
/>
</video>
## Public Buckets
Public Buckets have been one of our most requested features. We launched without them because there are too [many horror stories](https://www.google.com/search?q=s3+bucket+negligence+award&oq=s3+bucket+negligence+award) of S3 buckets unintentionally exposing objects. We wanted to take the time to implement safeguards against this.
To enable this feature safely, buckets are made private by default, with an extremely prominent warning in the dashboard when you choose to make them public.
You can make objects public in S3 via multiple mechanisms (e.g. tags, or prefixes). While this allows for flexibility, it makes it hard to discover publicly exposed objects. To prevent any confusion, we decided that buckets must be public in their entirety. This public visibility straightforward - if it's in a public bucket, it's public!
Objects in public buckets can be accessed via a URL without any Authorization tokens or headers. This makes them perfect for hosting assets for your web or mobile application.
Public buckets still require [Auth Policies](https://supabase.io/docs/guides/storage#policy-examples) to upload and delete objects, allowing you to securely manage their contents.
<video width="99%" autoPlay="autoplay" muted playsInline controls={true}>
<source src="/new/images/blog/2021-june/public-buckets.mp4" type="video/mp4" muted playsInline />
</video>
## Directory uploads
You can now upload an entire directory to Supabase Storage and the directory structure is fully preserved after the upload. We used the [File and Directory entries API](https://developer.mozilla.org/en-US/docs/Web/API/File_and_Directory_Entries_API) for implementing this. This is a non-standard API, but we didn't find any compatibility issues in the browsers we support. So, now you can upload the [Storage Github repo](https://github.com/supabase/storage-api/) to storage 🤓
<video width="99%" autoPlay="autoplay" muted playsInline controls={true}>
<source
src="/new/videos/blog/launch-week-storage-2/directory-uploads.mp4"
type="video/mp4"
muted
playsInline
/>
</video>
## A New Policy Editor
Postgres [Row Level Security](https://www.postgresql.org/docs/13/ddl-rowsecurity.html) (RLS) is at the core of Supabase Storage and Auth. RLS lets you define complex policies, tightly integrated with Supabase Auth users, using the language you're already comfortable with - SQL.
However, getting started with RLS can be daunting. To make it more approachable for beginners, we've included a set of pre-defined templates on our Dashboard, covering common use-cases.
![Policy editor templates](/new/images/blog/launch-week-sql-day-2/policy-editor-1.png)
Once you've selected a template, you choose which operations to allow and the Dashboard determines which API functions can access the bucket. For example, a user with INSERT permissions will be able to call the `createObject`, `copyObject` and `getSignedObject` functions in the `supabase-js` library.
![Policy editor permissions](/new/images/blog/launch-week-sql-day-2/policy-editor-2.png)
After writing the policy definition (which can be any valid SQL expression), you get an opportunity to review the final policy before saving. We made sure that there is no magic going on behind the scenes: you can always see the underlying SQL definition of the policies. As you become more comfortable with Row Level Security, you can define these policies directly using our SQL editor.
## Using Storage in Local development
It took some time to enable Storage on self-hosted Supabase. We wanted to provide a completely local experience during development, but storage had a hard dependency on an object storage service like S3. This required developers to create an S3 bucket, an IAM user in AWS, and add the credentials of the IAM user to the local setup, which was far from an ideal experience.
From day 1, Supabase Storage was designed so that it would be easy to add new Storage backends. We knew we'd add more storage options like Google Cloud Storage or Backblaze, but little did we expect that this would be useful for our self-hosting setup! We implemented a new Storage Backend which [use a local filesystem](https://github.com/supabase/storage-api/blob/master/src/backend/file.ts) for storing objects. You can now get started with Storage without any additional setup, giving you a completely self-contained instance of Supabase.
Check out our updated [self hosting guide](https://supabase.io/docs/guides/self-hosting) and our [CLI](https://github.com/supabase/cli) to get started.
## Upload anything
At launch, you could pass in a `File` object and `supabase-js` used `FormData` to send a request to the storage server to upload the file. This made it easy to send the cache control information and other options directly to the server as a multipart request.
However, `FormData` is only supported in the browser, making `supabase-js` incompatible with Node.js. The simplest way to solve this would have been to include the [FormData polyfill](https://www.npmjs.com/package/form-data) along with the library.
At Supabase, we are [maniacal about performance](https://supabase.io/blog/2020/12/13/supabase-dashboard-performance). Keeping our client libraries lean is a key differentiator. Our entire client library (including the clients for postgrest, storage, realtime and auth) is just 15.8 kb. If you are just interested in using a single service like storage, you can use the `storage-js` library directly which is [even smaller](https://bundlephobia.com/package/@supabase/storage-js@1.4.0). This made including polyfills like Formdata a no-go.
![Supabase JS bundle size](/new/images/blog/launch-week-sql-day-2/supabase-js-size.png)
We also considered shipping separate bundles for Node.js and the browser. This would have avoided polyfills for APIs which are already supported in each browser. However, this comes with an increase in complexity to our build process, and users would need to choose which flavor of the library to use in different environments like React Native, Deno, etc. We want to make our libraries universal.
Instead, we modified the storage server to accept Binary data directly. With this change, you can directly upload binary Data and even NodeJS streams to the storage API.
![NodeJS Stream upload](/new/images/blog/launch-week-sql-day-2/stream-upload.png)
With this change in place, the client library supports uploading `ArrayBuffer`, `ArrayBufferView`, `Blob`, `Buffer`, `File`, `FormData`, `NodeJS.ReadableStream`, `ReadableStream<Uint8Array>` - without any change to the bundle size! This should enable you to use storage from an even wider range of environments.
## Context menus
The storage explorer in our Dashboard feels like using a file explorer in your operating system. There were a lot of challenges to make it feel intuitive and robust, since S3 is a not a traditional filesystem. For example, S3 doesn't support a move operation natively - you need to copy the object to the new location and delete the original object. S3 also doesn't have a concept of directory, which means there is no API call to rename a directory. But to make the storage explorer feel like a native file explorer, we implemented these features.
Context menus on folders
![Context menu 1](/new/images/blog/launch-week-sql-day-2/context-menu-1.png)
Context menus on files
![Context menu 2](/new/images/blog/launch-week-sql-day-2/context-menu-2.png)
### The case of the disappearing folders
As we already mentioned, S3 doesn't really have a concept of directories. So if a user uploads an object with path `dir/subdir/avatar.png`, the dir and subdir are automatically "created" and there is no explicit API call to create them.
This leads to an issue where if a user creates an empty directory and refreshes the page, the directory disappears since it is not persisted to S3. To simulate a normal filesystem (where empty directories are not garbage collected), we upload an empty file when the user creates a directory on the dashboard. The dashboard hides this placeholder file and the placeholder is deleted when the user uploads an object in the directory - voila, no more disappearing directores!
## Performance improvements for large buckets
We significantly improved rendering for a large number of items in the Dashboard. We use a virtualization library to render the objects in view and actively discard DOM elements which are not currently rendered from memory. This makes scrolling through thousands of items buttery smooth.
Here is a demo testing rendering the heaviest object known to mankind - the `node_modules` folder!
<video width="99%" autoPlay="autoplay" muted playsInline controls={true}>
<source
src="/new/videos/blog/launch-week-storage-2/large-buckets.mp4"
type="video/mp4"
muted
playsInline
/>
</video>
## API changes
Supabase Storage now supports `upsert`. Shoutout to [@ankitjena](https://github.com/ankitjena) for
[this Pull Request](https://github.com/supabase/storage-api/pull/32).
![Storage now supports upserts](/new/images/blog/2021-june/supabase-storage-upsert.png)
We also have automated API docs generated [here](https://supabase.github.io/storage-api/#/) if you want to use the Storage API directly.
### Storage in the wild
We have a few production applications using Supabase Storage. Wataru is using Storage to power his community site [Shikutoku](https://shikutoku.me/) and Tyler is using Supabase Storage to store short video clips uploaded to his [Spot app](https://supabase.io/blog/2021/07/27/spot-flutter-with-postgres) built with Flutter
<Quote img="tyler-spot.jpg" caption="Tyler Shukert, creator of Spot">
<p>
As soon as I saw Supabase I knew it was the perfect technology to use alongside Flutter to build
apps faster than ever. For apps like Spot where we handle user submitted files, it is very easy
to manage them securely.
</p>
<p>
Supabaseを最初発見した時にこれとFlutterを組み合わせれば今まで以上に爆速でアプリ開発ができるだろうと思いました。Spotのようにユーザーがファイルを投稿するアプリの場合でもセキュアに取り扱うのが簡単で本当に助かります。
</p>
</Quote>
<Quote img="wataru.jpeg" caption="Wataru Yonamine, creator of Shikutoku">
<p>
I think it’s a great service, simple and scalable. I like that the dashboard makes it easy to
check and search for images.
</p>
<p>
シンプルで拡張性のある素晴らしいサービスだと思います。ダッシュボードで画像が確認しやすく、検索できるのもいいですね。
</p>
</Quote>
## What's next
We're planning a Content Delivery Network for faster downloads, as well as basic transformation and optimization support for media files (like resizing, etc). We will continue our Kaizen on smaller improvements like allowing configurable upload limits and improving service stability and scalability.
Anything else you want to see or can help implement in Storage? Reach out on our [Discord channel](https://discord.supabase.com/) and give Storage a try by [creating a project](https://app.supabase.io/) on Supabase!
+2 -2
View File
@@ -17,12 +17,12 @@ const a: A = data
const Annoucement = () => {
if (!a.show) return null
return (
<div className="bg-brand-700 dark:bg-brand-800">
<div className="bg-indigo-400 dark:bg-indigo-400">
<div className="flex items-center justify-center py-2 mx-auto space-x-2 text-white lg:container lg:px-16 xl:px-20 text-sm md:text-base">
<span>{a.text}</span>
<a
href={a.link.url}
className="inline-flex items-center px-2 py-1 space-x-1 text-xs transition-colors bg-white rounded-full text-brand-800 dark:hover:text-brand-800 hover:text-brand-800 hover:bg-opacity-90"
className="inline-flex items-center px-2 py-1 space-x-1 text-xs transition-colors bg-indigo-900 rounded text-white dark:hover:text-indigo-100 hover:text-indigo-100 hover:bg-opacity-90"
>
{a.link.text} <IconArrowRight size="tiny" />
</a>
+3 -3
View File
@@ -2,7 +2,7 @@ import React, { useState } from 'react'
import Link from 'next/link'
import { useRouter } from 'next/router'
import { Button, Badge, IconGitHub } from '@supabase/ui'
import { Button, Badge, IconStar } from '@supabase/ui'
import FlyOut from '~/components/UI/FlyOut'
import Transition from 'lib/Transition'
@@ -241,8 +241,8 @@ const Nav = (props: Props) => {
</div>
<div className="hidden lg:flex items-center sm:space-x-3">
<a href="https://github.com/supabase/supabase" target="_blank">
<Button type="default" icon={<IconGitHub />}>
GitHub
<Button type="default" icon={<IconStar />}>
Star us on GitHub
</Button>
</a>
<a href="https://app.supabase.io/api/login">
+4 -4
View File
@@ -1,8 +1,8 @@
{
"show": false,
"text": "We have released the April recap!",
"show": true,
"text": "We're now on Discord!",
"link": {
"url": "https://supabase.io/blog/2021/05/03/supabase-beta-april-2021",
"text": "Read more"
"url": "http://discord.supabase.com",
"text": "Join"
}
}
+2 -2
View File
@@ -29,12 +29,12 @@
}
},
{
"title": "Optimised database instances",
"title": "Optimzed database instances",
"tooltip": "Why? Unique workload requirements, heavy reads and writes, compliance",
"tiers": {
"free": false,
"pro": false,
"enterprise": true
"enterprise": "Starting from $50/month"
}
},
{
+1 -1
View File
@@ -58,7 +58,7 @@ const { data, error } = await supabase
const { data, error } = await supabase
.storage
.from('avatars')
.move('pubic/space-cat.png', 'private/space-cat.png')
.move('public/space-cat.png', 'private/space-cat.png')
+1 -1
View File
@@ -65,7 +65,7 @@
"steve_chavez": {
"author": "Steve Chavez",
"author_url": "https://github.com/steve-chavez",
"position": "Engineering",
"position": "Engineering & PostgREST maintainer",
"username": "steve-chavez",
"author_image_url": "https://github.com/steve-chavez.png"
}
@@ -166,14 +166,14 @@ function BlogPostPage(props: any) {
images: [
{
url: `https://supabase.io${basePath}/images/blog/${
props.blog.thumb ? props.blog.thumb : props.blog.image
props.blog.image ? props.blog.image : props.blog.thumb
}`,
},
],
}}
/>
<DefaultLayout>
<div className="bg-white dark:bg-dark-800 overflow-hidden py-12">
<div className="bg-white dark:bg-dark-800 overflow-hidden mb-12">
<div className="container px-8 sm:px-16 xl:px-20 lg:mt-16 mx-auto">
<div className="max-w-6xl mx-auto">
<div className="lg:py-12 grid grid-cols-12 lg:gap-16">
+23 -2
View File
@@ -148,7 +148,7 @@ export default function IndexPage() {
Pay as you go
</h2>
<p className="mt-4">
<span className="text-4xl font-normal text-gray-900 dark:text-white">$75</span>
<span className="text-4xl font-normal text-gray-900 dark:text-white">$25</span>
<Typography.Text type="secondary">/project /month plus usage costs</Typography.Text>
</p>
<p className="my-4 text-sm text-gray-500">
@@ -293,7 +293,7 @@ export default function IndexPage() {
<div className="relative h-full table">
<p>
<span className="text-4xl font-normal text-gray-900 dark:text-white">
$75
$25
</span>
<Typography.Text> /project /month plus usage costs</Typography.Text>
</p>
@@ -393,6 +393,27 @@ export default function IndexPage() {
</div>
</div>
</div>
<div className="bg-gray-50 dark:bg-gray-800 border-t dark:border-gray-600">
<div className="container mx-auto px-6 lg:px-16 xl:px-20 relative py-16 sm:py-18 md:py-24 lg:py-24">
<Typography.Title level={2}>Changelog</Typography.Title>
<div className="mt-4">
<Typography.Title level={4}>28 July 2021</Typography.Title>
<Typography className="w-full">
<p>
Clarified pricing on the "Optimzed database instances" to include the starting price
of $50/month.
</p>
</Typography>
</div>
<div className="mt-4">
<Typography.Title level={4}>29 March 2021</Typography.Title>
<Typography>Released our Beta pricing.</Typography>
</div>
</div>
</div>
<CTABanner />
</DefaultLayout>
)
Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 213 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 176 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 197 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 175 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 324 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 157 KiB

+33 -1
View File
@@ -5,9 +5,41 @@
<link>https://supabase.io</link>
<description>Latest news from Supabase</description>
<language>en</language>
<lastBuildDate>Sun, 25 Jul 2021 16:00:00 GMT</lastBuildDate>
<lastBuildDate>Mon, 26 Jul 2021 16:00:00 GMT</lastBuildDate>
<atom:link href="https://supabase.io/blog/rss.xml" rel="self" type="application/rss+xml"/>
<item>
<guid>https://supabase.io/blog/2021/07/27/storage-beta</guid>
<title>Supabase Storage now in Beta</title>
<link>https://supabase.io/blog/2021/07/27/storage-beta</link>
<description>Supabase Storage moves into Beta.</description>
<pubDate>Mon, 26 Jul 2021 16:00:00 GMT</pubDate>
</item>
<item>
<guid>https://supabase.io/blog/2021/07/27/spot-flutter-with-postgres</guid>
<title>Spot: a video sharing app built with Flutter</title>
<link>https://supabase.io/blog/2021/07/27/spot-flutter-with-postgres</link>
<description>Spot is a geolocation-based video-sharing app with some social networking features.</description>
<pubDate>Mon, 26 Jul 2021 16:00:00 GMT</pubDate>
</item>
<item>
<guid>https://supabase.io/blog/2021/07/26/supabase-postgres-13</guid>
<title>Supabase is now on Postgres 13.3</title>
<link>https://supabase.io/blog/2021/07/26/supabase-postgres-13</link>
<description>From today, new Supabase projects will be on a version of Supabase Postgres that runs on Postgres 13.3.</description>
<pubDate>Sun, 25 Jul 2021 16:00:00 GMT</pubDate>
</item>
<item>
<guid>https://supabase.io/blog/2021/07/26/supabase-community-day</guid>
<title>Supabase Community Day</title>
<link>https://supabase.io/blog/2021/07/26/supabase-community-day</link>
<description>Community Day</description>
<pubDate>Sun, 25 Jul 2021 16:00:00 GMT</pubDate>
</item>
<item>
<guid>https://supabase.io/blog/2021/07/26/epsilon3-self-hosting</guid>
<title>Epsilon3 Self-Host Supabase To Revolutionize Space Operations </title>