Compare commits
155 Commits
cojson@0.8
...
poc
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0589bf275f | ||
|
|
2f6ca4cdf4 | ||
|
|
cfbe745de3 | ||
|
|
7b96fd719b | ||
|
|
c391180093 | ||
|
|
8ea0858571 | ||
|
|
d1c0981024 | ||
|
|
bb0158ec51 | ||
|
|
8a40c02c52 | ||
|
|
b95937511f | ||
|
|
1967c736c5 | ||
|
|
b84edecb50 | ||
|
|
5631d53e3f | ||
|
|
244fd84a88 | ||
|
|
d4e93afdf9 | ||
|
|
26d4fa985c | ||
|
|
cefc6e27de | ||
|
|
452c284a01 | ||
|
|
191a7f33b1 | ||
|
|
d7be246f75 | ||
|
|
5c8717543c | ||
|
|
02cd6fe4b7 | ||
|
|
526a26a39d | ||
|
|
60adbffc26 | ||
|
|
d8cabe3fa6 | ||
|
|
928ac67a06 | ||
|
|
0458e12721 | ||
|
|
df59b53000 | ||
|
|
891baf2053 | ||
|
|
3a55c8a627 | ||
|
|
5a9770242f | ||
|
|
f6bbe18a53 | ||
|
|
0712546277 | ||
|
|
14b70aa445 | ||
|
|
47275a1340 | ||
|
|
ca54b4c1a8 | ||
|
|
86a2c914d3 | ||
|
|
d9c250386e | ||
|
|
73d5f18cb8 | ||
|
|
84e17a9189 | ||
|
|
0e8b04579a | ||
|
|
56a967cce6 | ||
|
|
f823b2a307 | ||
|
|
e43ca2bc98 | ||
|
|
bcdd8e9125 | ||
|
|
2d6352a2dc | ||
|
|
749350cb59 | ||
|
|
07e9a73c52 | ||
|
|
1ef9998b23 | ||
|
|
b00ee914c3 | ||
|
|
6e131eb0dc | ||
|
|
8a0cb69c72 | ||
|
|
d01286b723 | ||
|
|
0b636d26f3 | ||
|
|
f41a1b0d1d | ||
|
|
0a8753dfe0 | ||
|
|
3ca8b13f6c | ||
|
|
e06c18150a | ||
|
|
4c4499ce86 | ||
|
|
afa4c825ca | ||
|
|
60e04cb193 | ||
|
|
843a012f33 | ||
|
|
bd510a13ce | ||
|
|
b56d7e3e7c | ||
|
|
2f5bd74206 | ||
|
|
a4864d93d2 | ||
|
|
19376e6abd | ||
|
|
22f6db8141 | ||
|
|
3d9f12e9ea | ||
|
|
68620a3df9 | ||
|
|
1767f024d9 | ||
|
|
c55924a04a | ||
|
|
31e00a96ae | ||
|
|
7bb834f399 | ||
|
|
667f36e1cf | ||
|
|
07669923ad | ||
|
|
9082a099ee | ||
|
|
aba059db28 | ||
|
|
ae6b9c8dd2 | ||
|
|
7b9f96bf1a | ||
|
|
8df49546fe | ||
|
|
bb4460f422 | ||
|
|
2099099afc | ||
|
|
06b0758d7c | ||
|
|
6135250e57 | ||
|
|
aacd03bbdd | ||
|
|
ca7f250d47 | ||
|
|
83ad506b94 | ||
|
|
e9751f5b69 | ||
|
|
c84764acd5 | ||
|
|
c2a805bffa | ||
|
|
8728dde42b | ||
|
|
9dd9366734 | ||
|
|
48dd00f453 | ||
|
|
cc361aefe5 | ||
|
|
9e4438cb54 | ||
|
|
08706d557a | ||
|
|
02c1ec63cc | ||
|
|
df797dedcd | ||
|
|
74cb08e7d4 | ||
|
|
73720a8cc4 | ||
|
|
50c77fa788 | ||
|
|
9977a4ee85 | ||
|
|
441fe27802 | ||
|
|
1afbd2c7cc | ||
|
|
4955e39af5 | ||
|
|
ace151696c | ||
|
|
db9560ebc5 | ||
|
|
80b572710e | ||
|
|
bbb9d45969 | ||
|
|
83e9a3eaa8 | ||
|
|
9ff7e68f7d | ||
|
|
06740e840a | ||
|
|
b0e2c4fd4b | ||
|
|
4c1922c10e | ||
|
|
76bad9b5c3 | ||
|
|
7f16f2705e | ||
|
|
d12594e521 | ||
|
|
cf96350b01 | ||
|
|
947030433f | ||
|
|
b4cebd732e | ||
|
|
d0d95e6d5d | ||
|
|
a75383ac6a | ||
|
|
de503b6120 | ||
|
|
f7ae41254f | ||
|
|
8f348b28c6 | ||
|
|
3b185b4cd3 | ||
|
|
df5dc513bf | ||
|
|
8e6783ad88 | ||
|
|
79bf6f478f | ||
|
|
7fd93a5a61 | ||
|
|
8f9687323f | ||
|
|
47ee25786f | ||
|
|
0009aa19b2 | ||
|
|
741b9cbada | ||
|
|
259ade3099 | ||
|
|
b6f2da2221 | ||
|
|
44157945a0 | ||
|
|
4ff7bb500a | ||
|
|
db5ea54338 | ||
|
|
7c7880a9b2 | ||
|
|
49082a5aad | ||
|
|
b6653555f5 | ||
|
|
c9fd16ce21 | ||
|
|
e60f34d9e6 | ||
|
|
a04c7dca7a | ||
|
|
e067c29d81 | ||
|
|
1357306d1b | ||
|
|
3c6d9b20c1 | ||
|
|
f597316267 | ||
|
|
17f8bc25c3 | ||
|
|
c1d652cf7f | ||
|
|
10f3e4aabd | ||
|
|
63f5574003 | ||
|
|
9bb5c4ca5f |
@@ -6,18 +6,23 @@
|
||||
"linked": [
|
||||
[
|
||||
"cojson",
|
||||
"jazz-tools",
|
||||
"jazz-browser",
|
||||
"jazz-browser-media-images",
|
||||
"jazz-browser-auth-clerk",
|
||||
"jazz-react-auth-clerk",
|
||||
"jazz-react",
|
||||
"jazz-react-native",
|
||||
"jazz-nodejs",
|
||||
"jazz-run",
|
||||
"cojson-transport-ws",
|
||||
"cojson-storage",
|
||||
"cojson-storage-indexeddb",
|
||||
"cojson-storage-sqlite"
|
||||
"cojson-storage-sqlite",
|
||||
"cojson-transport-ws",
|
||||
"jazz-browser",
|
||||
"jazz-browser-auth-clerk",
|
||||
"jazz-browser-media-images",
|
||||
"jazz-nodejs",
|
||||
"jazz-react",
|
||||
"jazz-react-auth-clerk",
|
||||
"jazz-react-native",
|
||||
"jazz-react-native-auth-clerk",
|
||||
"jazz-react-native-media-images",
|
||||
"jazz-run",
|
||||
"jazz-svelte",
|
||||
"jazz-tools",
|
||||
"jazz-vue"
|
||||
]
|
||||
],
|
||||
"access": "public",
|
||||
|
||||
5
.changeset/sharp-needles-sin.md
Normal file
5
.changeset/sharp-needles-sin.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"cojson": patch
|
||||
---
|
||||
|
||||
Apply time travel when checking the roles on a parent group
|
||||
12
.github/workflows/playwright.yml
vendored
12
.github/workflows/playwright.yml
vendored
@@ -41,20 +41,20 @@ jobs:
|
||||
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pnpm-store-
|
||||
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Setup .env
|
||||
run: echo "VITE_WS_PEER=ws://localhost:4200/" >> .env
|
||||
working-directory: ./${{ matrix.project }}
|
||||
|
||||
- name: Pnpm Build
|
||||
run: pnpm turbo build
|
||||
working-directory: ./${{ matrix.project }}
|
||||
|
||||
- name: Build jazz-run
|
||||
run: pnpm exec turbo build && chmod +x dist/index.js;
|
||||
working-directory: ./packages/jazz-run
|
||||
|
||||
- name: Install Playwright Browsers
|
||||
run: pnpm exec playwright install --with-deps
|
||||
run: pnpm exec playwright install
|
||||
working-directory: ./${{ matrix.project }}
|
||||
|
||||
- name: Run Playwright tests
|
||||
|
||||
@@ -59,7 +59,7 @@ representative at an online or offline event.
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported to [the community leaders responsible for enforcement](mailto:hello@gcmp.io).
|
||||
reported to [the community leaders responsible for enforcement](mailto:hello@garden.co).
|
||||
All complaints will be reviewed and investigated promptly and fairly.
|
||||
|
||||
All community leaders are obligated to respect the privacy and security of the
|
||||
|
||||
@@ -6,7 +6,7 @@ Thank you for considering contributing to Jazz! Jazz is an open-source framework
|
||||
|
||||
### 1. Reporting Bugs
|
||||
|
||||
If you find a bug, please [open an issue with as much detail as possible](https://github.com/gardencmp/jazz/issues). Include:
|
||||
If you find a bug, please [open an issue with as much detail as possible](https://github.com/garden-co/jazz/issues). Include:
|
||||
|
||||
- A clear and descriptive title.
|
||||
- Steps to reproduce the issue.
|
||||
@@ -40,7 +40,7 @@ You'll need Node.js 20.x or 22.x installed (we're working on support for 23.x),
|
||||
|
||||
1. **Clone the repository**:
|
||||
```bash
|
||||
git clone https://github.com/gardencmp/jazz.git
|
||||
git clone https://github.com/garden-co/jazz.git
|
||||
```
|
||||
|
||||
2. **Install dependencies**:
|
||||
|
||||
@@ -15,6 +15,6 @@ For community and support, please join our [Discord](https://discord.gg/utDMjHYg
|
||||
- Homepage: [jazz.tools](https://jazz.tools)
|
||||
- Docs: [jazz.tools/docs](https://jazz.tools/docs)
|
||||
- Community & support: [Discord](https://discord.gg/utDMjHYg42)
|
||||
- Updates: [X](https://x.com/jazz_tools) & [Email](https://gcmp.io/news)
|
||||
- Updates: [X](https://x.com/jazz_tools) & [Email](https://garden.co/news)
|
||||
|
||||
Copyright 2024 — Garden Computing, Inc.
|
||||
|
||||
@@ -1,5 +1,22 @@
|
||||
# jazz-example-book-shelf
|
||||
|
||||
## 0.1.29
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react@0.8.37
|
||||
- jazz-tools@0.8.37
|
||||
- jazz-browser-media-images@0.8.37
|
||||
|
||||
## 0.1.28
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [441fe27]
|
||||
- jazz-tools@0.8.36
|
||||
- jazz-react@0.8.36
|
||||
- jazz-browser-media-images@0.8.36
|
||||
|
||||
## 0.1.27
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM caddy:2.7.3-alpine
|
||||
LABEL org.opencontainers.image.source="https://github.com/gardencmp/jazz"
|
||||
LABEL org.opencontainers.image.source="https://github.com/garden-co/jazz"
|
||||
|
||||
COPY ./dist /usr/share/caddy/
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "jazz-example-book-shelf",
|
||||
"version": "0.1.27",
|
||||
"version": "0.1.29",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
@@ -11,9 +11,9 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"clsx": "^2.0.0",
|
||||
"jazz-browser-media-images": "workspace:0.8.35",
|
||||
"jazz-react": "workspace:0.8.35",
|
||||
"jazz-tools": "workspace:0.8.35",
|
||||
"jazz-browser-media-images": "workspace:0.8.37",
|
||||
"jazz-react": "workspace:0.8.37",
|
||||
"jazz-tools": "workspace:0.8.37",
|
||||
"next": "14.2.5",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0"
|
||||
|
||||
@@ -1 +1 @@
|
||||
EXPO_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_ZXZpZGVudC1kYW5lLTg5LmNsZXJrLmFjY291bnRzLmRldiQ
|
||||
EXPO_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_ZXZpZGVudC1kYW5lLTg5LmNsZXJrLmFjY291bnRzLmRldiQ
|
||||
|
||||
@@ -1,5 +1,26 @@
|
||||
# chat-rn-clerk
|
||||
|
||||
## 1.0.29
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react-native@0.8.37
|
||||
- jazz-react-native-auth-clerk@0.8.37
|
||||
- jazz-tools@0.8.37
|
||||
- jazz-react-native-media-images@0.8.28
|
||||
|
||||
## 1.0.28
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- c84764a: feat: added jazz-react-native-auth-clerk package
|
||||
- Updated dependencies [c84764a]
|
||||
- Updated dependencies [441fe27]
|
||||
- jazz-react-native-auth-clerk@0.8.36
|
||||
- jazz-react-native@0.8.36
|
||||
- jazz-tools@0.8.36
|
||||
- jazz-react-native-media-images@0.8.27
|
||||
|
||||
## 1.0.27
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -35,7 +35,9 @@
|
||||
}
|
||||
}
|
||||
],
|
||||
"expo-secure-store"
|
||||
"expo-secure-store",
|
||||
"expo-font",
|
||||
"expo-router"
|
||||
],
|
||||
"extra": {
|
||||
"eas": {
|
||||
|
||||
@@ -4,7 +4,7 @@ import { Platform } from "react-native";
|
||||
export interface TokenCache {
|
||||
getToken: (key: string) => Promise<string | undefined | null>;
|
||||
saveToken: (key: string, token: string) => Promise<void>;
|
||||
clearToken?: (key: string) => void;
|
||||
clearToken: (key: string) => void;
|
||||
}
|
||||
|
||||
const createTokenCache = (): TokenCache => {
|
||||
@@ -27,6 +27,9 @@ const createTokenCache = (): TokenCache => {
|
||||
saveToken: (key: string, token: string) => {
|
||||
return SecureStore.setItemAsync(key, token);
|
||||
},
|
||||
clearToken: (key: string) => {
|
||||
return SecureStore.deleteItemAsync(key);
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -19,7 +19,10 @@ config.resolver.nodeModulesPaths = [
|
||||
];
|
||||
config.resolver.sourceExts = ["mjs", "js", "json", "ts", "tsx"];
|
||||
config.resolver.unstable_enablePackageExports = true;
|
||||
config.resolver.requireCycleIgnorePatterns = [/(^|\/|\\)node_modules($|\/|\\)/];
|
||||
config.resolver.requireCycleIgnorePatterns = [
|
||||
/(^|\/|\\)node_modules($|\/|\\)/,
|
||||
/(^|\/|\\)packages($|\/|\\)/,
|
||||
];
|
||||
|
||||
// Use turborepo to restore the cache when possible
|
||||
config.cacheStores = [
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "chat-rn-clerk",
|
||||
"main": "index.js",
|
||||
"version": "1.0.27",
|
||||
"version": "1.0.29",
|
||||
"scripts": {
|
||||
"build": "expo export -p ios",
|
||||
"start": "expo start",
|
||||
@@ -17,59 +17,58 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@azure/core-asynciterator-polyfill": "^1.0.2",
|
||||
"@bam.tech/react-native-image-resizer": "^3.0.10",
|
||||
"@bam.tech/react-native-image-resizer": "^3.0.11",
|
||||
"@clerk/clerk-expo": "^2.2.21",
|
||||
"@expo/vector-icons": "^14.0.2",
|
||||
"@react-native-community/netinfo": "^11.3.1",
|
||||
"@react-navigation/native": "^6.1.18",
|
||||
"@react-navigation/native-stack": "^6.11.0",
|
||||
"@react-native-community/netinfo": "^11.4.1",
|
||||
"@react-navigation/native": "^7.0.13",
|
||||
"@react-navigation/native-stack": "^7.1.14",
|
||||
"base-64": "^1.0.0",
|
||||
"buffer": "^6.0.3",
|
||||
"clsx": "^2.0.0",
|
||||
"expo": "~51.0.37",
|
||||
"expo-build-properties": "~0.12.5",
|
||||
"expo-clipboard": "~6.0.3",
|
||||
"expo-constants": "~16.0.2",
|
||||
"expo-crypto": "~13.0.2",
|
||||
"expo-dev-client": "~4.0.28",
|
||||
"expo-file-system": "^17.0.1",
|
||||
"expo-font": "~12.0.4",
|
||||
"expo-linking": "~6.3.1",
|
||||
"expo-router": "~3.5.23",
|
||||
"expo-secure-store": "~13.0.2",
|
||||
"expo-splash-screen": "~0.27.5",
|
||||
"expo-status-bar": "~1.12.1",
|
||||
"expo-system-ui": "~3.0.7",
|
||||
"expo-web-browser": "~13.0.3",
|
||||
"jazz-react-auth-clerk": "workspace:*",
|
||||
"expo": "^52.0.0",
|
||||
"expo-build-properties": "~0.13.1",
|
||||
"expo-clipboard": "~7.0.0",
|
||||
"expo-constants": "~17.0.3",
|
||||
"expo-crypto": "~14.0.1",
|
||||
"expo-dev-client": "~5.0.5",
|
||||
"expo-file-system": "^18.0.4",
|
||||
"expo-font": "~13.0.1",
|
||||
"expo-linking": "~7.0.3",
|
||||
"expo-router": "~4.0.11",
|
||||
"expo-secure-store": "~14.0.0",
|
||||
"expo-splash-screen": "~0.29.16",
|
||||
"expo-status-bar": "~2.0.0",
|
||||
"expo-system-ui": "~4.0.5",
|
||||
"expo-web-browser": "~14.0.1",
|
||||
"jazz-react-native": "workspace:*",
|
||||
"jazz-react-native-auth-clerk": "workspace:*",
|
||||
"jazz-react-native-media-images": "workspace:*",
|
||||
"jazz-tools": "workspace:*",
|
||||
"nativewind": "^2.0.11",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-native": "~0.74.5",
|
||||
"react-native": "~0.76.3",
|
||||
"react-native-fetch-api": "^3.0.0",
|
||||
"react-native-gesture-handler": "~2.16.1",
|
||||
"react-native-gesture-handler": "~2.20.2",
|
||||
"react-native-get-random-values": "^1.11.0",
|
||||
"react-native-mmkv": "3.0.1",
|
||||
"react-native-polyfill-globals": "^3.1.0",
|
||||
"react-native-quick-base64": "^2.1.2",
|
||||
"react-native-reanimated": "~3.10.1",
|
||||
"react-native-safe-area-context": "4.10.5",
|
||||
"react-native-screens": "3.31.1",
|
||||
"react-native-reanimated": "~3.16.3",
|
||||
"react-native-safe-area-context": "4.12.0",
|
||||
"react-native-screens": "4.1.0",
|
||||
"react-native-url-polyfill": "^2.0.0",
|
||||
"react-native-web": "~0.19.10",
|
||||
"react-native-web": "~0.19.13",
|
||||
"text-encoding": "^0.7.0",
|
||||
"web-streams-polyfill": "^3.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.20.0",
|
||||
"@types/jest": "^29.5.3",
|
||||
"@types/react": "^18.2.19",
|
||||
"@types/react": "^18.3.12",
|
||||
"@types/react-test-renderer": "^18.0.7",
|
||||
"jest": "^29.2.1",
|
||||
"jest-expo": "~51.0.3",
|
||||
"jest-expo": "~52.0.2",
|
||||
"react-test-renderer": "18.2.0",
|
||||
"tailwindcss": "3.3.2",
|
||||
"typescript": "^5.3.3"
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import { useClerk, useUser } from "@clerk/clerk-expo";
|
||||
import { useJazzClerkAuth } from "jazz-react-auth-clerk";
|
||||
import { useJazzClerkAuth } from "jazz-react-native-auth-clerk";
|
||||
import React, {
|
||||
useContext,
|
||||
createContext,
|
||||
PropsWithChildren,
|
||||
useContext,
|
||||
useEffect,
|
||||
useState,
|
||||
PropsWithChildren,
|
||||
} from "react";
|
||||
import { Text, View } from "react-native";
|
||||
import { Jazz } from "./jazz";
|
||||
import { Jazz, kvStore } from "./jazz";
|
||||
|
||||
const AuthContext = createContext<{
|
||||
isAuthenticated: boolean;
|
||||
@@ -25,7 +25,7 @@ export function useAuth() {
|
||||
export function JazzAndAuth({ children }: PropsWithChildren) {
|
||||
const { isSignedIn, isLoaded: isClerkLoaded } = useUser();
|
||||
const clerk = useClerk();
|
||||
const [auth, state] = useJazzClerkAuth(clerk);
|
||||
const [auth, state] = useJazzClerkAuth(clerk, kvStore);
|
||||
const [isAuthenticated, setIsAuthenticated] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -46,10 +46,10 @@ export function JazzAndAuth({ children }: PropsWithChildren) {
|
||||
<Text style={{ color: "red" }}>{error}</Text>
|
||||
</View>
|
||||
))}
|
||||
{auth ? (
|
||||
{auth && clerk.user ? (
|
||||
<Jazz.Provider
|
||||
auth={auth}
|
||||
peer="wss://cloud.jazz.tools/?key=chat-rn-clerk-example-jazz@gcmp.io"
|
||||
peer="wss://cloud.jazz.tools/?key=chat-rn-clerk-example-jazz@garden.co"
|
||||
storage={undefined}
|
||||
>
|
||||
{children}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { createJazzRNApp } from "jazz-react-native";
|
||||
|
||||
export const Jazz = createJazzRNApp();
|
||||
export const { useAccount, useCoState, useAcceptInvite } = Jazz;
|
||||
export const { useAccount, useCoState, useAcceptInvite, kvStore } = Jazz;
|
||||
|
||||
@@ -1,5 +1,21 @@
|
||||
# chat-rn
|
||||
|
||||
## 1.0.27
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react-native@0.8.37
|
||||
- jazz-tools@0.8.37
|
||||
|
||||
## 1.0.26
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [c84764a]
|
||||
- Updated dependencies [441fe27]
|
||||
- jazz-react-native@0.8.36
|
||||
- jazz-tools@0.8.36
|
||||
|
||||
## 1.0.25
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "chat-rn",
|
||||
"version": "1.0.25",
|
||||
"version": "1.0.27",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"build": "expo export -p ios",
|
||||
@@ -13,39 +13,38 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@azure/core-asynciterator-polyfill": "^1.0.2",
|
||||
"@react-native-community/netinfo": "^11.3.1",
|
||||
"@react-native-community/netinfo": "^11.4.1",
|
||||
"@react-navigation/native": "^6.1.18",
|
||||
"@react-navigation/native-stack": "^6.11.0",
|
||||
"base-64": "^1.0.0",
|
||||
"clsx": "^2.0.0",
|
||||
"expo": "~51.0.37",
|
||||
"expo-build-properties": "~0.12.5",
|
||||
"expo-clipboard": "~6.0.3",
|
||||
"expo-constants": "~16.0.2",
|
||||
"expo-crypto": "~13.0.2",
|
||||
"expo-dev-client": "~4.0.28",
|
||||
"expo-linking": "~6.3.1",
|
||||
"expo-secure-store": "~13.0.2",
|
||||
"expo-status-bar": "~1.12.1",
|
||||
"expo-web-browser": "~13.0.3",
|
||||
"expo": "^52.0.0",
|
||||
"expo-build-properties": "~0.13.1",
|
||||
"expo-clipboard": "~7.0.0",
|
||||
"expo-constants": "~17.0.3",
|
||||
"expo-crypto": "~14.0.1",
|
||||
"expo-dev-client": "~5.0.5",
|
||||
"expo-linking": "~7.0.3",
|
||||
"expo-secure-store": "~14.0.0",
|
||||
"expo-status-bar": "~2.0.0",
|
||||
"expo-web-browser": "~14.0.1",
|
||||
"jazz-react-native": "workspace:*",
|
||||
"jazz-tools": "workspace:*",
|
||||
"nativewind": "^2.0.11",
|
||||
"react": "^18.2.0",
|
||||
"react-native": "~0.74.5",
|
||||
"react": "18.2.0",
|
||||
"react-native": "~0.76.3",
|
||||
"react-native-fetch-api": "^3.0.0",
|
||||
"react-native-get-random-values": "^1.11.0",
|
||||
"react-native-mmkv": "3.0.1",
|
||||
"react-native-polyfill-globals": "^3.1.0",
|
||||
"react-native-safe-area-context": "4.10.5",
|
||||
"react-native-screens": "3.31.1",
|
||||
"react-native-safe-area-context": "4.12.0",
|
||||
"react-native-screens": "4.1.0",
|
||||
"react-native-url-polyfill": "^2.0.0",
|
||||
"text-encoding": "^0.7.0",
|
||||
"web-streams-polyfill": "^3.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.20.0",
|
||||
"@types/react": "^18.2.19",
|
||||
"@types/react": "^18.3.12",
|
||||
"tailwindcss": "3.3.2",
|
||||
"typescript": "^5.3.3"
|
||||
},
|
||||
|
||||
@@ -51,7 +51,7 @@ function App() {
|
||||
<StrictMode>
|
||||
<Jazz.Provider
|
||||
auth={auth}
|
||||
peer="wss://cloud.jazz.tools/?key=chat-rn-example-jazz@gcmp.io"
|
||||
peer="wss://cloud.jazz.tools/?key=chat-rn-example-jazz@garden.co"
|
||||
storage={undefined}
|
||||
>
|
||||
<NavigationContainer linking={linking} ref={navigationRef}>
|
||||
|
||||
@@ -1,5 +1,22 @@
|
||||
# chat-vue
|
||||
|
||||
## 0.0.20
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-browser@0.8.37
|
||||
- jazz-tools@0.8.37
|
||||
- jazz-vue@0.8.25
|
||||
|
||||
## 0.0.19
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [441fe27]
|
||||
- jazz-tools@0.8.36
|
||||
- jazz-browser@0.8.36
|
||||
- jazz-vue@0.8.24
|
||||
|
||||
## 0.0.18
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "chat-vue",
|
||||
"version": "0.0.18",
|
||||
"version": "0.0.20",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import "./index.css";
|
||||
import { DemoAuthBasicUI, createJazzVueApp, useDemoAuth } from "jazz-vue";
|
||||
import { createApp, defineComponent, h } from "vue";
|
||||
import App from "./App.vue";
|
||||
import "./index.css";
|
||||
import router from "./router";
|
||||
|
||||
const Jazz = createJazzVueApp();
|
||||
@@ -18,7 +18,7 @@ const RootComponent = defineComponent({
|
||||
JazzProvider,
|
||||
{
|
||||
auth: authMethod.value,
|
||||
peer: "wss://mesh.jazz.tools/?key=chat-example-jazz@gcmp.io",
|
||||
peer: "wss://cloud.jazz.tools/?key=chat-example-jazz@garden.co",
|
||||
},
|
||||
{
|
||||
default: () => h(App),
|
||||
|
||||
@@ -1,5 +1,23 @@
|
||||
# jazz-example-chat
|
||||
|
||||
## 0.0.115
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [3d9f12e]
|
||||
- cojson@0.8.37
|
||||
- jazz-react@0.8.37
|
||||
- jazz-tools@0.8.37
|
||||
|
||||
## 0.0.114
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [441fe27]
|
||||
- cojson@0.8.36
|
||||
- jazz-tools@0.8.36
|
||||
- jazz-react@0.8.36
|
||||
|
||||
## 0.0.113
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM caddy:2.7.3-alpine
|
||||
LABEL org.opencontainers.image.source="https://github.com/gardencmp/jazz"
|
||||
LABEL org.opencontainers.image.source="https://github.com/garden-co/jazz"
|
||||
|
||||
COPY ./dist /usr/share/caddy/
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "jazz-example-chat",
|
||||
"private": true,
|
||||
"version": "0.0.113",
|
||||
"version": "0.0.115",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
@@ -18,10 +18,10 @@
|
||||
"@radix-ui/react-toast": "^1.1.4",
|
||||
"class-variance-authority": "^0.7.0",
|
||||
"clsx": "^2.0.0",
|
||||
"cojson": "workspace:0.8.35",
|
||||
"cojson": "workspace:0.8.37",
|
||||
"hash-slash": "workspace:0.2.1",
|
||||
"jazz-react": "workspace:0.8.35",
|
||||
"jazz-tools": "workspace:0.8.35",
|
||||
"jazz-react": "workspace:0.8.37",
|
||||
"jazz-tools": "workspace:0.8.37",
|
||||
"lucide-react": "^0.274.0",
|
||||
"qrcode": "^1.5.3",
|
||||
"react": "^18.2.0",
|
||||
|
||||
@@ -13,7 +13,7 @@ function JazzAndAuth({ children }: { children: React.ReactNode }) {
|
||||
<>
|
||||
<Jazz.Provider
|
||||
auth={auth}
|
||||
peer="wss://cloud.jazz.tools/?key=chat-example-jazz@gcmp.io"
|
||||
peer="wss://cloud.jazz.tools/?key=chat-example-jazz@garden.co"
|
||||
>
|
||||
{children}
|
||||
</Jazz.Provider>
|
||||
|
||||
@@ -6,7 +6,7 @@ import { Account, CoValue, ID } from "jazz-tools";
|
||||
|
||||
export function waitForUpload(id: ID<CoValue>, me: Account) {
|
||||
const syncManager = me._raw.core.node.syncManager;
|
||||
const peers = syncManager.getPeers();
|
||||
const peers = me._raw.core.node.peers.getAll();
|
||||
|
||||
return Promise.all(
|
||||
peers.map((peer) => syncManager.waitForUploadIntoPeer(peer.id, id)),
|
||||
|
||||
@@ -1,5 +1,22 @@
|
||||
# minimal-auth-clerk
|
||||
|
||||
## 0.0.14
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react@0.8.37
|
||||
- jazz-react-auth-clerk@0.8.37
|
||||
- jazz-tools@0.8.37
|
||||
|
||||
## 0.0.13
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [441fe27]
|
||||
- jazz-tools@0.8.36
|
||||
- jazz-react@0.8.36
|
||||
- jazz-react-auth-clerk@0.8.36
|
||||
|
||||
## 0.0.12
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Passkey authentication example with Jazz and React
|
||||
# Clerk authentication example with Jazz and React
|
||||
|
||||
This is an example of how to use clerk authentication with Jazz.
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "clerk",
|
||||
"private": true,
|
||||
"version": "0.0.12",
|
||||
"version": "0.0.14",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
@@ -14,7 +14,7 @@
|
||||
"@clerk/clerk-react": "^5.4.1",
|
||||
"jazz-tools": "workspace:*",
|
||||
"jazz-react": "workspace:*",
|
||||
"jazz-react-auth-clerk": "workspace:0.8.35",
|
||||
"jazz-react-auth-clerk": "workspace:0.8.37",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1"
|
||||
},
|
||||
|
||||
@@ -28,7 +28,7 @@ function JazzAndAuth({ children }: { children: React.ReactNode }) {
|
||||
{clerk.user && auth ? (
|
||||
<Jazz.Provider
|
||||
auth={auth}
|
||||
peer="wss://cloud.jazz.tools/?key=minimal-auth-clerk-example@gcmp.io"
|
||||
peer="wss://cloud.jazz.tools/?key=minimal-auth-clerk-example@garden.co"
|
||||
>
|
||||
{children}
|
||||
</Jazz.Provider>
|
||||
|
||||
@@ -1,5 +1,22 @@
|
||||
# image-upload
|
||||
|
||||
## 0.0.12
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react@0.8.37
|
||||
- jazz-tools@0.8.37
|
||||
- jazz-browser-media-images@0.8.37
|
||||
|
||||
## 0.0.11
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [441fe27]
|
||||
- jazz-tools@0.8.36
|
||||
- jazz-react@0.8.36
|
||||
- jazz-browser-media-images@0.8.36
|
||||
|
||||
## 0.0.10
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "image-upload",
|
||||
"private": true,
|
||||
"version": "0.0.10",
|
||||
"version": "0.0.12",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
||||
@@ -5,17 +5,19 @@ function App() {
|
||||
const { me, logOut } = useAccount();
|
||||
|
||||
return (
|
||||
<div className="container">
|
||||
<nav>
|
||||
<span>
|
||||
You're logged in as <strong>{me?.profile?.name}</strong>
|
||||
</span>
|
||||
<button onClick={() => logOut()}>Logout</button>
|
||||
</nav>
|
||||
<main>
|
||||
<>
|
||||
<header>
|
||||
<nav className="container">
|
||||
<span>
|
||||
You're logged in as <strong>{me?.profile?.name}</strong>
|
||||
</span>
|
||||
<button onClick={() => logOut()}>Log out</button>
|
||||
</nav>
|
||||
</header>
|
||||
<main className="container">
|
||||
<ImageUpload />
|
||||
</main>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
text-rendering: optimizeLegibility;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
--border-color: #2f2e2d;
|
||||
}
|
||||
|
||||
html,
|
||||
@@ -19,6 +20,10 @@ body,
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
button {
|
||||
border-radius: 8px;
|
||||
border: 0;
|
||||
@@ -30,6 +35,7 @@ button {
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
:root {
|
||||
--border-color: #e5e5e5;
|
||||
color: #213547;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
@@ -43,23 +49,32 @@ button {
|
||||
}
|
||||
}
|
||||
|
||||
* {
|
||||
border-color: var(--border-color);
|
||||
}
|
||||
|
||||
header,
|
||||
main {
|
||||
padding: 0.5rem 0;
|
||||
}
|
||||
|
||||
header {
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
nav {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0.5rem 0;
|
||||
border-bottom: 1px solid whitesmoke;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 500px;
|
||||
margin: 0 auto;
|
||||
padding: 0 1rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
margin-right: auto;
|
||||
margin-left: auto;
|
||||
padding-right: 0.75rem;
|
||||
padding-left: 0.75rem;
|
||||
max-width: 800px;
|
||||
}
|
||||
|
||||
label {
|
||||
|
||||
@@ -18,11 +18,14 @@ function JazzAndAuth({ children }: { children: React.ReactNode }) {
|
||||
<>
|
||||
<Jazz.Provider
|
||||
auth={auth}
|
||||
peer="wss://cloud.jazz.tools/?key=image-upload-example@gcmp.io"
|
||||
peer="wss://cloud.jazz.tools/?key=image-upload-example@garden.co"
|
||||
>
|
||||
{children}
|
||||
</Jazz.Provider>
|
||||
<DemoAuthBasicUI appName="Image upload" state={authState} />
|
||||
|
||||
{authState.state !== "signedIn" && (
|
||||
<DemoAuthBasicUI appName="Image upload" state={authState} />
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,21 @@
|
||||
# jazz-example-inspector
|
||||
|
||||
## 0.0.84
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [3d9f12e]
|
||||
- cojson@0.8.37
|
||||
- cojson-transport-ws@0.8.37
|
||||
|
||||
## 0.0.83
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [441fe27]
|
||||
- cojson@0.8.36
|
||||
- cojson-transport-ws@0.8.36
|
||||
|
||||
## 0.0.82
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM caddy:2.7.3-alpine
|
||||
LABEL org.opencontainers.image.source="https://github.com/gardencmp/jazz"
|
||||
LABEL org.opencontainers.image.source="https://github.com/garden-co/jazz"
|
||||
|
||||
COPY ./dist /usr/share/caddy/
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "jazz-inspector",
|
||||
"private": true,
|
||||
"version": "0.0.82",
|
||||
"version": "0.0.84",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
@@ -16,8 +16,8 @@
|
||||
"@radix-ui/react-toast": "^1.1.4",
|
||||
"class-variance-authority": "^0.7.0",
|
||||
"clsx": "^2.0.0",
|
||||
"cojson": "workspace:0.8.35",
|
||||
"cojson-transport-ws": "workspace:0.8.35",
|
||||
"cojson": "workspace:0.8.37",
|
||||
"cojson-transport-ws": "workspace:0.8.37",
|
||||
"hash-slash": "workspace:0.2.1",
|
||||
"lucide-react": "^0.274.0",
|
||||
"qrcode": "^1.5.3",
|
||||
|
||||
@@ -1,5 +1,20 @@
|
||||
# jazz-example-musicplayer
|
||||
|
||||
## 0.0.35
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react@0.8.37
|
||||
- jazz-tools@0.8.37
|
||||
|
||||
## 0.0.34
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [441fe27]
|
||||
- jazz-tools@0.8.36
|
||||
- jazz-react@0.8.36
|
||||
|
||||
## 0.0.33
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM caddy:2.7.3-alpine
|
||||
LABEL org.opencontainers.image.source="https://github.com/gardencmp/jazz"
|
||||
LABEL org.opencontainers.image.source="https://github.com/garden-co/jazz"
|
||||
|
||||
COPY ./dist /usr/share/caddy/
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "jazz-example-music-player",
|
||||
"private": true,
|
||||
"version": "0.0.33",
|
||||
"version": "0.0.35",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
@@ -18,8 +18,8 @@
|
||||
"@radix-ui/react-toast": "^1.1.4",
|
||||
"class-variance-authority": "^0.7.0",
|
||||
"clsx": "^2.0.0",
|
||||
"jazz-react": "workspace:0.8.35",
|
||||
"jazz-tools": "workspace:0.8.35",
|
||||
"jazz-react": "workspace:0.8.37",
|
||||
"jazz-tools": "workspace:0.8.37",
|
||||
"lucide-react": "^0.274.0",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
|
||||
@@ -66,7 +66,7 @@ function JazzAndAuth({ children }: { children: React.ReactNode }) {
|
||||
(new URL(window.location.href).searchParams.get(
|
||||
"peer",
|
||||
) as `ws://${string}`) ??
|
||||
"wss://cloud.jazz.tools/?key=music-player-example-jazz@gcmp.io";
|
||||
"wss://cloud.jazz.tools/?key=music-player-example-jazz@garden.co";
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
@@ -1,5 +1,22 @@
|
||||
# jazz-example-onboarding
|
||||
|
||||
## 0.0.16
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react@0.8.37
|
||||
- jazz-tools@0.8.37
|
||||
- jazz-browser-media-images@0.8.37
|
||||
|
||||
## 0.0.15
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [441fe27]
|
||||
- jazz-tools@0.8.36
|
||||
- jazz-react@0.8.36
|
||||
- jazz-browser-media-images@0.8.36
|
||||
|
||||
## 0.0.14
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM caddy:2.7.3-alpine
|
||||
LABEL org.opencontainers.image.source="https://github.com/gardencmp/jazz"
|
||||
LABEL org.opencontainers.image.source="https://github.com/garden-co/jazz"
|
||||
|
||||
COPY ./dist /usr/share/caddy/
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "jazz-example-onboarding",
|
||||
"private": true,
|
||||
"version": "0.0.14",
|
||||
"version": "0.0.16",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import App from "@/App.tsx";
|
||||
import React from "react";
|
||||
import ReactDOM from "react-dom/client";
|
||||
import "@/index.css";
|
||||
import { HRAccount } from "@/schema.ts";
|
||||
import { DemoAuthBasicUI, createJazzReactApp, useDemoAuth } from "jazz-react";
|
||||
import React from "react";
|
||||
import ReactDOM from "react-dom/client";
|
||||
|
||||
const Jazz = createJazzReactApp({
|
||||
AccountSchema: HRAccount,
|
||||
@@ -14,7 +14,7 @@ const peer =
|
||||
(new URL(window.location.href).searchParams.get(
|
||||
"peer",
|
||||
) as `ws://${string}`) ??
|
||||
"wss://cloud.jazz.tools/?key=onboarding-example-jazz@gcmp.io";
|
||||
"wss://cloud.jazz.tools/?key=onboarding-example-jazz@garden.co";
|
||||
|
||||
function JazzAndAuth({ children }: { children: React.ReactNode }) {
|
||||
const [auth, authState] = useDemoAuth();
|
||||
|
||||
@@ -1,5 +1,17 @@
|
||||
# passkey-svelte
|
||||
|
||||
## 0.0.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-svelte@0.0.4
|
||||
|
||||
## 0.0.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-svelte@0.0.3
|
||||
|
||||
## 0.0.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
{
|
||||
"name": "passkey-svelte",
|
||||
"version": "0.0.2",
|
||||
"version": "0.0.4",
|
||||
"type": "module",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "vite dev",
|
||||
"build": "vite build",
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
{#if auth.current}
|
||||
<Provider
|
||||
auth={auth.current}
|
||||
peer="wss://cloud.jazz.tools/?key=minimal-svelte-auth-passkey@gcmp.io"
|
||||
peer="wss://cloud.jazz.tools/?key=minimal-svelte-auth-passkey@garden.co"
|
||||
>
|
||||
{@render children?.()}
|
||||
</Provider>
|
||||
|
||||
@@ -1,5 +1,20 @@
|
||||
# minimal-auth-passkey
|
||||
|
||||
## 0.0.13
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react@0.8.37
|
||||
- jazz-tools@0.8.37
|
||||
|
||||
## 0.0.12
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [441fe27]
|
||||
- jazz-tools@0.8.36
|
||||
- jazz-react@0.8.36
|
||||
|
||||
## 0.0.11
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "passkey",
|
||||
"private": true,
|
||||
"version": "0.0.11",
|
||||
"version": "0.0.13",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
||||
@@ -21,7 +21,7 @@ function JazzAndAuth({ children }: { children: React.ReactNode }) {
|
||||
<>
|
||||
<Jazz.Provider
|
||||
auth={auth}
|
||||
peer="wss://cloud.jazz.tools/?key=minimal-auth-passkey-example@gcmp.io"
|
||||
peer="wss://cloud.jazz.tools/?key=minimal-auth-passkey-example@garden.co"
|
||||
>
|
||||
{children}
|
||||
</Jazz.Provider>
|
||||
|
||||
@@ -1,5 +1,20 @@
|
||||
# jazz-password-manager
|
||||
|
||||
## 0.0.34
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react@0.8.37
|
||||
- jazz-tools@0.8.37
|
||||
|
||||
## 0.0.33
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [441fe27]
|
||||
- jazz-tools@0.8.36
|
||||
- jazz-react@0.8.36
|
||||
|
||||
## 0.0.32
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "jazz-password-manager",
|
||||
"private": true,
|
||||
"version": "0.0.32",
|
||||
"version": "0.0.34",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
@@ -12,8 +12,8 @@
|
||||
"clean-install": "rm -rf node_modules pnpm-lock.yaml && pnpm install"
|
||||
},
|
||||
"dependencies": {
|
||||
"jazz-react": "workspace:0.8.35",
|
||||
"jazz-tools": "workspace:0.8.35",
|
||||
"jazz-react": "workspace:0.8.37",
|
||||
"jazz-tools": "workspace:0.8.37",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-hook-form": "^7.41.5",
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import ReactDOM from "react-dom/client";
|
||||
import App from "./5_App.tsx";
|
||||
import "./index.css";
|
||||
import {
|
||||
PasskeyAuthBasicUI,
|
||||
createJazzReactApp,
|
||||
usePasskeyAuth,
|
||||
} from "jazz-react";
|
||||
import React from "react";
|
||||
import ReactDOM from "react-dom/client";
|
||||
import { PasswordManagerAccount } from "./1_schema.ts";
|
||||
import App from "./5_App.tsx";
|
||||
import "./index.css";
|
||||
|
||||
const Jazz = createJazzReactApp<PasswordManagerAccount>({
|
||||
AccountSchema: PasswordManagerAccount,
|
||||
@@ -24,7 +24,7 @@ function JazzAndAuth({ children }: { children: React.ReactNode }) {
|
||||
<>
|
||||
<Jazz.Provider
|
||||
auth={auth}
|
||||
peer="wss://cloud.jazz.tools/?key=password-manager-example-jazz@gcmp.io"
|
||||
peer="wss://cloud.jazz.tools/?key=password-manager-example-jazz@garden.co"
|
||||
>
|
||||
{children}
|
||||
</Jazz.Provider>
|
||||
|
||||
@@ -1,5 +1,22 @@
|
||||
# jazz-example-pets
|
||||
|
||||
## 0.0.132
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react@0.8.37
|
||||
- jazz-tools@0.8.37
|
||||
- jazz-browser-media-images@0.8.37
|
||||
|
||||
## 0.0.131
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [441fe27]
|
||||
- jazz-tools@0.8.36
|
||||
- jazz-react@0.8.36
|
||||
- jazz-browser-media-images@0.8.36
|
||||
|
||||
## 0.0.130
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM caddy:2.7.3-alpine
|
||||
LABEL org.opencontainers.image.source="https://github.com/gardencmp/jazz"
|
||||
LABEL org.opencontainers.image.source="https://github.com/garden-co/jazz"
|
||||
|
||||
COPY ./dist /usr/share/caddy/
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "jazz-example-pets",
|
||||
"private": true,
|
||||
"version": "0.0.130",
|
||||
"version": "0.0.132",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
@@ -19,9 +19,9 @@
|
||||
"@radix-ui/react-toast": "^1.1.4",
|
||||
"class-variance-authority": "^0.7.0",
|
||||
"clsx": "^2.0.0",
|
||||
"jazz-browser-media-images": "workspace:0.8.35",
|
||||
"jazz-react": "workspace:0.8.35",
|
||||
"jazz-tools": "workspace:0.8.35",
|
||||
"jazz-browser-media-images": "workspace:0.8.37",
|
||||
"jazz-react": "workspace:0.8.37",
|
||||
"jazz-tools": "workspace:0.8.37",
|
||||
"lucide-react": "^0.274.0",
|
||||
"qrcode": "^1.5.3",
|
||||
"react": "^18.2.0",
|
||||
@@ -41,7 +41,7 @@
|
||||
"@vitejs/plugin-react-swc": "^3.3.2",
|
||||
"autoprefixer": "^10.4.14",
|
||||
"is-ci": "^3.0.1",
|
||||
"jazz-run": "workspace:0.8.35",
|
||||
"jazz-run": "workspace:0.8.37",
|
||||
"postcss": "^8.4.27",
|
||||
"tailwindcss": "3.3.2",
|
||||
"typescript": "^5.3.3",
|
||||
|
||||
@@ -27,7 +27,7 @@ export default defineConfig({
|
||||
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
|
||||
use: {
|
||||
/* Base URL to use in actions like `await page.goto('/')`. */
|
||||
baseURL: "http://localhost:5173/?peer=ws://localhost:1234",
|
||||
baseURL: "http://localhost:5173/",
|
||||
|
||||
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
|
||||
trace: "on-first-retry",
|
||||
@@ -49,10 +49,5 @@ export default defineConfig({
|
||||
url: "http://localhost:5173/",
|
||||
reuseExistingServer: !isCI,
|
||||
},
|
||||
{
|
||||
command: "pnpm sync --in-memory --port 1234",
|
||||
url: "http://localhost:1234/health",
|
||||
reuseExistingServer: !isCI,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
@@ -23,7 +23,8 @@ const peer =
|
||||
(new URL(window.location.href).searchParams.get(
|
||||
"peer",
|
||||
) as `ws://${string}`) ??
|
||||
"wss://cloud.jazz.tools/?key=pets-example-jazz@gcmp.io";
|
||||
"wss://cloud.jazz.tools/?key=pets-example-jazz@garden.co";
|
||||
// "ws://localhost:4200/?key=pets-example-jazz@gcmp.io";
|
||||
|
||||
/** Walkthrough: The top-level provider `<Jazz.Provider/>`
|
||||
*
|
||||
|
||||
@@ -1,5 +1,22 @@
|
||||
# reactions
|
||||
|
||||
## 0.0.12
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react@0.8.37
|
||||
- jazz-tools@0.8.37
|
||||
- jazz-browser-media-images@0.8.37
|
||||
|
||||
## 0.0.11
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [441fe27]
|
||||
- jazz-tools@0.8.36
|
||||
- jazz-react@0.8.36
|
||||
- jazz-browser-media-images@0.8.36
|
||||
|
||||
## 0.0.10
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "reactions",
|
||||
"private": true,
|
||||
"version": "0.0.10",
|
||||
"version": "0.0.12",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
||||
@@ -17,21 +17,27 @@ function App() {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="container">
|
||||
<nav>
|
||||
<span>
|
||||
You're logged in as <strong>{me?.profile?.name}</strong>
|
||||
</span>
|
||||
<button className="btn" onClick={() => logOut()}>
|
||||
Logout
|
||||
</button>
|
||||
</nav>
|
||||
<>
|
||||
<header>
|
||||
<nav className="container">
|
||||
<span>
|
||||
You're logged in as <strong>{me?.profile?.name}</strong>
|
||||
</span>
|
||||
<button className="btn" onClick={() => logOut()}>
|
||||
Log out
|
||||
</button>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
{router.route({
|
||||
"/": () => createReactions() as never,
|
||||
"/reactions/:id": (id) => <ReactionsScreen id={id as ID<Reactions>} />,
|
||||
})}
|
||||
</div>
|
||||
<main className="container">
|
||||
{router.route({
|
||||
"/": () => createReactions() as never,
|
||||
"/reactions/:id": (id) => (
|
||||
<ReactionsScreen id={id as ID<Reactions>} />
|
||||
),
|
||||
})}
|
||||
</main>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,13 +5,27 @@
|
||||
|
||||
color-scheme: light dark;
|
||||
color: rgba(255, 255, 255, 0.87);
|
||||
background-color: #000;
|
||||
background-color: #242424;
|
||||
|
||||
font-synthesis: none;
|
||||
text-rendering: optimizeLegibility;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
--border-color: #404040;
|
||||
--border-color: #2f2e2d;
|
||||
}
|
||||
|
||||
html,
|
||||
body,
|
||||
#root {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
button {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
button.btn {
|
||||
@@ -43,29 +57,28 @@ button.btn {
|
||||
border-color: var(--border-color);
|
||||
}
|
||||
|
||||
html,
|
||||
body,
|
||||
#root {
|
||||
height: 100%;
|
||||
header,
|
||||
main {
|
||||
padding: 0.5rem 0;
|
||||
}
|
||||
|
||||
header {
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
nav {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0.5rem 0;
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 500px;
|
||||
margin: 0 auto;
|
||||
padding: 0 1rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
margin-right: auto;
|
||||
margin-left: auto;
|
||||
padding-right: 0.75rem;
|
||||
padding-left: 0.75rem;
|
||||
max-width: 800px;
|
||||
}
|
||||
|
||||
h1,
|
||||
|
||||
@@ -15,11 +15,14 @@ function JazzAndAuth({ children }: { children: React.ReactNode }) {
|
||||
<>
|
||||
<Jazz.Provider
|
||||
auth={auth}
|
||||
peer="wss://cloud.jazz.tools/?key=reactions-example@gcmp.io"
|
||||
peer="wss://cloud.jazz.tools/?key=reactions-example@garden.co"
|
||||
>
|
||||
{children}
|
||||
</Jazz.Provider>
|
||||
<DemoAuthBasicUI appName="Reactions" state={authState} />
|
||||
|
||||
{authState.state !== "signedIn" && (
|
||||
<DemoAuthBasicUI appName="Reactions" state={authState} />
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,22 @@
|
||||
# todo-vue
|
||||
|
||||
## 0.0.18
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-browser@0.8.37
|
||||
- jazz-tools@0.8.37
|
||||
- jazz-vue@0.8.25
|
||||
|
||||
## 0.0.17
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [441fe27]
|
||||
- jazz-tools@0.8.36
|
||||
- jazz-browser@0.8.36
|
||||
- jazz-vue@0.8.24
|
||||
|
||||
## 0.0.16
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "todo-vue",
|
||||
"version": "0.0.16",
|
||||
"version": "0.0.18",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import "./assets/main.css";
|
||||
import { DemoAuthBasicUI, createJazzVueApp, useDemoAuth } from "jazz-vue";
|
||||
import { createApp, defineComponent, h } from "vue";
|
||||
import App from "./App.vue";
|
||||
import "./assets/main.css";
|
||||
import router from "./router";
|
||||
import { ToDoAccount } from "./schema";
|
||||
|
||||
@@ -19,7 +19,7 @@ const RootComponent = defineComponent({
|
||||
JazzProvider,
|
||||
{
|
||||
auth: authMethod.value,
|
||||
peer: "wss://mesh.jazz.tools/?key=vue-todo-example-jazz@gcmp.io",
|
||||
peer: "wss://cloud.jazz.tools/?key=vue-todo-example-jazz@garden.co",
|
||||
},
|
||||
{
|
||||
default: () => h(App),
|
||||
|
||||
@@ -1,5 +1,20 @@
|
||||
# jazz-example-todo
|
||||
|
||||
## 0.0.131
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react@0.8.37
|
||||
- jazz-tools@0.8.37
|
||||
|
||||
## 0.0.130
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [441fe27]
|
||||
- jazz-tools@0.8.36
|
||||
- jazz-react@0.8.36
|
||||
|
||||
## 0.0.129
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM caddy:2.7.3-alpine
|
||||
LABEL org.opencontainers.image.source="https://github.com/gardencmp/jazz"
|
||||
LABEL org.opencontainers.image.source="https://github.com/garden-co/jazz"
|
||||
|
||||
COPY ./dist /usr/share/caddy/
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "jazz-example-todo",
|
||||
"private": true,
|
||||
"version": "0.0.129",
|
||||
"version": "0.0.131",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
@@ -16,8 +16,8 @@
|
||||
"@radix-ui/react-toast": "^1.1.4",
|
||||
"class-variance-authority": "^0.7.0",
|
||||
"clsx": "^2.0.0",
|
||||
"jazz-react": "workspace:0.8.35",
|
||||
"jazz-tools": "workspace:0.8.35",
|
||||
"jazz-react": "workspace:0.8.37",
|
||||
"jazz-tools": "workspace:0.8.37",
|
||||
"lucide-react": "^0.274.0",
|
||||
"qrcode": "^1.5.3",
|
||||
"react": "^18.2.0",
|
||||
|
||||
@@ -48,7 +48,7 @@ function JazzAndAuth({ children }: { children: React.ReactNode }) {
|
||||
<>
|
||||
<Jazz.Provider
|
||||
auth={passkeyAuth}
|
||||
peer="wss://cloud.jazz.tools/?key=todo-example-jazz@gcmp.io"
|
||||
peer="wss://cloud.jazz.tools/?key=todo-example-jazz@garden.co"
|
||||
>
|
||||
{children}
|
||||
</Jazz.Provider>
|
||||
|
||||
@@ -76,6 +76,13 @@ export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
|
||||
>
|
||||
<ButtonIcon icon={icon} loading={loading} />
|
||||
{children}
|
||||
{newTab ? (
|
||||
<span className="inline-block text-stone-300 dark:text-stone-700 relative -top-0.5 -left-2 -mr-2">
|
||||
⌝
|
||||
</span>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -7,22 +7,30 @@ export function GappedGrid({
|
||||
className,
|
||||
title,
|
||||
cols = 3,
|
||||
gap = "md",
|
||||
}: {
|
||||
children: ReactNode;
|
||||
className?: string;
|
||||
title?: string;
|
||||
cols?: 3 | 4;
|
||||
gap?: "none" | "md";
|
||||
}) {
|
||||
const colsClassName =
|
||||
cols === 3
|
||||
? "grid-cols-2 md:grid-cols-4 lg:grid-cols-6"
|
||||
: "sm:grid-cols-2 lg:grid-cols-4";
|
||||
|
||||
const gapClassName = {
|
||||
none: "gap-0",
|
||||
md: "gap-4 lg:gap-8",
|
||||
}[gap];
|
||||
|
||||
return (
|
||||
<div
|
||||
className={clsx(
|
||||
"grid gap-4 lg:gap-8",
|
||||
"grid",
|
||||
colsClassName,
|
||||
gapClassName,
|
||||
"items-stretch",
|
||||
className,
|
||||
)}
|
||||
|
||||
@@ -3,10 +3,14 @@
|
||||
import clsx from "clsx";
|
||||
import { MoonIcon, SunIcon } from "lucide-react";
|
||||
import { useTheme } from "next-themes";
|
||||
import { UseThemeProps } from "next-themes/dist/types";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
export function ThemeToggle({ className }: { className?: string }) {
|
||||
let { resolvedTheme, setTheme } = useTheme();
|
||||
export function ThemeToggle({
|
||||
className,
|
||||
resolvedTheme,
|
||||
setTheme,
|
||||
}: { className?: string } & UseThemeProps) {
|
||||
let otherTheme = resolvedTheme === "dark" ? "light" : "dark";
|
||||
let [mounted, setMounted] = useState(false);
|
||||
|
||||
|
||||
@@ -1,13 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { ThemeProvider as NextThemesProvider, useTheme } from "next-themes";
|
||||
import { type ThemeProviderProps } from "next-themes/dist/types";
|
||||
import * as React from "react";
|
||||
import { UseThemeProps } from "next-themes/dist/types";
|
||||
import { useEffect } from "react";
|
||||
|
||||
function ThemeWatcher() {
|
||||
let { resolvedTheme, setTheme } = useTheme();
|
||||
|
||||
export function ThemeWatcher({ resolvedTheme, setTheme }: UseThemeProps) {
|
||||
useEffect(() => {
|
||||
let media = window.matchMedia("(prefers-color-scheme: dark)");
|
||||
|
||||
@@ -28,12 +22,3 @@ function ThemeWatcher() {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
export function ThemeProvider({ children, ...props }: ThemeProviderProps) {
|
||||
return (
|
||||
<NextThemesProvider {...props}>
|
||||
<ThemeWatcher />
|
||||
{children}
|
||||
</NextThemesProvider>
|
||||
);
|
||||
}
|
||||
@@ -3,8 +3,7 @@
|
||||
import clsx from "clsx";
|
||||
import Link from "next/link";
|
||||
import { usePathname } from "next/navigation";
|
||||
import { ReactNode } from "react";
|
||||
import { ThemeToggle } from "../molecules/ThemeToggle";
|
||||
import { ComponentType, ReactNode } from "react";
|
||||
import { NewsletterForm } from "./NewsletterForm";
|
||||
import { SocialLinks, SocialLinksProps } from "./SocialLinks";
|
||||
|
||||
@@ -22,6 +21,7 @@ type FooterProps = {
|
||||
companyName: string;
|
||||
sections: FooterSection[];
|
||||
socials: SocialLinksProps;
|
||||
themeToggle: ComponentType<{ className?: string }>;
|
||||
};
|
||||
|
||||
function Copyright({
|
||||
@@ -38,7 +38,13 @@ function Copyright({
|
||||
);
|
||||
}
|
||||
|
||||
export function Footer({ logo, companyName, sections, socials }: FooterProps) {
|
||||
export function Footer({
|
||||
logo,
|
||||
companyName,
|
||||
sections,
|
||||
socials,
|
||||
themeToggle: ThemeToggle,
|
||||
}: FooterProps) {
|
||||
return (
|
||||
<footer className="w-full py-8 mt-12 md:mt-20">
|
||||
<div className="container grid gap-8 md:gap-12">
|
||||
|
||||
@@ -11,9 +11,15 @@ import clsx from "clsx";
|
||||
import { ChevronDownIcon, MenuIcon, XIcon } from "lucide-react";
|
||||
import Link from "next/link";
|
||||
import { usePathname } from "next/navigation";
|
||||
import { ReactNode, useEffect, useLayoutEffect, useRef, useState } from "react";
|
||||
import {
|
||||
ComponentType,
|
||||
ReactNode,
|
||||
useEffect,
|
||||
useLayoutEffect,
|
||||
useRef,
|
||||
useState,
|
||||
} from "react";
|
||||
import { BreadCrumb } from "../molecules/Breadcrumb";
|
||||
import { ThemeToggle } from "../molecules/ThemeToggle";
|
||||
import { SocialLinks, SocialLinksProps } from "./SocialLinks";
|
||||
|
||||
type NavItemProps = {
|
||||
@@ -32,6 +38,7 @@ type NavProps = {
|
||||
docNav?: ReactNode;
|
||||
cta?: ReactNode;
|
||||
socials?: SocialLinksProps;
|
||||
themeToggle: ComponentType<{ className?: string }>;
|
||||
};
|
||||
|
||||
function NavItem({
|
||||
@@ -112,7 +119,14 @@ function NavItem({
|
||||
);
|
||||
}
|
||||
|
||||
export function MobileNav({ mainLogo, items, docNav, cta, socials }: NavProps) {
|
||||
export function MobileNav({
|
||||
mainLogo,
|
||||
items,
|
||||
docNav,
|
||||
cta,
|
||||
socials,
|
||||
themeToggle: ThemeToggle,
|
||||
}: NavProps) {
|
||||
const [menuOpen, setMenuOpen] = useState(false);
|
||||
const [searchOpen, setSearchOpen] = useState(false);
|
||||
const searchRef = useRef<HTMLInputElement>(null);
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import "./globals.css";
|
||||
import { ThemeProvider } from "gcmp-design-system/src/app/components/molecules/ThemeProvider";
|
||||
import { ThemeProvider } from "@/components/ThemeProvider";
|
||||
import type { Metadata } from "next";
|
||||
import "./globals.css";
|
||||
|
||||
import { Inter, Manrope } from "next/font/google";
|
||||
import localFont from "next/font/local";
|
||||
|
||||
import { GcmpNav } from "@/components/Nav";
|
||||
import { ThemeToggle } from "@/components/ThemeToggle";
|
||||
import { Analytics } from "@vercel/analytics/react";
|
||||
import { SpeedInsights } from "@vercel/speed-insights/next";
|
||||
import { ThemeToggle } from "gcmp-design-system/src/app/components/molecules/ThemeToggle";
|
||||
|
||||
// If loading a variable font, you don't need to specify the font weight
|
||||
const manrope = Manrope({
|
||||
@@ -44,7 +44,7 @@ const metaTags = {
|
||||
title: "garden computing",
|
||||
description:
|
||||
"Computers are magic. So why do we put up with so much complexity? We believe just a few new ideas can make all the difference.",
|
||||
url: "https://gcmp.io",
|
||||
url: "https://garden.co",
|
||||
};
|
||||
|
||||
export const metadata: Metadata = {
|
||||
|
||||
@@ -20,7 +20,7 @@ export default function NewsPage() {
|
||||
<NewsletterForm />
|
||||
|
||||
<p>
|
||||
Follow us on <Link href="https://x.com/gcmp_io">@gcmp.io</Link> or{" "}
|
||||
Follow us on <Link href="https://x.com/gcmp_io">@garden.co</Link> or{" "}
|
||||
<Link href="https://x.com/jazz_tools">@jazz_tools</Link>.
|
||||
</p>
|
||||
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
import { ThemeToggle } from "@/components/ThemeToggle";
|
||||
import { Button } from "gcmp-design-system/src/app/components/atoms/Button";
|
||||
import { GcmpLogo } from "gcmp-design-system/src/app/components/atoms/logos/GcmpLogo";
|
||||
import { Nav } from "gcmp-design-system/src/app/components/organisms/Nav";
|
||||
export function GcmpNav() {
|
||||
const cta = (
|
||||
<Button variant="secondary" className="ml-auto" href="mailto:hello@gcmp.io">
|
||||
<Button
|
||||
variant="secondary"
|
||||
className="ml-auto"
|
||||
href="mailto:hello@garden.co"
|
||||
>
|
||||
Contact us
|
||||
</Button>
|
||||
);
|
||||
@@ -16,6 +21,7 @@ export function GcmpNav() {
|
||||
{ title: "Team", href: "/team" },
|
||||
]}
|
||||
cta={cta}
|
||||
themeToggle={ThemeToggle}
|
||||
></Nav>
|
||||
);
|
||||
}
|
||||
|
||||
16
homepage/gcmp/components/ThemeProvider.tsx
Normal file
16
homepage/gcmp/components/ThemeProvider.tsx
Normal file
@@ -0,0 +1,16 @@
|
||||
"use client";
|
||||
|
||||
import { ThemeWatcher } from "gcmp-design-system/src/app/components/molecules/ThemeWatcher";
|
||||
import { ThemeProvider as NextThemesProvider, useTheme } from "next-themes";
|
||||
import { type ThemeProviderProps } from "next-themes/dist/types";
|
||||
import * as React from "react";
|
||||
|
||||
export function ThemeProvider({ children, ...props }: ThemeProviderProps) {
|
||||
const useThemeProps = useTheme();
|
||||
return (
|
||||
<NextThemesProvider {...props}>
|
||||
<ThemeWatcher {...useThemeProps} />
|
||||
{children}
|
||||
</NextThemesProvider>
|
||||
);
|
||||
}
|
||||
10
homepage/gcmp/components/ThemeToggle.tsx
Normal file
10
homepage/gcmp/components/ThemeToggle.tsx
Normal file
@@ -0,0 +1,10 @@
|
||||
"use client";
|
||||
|
||||
import { ThemeToggle as GardenThemeToggle } from "gcmp-design-system/src/app/components/molecules/ThemeToggle";
|
||||
import { useTheme } from "next-themes";
|
||||
|
||||
export function ThemeToggle({ className }: { className?: string }) {
|
||||
let useThemeProps = useTheme();
|
||||
|
||||
return <GardenThemeToggle className={className} {...useThemeProps} />;
|
||||
}
|
||||
@@ -26,6 +26,7 @@
|
||||
"mdast-util-mdx": "^3.0.0",
|
||||
"micromark-extension-mdxjs": "^3.0.0",
|
||||
"next": "14.2.15",
|
||||
"next-themes": "^0.2.1",
|
||||
"react": "^18",
|
||||
"react-dom": "^18",
|
||||
"shiki": "^0.14.6",
|
||||
|
||||
@@ -3,8 +3,6 @@ import { clsx } from "clsx";
|
||||
import { MessageCircleQuestionIcon, PackageIcon } from "lucide-react";
|
||||
import Link from "next/link";
|
||||
|
||||
import { DocNav } from "@/components/docs/nav";
|
||||
|
||||
const CardHeading = ({
|
||||
children,
|
||||
className,
|
||||
@@ -95,7 +93,7 @@ export default function Page() {
|
||||
</Link>
|
||||
, or open an issue on{" "}
|
||||
<Link
|
||||
href="https://github.com/gardencmp/jazz"
|
||||
href="https://github.com/garden-co/jazz"
|
||||
className="underline"
|
||||
>
|
||||
GitHub
|
||||
|
||||
235
homepage/homepage/app/api/latencyMap/route.ts
Normal file
235
homepage/homepage/app/api/latencyMap/route.ts
Normal file
@@ -0,0 +1,235 @@
|
||||
import * as turf from "@turf/turf";
|
||||
import type { FeatureCollection, Point, Position } from "geojson";
|
||||
import { type NextRequest } from "next/server";
|
||||
import land from "../../../components/cloud/ne_110m_land.json";
|
||||
|
||||
import { pingColorThresholds } from "../../../components/cloud/pingColorThresholds";
|
||||
// generated with: globalping ping cloud.jazz.tools from world --limit 500 --packets 16 --json | jq "del(.results[].result.rawOutput)" > pings.json
|
||||
import pings from "../../../components/cloud/pings.json";
|
||||
|
||||
export const revalidate = 2 * 60 * 60; // 2 hours
|
||||
|
||||
export async function GET(req: NextRequest) {
|
||||
const spacing = parseFloat(req.nextUrl.searchParams.get("spacing") || "1.5");
|
||||
const dark = req.nextUrl.searchParams.get("dark") === "true";
|
||||
const addMouseScript = req.nextUrl.searchParams.get("mouse") === "true";
|
||||
|
||||
const serverLocations = [
|
||||
{
|
||||
city: "Los Angeles",
|
||||
lat: 34.0522,
|
||||
lng: -118.2437,
|
||||
ip: "134.195.91.235",
|
||||
color: "hsl(0, 50%, 50%)",
|
||||
},
|
||||
{
|
||||
city: "New York",
|
||||
lat: 40.7128,
|
||||
lng: -74.006,
|
||||
ip: "45.45.219.149",
|
||||
color: "hsl(25, 50%, 50%)",
|
||||
},
|
||||
{
|
||||
city: "London",
|
||||
lat: 51.5074,
|
||||
lng: -0.1278,
|
||||
ip: "150.107.201.83",
|
||||
color: "hsl(50, 50%, 50%)",
|
||||
},
|
||||
{
|
||||
city: "Singapore",
|
||||
lat: 1.3521,
|
||||
lng: 103.8198,
|
||||
ip: "103.214.23.227",
|
||||
color: "hsl(250, 50%, 50%)",
|
||||
},
|
||||
{
|
||||
city: "Sydney",
|
||||
lat: -33.8688,
|
||||
lng: 151.2153,
|
||||
ip: "103.73.65.179",
|
||||
color: "hsl(100, 50%, 50%)",
|
||||
},
|
||||
{
|
||||
city: "Tokyo",
|
||||
lat: 35.6895,
|
||||
lng: 139.7014,
|
||||
ip: "103.173.179.181",
|
||||
color: "hsl(150, 50%, 50%)",
|
||||
},
|
||||
{
|
||||
city: "Tel Aviv",
|
||||
lat: 32.0853,
|
||||
lng: 34.7818,
|
||||
ip: "64.176.162.228",
|
||||
color: "hsl(200, 50%, 50%)",
|
||||
},
|
||||
{
|
||||
city: "Johannesburg",
|
||||
lat: -26.2041,
|
||||
lng: 28.0473,
|
||||
ip: "139.84.228.42",
|
||||
color: "hsl(225, 50%, 50%)",
|
||||
},
|
||||
{
|
||||
city: "Vienna",
|
||||
lat: 48.2085,
|
||||
lng: 16.3721,
|
||||
ip: "185.175.59.44",
|
||||
color: "hsl(75, 50%, 50%)",
|
||||
},
|
||||
{
|
||||
city: "Sao Paulo",
|
||||
lat: -23.5505,
|
||||
lng: -46.6333,
|
||||
ip: "216.238.99.7",
|
||||
color: "hsl(275, 50%, 50%)",
|
||||
},
|
||||
{
|
||||
city: "Dallas",
|
||||
lat: 32.7767,
|
||||
lng: -96.797,
|
||||
ip: "45.32.192.94",
|
||||
color: "hsl(300, 50%, 50%)",
|
||||
},
|
||||
];
|
||||
|
||||
// create a grid of dots that are green if on land (contained in landOutlines) and blue if not
|
||||
const extentX = 720;
|
||||
const extentY = 160;
|
||||
const grid = new Array(Math.round(extentX / spacing))
|
||||
.fill(0)
|
||||
.map((_, i) =>
|
||||
new Array(Math.round(extentY / spacing))
|
||||
.fill(0)
|
||||
.map((_, j) => ({ x: i, y: j })),
|
||||
);
|
||||
// manually add Hawaii by lat/lng
|
||||
grid.push([{ x: -155.844437, y: 19.8987 }]);
|
||||
const dots = grid.flatMap((row) =>
|
||||
row.map(({ x, y }) => ({
|
||||
x: -450 + x * spacing + ((y % 2) * spacing) / 2,
|
||||
y: -60 + y * spacing,
|
||||
})),
|
||||
);
|
||||
const landPolygon = turf.multiPolygon(
|
||||
land.geometries.map((g) => g.coordinates),
|
||||
);
|
||||
const dotsOnLand = turf.pointsWithinPolygon(
|
||||
turf.points(dots.map((d) => [d.x, d.y])),
|
||||
landPolygon,
|
||||
) as FeatureCollection<Point>;
|
||||
|
||||
const scaleX = 3;
|
||||
const scaleY = 3;
|
||||
const offsetX = 600;
|
||||
const offsetY = 260;
|
||||
|
||||
const svg = `<svg
|
||||
viewBox="0 0 1200 440"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<style>
|
||||
circle {
|
||||
transition: fill 0.2s ease-in-out;
|
||||
}
|
||||
</style>
|
||||
${dotsOnLand.features
|
||||
.map((dot, index) => {
|
||||
const nearestMeasurement = pings.results.reduce(
|
||||
(minDistance, ping) => {
|
||||
if (
|
||||
!ping.result.stats ||
|
||||
ping.result.stats.rcv === 0 ||
|
||||
ping.result.stats.avg === null
|
||||
)
|
||||
return minDistance;
|
||||
const distance = turf.distance(
|
||||
dot.geometry.coordinates,
|
||||
[ping.probe.longitude, ping.probe.latitude],
|
||||
{ units: "kilometers" },
|
||||
);
|
||||
const totalPing =
|
||||
(2 * 1000 * distance) / (0.66 * 299_792) +
|
||||
ping.result.stats.min;
|
||||
|
||||
if (distance < minDistance.dist) {
|
||||
return {
|
||||
city: ping.probe.city,
|
||||
dist: distance,
|
||||
ping: ping.result.stats.min,
|
||||
totalPing,
|
||||
resolvedAddress: ping.result.resolvedAddress,
|
||||
};
|
||||
}
|
||||
return minDistance;
|
||||
},
|
||||
{
|
||||
city: "",
|
||||
dist: Infinity,
|
||||
ping: Infinity,
|
||||
totalPing: Infinity,
|
||||
resolvedAddress: "",
|
||||
},
|
||||
);
|
||||
|
||||
return `<circle cx="${
|
||||
dot.geometry.coordinates[0] * scaleX + offsetX
|
||||
}" cy="${
|
||||
-dot.geometry.coordinates[1] * scaleY + offsetY
|
||||
}" r="${1.9 * spacing}" fill="${
|
||||
pingColorThresholds.find(
|
||||
(t) => nearestMeasurement.totalPing < t.ping,
|
||||
)?.[dark ? "darkFill" : "fill"]
|
||||
// serverLocations.find(
|
||||
// (srv) => srv.ip == nearestMeasurement.resolvedAddress,
|
||||
// )?.color
|
||||
}" data-ping="${nearestMeasurement.totalPing.toFixed(
|
||||
1,
|
||||
)}ms" data-via="${nearestMeasurement.city + ""}" data-to="${
|
||||
serverLocations.find(
|
||||
(srv) => srv.ip == nearestMeasurement.resolvedAddress,
|
||||
)?.city
|
||||
}"/>`;
|
||||
})
|
||||
.join("\n")}
|
||||
${
|
||||
addMouseScript
|
||||
? `<script>
|
||||
document.addEventListener("mousemove", (e) => {
|
||||
const target = e.target;
|
||||
|
||||
if (target?.nodeName === "circle") {
|
||||
const x = target.cx.baseVal.value;
|
||||
const y = target.cy.baseVal.value;
|
||||
const ping = parseInt(target.dataset.ping || "0");
|
||||
const via = target.dataset.via;
|
||||
const to = target.dataset.to;
|
||||
const text = \`\${ping}ms via \${via} to \${to}\`;
|
||||
|
||||
window.parent.postMessage({
|
||||
type: "svgmouseover",
|
||||
x,
|
||||
y,
|
||||
ping,
|
||||
via,
|
||||
to,
|
||||
}, "*");
|
||||
} else {
|
||||
window.parent.postMessage({
|
||||
type: "svgmouseout",
|
||||
}, "*");
|
||||
}
|
||||
});
|
||||
</script>`
|
||||
: ""
|
||||
}
|
||||
</svg>`;
|
||||
|
||||
return new Response(svg, {
|
||||
headers: {
|
||||
"Content-Type": "image/svg+xml",
|
||||
"Cache-Control": "public, s-maxage=7200, stale-while-revalidate=3600",
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
#### Jazz Cloud + Data Backup Node
|
||||
|
||||
<p className="no-prose text-base">
|
||||
<span className="no-prose text-base">
|
||||
Connect your users to Jazz Cloud for all its benefits, but also run and
|
||||
connect your own data backup node.
|
||||
</p>
|
||||
</span>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#### Jazz Cloud + DIY Cloud
|
||||
|
||||
<p className="no-prose text-base">
|
||||
<span className="no-prose text-base">
|
||||
Connect your users to Jazz Cloud, or your own nodes as a lower-performance
|
||||
fallback. The two networks stay in constant sync.
|
||||
</p>
|
||||
</span>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#### Completely DIY Cloud
|
||||
<p className="no-prose text-base">
|
||||
|
||||
<span className="no-prose text-base">
|
||||
Build your own network of sync and storage nodes. Handle
|
||||
devops,networking, security and backups yourself.
|
||||
</p>
|
||||
</span>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Pricing } from "@/components/Pricing";
|
||||
import { LatencyMap } from "@/components/cloud/latencyMap";
|
||||
import { GridCard } from "gcmp-design-system/src/app/components/atoms/GridCard";
|
||||
import {
|
||||
H2,
|
||||
@@ -24,12 +25,12 @@ export const metadata = {
|
||||
export default function Cloud() {
|
||||
return (
|
||||
<div className="space-y-16">
|
||||
<HeroHeader
|
||||
className="container"
|
||||
title="Jazz Cloud"
|
||||
slogan="Real-time sync and storage infrastructure that scales up to millions of users."
|
||||
/>
|
||||
<div className="container">
|
||||
<div className="container space-y-12 overflow-x-hidden sm:overflow-x-visible">
|
||||
<HeroHeader
|
||||
title="Jazz Cloud"
|
||||
slogan="Real-time sync and storage infrastructure that scales up to millions of users."
|
||||
/>
|
||||
<LatencyMap />
|
||||
<GappedGrid>
|
||||
<GridCard>
|
||||
<H3>Optimal cloud routing</H3>
|
||||
@@ -66,69 +67,6 @@ export default function Cloud() {
|
||||
</div>
|
||||
|
||||
<div className="container space-y-16">
|
||||
<div>
|
||||
<SectionHeader
|
||||
title="Global footprint"
|
||||
slogan="We're rapidly expanding our network of sync & storage nodes. This is our current coverage."
|
||||
/>
|
||||
<GappedGrid>
|
||||
<div className="text-sm">
|
||||
<H4>Under 50ms RTT</H4>
|
||||
<UL>
|
||||
<LI>Frankfurt</LI>
|
||||
<LI>New York</LI>
|
||||
<LI>Newark</LI>
|
||||
<LI>North California</LI>
|
||||
<LI>North Virginia</LI>
|
||||
<LI>San Francisco</LI>
|
||||
<LI>Singapore</LI>
|
||||
<LI>Toronto</LI>
|
||||
</UL>
|
||||
</div>
|
||||
|
||||
<div className="text-sm">
|
||||
<H4>Under 100ms RTT</H4>
|
||||
<UL>
|
||||
<LI>Amsterdam</LI>
|
||||
<LI>Atlanta</LI>
|
||||
<LI>London</LI>
|
||||
<LI>Ohio</LI>
|
||||
<LI>Paris</LI>
|
||||
</UL>
|
||||
</div>
|
||||
|
||||
<div className="text-sm">
|
||||
<H4>Under 200ms RTT</H4>
|
||||
<UL>
|
||||
<LI>Bangalore</LI>
|
||||
<LI>Dallas</LI>
|
||||
<LI>Mumbai</LI>
|
||||
<LI>Oregon</LI>
|
||||
</UL>
|
||||
|
||||
<H4>Under 300ms RTT</H4>
|
||||
<UL>
|
||||
<LI> Seoul</LI>
|
||||
<LI> Tokyo</LI>
|
||||
</UL>
|
||||
</div>
|
||||
|
||||
<div className="text-sm">
|
||||
<H4>Under 400ms RTT</H4>
|
||||
<UL>
|
||||
<LI>Sao Paulo</LI>
|
||||
<LI>Sydney</LI>
|
||||
</UL>
|
||||
|
||||
<H4>Under 500ms RTT</H4>
|
||||
|
||||
<UL>
|
||||
<LI>Cape Town</LI>
|
||||
</UL>
|
||||
</div>
|
||||
</GappedGrid>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<SectionHeader
|
||||
title="Custom deployment scenarios"
|
||||
|
||||
@@ -16,7 +16,7 @@ Passphrase authentication is supported out of the box and imported from `jazz-re
|
||||
|
||||
### How to use
|
||||
|
||||
1. Setup up Jazz as described in the [React setup guide](/docs/project-setup/react).
|
||||
1. Setup up Jazz as described in the [setup guide](/docs/project-setup).
|
||||
|
||||
2. Use the `usePassphraseAuth` hook to authenticate.
|
||||
|
||||
@@ -36,11 +36,11 @@ Passkey authentication allows users to create a new account or log in with an ex
|
||||
|
||||
Passkey authentication is supported out of the box.
|
||||
|
||||
We have a [minimal example of a passkey authentication setup](https://github.com/garden-co/jazz/tree/main/examples/minimal-auth-passkey).
|
||||
We have a [minimal example of a passkey authentication setup](https://github.com/garden-co/jazz/tree/main/examples/passkey).
|
||||
|
||||
### How to use
|
||||
|
||||
1. Setup up Jazz as described in the [React setup guide](/docs/project-setup/react).
|
||||
1. Setup up Jazz as described in the [setup guide](/docs/project-setup).
|
||||
|
||||
2. Use the `usePasskeyAuth` hook to authenticate.
|
||||
|
||||
@@ -56,13 +56,13 @@ const [passkeyAuth, passkeyState] = usePasskeyAuth({ appName });
|
||||
|
||||
## Clerk
|
||||
|
||||
We have a React package `jazz-react-auth-clerk` to add Clerk authentication to your app.
|
||||
We have a React package `jazz-react-auth-clerk` to add Clerk authentication to your app.
|
||||
|
||||
We have a [minimal example of a Clerk authentication setup](https://github.com/garden-co/jazz/tree/main/examples/minimal-auth-clerk).
|
||||
We have a [minimal example of a Clerk authentication setup](https://github.com/garden-co/jazz/tree/main/examples/clerk).
|
||||
|
||||
### How to use
|
||||
|
||||
1. Setup up Jazz as described in the [React setup guide](/docs/project-setup/react).
|
||||
1. Setup up Jazz as described in the [setup guide](/docs/project-setup).
|
||||
|
||||
2. Install Clerk as described in the [Clerk docs](https://clerk.com/docs/components/overview).
|
||||
|
||||
@@ -108,4 +108,4 @@ createRoot(document.getElementById("root")!).render(
|
||||
</StrictMode>,
|
||||
);
|
||||
```
|
||||
</CodeGroup>
|
||||
</CodeGroup>
|
||||
|
||||
@@ -1,33 +1,21 @@
|
||||
import DocsLayout from "@/app/docs/[framework]/(others)/layout";
|
||||
import { TableOfContents } from "@/components/docs/TableOfContents";
|
||||
import ComingSoonPage from "@/components/docs/coming-soon.mdx";
|
||||
import { docNavigationItems } from "@/lib/docNavigationItems";
|
||||
import { Framework, frameworks, isValidFramework } from "@/lib/framework";
|
||||
import type { Toc } from "@stefanprobst/rehype-extract-toc";
|
||||
import { Prose } from "gcmp-design-system/src/app/components/molecules/Prose";
|
||||
|
||||
function Error({ slugPath }: { slugPath: string }) {
|
||||
return (
|
||||
<Prose className="overflow-x-hidden lg:flex-1">
|
||||
<h3>Error loading page: {slugPath}</h3>
|
||||
</Prose>
|
||||
);
|
||||
}
|
||||
|
||||
export default async function Page({
|
||||
params: { slug, framework },
|
||||
}: { params: { slug: string[]; framework: string } }) {
|
||||
const slugPath = slug.join("/");
|
||||
|
||||
// if the route ends in a framework name, return 404
|
||||
// because we want the framework name to be in /docs/[framework]/[...slug]
|
||||
if (isValidFramework(slug[slug.length - 1]))
|
||||
return <Error slugPath={slugPath} />;
|
||||
|
||||
try {
|
||||
let mdxSource;
|
||||
try {
|
||||
mdxSource = await import(`./${slugPath}.mdx`);
|
||||
} catch (error) {
|
||||
console.log("Error loading MDX file:" + slugPath, error);
|
||||
mdxSource = await import(`./${slugPath}/${framework}.mdx`);
|
||||
}
|
||||
|
||||
@@ -42,8 +30,11 @@ export default async function Page({
|
||||
</>
|
||||
);
|
||||
} catch (error) {
|
||||
console.error("Error loading MDX file:" + slugPath, error);
|
||||
return <Error slugPath={slugPath} />;
|
||||
return (
|
||||
<DocsLayout>
|
||||
<ComingSoonPage />
|
||||
</DocsLayout>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,7 +48,7 @@ export async function generateStaticParams() {
|
||||
for (const framework of frameworks) {
|
||||
for (const heading of docNavigationItems) {
|
||||
for (const item of heading?.items) {
|
||||
if (item.href && item.href.startsWith("/docs") && item.done) {
|
||||
if (item.href && item.href.startsWith("/docs")) {
|
||||
const slug = item.href
|
||||
.replace("/docs", "")
|
||||
.split("/")
|
||||
|
||||
@@ -32,7 +32,7 @@ Tested with:
|
||||
|
||||
<CodeGroup>
|
||||
```bash
|
||||
npx expo install expo-linking expo-secure-store expo-file-system @react-native-community/netinfo @bam.tech/react-native-image-resizer
|
||||
npx expo install expo-linking expo-secure-store expo-file-system @react-native-community/netinfo @bam.tech/react-native-image-resizer @azure/core-asynciterator-polyfill
|
||||
|
||||
npm i -S react-native-polyfill-globals react-native-url-polyfill web-streams-polyfill@3.2.1 base-64 text-encoding react-native-fetch-api react-native-get-random-values buffer
|
||||
|
||||
@@ -207,8 +207,8 @@ You can optionally pass a custom `kvStore` and `AccountSchema` to `createJazzRNA
|
||||
|
||||
Refer to the Jazz + React Native demo projects for implementing authentication:
|
||||
|
||||
- [DemoAuth Example](https://github.com/gardencmp/jazz/tree/main/examples/chat-rn)
|
||||
- [ClerkAuth Example](https://github.com/gardencmp/jazz/tree/main/examples/chat-rn-clerk)
|
||||
- [DemoAuth Example](https://github.com/garden-co/jazz/tree/main/examples/chat-rn)
|
||||
- [ClerkAuth Example](https://github.com/garden-co/jazz/tree/main/examples/chat-rn-clerk)
|
||||
|
||||
In the demos, you'll find details on:
|
||||
|
||||
@@ -219,7 +219,7 @@ In the demos, you'll find details on:
|
||||
|
||||
### Working with Images
|
||||
|
||||
To work with images in Jazz, import the `createImage` function from [`jazz-react-native-media-images`](https://github.com/gardencmp/jazz/tree/main/packages/jazz-react-native-media-images).
|
||||
To work with images in Jazz, import the `createImage` function from [`jazz-react-native-media-images`](https://github.com/garden-co/jazz/tree/main/packages/jazz-react-native-media-images).
|
||||
|
||||
<CodeGroup>
|
||||
```tsx
|
||||
@@ -236,7 +236,7 @@ To work with images in Jazz, import the `createImage` function from [`jazz-react
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
For a complete implementation, please refer to [this](https://github.com/gardencmp/jazz/blob/main/examples/pets/src/3_NewPetPostForm.tsx) demo.
|
||||
For a complete implementation, please refer to [this](https://github.com/garden-co/jazz/blob/main/examples/pets/src/3_NewPetPostForm.tsx) demo.
|
||||
|
||||
### Running your app
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ Currently, the recommended pattern to set up a React app with Jazz is to create
|
||||
|
||||
- the context provider of the Jazz React app context you just created
|
||||
|
||||
- the hooks and default/custom UI of one of the [Auth Methods](/docs/react/auth/auth-methods).
|
||||
- the hooks and default/custom UI of one of the [Auth Methods](/docs/react/authentication/auth-methods).
|
||||
|
||||
This is also where you specify the sync & storage server to connect to (see [Sync and storage](/docs/react/sync-and-storage)).
|
||||
|
||||
@@ -108,7 +108,7 @@ The easiest way to use Jazz with Next.JS is to only use it on the client side. Y
|
||||
<>// old
|
||||
<Jazz.Provider// old
|
||||
auth={passkeyAuth}// old
|
||||
peer="wss://mesh.jazz.tools/?key=you@example.com"// old
|
||||
peer="wss://cloud.jazz.tools/?key=you@example.com"// old
|
||||
>// old
|
||||
{children}// old
|
||||
</Jazz.Provider>// old
|
||||
|
||||
@@ -4,7 +4,7 @@ import { CodeGroup } from "@/components/forMdx";
|
||||
|
||||
This guide provides step-by-step instructions for setting up and running a Jazz-powered Todo application using VueJS.
|
||||
|
||||
See the full example [here](https://github.com/gardencmp/jazz/tree/main/examples/todo-vue).
|
||||
See the full example [here](https://github.com/garden-co/jazz/tree/main/examples/todo-vue).
|
||||
|
||||
---
|
||||
|
||||
@@ -127,7 +127,7 @@ const RootComponent = defineComponent({
|
||||
JazzProvider,
|
||||
{
|
||||
auth: authMethod.value,
|
||||
peer: "wss://mesh.jazz.tools/?key=vue-todo-example-jazz@gcmp.io",
|
||||
peer: "wss://cloud.jazz.tools/?key=vue-todo-example-jazz@garden.co",
|
||||
},
|
||||
{
|
||||
default: () => h(App),
|
||||
@@ -227,7 +227,7 @@ const folders = useCoState(FolderList, computedFoldersId, [{ items: [{}] }]);
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
See the full example [here](https://github.com/gardencmp/jazz/tree/main/examples/todo-vue).
|
||||
See the full example [here](https://github.com/garden-co/jazz/tree/main/examples/todo-vue).
|
||||
|
||||
## Mutating a CoValue
|
||||
|
||||
@@ -259,4 +259,4 @@ const createFolder = async (name: string) => {
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
See the full example [here](https://github.com/gardencmp/jazz/tree/main/examples/todo-vue).
|
||||
See the full example [here](https://github.com/garden-co/jazz/tree/main/examples/todo-vue).
|
||||
|
||||
@@ -1,29 +1,32 @@
|
||||
import { CodeGroup, ComingSoon } from "@/components/forMdx";
|
||||
|
||||
# CoValues
|
||||
# Defining schemas: CoValues
|
||||
|
||||
**CoValues ("Collaborative Values") are the core abstraction of Jazz.** Think of them as bread-and-butter datastructures that you can use to represent everything you need in your app.
|
||||
**CoValues ("Collaborative Values") are the core abstraction of Jazz.** They're your bread-and-butter datastructures that you use to represent everything in your app.
|
||||
|
||||
As their name suggests, they are inherently collaborative, meaning **multiple users and devices can edit them at the same time.**
|
||||
As their name suggests, CoValues are inherently collaborative, meaning **multiple users and devices can edit them at the same time.**
|
||||
|
||||
- CoValues allow for concurrent edits by always keeping their full edit histories, deriving the "current state" based on the currently locally available history.
|
||||
- **Think of CoValues as "super-fast Git for lots of tiny data".**
|
||||
- (The fact that this happens in an eventually-consistent way makes them [CRDTs](https://en.wikipedia.org/wiki/Conflict-free_replicated_data_type))
|
||||
- Having the full history around also means that you often don't need explicit timestamps and author info - you get this for free, just by having different accounts edit a value and then looking at its [edit metadata](/docs/coming-soon).
|
||||
**Think of CoValues as "super-fast Git for lots of tiny data."**
|
||||
|
||||
CoValues mostly model JSON with CoMaps and CoLists, but also offer CoStreams for simple per-user value streams, and also let you represent binary data with BinaryCoStreams.
|
||||
- CoValues keep their full edit histories, from which they derive their "current state".
|
||||
- The fact that this happens in an eventually-consistent way makes them [CRDTs](https://en.wikipedia.org/wiki/Conflict-free_replicated_data_type).
|
||||
- Having the full history also means that you often don't need explicit timestamps and author info - you get this for free as part of a CoValue's [edit metadata](/docs/using-covalues/metadata).
|
||||
|
||||
## Schemas as your app's first step
|
||||
CoValues model JSON with CoMaps and CoLists, but also offer CoFeeds for simple per-user value feeds, and let you represent binary data with FileStreams.
|
||||
|
||||
Under the hood, CoValues are as dynamic and flexible as JSON itself, but the way you use them in Jazz is by defining fixed schemas to describe the shape of data in your app.
|
||||
## Start your app with a schema
|
||||
|
||||
- This helps correctness and development speed in general, but is particularly important
|
||||
- when you evolve your app and need migrations
|
||||
- when different clients and server workers collaborate on CoValues and need to make compatible changes
|
||||
Fundamentally, CoValues are as dynamic and flexible as JSON, but in Jazz you use them by defining fixed schemas to describe the shape of data in your app.
|
||||
|
||||
- Luckily, thinking about the shape of your data first is also a really good way to model your app. Even before you know the details of how your app will work, you'll probably know which kinds of objects it will deal with, and how they relate to each other.
|
||||
This helps correctness and development speed, but is particularly important...
|
||||
- when you evolve your app and need migrations
|
||||
- when different clients and server workers collaborate on CoValues and need to make compatible changes
|
||||
|
||||
Jazz makes it really quick to define and update schemas, since they are simple TypeScript classes:
|
||||
Thinking about the shape of your data is also a great first step to model your app.
|
||||
|
||||
Even before you know the details of how your app will work, you'll probably know which kinds of objects it will deal with, and how they relate to each other.
|
||||
|
||||
Jazz makes it quick to declare schemas, since they are simple TypeScript classes:
|
||||
|
||||
<CodeGroup>
|
||||
{/* prettier-ignore */}
|
||||
@@ -35,14 +38,14 @@ export class TodoProject extends CoMap {
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
Here you can see how we use the `co` definer for declaring collaboratively editable fields, which ensures that schema info is correct at the type level and at runtime.
|
||||
Here you can see how we extend a CoValue type and use `co` for declaring (collaboratively) editable fields. This means that schema info is available for type inference *and* at runtime.
|
||||
|
||||
Classes might look a bit old-fashioned to some, but one nice property they have is that they are both types and values in TypeScript, so we can use them as both (with a single definition & import).
|
||||
Classes might look old-fashioned, but Jazz makes use of them being both types and values in TypeScript, letting you refer to either with a single definition and import.
|
||||
|
||||
<CodeGroup>
|
||||
{/* prettier-ignore */}
|
||||
```ts
|
||||
import { TodoProject } from "./schema";
|
||||
import { TodoProject, ListOfTasks } from "./schema";
|
||||
|
||||
const project: TodoProject = TodoProject.create(
|
||||
{
|
||||
@@ -54,13 +57,154 @@ const project: TodoProject = TodoProject.create(
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
## CoValue field types
|
||||
## Types of CoValues
|
||||
|
||||
Before we look at the different types of CoValues, let's learn what we can put *into* them.
|
||||
### `CoMap` (declaration)
|
||||
|
||||
CoMaps are the most commonly used type of CoValue. They are the equivalent of JSON objects. (Collaborative editing follows a last-write-wins strategy per-key.)
|
||||
|
||||
You can either declare struct-like CoMaps:
|
||||
|
||||
<CodeGroup>
|
||||
{/* prettier-ignore */}
|
||||
```ts
|
||||
class Person extends CoMap {
|
||||
name = co.string;
|
||||
age = co.number;
|
||||
pet = co.optional.ref(Pet);
|
||||
}
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
Or record-like CoMaps (key-value pairs, where keys are always `string`):
|
||||
|
||||
<CodeGroup>
|
||||
{/* prettier-ignore */}
|
||||
```ts
|
||||
class ColorToHex extends CoMap.Record(co.string) {}
|
||||
|
||||
class ColorToFruit extends CoMap.Record(co.ref(Fruit)) {}
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
|
||||
See the corresponding sections for [creating](/docs/using-covalues/creation#comap-creation),
|
||||
[subscribing/loading](/docs/using-covalues/subscription-and-loading),
|
||||
[reading from](/docs/using-covalues/reading#comap-reading) and
|
||||
[writing to](/docs/using-covalues/writing#comap-writing) CoMaps.
|
||||
|
||||
### `CoList` (declaration)
|
||||
|
||||
CoLists are ordered lists and are the equivalent of JSON arrays. (They support concurrent insertions and deletions, maintaining a consistent order.)
|
||||
|
||||
You define them by specifying the type of the items they contain:
|
||||
|
||||
<CodeGroup>
|
||||
{/* prettier-ignore */}
|
||||
```ts
|
||||
class ListOfColors extends CoList.Of(co.string) {}
|
||||
|
||||
class ListOfTasks extends CoList.Of(co.ref(Task)) {}
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
See the corresponding sections for [creating](/docs/using-covalues/creation#colist-creation),
|
||||
[subscribing/loading](/docs/using-covalues/subscription-and-loading),
|
||||
[reading from](/docs/using-covalues/reading#colist-reading) and
|
||||
[writing to](/docs/using-covalues/writing#colist-writing) CoLists.
|
||||
|
||||
### `CoFeed` (declaration)
|
||||
|
||||
CoFeeds are a special CoValue type that represent a feed of values for a set of users / sessions. (Each session of a user gets its own append-only feed.)
|
||||
|
||||
They allow easy access of the latest or all items belonging to a user or their sessions. This makes them particularly useful for user presence, reactions, notifications, etc.
|
||||
|
||||
You define them by specifying the type of feed item:
|
||||
|
||||
<CodeGroup>
|
||||
{/* prettier-ignore */}
|
||||
```ts
|
||||
class FeedOfTasks extends CoFeed.Of(co.ref(Task)) {}
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
See the corresponding sections for [creating](/docs/using-covalues/creation#cofeed-creation),
|
||||
[subscribing/loading](/docs/using-covalues/subscription-and-loading),
|
||||
[reading from](/docs/using-covalues/reading#cofeed-reading) and
|
||||
[writing to](/docs/using-covalues/writing#cofeed-writing) CoFeeds.
|
||||
|
||||
### `FileStream` (declaration)
|
||||
|
||||
FileStreams are a special type of CoValue that represent binary data. (They are created by a single user and offer no internal collaboration.)
|
||||
|
||||
They allow you to upload and reference files, images, etc.
|
||||
|
||||
You typically don't need to declare or extend them yourself, you simply refer to the built-in `FileStream` from another CoValue:
|
||||
|
||||
<CodeGroup>
|
||||
{/* prettier-ignore */}
|
||||
```ts
|
||||
import { FileStream } from "jazz-tools";
|
||||
|
||||
class UserProfile extends CoMap {
|
||||
name = co.string;
|
||||
avatar = co.ref(FileStream);
|
||||
}
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
See the corresponding sections for [creating](/docs/using-covalues/creation#filestream-creation),
|
||||
[subscribing/loading](/docs/using-covalues/subscription-and-loading),
|
||||
[reading from](/docs/using-covalues/reading#filestream-reading) and
|
||||
[writing to](/docs/using-covalues/writing#filestream-writing) FileStreams.
|
||||
|
||||
### `SchemaUnion` (declaration)
|
||||
|
||||
SchemaUnion is a helper type that allows you to load and refer to multiple subclasses of a CoMap schema, distinguished by a discriminating field.
|
||||
|
||||
You declare them with a base class type and discriminating lambda, in which you have access to the `RawCoMap`, on which you can call `get` with the field name to get the discriminating value.
|
||||
|
||||
<CodeGroup>
|
||||
{/* prettier-ignore */}
|
||||
```ts
|
||||
import { SchemaUnion, CoMap } from "jazz-tools";
|
||||
|
||||
class BaseWidget extends CoMap {
|
||||
type = co.string;
|
||||
}
|
||||
|
||||
class ButtonWidget extends BaseWidget {
|
||||
type = co.literal("button");
|
||||
label = co.string;
|
||||
}
|
||||
|
||||
class SliderWidget extends BaseWidget {
|
||||
type = co.literal("slider");
|
||||
min = co.number;
|
||||
max = co.number;
|
||||
}
|
||||
|
||||
const WidgetUnion = SchemaUnion.Of<BaseWidget>((raw) => {
|
||||
switch (raw.get("type")) {
|
||||
case "button": return ButtonWidget;
|
||||
case "slider": return SliderWidget;
|
||||
default: throw new Error("Unknown widget type");
|
||||
}
|
||||
});
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
See the corresponding sections for [creating](/docs/using-covalues/creation#schemaunion-creation),
|
||||
[subscribing/loading](/docs/using-covalues/subscription-and-loading) and
|
||||
[narrowing](/docs/using-covalues/reading#schemaunion-narrowing) SchemaUnions.
|
||||
|
||||
## CoValue field/item types
|
||||
|
||||
Now that we've seen the different types of CoValues, let's see more precisely how we declare the fields or items they contain.
|
||||
|
||||
### Primitive fields
|
||||
|
||||
You can define primitive field types using the `co` definer:
|
||||
You can declare primitive field types using the `co` declarer:
|
||||
|
||||
<CodeGroup>
|
||||
{/* prettier-ignore */}
|
||||
@@ -89,7 +233,7 @@ co.literal("waiting", "ready");
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
Finally, for more complex JSON data, that you *don't want to be collaborative internally* (but only every update as a whole), you can use `co.json<T>()`:
|
||||
Finally, for more complex JSON data, that you *don't want to be collaborative internally* (but only ever update as a whole), you can use `co.json<T>()`:
|
||||
|
||||
<CodeGroup>
|
||||
{/* prettier-ignore */}
|
||||
@@ -98,7 +242,7 @@ co.json<{ name: string }>();
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
For more detail, see the API Reference for the [`co` Field Definer](/api-reference/jazz-tools#co).
|
||||
For more detail, see the API Reference for the [`co` field declarer](/api-reference/jazz-tools#co).
|
||||
|
||||
### Refs to other CoValues
|
||||
|
||||
@@ -106,9 +250,9 @@ To represent complex structured data with Jazz, you form trees or graphs of CoVa
|
||||
|
||||
Internally, this is represented by storing the IDs of the referenced CoValues in the corresponding fields, but Jazz abstracts this away, making it look like nested CoValues you can get or assign/insert.
|
||||
|
||||
The important caveat here is that **a referenced CoValue might or might not be loaded yet,** but we'll see what exactly that means in [Subscribing and Deep Loading](/docs/coming-soon).
|
||||
The important caveat here is that **a referenced CoValue might or might not be loaded yet,** but we'll see what exactly that means in [Subscribing and Deep Loading](/docs/using-covalues/subscription-and-loading).
|
||||
|
||||
In Schemas, you define Refs using the `co.ref<T>()` definer:
|
||||
In Schemas, you declare Refs using the `co.ref<T>()` declarer:
|
||||
|
||||
<CodeGroup>
|
||||
{/* prettier-ignore */}
|
||||
@@ -123,7 +267,7 @@ class ListOfPeople extends CoList.Of(co.ref(Person)) {}
|
||||
|
||||
#### Optional Refs
|
||||
|
||||
If you want to make a referenced CoValue field optional, you *have to* use `co.optional.ref<T>()`:
|
||||
⚠️ If you want to make a referenced CoValue field optional, you *have to* use `co.optional.ref<T>()`: ⚠️
|
||||
|
||||
<CodeGroup>
|
||||
{/* prettier-ignore */}
|
||||
@@ -134,6 +278,25 @@ class Person extends CoMap {
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
### Computed fields, methods & constructors
|
||||
### Computed fields & methods
|
||||
|
||||
<ComingSoon/>
|
||||
Since CoValue schemas are based on classes, you can easily add computed fields and methods:
|
||||
|
||||
<CodeGroup>
|
||||
{/* prettier-ignore */}
|
||||
```ts
|
||||
class Person extends CoMap {
|
||||
firstName = co.string;
|
||||
lastName = co.string;
|
||||
dateOfBirth = co.Date;
|
||||
|
||||
get name() {
|
||||
return `${this.firstName} ${this.lastName}`;
|
||||
}
|
||||
|
||||
ageAsOf(date: Date) {
|
||||
return differenceInYears(date, this.dateOfBirth);
|
||||
}
|
||||
}
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
@@ -44,4 +44,4 @@ In this case, provide the WebSocket endpoint your proxy exposes as the sync serv
|
||||
|
||||
### Source code
|
||||
|
||||
The implementation of this simple sync server is available open-source [on GitHub](https://github.com/gardencmp/jazz/blob/main/packages/jazz-run/src/startSync.ts).
|
||||
The implementation of this simple sync server is available open-source [on GitHub](https://github.com/garden-co/jazz/blob/main/packages/jazz-run/src/startSync.ts).
|
||||
|
||||
@@ -3,37 +3,22 @@ import { NextjsLogo } from "@/components/icons/NextjsLogo";
|
||||
import { ReactLogo } from "@/components/icons/ReactLogo";
|
||||
import { ReactNativeLogo } from "@/components/icons/ReactNativeLogo";
|
||||
import { VueLogo } from "@/components/icons/VueLogo";
|
||||
import { Button } from "gcmp-design-system/src/app/components/atoms/Button";
|
||||
import { H2 } from "gcmp-design-system/src/app/components/atoms/Headings";
|
||||
import { GappedGrid } from "gcmp-design-system/src/app/components/molecules/GappedGrid";
|
||||
import { HeroHeader } from "gcmp-design-system/src/app/components/molecules/HeroHeader";
|
||||
import { CloudUploadIcon, FingerprintIcon, ImageIcon } from "lucide-react";
|
||||
|
||||
type Example = {
|
||||
name: string;
|
||||
slug: string;
|
||||
description?: string;
|
||||
illustration?: React.ReactNode;
|
||||
tech?: string[];
|
||||
features?: string[];
|
||||
demoUrl?: string;
|
||||
};
|
||||
|
||||
const tech = {
|
||||
react: "React",
|
||||
nextjs: "Next.js",
|
||||
reactNative: "React Native",
|
||||
vue: "Vue",
|
||||
};
|
||||
|
||||
const features = {
|
||||
fileUpload: "File upload",
|
||||
imageUpload: "Image upload",
|
||||
passkey: "Passkey auth",
|
||||
clerk: "Clerk auth",
|
||||
inviteLink: "Invite link",
|
||||
coFeed: "CoFeed",
|
||||
};
|
||||
import {
|
||||
Schema_ts as ImageUploadSchema,
|
||||
ImageUpload_tsx,
|
||||
} from "@/codeSamples/examples/image-upload/src";
|
||||
import {
|
||||
Schema_ts as ReactionsSchema,
|
||||
ReactionsScreen_tsx,
|
||||
} from "@/codeSamples/examples/reactions/src";
|
||||
import { ExampleCard } from "@/components/examples/ExampleCard";
|
||||
import { ExampleDemo } from "@/components/examples/ExampleDemo";
|
||||
import { Example, features, tech } from "@/lib/example";
|
||||
|
||||
const MockButton = ({ children }: { children: React.ReactNode }) => (
|
||||
<p className="bg-blue-100 text-blue-800 py-1 p-2 rounded-full font-medium text-center text-xs">
|
||||
@@ -206,7 +191,7 @@ const PasswordManagerIllustration = () => (
|
||||
</div>
|
||||
);
|
||||
|
||||
const reactExamples = [
|
||||
const reactExamples: Example[] = [
|
||||
{
|
||||
name: "Chat",
|
||||
slug: "chat",
|
||||
@@ -215,53 +200,6 @@ const reactExamples = [
|
||||
demoUrl: "https://chat.jazz.tools",
|
||||
illustration: <ChatIllustration />,
|
||||
},
|
||||
{
|
||||
name: "Clerk",
|
||||
slug: "clerk",
|
||||
description: "A React app that uses Clerk for authentication",
|
||||
tech: [tech.react],
|
||||
features: [features.clerk],
|
||||
demoUrl: "https://clerk-demo.jazz.tools",
|
||||
illustration: <ClerkIllustration />,
|
||||
},
|
||||
{
|
||||
name: "Passkey",
|
||||
slug: "passkey",
|
||||
description: "A React app that uses Passkey for authentication",
|
||||
tech: [tech.react],
|
||||
features: [features.passkey],
|
||||
demoUrl: "https://passkey-demo.jazz.tools",
|
||||
illustration: (
|
||||
<div className="flex bg-stone-100 h-full flex-col items-center justify-center dark:bg-transparent">
|
||||
<div className="p-4 flex flex-col items-center gap-3 rounded-md shadow-xl shadow-stone-400/20 bg-white dark:shadow-none">
|
||||
<FingerprintIcon
|
||||
size={36}
|
||||
strokeWidth={0.75}
|
||||
className="stroke-red-600"
|
||||
/>
|
||||
<p className="text-xs dark:text-stone-900">Continue with Touch ID</p>
|
||||
</div>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
name: "Image upload",
|
||||
slug: "image-upload",
|
||||
description: "Learn how to upload and delete images",
|
||||
tech: [tech.react],
|
||||
features: [features.imageUpload],
|
||||
demoUrl: "https://image-upload-demo.jazz.tools",
|
||||
illustration: <ImageUploadIllustration />,
|
||||
},
|
||||
{
|
||||
name: "Reactions",
|
||||
slug: "reactions",
|
||||
description: "Collect and render reactions from multiple users.",
|
||||
tech: [tech.react],
|
||||
features: [features.coFeed],
|
||||
demoUrl: "https://reactions-demo.jazz.tools",
|
||||
illustration: <ReactionsIllustration />,
|
||||
},
|
||||
{
|
||||
name: "Rate my pet",
|
||||
slug: "pets",
|
||||
@@ -302,9 +240,38 @@ const reactExamples = [
|
||||
demoUrl: "https://music-demo.jazz.tools",
|
||||
illustration: <MusicIllustration />,
|
||||
},
|
||||
{
|
||||
name: "Clerk",
|
||||
slug: "clerk",
|
||||
description: "A React app that uses Clerk for authentication",
|
||||
tech: [tech.react],
|
||||
features: [features.clerk],
|
||||
demoUrl: "https://clerk-demo.jazz.tools",
|
||||
illustration: <ClerkIllustration />,
|
||||
},
|
||||
{
|
||||
name: "Passkey",
|
||||
slug: "passkey",
|
||||
description: "A React app that uses Passkey for authentication",
|
||||
tech: [tech.react],
|
||||
features: [features.passkey],
|
||||
demoUrl: "https://passkey-demo.jazz.tools",
|
||||
illustration: (
|
||||
<div className="flex bg-stone-100 h-full flex-col items-center justify-center dark:bg-transparent">
|
||||
<div className="p-4 flex flex-col items-center gap-3 rounded-md shadow-xl shadow-stone-400/20 bg-white dark:shadow-none">
|
||||
<FingerprintIcon
|
||||
size={36}
|
||||
strokeWidth={0.75}
|
||||
className="stroke-red-600"
|
||||
/>
|
||||
<p className="text-xs dark:text-stone-900">Continue with Touch ID</p>
|
||||
</div>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
const nextExamples = [
|
||||
const nextExamples: Example[] = [
|
||||
{
|
||||
name: "Book shelf",
|
||||
slug: "book-shelf",
|
||||
@@ -358,6 +325,49 @@ const vueExamples: Example[] = [
|
||||
},
|
||||
];
|
||||
|
||||
const demos = [
|
||||
{
|
||||
name: "Image upload",
|
||||
slug: "image-upload",
|
||||
description: "Learn how to upload and delete images",
|
||||
tech: [tech.react],
|
||||
features: [features.imageUpload],
|
||||
demoUrl: "https://image-upload-demo.jazz.tools",
|
||||
illustration: <ImageUploadIllustration />,
|
||||
showDemo: true,
|
||||
codeSamples: [
|
||||
{
|
||||
name: "image-upload.tsx",
|
||||
content: <ImageUpload_tsx />,
|
||||
},
|
||||
{
|
||||
name: "schema.ts",
|
||||
content: <ImageUploadSchema />,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Reactions",
|
||||
slug: "reactions",
|
||||
description: "Collect and render reactions from multiple users.",
|
||||
tech: [tech.react],
|
||||
features: [features.coFeed],
|
||||
demoUrl: "https://reactions-demo.jazz.tools",
|
||||
illustration: <ReactionsIllustration />,
|
||||
showDemo: true,
|
||||
codeSamples: [
|
||||
{
|
||||
name: "reactions.tsx",
|
||||
content: <ReactionsScreen_tsx />,
|
||||
},
|
||||
{
|
||||
name: "schema.ts",
|
||||
content: <ReactionsSchema />,
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const categories = [
|
||||
{
|
||||
name: "React",
|
||||
@@ -385,55 +395,6 @@ const categories = [
|
||||
},
|
||||
];
|
||||
|
||||
function Example({ example }: { example: Example }) {
|
||||
const { name, slug, tech, features, description, demoUrl, illustration } =
|
||||
example;
|
||||
const githubUrl = `https://github.com/gardencmp/jazz/tree/main/examples/${slug}`;
|
||||
|
||||
return (
|
||||
<div className="col-span-2 border bg-stone-50 shadow-sm p-3 flex flex-col rounded-lg dark:bg-stone-950">
|
||||
<div className="mb-3 aspect-[16/9] overflow-hidden w-full rounded-md bg-white border dark:bg-stone-925 sm:aspect-[2/1] md:aspect-[3/2]">
|
||||
{illustration}
|
||||
</div>
|
||||
|
||||
<div className="flex-1 space-y-2 mb-2">
|
||||
<h2 className="font-medium text-stone-900 dark:text-white leading-none">
|
||||
{name}
|
||||
</h2>
|
||||
<div className="flex gap-1">
|
||||
{tech?.map((tech) => (
|
||||
<p
|
||||
className="bg-green-50 border border-green-500 text-green-600 rounded-full py-0.5 px-2 text-xs dark:bg-green-800 dark:text-green-200 dark:border-green-700"
|
||||
key={tech}
|
||||
>
|
||||
{tech}
|
||||
</p>
|
||||
))}
|
||||
{features?.map((feature) => (
|
||||
<p
|
||||
className="bg-pink-50 border border-pink-500 text-pink-600 rounded-full py-0.5 px-2 text-xs dark:bg-pink-800 dark:text-pink-200 dark:border-pink-700"
|
||||
key={feature}
|
||||
>
|
||||
{feature}
|
||||
</p>
|
||||
))}
|
||||
</div>
|
||||
<p className="text-sm">{description}</p>
|
||||
</div>
|
||||
<div className="flex gap-2">
|
||||
<Button href={githubUrl} variant="secondary" size="sm">
|
||||
View code
|
||||
</Button>
|
||||
{demoUrl && (
|
||||
<Button href={demoUrl} variant="secondary" size="sm">
|
||||
View demo
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default function Page() {
|
||||
return (
|
||||
<div className="container flex flex-col gap-6 pb-10 lg:pb-20">
|
||||
@@ -442,6 +403,14 @@ export default function Page() {
|
||||
slogan="Find an example app with code most similar to what you want to build"
|
||||
/>
|
||||
|
||||
<div className="grid gap-8 mb-12 lg:gap-12">
|
||||
<h2 className="sr-only">Example apps with demo and code</h2>
|
||||
{demos.map(
|
||||
(demo) =>
|
||||
demo.showDemo && <ExampleDemo key={demo.slug} example={demo} />,
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="grid gap-12 lg:gap-20">
|
||||
{categories.map((category) => (
|
||||
<div key={category.name}>
|
||||
@@ -453,9 +422,17 @@ export default function Page() {
|
||||
</div>
|
||||
|
||||
<GappedGrid>
|
||||
{category.examples.map((example) => (
|
||||
<Example key={example.slug} example={example} />
|
||||
))}
|
||||
{category.examples.map((example) =>
|
||||
example.showDemo ? (
|
||||
<ExampleDemo key={example.slug} example={example} />
|
||||
) : (
|
||||
<ExampleCard
|
||||
className="border bg-stone-50 shadow-sm p-3 rounded-lg dark:bg-stone-950"
|
||||
key={example.slug}
|
||||
example={example}
|
||||
/>
|
||||
),
|
||||
)}
|
||||
</GappedGrid>
|
||||
</div>
|
||||
))}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user