feat: content

This commit is contained in:
Andreas Thomas 2023-03-26 14:00:02 +02:00
parent 82464d8091
commit 16a4d5e66d
No known key found for this signature in database
28 changed files with 557 additions and 289 deletions

View File

@ -5,97 +5,93 @@ import rehypePrettyCode from "rehype-pretty-code";
import rehypeSlug from "rehype-slug"; import rehypeSlug from "rehype-slug";
import rehypeAutolinkHeadings from "rehype-autolink-headings"; import rehypeAutolinkHeadings from "rehype-autolink-headings";
var computedFields = { var computedFields = {
path: { path: {
type: "string", type: "string",
resolve: (doc) => `/${doc._raw.flattenedPath}` resolve: (doc) => `/${doc._raw.flattenedPath}`,
}, },
slug: { slug: {
type: "string", type: "string",
resolve: (doc) => doc._raw.flattenedPath.split("/").slice(1).join("/") resolve: (doc) => doc._raw.flattenedPath.split("/").slice(1).join("/"),
} },
}; };
var Project = defineDocumentType(() => ({ var Project = defineDocumentType(() => ({
name: "Project", name: "Project",
filePathPattern: "./projects/**/*.mdx", filePathPattern: "./projects/**/*.mdx",
contentType: "mdx", contentType: "mdx",
fields: { fields: {
published: { published: {
type: "boolean" type: "boolean",
}, },
title: { title: {
type: "string", type: "string",
required: true required: true,
}, },
description: { description: {
type: "string", type: "string",
required: true required: true,
}, },
date: { date: {
type: "date" type: "date",
}, },
url: { url: {
type: "string" type: "string",
}, },
repository: { repository: {
type: "string" type: "string",
} },
}, },
computedFields computedFields,
})); }));
var Page = defineDocumentType(() => ({ var Page = defineDocumentType(() => ({
name: "Page", name: "Page",
filePathPattern: "pages/**/*.mdx", filePathPattern: "pages/**/*.mdx",
contentType: "mdx", contentType: "mdx",
fields: { fields: {
title: { title: {
type: "string", type: "string",
required: true required: true,
}, },
description: { description: {
type: "string" type: "string",
} },
}, },
computedFields computedFields,
})); }));
var contentlayer_config_default = makeSource({ var contentlayer_config_default = makeSource({
contentDirPath: "./content", contentDirPath: "./content",
documentTypes: [Page, Project], documentTypes: [Page, Project],
mdx: { mdx: {
remarkPlugins: [remarkGfm], remarkPlugins: [remarkGfm],
rehypePlugins: [ rehypePlugins: [
rehypeSlug, rehypeSlug,
[ [
rehypePrettyCode, rehypePrettyCode,
{ {
theme: "github-dark", theme: "github-dark",
onVisitLine(node) { onVisitLine(node) {
if (node.children.length === 0) { if (node.children.length === 0) {
node.children = [{ type: "text", value: " " }]; node.children = [{ type: "text", value: " " }];
} }
}, },
onVisitHighlightedLine(node) { onVisitHighlightedLine(node) {
node.properties.className.push("line--highlighted"); node.properties.className.push("line--highlighted");
}, },
onVisitHighlightedWord(node) { onVisitHighlightedWord(node) {
node.properties.className = ["word--highlighted"]; node.properties.className = ["word--highlighted"];
} },
} },
], ],
[ [
rehypeAutolinkHeadings, rehypeAutolinkHeadings,
{ {
properties: { properties: {
className: ["subheading-anchor"], className: ["subheading-anchor"],
ariaLabel: "Link to section" ariaLabel: "Link to section",
} },
} },
] ],
] ],
} },
}); });
export { export { Page, Project, contentlayer_config_default as default };
Page,
Project,
contentlayer_config_default as default
};
//# sourceMappingURL=compiled-contentlayer-config-AAEZAM7W.mjs.map //# sourceMappingURL=compiled-contentlayer-config-AAEZAM7W.mjs.map

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,3 @@
// NOTE This file is auto-generated by Contentlayer // NOTE This file is auto-generated by Contentlayer
export const allPages = [];
export const allPages = []

File diff suppressed because one or more lines are too long

View File

