Compare commits

...

95 Commits

Author SHA1 Message Date
Guido D'Orsi
28930ee1d5 fix(jazz-run): fix console output 2024-12-08 11:09:53 +01:00
Guido D'Orsi
843a012f33 Merge pull request #967 from garden-co/update-changeset-config
fix(changeset): update config
2024-12-08 10:39:17 +01:00
Guido D'Orsi
bd510a13ce fix(changeset): update config 2024-12-08 10:38:36 +01:00
Anselm
b56d7e3e7c Make passkey-svelte example private on npm 2024-12-07 19:17:06 +00:00
Anselm Eickhoff
2f5bd74206 Merge pull request #966 from garden-co/changeset-release/main
Version Packages
2024-12-07 19:09:20 +00:00
github-actions[bot]
a4864d93d2 Version Packages 2024-12-07 19:04:33 +00:00
Anselm Eickhoff
19376e6abd Merge pull request #965 from garden-co/perf/coMapAtTime
perf(CoMap): optimize the atTime processing
2024-12-07 19:02:56 +00:00
Guido D'Orsi
22f6db8141 test: cover CoMap public methods with tests 2024-12-07 19:40:44 +01:00
Guido D'Orsi
3d9f12e9ea chore: changeset 2024-12-07 19:28:12 +01:00
Guido D'Orsi
68620a3df9 perf(CoMap): optimize the atTime processing 2024-12-07 19:07:52 +01:00
Anselm Eickhoff
1767f024d9 Merge pull request #964 from garden-co/jazz-567-speed-up-latency-map-rendering
Fix caching for latency map
2024-12-07 14:06:46 +00:00
Anselm
c55924a04a Fix caching 2024-12-07 13:56:48 +00:00
Anselm Eickhoff
31e00a96ae Merge pull request #963 from garden-co/jazz-567-speed-up-latency-map-rendering
Speed up latency map rendering
2024-12-07 12:59:44 +00:00
Anselm
7bb834f399 Lint & format 2024-12-07 12:54:37 +00:00
pax
667f36e1cf Merge pull request #957 from garden-co/rn-examples-new-arch
fix: upgraded RN examples to Expo SDK 52 with new arch
2024-12-07 14:50:50 +02:00
pax-k
07669923ad Merge branch 'main' into rn-examples-new-arch 2024-12-07 14:48:28 +02:00
Anselm
9082a099ee Merge branch 'main' into jazz-567-speed-up-latency-map-rendering 2024-12-07 12:31:58 +00:00
Anselm
aba059db28 Try strongarming vercel into using the right pnpm version 2024-12-07 12:23:15 +00:00
Anselm
ae6b9c8dd2 Speed up latency map rendering 2024-12-06 18:59:21 +00:00
pax-k
7b9f96bf1a chore: pnpm lock 2024-12-06 18:52:25 +02:00
pax-k
8df49546fe Merge branch 'main' into rn-examples-new-arch 2024-12-06 18:52:08 +02:00
pax-k
bb4460f422 fix: upgraded RN examples to Expo SDK 52 with new arch 2024-12-06 18:51:35 +02:00
Anselm Eickhoff
2099099afc Merge pull request #956 from nikitavoloboev/patch-1
fix 404 urls in docs
2024-12-06 16:47:19 +00:00
Nikita
06b0758d7c fix urls 2024-12-06 17:43:06 +01:00
Nikita
6135250e57 fix 404 url 2024-12-06 17:38:32 +01:00
Anselm Eickhoff
aacd03bbdd Merge pull request #945 from garden-co/changeset-release/main
Version Packages
2024-12-06 15:39:02 +00:00
github-actions[bot]
ca7f250d47 Version Packages 2024-12-06 14:46:52 +00:00
pax
83ad506b94 Merge pull request #954 from garden-co/jazz-react-native-auth-clerk
jazz-react-native-auth-clerk package
2024-12-06 16:45:42 +02:00
pax-k
e9751f5b69 Merge branch 'main' into jazz-react-native-auth-clerk 2024-12-06 16:36:14 +02:00
pax-k
c84764acd5 chore: changeset 2024-12-06 16:30:35 +02:00
pax-k
c2a805bffa chore: added expo-font 2024-12-06 16:27:27 +02:00
pax-k
8728dde42b feat: added package jazz-react-native-auth-clerk 2024-12-06 15:13:45 +02:00
Benjamin S. Leveritt
9dd9366734 Merge pull request #949 from garden-co/jazz-518-write-initial-defining-schemas-docs
Write initial defining schemas docs
2024-12-05 20:23:03 +00:00
Anselm Eickhoff
48dd00f453 Merge pull request #946 from garden-co/jazz-563-fix-github-url
Replaces github url with new one
2024-12-05 18:25:57 +00:00
Anselm Eickhoff
cc361aefe5 Merge pull request #919 from garden-co/jazz-544-refactor-sqlite-storage-the-same-way-as-the-idbs-done
Refactor SQLite storage
2024-12-05 17:12:54 +00:00
Anselm
9e4438cb54 Write initial defining schemas docs 2024-12-05 17:09:01 +00:00
Benjamin S. Leveritt
08706d557a Update general web urls 2024-12-05 16:55:44 +00:00
Benjamin S. Leveritt
02c1ec63cc Change cloud keys and peer addresses 2024-12-05 16:54:33 +00:00
Benjamin S. Leveritt
df797dedcd Change email addresses 2024-12-05 16:53:01 +00:00
Benjamin S. Leveritt
74cb08e7d4 Replaces github url with new one 2024-12-05 16:48:44 +00:00
Anselm Eickhoff
73720a8cc4 Merge pull request #907 from garden-co/latency-map
Add a latency map to cloud page
2024-12-05 16:36:39 +00:00
Anselm Eickhoff
50c77fa788 Merge pull request #916 from garden-co/docs/examples-demo
Show demo and code for minimal examples
2024-12-05 16:35:04 +00:00
Benjamin S. Leveritt
9977a4ee85 Use jsxEmit value rather than string 2024-12-05 16:06:46 +00:00
Guido D'Orsi
441fe27802 chore: changeset 2024-12-05 15:53:19 +01:00
Marina Orlova
1afbd2c7cc Add changeset 2024-12-05 15:43:12 +01:00
Marina Orlova
4955e39af5 Create cojson-storage 2024-12-05 15:43:12 +01:00
Marina Orlova
ace151696c Copy syncUtils code into sqlite package 2024-12-05 15:43:12 +01:00
Marina Orlova
db9560ebc5 Fix ERR_MODULE_NOT_FOUND 2024-12-05 15:43:12 +01:00
Marina Orlova
80b572710e Fix tests 2024-12-05 15:43:12 +01:00
Marina Orlova
bbb9d45969 Unify IDB and SQLite storage code 2024-12-05 15:43:12 +01:00
Marina Orlova
83e9a3eaa8 Normalise sqlite code against indexedb 2024-12-05 15:43:12 +01:00
Marina Orlova
9ff7e68f7d Split sqlite storage 2024-12-05 15:43:12 +01:00
Anselm Eickhoff
06740e840a Merge pull request #927 from garden-co/jazz-551-optimise-large-record-like-comaps-for-access-of-latest-value
Optimise large record-like CoMaps for access of latest value
2024-12-05 10:28:19 +00:00
Guido D'Orsi
b0e2c4fd4b fix: revert the incremental processing optimization as it doesn't take into account that older transactions might be synced after the new ones 2024-12-05 11:11:49 +01:00
Guido D'Orsi
4c1922c10e perf(coMap): process only the new transactions on update 2024-12-05 11:03:35 +01:00
Anselm Eickhoff
76bad9b5c3 Merge pull request #922 from garden-co/jazz-547-explicitly-reference-homepage-dependencies
Explicitly reference homepage dependencies
2024-12-05 09:46:55 +00:00
Trisha Lim
7f16f2705e Attempt fix build 2024-12-04 21:54:08 +00:00
Guido D'Orsi
d12594e521 fix: fix timing issues and invalidate on update 2024-12-04 21:13:43 +01:00
Guido D'Orsi
cf96350b01 Merge remote-tracking branch 'origin/main' into jazz-551-optimise-large-record-like-comaps-for-access-of-latest-value 2024-12-04 20:21:53 +01:00
Anselm
947030433f Merge branch 'main' into latency-map 2024-12-04 18:27:34 +00:00
Anselm
b4cebd732e Merge branch 'main' into docs/examples-demo 2024-12-04 18:26:40 +00:00
Anselm
d0d95e6d5d Merge branch 'main' into jazz-547-explicitly-reference-homepage-dependencies 2024-12-04 18:23:47 +00:00
Trisha Lim
a75383ac6a Fix build 2024-12-04 18:15:44 +00:00
Trisha Lim
de503b6120 Formatting fixes 2024-12-04 18:07:59 +00:00
Trisha Lim
f7ae41254f Merge branch 'main' into docs/examples-demo 2024-12-04 18:06:09 +00:00
Trisha Lim
8f348b28c6 Improve code example styling 2024-12-04 18:05:53 +00:00
Trisha Lim
3b185b4cd3 Merge branch 'main' into latency-map 2024-12-04 16:54:50 +00:00
Anselm
df5dc513bf Don't reverse iterate over valid transactions for now 2024-12-04 16:51:11 +00:00
Benjamin S. Leveritt
8e6783ad88 Link dependant jazz packages for api docs generation 2024-12-04 16:48:59 +00:00
Benjamin S. Leveritt
79bf6f478f Add Turbo build config to homepage workspace 2024-12-04 16:48:59 +00:00
Trisha Lim
7fd93a5a61 Move Examples page before API Ref nav link 2024-12-04 16:48:39 +00:00
Trisha Lim
8f9687323f Reorder examples 2024-12-04 16:48:39 +00:00
Trisha Lim
47ee25786f Spacing 2024-12-04 16:48:39 +00:00
Trisha Lim
0009aa19b2 Example demo header design 2024-12-04 16:48:39 +00:00
Trisha Lim
741b9cbada Move components out of page.tsx 2024-12-04 16:48:39 +00:00
Trisha Lim
259ade3099 Consistent layout and styling in demo apps 2024-12-04 16:48:39 +00:00
Trisha Lim
b6f2da2221 Move demos to separate section 2024-12-04 16:48:39 +00:00
Trisha Lim
44157945a0 Show code samples 2024-12-04 16:48:39 +00:00
Trisha Lim
4ff7bb500a Show iframe for examples 2024-12-04 16:48:39 +00:00
Anselm
db5ea54338 Fix jazz-tools use of _raw.ops 2024-12-04 16:26:19 +00:00
Anselm
7c7880a9b2 Optimise large record-like CoMaps for access of latest value 2024-12-04 16:21:01 +00:00
Trisha Lim
49082a5aad Merge branch 'main' into latency-map 2024-12-04 10:41:18 +00:00
Trisha Lim
b6653555f5 Fix build 2024-12-03 15:45:24 +00:00
Trisha Lim
c9fd16ce21 Desktop view 2024-12-03 14:46:14 +00:00
Trisha Lim
e60f34d9e6 Mobile view 2024-12-03 14:28:24 +00:00
Trisha Lim
a04c7dca7a Install next-themes 2024-12-03 12:37:00 +00:00
Trisha Lim
e067c29d81 Map positioning 2024-12-03 12:36:14 +00:00
Trisha Lim
1357306d1b Switch latency map colors according to theme 2024-12-03 12:10:22 +00:00
Trisha Lim
3c6d9b20c1 Move theme controls to gcmp/jazz, and out of design system 2024-12-03 12:03:22 +00:00
Trisha Lim
f597316267 Remove console logs 2024-12-03 11:18:50 +00:00
Trisha Lim
17f8bc25c3 Update colors for dark mode 2024-12-02 20:21:29 +00:00
Trisha Lim
c1d652cf7f Update colors for light mode 2024-12-02 20:05:38 +00:00
Trisha Lim
10f3e4aabd Update colors for light mode 2024-12-02 17:24:42 +00:00
Anselm
63f5574003 Improve map 2024-12-02 16:26:38 +00:00
Anselm
9bb5c4ca5f Add a latency map to cloud page 2024-12-01 16:03:38 +00:00
198 changed files with 28352 additions and 2606 deletions