@ -1,19 +1,65 @@
// NOTE This file is auto-generated by Contentlayer // NOTE This file is auto-generated by Contentlayer
import projects__accessMdx from './projects__access.mdx.json' assert { type: 'json' } import projects__accessMdx from "./projects__access.mdx.json" assert {
import projects__envshareMdx from './projects__envshare.mdx.json' assert { type: 'json' } type: "json",
import projects__planetfallMdx from './projects__planetfall.mdx.json' assert { type: 'json' } };
import projects__qstashMdx from './projects__qstash.mdx.json' assert { type: 'json' } import projects__envshareMdx from "./projects__envshare.mdx.json" assert {
import projects__terraformProviderVercelMdx from './projects__terraform-provider-vercel.mdx.json' assert { type: 'json' } type: "json",
import projects__upstashAuthAnalyticsMdx from './projects__upstash-auth-analytics.mdx.json' assert { type: 'json' } };
import projects__upstashCliMdx from './projects__upstash-cli.mdx.json' assert { type: 'json' } import projects__planetfallMdx from "./projects__planetfall.mdx.json" assert {
import projects__upstashCoreAnalyticsMdx from './projects__upstash-core-analytics.mdx.json' assert { type: 'json' } type: "json",
import projects__upstashEdgeFlagsMdx from './projects__upstash-edge-flags.mdx.json' assert { type: 'json' } };
import projects__upstashKafkaMdx from './projects__upstash-kafka.mdx.json' assert { type: 'json' } import projects__qstashMdx from "./projects__qstash.mdx.json" assert {
import projects__upstashQstashSdkMdx from './projects__upstash-qstash-sdk.mdx.json' assert { type: 'json' } type: "json",
import projects__upstashRatelimitMdx from './projects__upstash-ratelimit.mdx.json' assert { type: 'json' } };
import projects__upstashReactUiMdx from './projects__upstash-react-ui.mdx.json' assert { type: 'json' } import projects__terraformProviderVercelMdx from "./projects__terraform-provider-vercel.mdx.json" assert {
import projects__upstashRedisMdx from './projects__upstash-redis.mdx.json' assert { type: 'json' } type: "json",
import projects__upstashWebAnalyticsMdx from './projects__upstash-web-analytics.mdx.json' assert { type: 'json' } };
import projects__upstashAuthAnalyticsMdx from "./projects__upstash-auth-analytics.mdx.json" assert {
type: "json",
};
import projects__upstashCliMdx from "./projects__upstash-cli.mdx.json" assert {
type: "json",
};
import projects__upstashCoreAnalyticsMdx from "./projects__upstash-core-analytics.mdx.json" assert {
type: "json",
};
import projects__upstashEdgeFlagsMdx from "./projects__upstash-edge-flags.mdx.json" assert {
type: "json",
};
import projects__upstashKafkaMdx from "./projects__upstash-kafka.mdx.json" assert {
type: "json",
};
import projects__upstashQstashSdkMdx from "./projects__upstash-qstash-sdk.mdx.json" assert {
type: "json",
};
import projects__upstashRatelimitMdx from "./projects__upstash-ratelimit.mdx.json" assert {
type: "json",
};
import projects__upstashReactUiMdx from "./projects__upstash-react-ui.mdx.json" assert {
type: "json",
};
import projects__upstashRedisMdx from "./projects__upstash-redis.mdx.json" assert {
type: "json",
};
import projects__upstashWebAnalyticsMdx from "./projects__upstash-web-analytics.mdx.json" assert {
type: "json",
};
export const allProjects = [projects__accessMdx, projects__envshareMdx, projects__planetfallMdx, projects__qstashMdx, projects__terraformProviderVercelMdx, projects__upstashAuthAnalyticsMdx, projects__upstashCliMdx, projects__upstashCoreAnalyticsMdx, projects__upstashEdgeFlagsMdx, projects__upstashKafkaMdx, projects__upstashQstashSdkMdx, projects__upstashRatelimitMdx, projects__upstashReactUiMdx, projects__upstashRedisMdx, projects__upstashWebAnalyticsMdx] export const allProjects = [
projects__accessMdx,
projects__envshareMdx,
projects__planetfallMdx,
projects__qstashMdx,
projects__terraformProviderVercelMdx,
projects__upstashAuthAnalyticsMdx,
projects__upstashCliMdx,
projects__upstashCoreAnalyticsMdx,
projects__upstashEdgeFlagsMdx,
projects__upstashKafkaMdx,
projects__upstashQstashSdkMdx,
projects__upstashRatelimitMdx,
projects__upstashReactUiMdx,
projects__upstashRedisMdx,
projects__upstashWebAnalyticsMdx,
];

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,11 +1,10 @@
// NOTE This file is auto-generated by Contentlayer // NOTE This file is auto-generated by Contentlayer
import { Page, Project, DocumentTypes } from './types' import { Page, Project, DocumentTypes } from "./types";
export * from './types' export * from "./types";
export declare const allPages: Page[] export declare const allPages: Page[];
export declare const allProjects: Project[] export declare const allProjects: Project[];
export declare const allDocuments: DocumentTypes[]
export declare const allDocuments: DocumentTypes[];

View File

@ -1,12 +1,12 @@
// NOTE This file is auto-generated by Contentlayer // NOTE This file is auto-generated by Contentlayer
export { isType } from 'contentlayer/client' export { isType } from "contentlayer/client";
// NOTE During development Contentlayer imports from `.mjs` files to improve HMR speeds. // NOTE During development Contentlayer imports from `.mjs` files to improve HMR speeds.
// During (production) builds Contentlayer it imports from `.json` files to improve build performance. // During (production) builds Contentlayer it imports from `.json` files to improve build performance.
import { allPages } from './Page/_index.mjs' import allPages from "./Page/_index.json" assert { type: "json" };
import { allProjects } from './Project/_index.mjs' import allProjects from "./Project/_index.json" assert { type: "json" };
export { allPages, allProjects } export { allPages, allProjects };
export const allDocuments = [...allPages, ...allProjects] export const allDocuments = [...allPages, ...allProjects];

View File

@ -1,79 +1,78 @@
// NOTE This file is auto-generated by Contentlayer // NOTE This file is auto-generated by Contentlayer
import type { Markdown, MDX, ImageFieldData, IsoDateTimeString } from 'contentlayer/core' import type {
import * as Local from 'contentlayer/source-files' Markdown,
MDX,
ImageFieldData,
IsoDateTimeString,
} from "contentlayer/core";
import * as Local from "contentlayer/source-files";
export { isType } from 'contentlayer/client' export { isType } from "contentlayer/client";
export type { Markdown, MDX, ImageFieldData, IsoDateTimeString } export type { Markdown, MDX, ImageFieldData, IsoDateTimeString };
/** Document types */ /** Document types */
export type Page = { export type Page = {
/** File path relative to `contentDirPath` */ /** File path relative to `contentDirPath` */
_id: string _id: string;
_raw: Local.RawDocumentData _raw: Local.RawDocumentData;
type: 'Page' type: "Page";
title: string title: string;
description?: string | undefined description?: string | undefined;
/** MDX file body */ /** MDX file body */
body: MDX body: MDX;
path: string path: string;
slug: string slug: string;
} };
export type Project = { export type Project = {
/** File path relative to `contentDirPath` */ /** File path relative to `contentDirPath` */
_id: string _id: string;
_raw: Local.RawDocumentData _raw: Local.RawDocumentData;
type: 'Project' type: "Project";
published?: boolean | undefined published?: boolean | undefined;
title: string title: string;
description: string description: string;
date?: IsoDateTimeString | undefined date?: IsoDateTimeString | undefined;
url?: string | undefined url?: string | undefined;
repository?: string | undefined repository?: string | undefined;
/** MDX file body */ /** MDX file body */
body: MDX body: MDX;
path: string path: string;
slug: string slug: string;
} };
/** Nested types */ /** Nested types */
/** Helper types */ /** Helper types */
export type AllTypes = DocumentTypes | NestedTypes export type AllTypes = DocumentTypes | NestedTypes;
export type AllTypeNames = DocumentTypeNames | NestedTypeNames export type AllTypeNames = DocumentTypeNames | NestedTypeNames;
export type DocumentTypes = Page | Project export type DocumentTypes = Page | Project;
export type DocumentTypeNames = 'Page' | 'Project' export type DocumentTypeNames = "Page" | "Project";
export type NestedTypes = never
export type NestedTypeNames = never
export type NestedTypes = never;
export type NestedTypeNames = never;
export interface ContentlayerGenTypes { export interface ContentlayerGenTypes {
documentTypes: DocumentTypes documentTypes: DocumentTypes;
documentTypeMap: DocumentTypeMap documentTypeMap: DocumentTypeMap;
documentTypeNames: DocumentTypeNames documentTypeNames: DocumentTypeNames;
nestedTypes: NestedTypes nestedTypes: NestedTypes;
nestedTypeMap: NestedTypeMap nestedTypeMap: NestedTypeMap;
nestedTypeNames: NestedTypeNames nestedTypeNames: NestedTypeNames;
allTypeNames: AllTypeNames allTypeNames: AllTypeNames;
} }
declare global { declare global {
interface ContentlayerGen extends ContentlayerGenTypes {} interface ContentlayerGen extends ContentlayerGenTypes {}
} }
export type DocumentTypeMap = { export type DocumentTypeMap = {
Page: Page Page: Page;
Project: Project Project: Project;
} };
export type NestedTypeMap = { export type NestedTypeMap = {};
}