View File

@@ -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",

View File

@@ -0,0 +1,5 @@
---
"jazz-run": patch
---
Log the server address when running the local sync server

View File

@@ -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

View File

@@ -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**:

View File

@@ -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.

View File

@@ -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

View File

@@ -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/

View File

@@ -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"

View File

@@ -1 +1 @@
EXPO_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_ZXZpZGVudC1kYW5lLTg5LmNsZXJrLmFjY291bnRzLmRldiQ
EXPO_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_ZXZpZGVudC1kYW5lLTg5LmNsZXJrLmFjY291bnRzLmRldiQ

View File

@@ -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

View File

@@ -35,7 +35,9 @@
}
}
],
"expo-secure-store"
"expo-secure-store",
"expo-font",
"expo-router"
],
"extra": {
"eas": {

View File

@@ -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);
},
};
};

View File

@@ -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 = [

View File

@@ -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"

View File

@@ -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}

View File

@@ -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;

View File

@@ -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

View File

@@ -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"
},

View File

@@ -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}>

View File

@@ -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

View File

@@ -1,6 +1,6 @@
{
"name": "chat-vue",
"version": "0.0.18",
"version": "0.0.20",
"private": true,
"type": "module",
"scripts": {

View File

@@ -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),

View File

@@ -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

View File

@@ -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/

View File

@@ -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",

View File

@@ -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>

View File

@@ -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

View File

@@ -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"
},

View File

@@ -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>

View File

@@ -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

View File

@@ -1,7 +1,7 @@
{
"name": "image-upload",
"private": true,
"version": "0.0.10",
"version": "0.0.12",
"type": "module",
"scripts": {
"dev": "vite",

View File

@@ -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>
</>
);
}

View File

@@ -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 {

View File

@@ -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} />
)}
</>
);
}

View File

@@ -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

View File

@@ -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/

View File

@@ -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",

View File

@@ -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

View File

@@ -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/

View File

@@ -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",

View File

@@ -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 (
<>

View File

@@ -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

View File

@@ -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/

View File

@@ -1,7 +1,7 @@
{
"name": "jazz-example-onboarding",
"private": true,
"version": "0.0.14",
"version": "0.0.16",
"type": "module",
"scripts": {
"dev": "vite",

View File

@@ -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();

View File

@@ -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

View File

@@ -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",

View File

@@ -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>

View File

@@ -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

View File

@@ -1,7 +1,7 @@
{
"name": "passkey",
"private": true,
"version": "0.0.11",
"version": "0.0.13",
"type": "module",
"scripts": {
"dev": "vite",

View File

@@ -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>

View File

@@ -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

View File

@@ -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",

View File

@@ -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>

View File

@@ -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

View File

@@ -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/

View File

@@ -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",

View File

@@ -23,7 +23,7 @@ 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";
/** Walkthrough: The top-level provider `<Jazz.Provider/>`
*

View File

@@ -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

View File

@@ -1,7 +1,7 @@
{
"name": "reactions",
"private": true,
"version": "0.0.10",
"version": "0.0.12",
"type": "module",
"scripts": {
"dev": "vite",

View File

@@ -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>
</>
);
}

View File

@@ -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,

View File

@@ -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} />
)}
</>
);
}

View File

@@ -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

View File

@@ -1,6 +1,6 @@
{
"name": "todo-vue",
"version": "0.0.16",
"version": "0.0.18",
"private": true,
"type": "module",
"scripts": {

View File

@@ -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),

View File

@@ -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

View File

@@ -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/

View File

@@ -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",

View File

@@ -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>

View File

@@ -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>
);
}

View File

@@ -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,
)}

View File

@@ -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);

View File

@@ -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>
);
}

View File

@@ -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">

View File

@@ -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);

View File

@@ -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 = {

View File

@@ -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>

View File

@@ -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>
);
}

View 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>
);
}

View 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} />;
}

View File

@@ -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",

View File

@@ -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

View 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",
},
});
}

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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"

View File

@@ -36,7 +36,7 @@ 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
@@ -58,7 +58,7 @@ const [passkeyAuth, passkeyState] = usePasskeyAuth({ appName });
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
@@ -108,4 +108,4 @@ createRoot(document.getElementById("root")!).render(
</StrictMode>,
);
```
</CodeGroup>
</CodeGroup>

View File

@@ -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

View File

@@ -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

View File

@@ -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).

View File

@@ -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/coming-soon).
## 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
@@ -108,7 +252,7 @@ Internally, this is represented by storing the IDs of the referenced CoValues in
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).
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>

View File

@@ -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).

View File

@@ -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>
))}

View File

@@ -4,11 +4,11 @@ import type { Metadata } from "next";
import { Inter, Manrope } from "next/font/google";
import localFont from "next/font/local";
import { ThemeProvider } from "@/components/ThemeProvider";
import { JazzFooter } from "@/components/footer";
import { JazzNav } from "@/components/nav";
import { Analytics } from "@vercel/analytics/react";
import { SpeedInsights } from "@vercel/speed-insights/next";
import { ThemeProvider } from "gcmp-design-system/src/app/components/molecules/ThemeProvider";
// If loading a variable font, you don't need to specify the font weight
const manrope = Manrope({

View File

@@ -79,7 +79,7 @@ pre.twoslash data-lsp:hover::before {
}
pre .code-container {
@apply overflow-auto p-2 pl-0 bg-white dark:bg-stone-925 rounded-b-xl text-xs h-full;
@apply overflow-auto p-2 pl-0 bg-white dark:bg-stone-950 rounded-b-xl text-xs h-full leading-5;
}
/* The try button */
pre .code-container > a {

View 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>
);
}

View 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} />;
}

View File

@@ -0,0 +1,28 @@
import { clsx } from "clsx";
import MapTooltip from "./mapTooltip";
import { pingColorThresholds } from "./pingColorThresholds";
export const LatencyMap = () => {
return (
<div className="mb-4 rounded-lg relative">
<div className="relative xl:-mx-[10%] xl:w-[120%] aspect-[12/4]">
<MapTooltip />
</div>
<div className="absolute bottom-0 left-0 lg:bottom-8 flex flex-col md:gap-1">
{pingColorThresholds.map((t, i) => (
<div
key={t.ping}
className={clsx("flex items-center gap-1", {
"hidden sm:flex": i % 2 !== 0,
})}
>
<div className={"size-2 md:size-3 rounded-full " + t.bgClass}></div>
<div className="text-[9px] md:text-xs font-mono">
&lt;{t.ping}ms
</div>
</div>
))}
</div>
</div>
);
};

Some files were not shown because too many files have changed in this diff Show More