View File

@ -1,9 +1,8 @@
"use client"; "use client";
import { ArrowLeft, Github, Twitter } from "lucide-react"; import { ArrowLeft, Github, Twitter } from "lucide-react";
import Link from "next/link"; import Link from "next/link";
import React, { useEffect, useMemo, useRef, useState } from "react"; import React, { useEffect, useRef, useState } from "react";
import { usePathname } from "next/navigation"; import { usePathname } from "next/navigation";
import Balancer from "react-wrap-balancer";
type Props = { type Props = {
project: { project: {
@ -27,7 +26,7 @@ export const Header: React.FC<Props> = ({ project }) => {
} }
if (project.url) { if (project.url) {
links.push({ links.push({
label: "Live", label: "Website",
href: project.url, href: project.url,
}); });
} }
@ -91,7 +90,7 @@ export const Header: React.FC<Props> = ({ project }) => {
<div className="mx-auto max-w-7xl px-6 lg:px-8 text-center flex flex-col items-center"> <div className="mx-auto max-w-7xl px-6 lg:px-8 text-center flex flex-col items-center">
<div className="mx-auto max-w-2xl lg:mx-0"> <div className="mx-auto max-w-2xl lg:mx-0">
<h1 className="text-4xl font-bold tracking-tight text-white sm:text-6xl"> <h1 className="text-4xl font-bold tracking-tight text-white sm:text-6xl">
<Balancer>{project.title}</Balancer> {project.title}
</h1> </h1>
<p className="mt-6 text-lg leading-8 text-zinc-300"> <p className="mt-6 text-lg leading-8 text-zinc-300">
{project.description} {project.description}

View File

@ -33,7 +33,7 @@ export default async function PostPage({ params }: Props) {
<ReportView slug={project.slug} /> <ReportView slug={project.slug} />
<main className="bg-zinc-50"> <main className="bg-zinc-50">
<article className="px-4 py-12 mx-auto prose prose-zinc"> <article className="px-4 py-12 mx-auto prose prose-zinc prose-quoteless">
<Mdx code={project.body.code} /> <Mdx code={project.body.code} />
</article> </article>
</main> </main>

View File

@ -8,4 +8,109 @@ published: true
--- ---
TODO:
Manage Upstash resources in your terminal or CI.
![](https://raw.githubusercontent.com/upstash/cli/main/img/banner.svg)
![GitHub release (latest SemVer)](https://img.shields.io/github/v/release/upstash/cli)
[![Downloads/week](https://img.shields.io/npm/dw/lstr.svg)](https://npmjs.org/package/@upstash/cli)
# Installation
## npm
You can install upstash's cli directly from npm
```bash
npm i -g @upstash/cli
```
It will be added as `upstash` to your system's path.
## Compiled binaries:
`upstash` is also available from the
[releases page](https://github.com/upstash/upstash-cli/releases/latest) compiled
for windows, linux and mac (both intel and m1).
# Usage
```bash
> upstash
Usage: upstash
Version: development
Description:
Official cli for Upstash products
Options:
-h, --help - Show this help.
-V, --version - Show the version number for this program.
-c, --config <string> - Path to .upstash.json file
Commands:
auth - Login and logout
redis - Manage redis database instances
kafka - Manage kafka clusters and topics
team - Manage your teams and their members
Environment variables:
UPSTASH_EMAIL <string> - The email you use on upstash
UPSTASH_API_KEY <string> - The api key from upstash
```
## Authentication
When running `upstash` for the first time, you should log in using
`upstash auth login`. Provide your email and an api key.
[See here for how to get a key.](https://docs.upstash.com/redis/howto/developerapi#api-development)
As an alternative to logging in, you can provide `UPSTASH_EMAIL` and
`UPSTASH_API_KEY` as environment variables.
## Usage
Let's create a new redis database:
```
> upstash redis create --name=my-db --region=eu-west-1
Database has been created
database_id a3e25299-132a-45b9-b026-c73f5a807859
database_name my-db
database_type Pay as You Go
region eu-west-1
type paid
port 37090
creation_time 1652687630
state active
password 88ae6392a1084d1186a3da37fb5f5a30
user_email andreas@upstash.com
endpoint eu1-magnetic-lacewing-37090.upstash.io
edge false
multizone false
rest_token AZDiASQgYTNlMjUyOTktMTMyYS00NWI5LWIwMjYtYzczZjVhODA3ODU5ODhhZTYzOTJhMTA4NGQxMTg2YTNkYTM3ZmI1ZjVhMzA=
read_only_rest_token ApDiASQgYTNlMjUyOTktMTMyYS00NWI5LWIwMjYtYzczZjVhODA3ODU5O_InFjRVX1XHsaSjq1wSerFCugZ8t8O1aTfbF6Jhq1I=
You can visit your database details page: https://console.upstash.com/redis/a3e25299-132a-45b9-b026-c73f5a807859
Connect to your database with redis-cli: redis-cli -u redis://88ae6392a1084d1186a3da37fb5f5a30@eu1-magnetic-lacewing-37090.upstash.io:37090
```
## Output
Most commands support the `--json` flag to return the raw api response as json,
which you can parse and automate your system.
```bash
> upstash redis create --name=test2113 --region=us-central1 --json | jq '.endpoint'
"gusc1-clean-gelding-30208.upstash.io"
```

View File

@ -8,4 +8,93 @@ published: true
--- ---
TODO:
This library offers some low level building blocks to record and analyze custom events in Redis.
It's main purpose is to provide a simple way to record and query events in Redis without having to worry about the underlying data structure so we can build more advanced analytics features on top of it.
## Quickstart
1. Create a redis database
Go to [console.upstash.com/redis](https://console.upstash.com/redis) and create
a new global database.
After creating the db, copy the `UPSTASH_REDIS_REST_URL` and `UPSTASH_REDIS_REST_TOKEN` to your `.env` file.
3. Install `@upstash/analytics` in your project
```bash
npm install @upstash/analytics @upstash/redis
```
4. Create an analytics client
```ts
import { Analytyics } from "@upstash/analytics";
import { Redis } from "@upstash/redis";
const analytics = new Analytics({
redis: Redis.fromEnv(),
window: "1d",
});
```
5. Ingest some events
An event consists of a `time` field and any additional key-value pairs that you can use to record any information you want.
```ts
const event = {
time: Date.now() // optional (default: Date.now())
userId: "chronark",
page: "/auth/login",
country: "DE",
}
await analytics.ingest("pageviews", event);
```
4. Query your events
```ts
const result = await analytics.query("pageviews");
```
## Development
This project uses `pnpm` for dependency management.
#### Install dependencies
```bash
pnpm install
```
#### Build
```bash
pnpm build
```
## Database Schema
All metrics are stored in Redis `Hash` data types and sharded into buckets based on the `window` option.
```
@upstash/analytics:{TABLE}:{TIMESTAMP}
```
- `TABLE` is a namespace to group events together. ie for managing multiple projects int a single database
- `TIMESTAMP` is the starting timestamp of each window
The field of each hash is a serialized JSON object with the user's event data and the value is the number of times this event has been recorded.
```json
{
'{"page": "/auth/login","country": "DE"}': 5,
'{"page": "/auth/login","country": "US"}': 2
}
```

View File

@ -8,4 +8,22 @@ published: true
--- ---
TODO:
Whether you want to ship without breaking things, run A/B tests or just want to test in production,
feature flags are a great way to dynamically change the behaviour of your app without redeploying. We're excited to announce the public
beta release of our new feature flagging library: [@upstash/edge-flags](https://github.com/upstash/edge-flags).
*Edge Flags*, as the name implies, is a feature flag solution built to run at the edge. It is using [Upstash Redis](https://upstash.com/), a globally replicated serverless Redis service, to store configuration and is
designed to work with [Next.js](https://nextjs.org) and [Vercel](https://vercel.com). We want to support other frameworks in the future, so if you have a suggestion, please let us know!
With the ability to toggle features on and off at the edge, you can quickly respond
to user feedback and optimize the user experience. Whether you are looking to
perform A/B testing, gradually roll out a new feature, or simply have the
ability to turn things off in case of an issue, our feature flagging library has
you covered.
## Reference
Check out the full announcement on [upstash.com](https://upstash.com/blog/edge-flags-beta) for more details.

View File

@ -7,4 +7,15 @@ repository: upstash/sdk-qstash-ts
published: true published: true
--- ---
TODO:
@upstash/qstash is the official client and consumer for [QStash](https://chronark.com/projects/qstash).
QStash is the message broker between your serverless apps. You send an HTTP
request to QStash, that includes a destination, a payload and optional settings.
We durably store your message and will deliver it to the destination API via
HTTP. In case the destination is not ready to receive the message, we will retry
the message later, to guarentee at-least-once delivery.
```bash
npm install @upstash/qstash
```

View File

@ -1,8 +1,7 @@
--- ---
title: Upstash Ratelimit Analytics title: Upstash Ratelimit Analytics
description: Near realtime analytics for your ratelimits. Integrated into the @upstash/ratelimit library. description: Near realtime analytics for your ratelimits. Integrated into the @upstash/ratelimit library.
repository: upstash/ratelimit repository: upstash/ratelimit"
date: "2023-03-01"
website: https://console.upstash.com/ratelimit website: https://console.upstash.com/ratelimit
published: true published: true

View File

@ -8,4 +8,42 @@ published: true
--- ---
TODO: In today's digital age, serverless computing has become increasingly popular due to its scalability and cost-efficiency. One of the challenges of serverless computing is to manage resources efficiently, and one critical aspect of this is rate limiting. Rate limiting is a technique that limits the number of requests a client can make to a server over a given period. This technique can prevent abuse, improve performance, and reduce costs. One npm package that helps implement rate limiting for serverless applications is @upstash/ratelimit, built on top of Upstash Redis.
Upstash is a managed Redis-compatible database service designed for serverless applications.
`@upstash/ratelimit` is an npm package that provides serverless rate limiting using Upstash Redis. The package offers a simple API that can be used to limit the number of requests a client can make within a given time frame. The following algorithms are supported:
- Fixed window
- Sliding window
- Leaky bucket
Using `@upstash/ratelimit` is straightforward. First, you need to install the package using npm:
```bash
npm install @upstash/ratelimit @upstash/redis
```
Then, you can use it in your application:
```ts
import { Ratelimit } from "@upstash/ratelimit"
import { Redis } from "@upstash/redis"
const ratelimit = new Ratelimit({
redis: new Redis({
url: "",
token: ""
}),
limiter: Ratelimit.slidingWindow(10, "10s"),
analytics: true
})
// Check if the client has exceeded the rate limit
const { success } = await ratelimit.limit("identifier")
```
In the code above, we initialize Upstash with our Upstash Redis credentials and define our rate limiting rules. We then call the `limit` function, passing the identifier. The function returns a Promise that resolves with `success` and some other useful data.
`@upstash/ratelimit` is a useful npm package for serverless rate limiting that simplifies the process of implementing rate limiting for serverless applications. The package is built on top of Upstash Redis, which provides a complete solution for serverless applications. With `@upstash/ratelimit`, serverless developers can easily implement rate limiting, which can help prevent abuse, improve performance, and reduce costs.

View File

@ -8,4 +8,5 @@ published: true
--- ---
TODO:
`@upstash/react-ui` is powering the CLI in your browser on [console.upstash.com](https://comsole.upstash.com). It allows you to interact with your Upstash Redis database in a simple and intuitive way.

View File

@ -8,47 +8,15 @@ published: true
--- ---
Upstash is a cloud-based service provider that offers a Redis-compatible service. In addition to that, we have also created an npm package called `@upstash/redis`. This package provides a strongly typed Redis client that uses HTTP instead of TCP to communicate with the database, making it perfect for serverless and edge runtimes.
`@upstash/redis` is an HTTP/REST based Redis client for typescript, built on top Redis is a popular open-source, in-memory data structure store that can be used as a database, cache, and message broker. It is commonly used for web applications that require fast data access and manipulation. Redis clients communicate with Redis servers using the Redis protocol over TCP/IP.
of [Upstash REST API](https://docs.upstash.com/features/restapi).
It is the only connectionless (HTTP based) Redis client and designed for: However, in some cases, TCP is not available. For example, edge functions run on cloud platforms, which often block TCP connections for various reasons. This is where `@upstash/redis` comes in handy. Instead of using TCP, it uses HTTP to communicate with the servers.
- Serverless functions (AWS Lambda ...) The package is designed to be easy to use and provides a simple API for Redis commands. It also includes support for Redis transactions and Lua scripting. It is written in TypeScript, which provides static typing and better code completion in modern editors.
- Cloudflare Workers (see
[the example](https://github.com/upstash/upstash-redis/tree/main/examples/cloudflare-workers))
- Fastly Compute@Edge (see
[the example](https://github.com/upstash/upstash-redis/tree/main/examples/fastly))
- Next.js, Jamstack ...
- Client side web/mobile applications
- WebAssembly
- and other environments where HTTP is preferred over TCP.
See One of the main benefits of using `@upstash/redis` is that it is strongly typed. This means that you get better type checking and error handling in your code. Additionally, the package is designed to be lightweight and optimized for performance. This makes it an excellent choice for applications that require fast data access and manipulation.
[the list of APIs](https://docs.upstash.com/features/restapi#rest---redis-api-compatibility)
supported.
## Quick Start
### Install
#### Node.js
```bash
npm install @upstash/redis
```
#### Deno
```ts
import { Redis } from "https://deno.land/x/upstash_redis/mod.ts";
```
### Create database
Create a new redis database on [upstash](https://console.upstash.com/)
## Basic Usage:
```ts ```ts
import { Redis } from "@upstash/redis" import { Redis } from "@upstash/redis"
@ -74,14 +42,4 @@ console.log(data)
await redis.lpush('elements', 'magnesium') await redis.lpush('elements', 'magnesium')
data = await redis.lrange('elements', 0, 100 ) data = await redis.lrange('elements', 0, 100 )
console.log(data) console.log(data)
```
// hash
await redis.hset('people', {name: 'joe'})
data = await redis.hget('people', 'name' )
console.log(data)
// sets
await redis.sadd('animals', 'cat')
data = await redis.spop('animals', 1)
console.log(data)
```

View File

@ -5,4 +5,4 @@ repository: upstash/web-analytics
published: true published: true
--- ---
TODO: Coming soon

View File

@ -2,10 +2,22 @@ const defaultTheme = require("tailwindcss/defaultTheme");
/** @type {import('tailwindcss').Config} */ /** @type {import('tailwindcss').Config} */
module.exports = { module.exports = {
content: ["./app/**/*.{js,ts,jsx,tsx}", "./mdx-components.tsx"], content: [
"./app/**/*.{js,ts,jsx,tsx}",
"./mdx-components.tsx",
"content/**/*.mdx",
],
theme: { theme: {
extend: { extend: {
typography: {
quoteless: {
css: {
"blockquote p:first-of-type::before": { content: "none" },
"blockquote p:first-of-type::after": { content: "none" },
},
},
},
fontFamily: { fontFamily: {
sans: ["var(--font-inter)", ...defaultTheme.fontFamily.sans], sans: ["var(--font-inter)", ...defaultTheme.fontFamily.sans],
display: ["var(--font-grotesk)"], display: ["var(--font-grotesk)"],