Compare commits

...

42 Commits

Author SHA1 Message Date
Guido D'Orsi
246f91937c feat(svelte): syncronously resolve local values in useCoState 2025-01-08 12:49:41 +01:00
Guido D'Orsi
ee292b8855 docs: migration docs for rn, vue and svelte 2025-01-08 12:40:26 +01:00
Guido D'Orsi
38a6361aed Merge remote-tracking branch 'origin/main' into next 2025-01-08 12:28:01 +01:00
Guido D'Orsi
0231650b6b Merge pull request #1148 from garden-co/styling/code-snippet
Styling improvements for code snippets
2025-01-08 12:26:36 +01:00
Guido D'Orsi
35e4af88d0 Merge pull request #1139 from garden-co/top-level-imports-vue
feat(jazz-vue): simplify app setup and make composables available as top-level imports
2025-01-08 12:01:29 +01:00
Guido D'Orsi
a44a1496ca Merge pull request #1145 from garden-co/react-0.9.0-migration-docs
docs: migration docs for jazz-react 0.9.0
2025-01-08 11:26:15 +01:00
Guido D'Orsi
2269bd4d8f docs: improvements 2025-01-07 19:28:27 +01:00
Guido D'Orsi
b3bd55f969 chore: add comment 2025-01-07 18:51:06 +01:00
Guido D'Orsi
dd91354eb4 docs: migration docs for jazz-react 0.9.0 2025-01-07 18:51:05 +01:00
Guido D'Orsi
27c294166b Merge remote-tracking branch 'origin/main' into next 2025-01-07 18:50:47 +01:00
Guido D'Orsi
0cdf004902 Merge pull request #1129 from garden-co/jazz-621-add-upgrade-guides-section-to-document-breaking-changes
Add upgrade guides section to docs
2025-01-07 17:10:23 +01:00
Guido D'Orsi
9dd8d9510b feat: simplify app setup and make hooks available as top-level imports 2025-01-07 16:08:31 +01:00
Guido D'Orsi
6de44dd8d1 feat: move the common test API to jazz-tools 2025-01-07 14:36:12 +01:00
Guido D'Orsi
41e88b82b7 Merge pull request #1117 from garden-co/react-native-top-level-hooks
feat: top-level imports for react native hooks
2025-01-07 14:04:23 +01:00
pax-k
afe73c05fe chore: cleanup 2025-01-07 14:31:44 +02:00
Guido D'Orsi
d56fc0874c Merge pull request #1118 from garden-co/svelte-top-level-hooks
feat: top-level imports for svelte hooks
2025-01-04 12:23:20 +01:00
Guido D'Orsi
ade4890ede chore: changeset 2025-01-03 18:45:36 +01:00
Guido D'Orsi
b734c66a90 fix(testing): mock crypto functions incompatible with jsDom 2025-01-03 18:44:00 +01:00
Trisha Lim
bc979ba26e Hide/show content based on framework 2025-01-03 17:20:14 +00:00
Guido D'Orsi
906acaf417 fix: handle kvStore init inside RNDemoAuth 2025-01-03 18:11:28 +01:00
Trisha Lim
432724f63e Render example guide 2025-01-03 17:09:42 +00:00
Guido D'Orsi
1e5e3a1599 feat: top-level imports for react native hooks 2025-01-03 17:45:45 +01:00
Guido D'Orsi
37699c1831 test: update svelte tests 2025-01-03 17:45:14 +01:00
Guido D'Orsi
6c6da24281 feat: top-level imports for svelte hooks 2025-01-03 17:45:13 +01:00
Guido D'Orsi
2d85476433 chore: update the version history example 2025-01-03 17:39:14 +01:00
Trisha Lim
cdc8a6b568 Add example guides 2025-01-03 15:22:01 +00:00
Trisha Lim
1b539483d1 Add page in docs for upgrade guides 2025-01-03 14:37:20 +00:00
Guido D'Orsi
25eab61cd0 Merge pull request #1104 from garden-co/jazz-361-make-jazz-react-hooks-global
feat: top-level imports for Jazz react hooks
2025-01-03 15:16:37 +01:00
Guido D'Orsi
43a782937f chore: update docs 2025-01-03 15:16:10 +01:00
Guido D'Orsi
de1a3ee84a Update homepage/homepage/app/docs/[framework]/[...slug]/project-setup/react.mdx
Co-authored-by: Anselm Eickhoff <anselm.eickhoff@gmail.com>
2025-01-03 15:14:33 +01:00
Guido D'Orsi
b12eb407cb Merge remote-tracking branch 'origin/main' into jazz-361-make-jazz-react-hooks-global 2025-01-03 11:10:11 +01:00
Guido D'Orsi
90096d65e9 chore: remove unused import 2025-01-02 17:22:03 +01:00
Guido D'Orsi
0e7f1aa44a chore: move platform agnostic code in jazz-react-core 2025-01-02 16:52:24 +01:00
Guido D'Orsi
68932ee4ce feat(react): hard deprecate the previous way of creating React Jazz apps 2025-01-02 13:38:17 +01:00
Guido D'Orsi
cf22cfcc88 fix: fix typescript errors 2024-12-30 19:15:04 +01:00
Guido D'Orsi
c5b5eacba5 docs(guide): fix the snippets indentation 2024-12-30 18:34:53 +01:00
Guido D'Orsi
380bcb2d14 chore: simplfy comment about the AccountSchema registration 2024-12-30 18:21:32 +01:00
Guido D'Orsi
956a4d1b5e chore: migrate to use top-level hook imports 2024-12-30 18:16:06 +01:00
Guido D'Orsi
b7fb4b4b0b docs: update React docs to use the top-level imports 2024-12-30 18:15:09 +01:00
Guido D'Orsi
4433745cff feat: simplify App creation and make the hooks available as top-level imports 2024-12-30 18:14:57 +01:00
Guido D'Orsi
8eda79227b perf(subscribe): add an option to resolve locally available CoValues syncronously 2024-12-30 18:11:19 +01:00
Guido D'Orsi
1a3ec55e6e feat: makes possible to directly import the crypto module 2024-12-30 17:53:35 +01:00
201 changed files with 4476 additions and 2493 deletions

View File

@@ -0,0 +1,5 @@
---
"cojson": patch
---
Add a crypto entry to optionally import the crypto modules

View File

@@ -0,0 +1,7 @@
---
"jazz-svelte": minor
---
Change the way the JazzProvider is created and make the API available as top-level imports.
This is a breaking change.

View File

@@ -0,0 +1,7 @@
---
"jazz-vue": minor
---
Change the way the JazzProvider is created and make the composables available as top-level imports.
This is a breaking change.

View File

@@ -0,0 +1,7 @@
---
"jazz-react": minor
---
Change the way the JazzProvider is created and make the hooks available as top-level imports.
This is a breaking change.

View File

@@ -0,0 +1,5 @@
---
"jazz-tools": patch
---
Optimize the subscribe to resolve the CoValues stored in memory synchronously

View File

@@ -0,0 +1,5 @@
---
"jazz-react-native": minor
---
Change the way the JazzProvider is created and make the hooks available as top-level imports.

View File

@@ -1,9 +1,9 @@
import { useAccount, useCoState } from "@/src/jazz";
import { Chat, Message } from "@/src/schema";
import { useFocusEffect, useNavigation } from "@react-navigation/native";
import { useNavigation } from "@react-navigation/native";
import clsx from "clsx";
import * as Clipboard from "expo-clipboard";
import { useLocalSearchParams } from "expo-router";
import { useAccount, useCoState } from "jazz-react-native";
import { Group, ID } from "jazz-tools";
import { useEffect, useLayoutEffect, useState } from "react";
import React, {

View File

@@ -11,7 +11,7 @@ import React, {
} from "react-native";
import { useUser } from "@clerk/clerk-expo";
import { useAccount } from "../../src/jazz";
import { useAccount } from "jazz-react-native";
import { Chat } from "../../src/schema";
export default function ChatScreen() {

View File

@@ -1,4 +1,5 @@
import { useClerk, useUser } from "@clerk/clerk-expo";
import { JazzProvider, setupKvStore } from "jazz-react-native";
import { useJazzClerkAuth } from "jazz-react-native-auth-clerk";
import React, {
createContext,
@@ -8,8 +9,6 @@ import React, {
useState,
} from "react";
import { Text, View } from "react-native";
import { Jazz, kvStore } from "./jazz";
const AuthContext = createContext<{
isAuthenticated: boolean;
isLoading: boolean;
@@ -22,6 +21,8 @@ export function useAuth() {
return useContext(AuthContext);
}
const kvStore = setupKvStore();
export function JazzAndAuth({ children }: PropsWithChildren) {
const { isSignedIn, isLoaded: isClerkLoaded } = useUser();
const clerk = useClerk();
@@ -47,13 +48,12 @@ export function JazzAndAuth({ children }: PropsWithChildren) {
</View>
))}
{auth && clerk.user ? (
<Jazz.Provider
<JazzProvider
auth={auth}
peer="wss://cloud.jazz.tools/?key=chat-rn-clerk-example-jazz@garden.co"
storage={undefined}
>
{children}
</Jazz.Provider>
</JazzProvider>
) : (
children
)}

View File

@@ -1,4 +0,0 @@
import { createJazzRNApp } from "jazz-react-native";
export const Jazz = createJazzRNApp();
export const { useAccount, useCoState, useAcceptInvite, kvStore } = Jazz;

View File

@@ -9,9 +9,8 @@ import * as Linking from "expo-linking";
import React, { StrictMode, useEffect, useState } from "react";
import HandleInviteScreen from "./invite";
import { DemoAuthBasicUI, useDemoAuth } from "jazz-react-native";
import { DemoAuthBasicUI, JazzProvider, useDemoAuth } from "jazz-react-native";
import ChatScreen from "./chat";
import { Jazz } from "./jazz";
const Stack = createNativeStackNavigator();
@@ -51,10 +50,9 @@ function App() {
return (
<StrictMode>
<Jazz.Provider
<JazzProvider
auth={auth}
peer="wss://cloud.jazz.tools/?key=chat-rn-example-jazz@garden.co"
storage={undefined}
>
<NavigationContainer linking={linking} ref={navigationRef}>
<Stack.Navigator initialRouteName={initialRoute}>
@@ -70,7 +68,7 @@ function App() {
/>
</Stack.Navigator>
</NavigationContainer>
</Jazz.Provider>
</JazzProvider>
{state.state !== "signedIn" ? (
<DemoAuthBasicUI appName="Jazz Chat" state={state} />
) : null}

View File

@@ -14,7 +14,7 @@ import React, {
Alert,
} from "react-native";
import { useAccount, useCoState } from "./jazz";
import { useAccount, useCoState } from "jazz-react-native";
import { Chat, Message } from "./schema";
export default function ChatScreen({ navigation }: { navigation: any }) {

View File

@@ -1,13 +1,7 @@
import { useAcceptInvite } from "jazz-react-native";
import React, { Text } from "react-native";
import { useAcceptInvite } from "./jazz";
import { Chat } from "./schema";
type ChatScreenParams = {
valueHint?: string;
valueID?: string;
inviteSecret?: string;
};
export default function HandleInviteScreen({
navigation,
}: {

View File

@@ -1,4 +0,0 @@
import { createJazzRNApp } from "jazz-react-native";
export const Jazz = createJazzRNApp();
export const { useAccount, useCoState, useAcceptInvite } = Jazz;

View File

@@ -9,9 +9,9 @@
</template>
<script setup lang="ts">
import { useAccount } from "jazz-vue";
import AppContainer from "./components/AppContainer.vue";
import TopBar from "./components/TopBar.vue";
import { useAccount } from "./main";
const { me, logOut } = useAccount();
</script>

View File

@@ -1,13 +1,9 @@
import { DemoAuthBasicUI, createJazzVueApp, useDemoAuth } from "jazz-vue";
import { DemoAuthBasicUI, JazzProvider, 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();
export const { useAccount, useCoState } = Jazz;
const { JazzProvider } = Jazz;
const RootComponent = defineComponent({
name: "RootComponent",
setup() {

View File

@@ -26,12 +26,12 @@
<script lang="ts">
import type { ID } from "jazz-tools";
import { useCoState } from "jazz-vue";
import { type PropType, computed, defineComponent, ref } from "vue";
import ChatBody from "../components/ChatBody.vue";
import ChatBubble from "../components/ChatBubble.vue";
import ChatInput from "../components/ChatInput.vue";
import EmptyChatMessage from "../components/EmptyChatMessage.vue";
import { useCoState } from "../main";
import { Chat, Message } from "../schema";
export default defineComponent({

View File

@@ -4,8 +4,8 @@
<script setup lang="ts">
import { Group } from "jazz-tools";
import { useAccount } from "jazz-vue";
import { useRouter } from "vue-router";
import { useAccount } from "../main";
import { Chat } from "../schema";
const router = useRouter();

View File

@@ -34,4 +34,4 @@ If you have feedback, let us know on [Discord](https://discord.gg/utDMjHYg42) or
By default, the example app uses [Jazz Cloud](https://jazz.tools/cloud) (`wss://cloud.jazz.tools`) - so cross-device use, invites and collaboration should just work.
You can also run a local sync server by running `npx jazz-run sync` and adding the query param `?sync=ws://localhost:4200` to the URL of the example app (for example: `http://localhost:5173/?peer=ws://localhost:4200`), or by setting the `sync` parameter of the `<Jazz.Provider>` provider component in [./src/main.tsx](./src/main.tsx).
You can also run a local sync server by running `npx jazz-run sync` and adding the query param `?sync=ws://localhost:4200` to the URL of the example app (for example: `http://localhost:5173/?peer=ws://localhost:4200`), or by setting the `sync` parameter of the `<JazzProvider>` provider component in [./src/main.tsx](./src/main.tsx).

View File

@@ -1,9 +1,13 @@
import { inIframe, onChatLoad } from "@/util.ts";
import { useIframeHashRouter } from "hash-slash";
import { useAccount } from "jazz-react";
import { Group, ID } from "jazz-tools";
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import { ChatScreen } from "./chatScreen.tsx";
import { useAccount } from "./main.tsx";
import { JazzAndAuth } from "./jazz.tsx";
import { Chat } from "./schema.ts";
import { ThemeProvider } from "./themeProvider.tsx";
import { AppContainer, TopBar } from "./ui.tsx";
export function App() {
@@ -34,3 +38,13 @@ export function App() {
</AppContainer>
);
}
createRoot(document.getElementById("root")!).render(
<ThemeProvider>
<StrictMode>
<JazzAndAuth>
<App />
</JazzAndAuth>
</StrictMode>
</ThemeProvider>,
);

View File

@@ -1,7 +1,7 @@
import { createImage } from "jazz-browser-media-images";
import { useAccount, useCoState } from "jazz-react";
import { ID } from "jazz-tools";
import { useState } from "react";
import { useAccount, useCoState } from "./main.tsx";
import { Chat, Message } from "./schema.ts";
import {
BubbleBody,

View File

@@ -0,0 +1,19 @@
import { DemoAuthBasicUI, JazzProvider, useDemoAuth } from "jazz-react";
export function JazzAndAuth({ children }: { children: React.ReactNode }) {
const [auth, state] = useDemoAuth();
return (
<>
<JazzProvider
auth={auth}
peer="wss://cloud.jazz.tools/?key=chat-example-jazz@garden.co"
>
{children}
</JazzProvider>
{state.state !== "signedIn" && (
<DemoAuthBasicUI appName="Jazz Chat" state={state} />
)}
</>
);
}

View File

@@ -1,36 +0,0 @@
import { ThemeProvider } from "@/themeProvider.tsx";
import { DemoAuthBasicUI, createJazzReactApp, useDemoAuth } from "jazz-react";
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import { App } from "./app.tsx";
const Jazz = createJazzReactApp();
export const { useAccount, useCoState } = Jazz;
function JazzAndAuth({ children }: { children: React.ReactNode }) {
const [auth, state] = useDemoAuth();
return (
<>
<Jazz.Provider
auth={auth}
peer="wss://cloud.jazz.tools/?key=chat-example-jazz@garden.co"
>
{children}
</Jazz.Provider>
{state.state !== "signedIn" && (
<DemoAuthBasicUI appName="Jazz Chat" state={state} />
)}
</>
);
}
createRoot(document.getElementById("root")!).render(
<ThemeProvider>
<StrictMode>
<JazzAndAuth>
<App />
</JazzAndAuth>
</StrictMode>
</ThemeProvider>,
);

View File

@@ -1,4 +1,4 @@
import { useAccount } from "./main";
import { useAccount } from "jazz-react";
function App() {
const { me, logOut } = useAccount();

View File

@@ -1,10 +1,10 @@
import { ClerkProvider, SignInButton, useClerk } from "@clerk/clerk-react";
import { createJazzReactApp } from "jazz-react";
import { useJazzClerkAuth } from "jazz-react-auth-clerk";
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import App from "./App.tsx";
import "./index.css";
import { JazzProvider } from "jazz-react";
// Import your publishable key
const PUBLISHABLE_KEY = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY;
@@ -13,9 +13,6 @@ if (!PUBLISHABLE_KEY) {
throw new Error("Add your Clerk publishable key to the .env.local file");
}
const Jazz = createJazzReactApp();
export const { useAccount, useCoState } = Jazz;
function JazzAndAuth({ children }: { children: React.ReactNode }) {
const clerk = useClerk();
const [auth, state] = useJazzClerkAuth(clerk);
@@ -26,12 +23,12 @@ function JazzAndAuth({ children }: { children: React.ReactNode }) {
<div key={error}>{error}</div>
))}
{clerk.user && auth ? (
<Jazz.Provider
<JazzProvider
auth={auth}
peer="wss://cloud.jazz.tools/?key=minimal-auth-clerk-example@garden.co"
>
{children}
</Jazz.Provider>
</JazzProvider>
) : (
<SignInButton />
)}

View File

@@ -3,7 +3,7 @@
import { SharedFile } from '$lib/schema';
import { FileStream } from 'jazz-tools';
import { File, FileDown, Trash2, Link2 } from 'lucide-svelte';
import { useAccount } from '$lib/jazz';
import { useAccount } from 'jazz-svelte';
import { toast } from 'svelte-sonner';
import { formatFileSize } from '$lib/utils';

View File

@@ -1,7 +0,0 @@
import { createJazzApp } from 'jazz-svelte';
import { FileShareAccount } from './schema';
export const { useAccount, useCoState, useAcceptInvite, useAccountOrGuest, Provider } =
createJazzApp({
AccountSchema: FileShareAccount
});

View File

@@ -1,8 +1,17 @@
<script lang="ts" module>
declare module 'jazz-svelte' {
interface Register {
Account: FileShareAccount;
}
}
</script>
<script lang="ts">
import { Provider } from '$lib/jazz';
import { JazzProvider } from 'jazz-svelte';
import { PasskeyAuthBasicUI, usePasskeyAuth } from 'jazz-svelte';
import { Toaster } from 'svelte-sonner';
import '../app.css';
import { FileShareAccount } from '$lib/schema';
let { children } = $props();
const auth = usePasskeyAuth({
@@ -24,9 +33,13 @@
</div>
{/if}
{#if auth.current}
<Provider auth={auth.current} peer="wss://cloud.jazz.tools/?key=file-share-svelte@garden.co">
<JazzProvider
AccountSchema={FileShareAccount}
auth={auth.current}
peer="wss://cloud.jazz.tools/?key=file-share-svelte@garden.co"
>
<div class="min-h-screen bg-gray-100">
{@render children()}
</div>
</Provider>
</JazzProvider>
{/if}

View File

@@ -1,5 +1,5 @@
<script lang="ts">
import { useAccount, useCoState } from '$lib/jazz';
import { useAccount, useCoState } from 'jazz-svelte';
import { SharedFile, ListOfSharedFiles } from '$lib/schema';
import { createInviteLink } from 'jazz-svelte';
import { FileStream } from 'jazz-tools';

View File

@@ -1,6 +1,6 @@
<script lang="ts">
import { page } from '$app/stores';
import { useAccount, useCoState } from '$lib/jazz';
import { useAccount, useCoState } from 'jazz-svelte';
import { SharedFile } from '$lib/schema';
import { File, FileDown, Link2 } from 'lucide-svelte';
import type { ID } from 'jazz-tools';

View File

@@ -49,4 +49,4 @@ If you have feedback, let us know on [Discord](https://discord.gg/utDMjHYg42) or
By default, the example app uses [Jazz Cloud](https://jazz.tools/cloud) (`wss://cloud.jazz.tools`) - so cross-device use, invites and collaboration should just work.
You can also run a local sync server by running `npx jazz-run sync` and adding the query param `?sync=ws://localhost:4200` to the URL of the example app (for example: `http://localhost:5173/?peer=ws://localhost:4200`), or by setting the `sync` parameter of the `<Jazz.Provider>` provider component in [./src/main.tsx](./src/main.tsx).
You can also run a local sync server by running `npx jazz-run sync` and adding the query param `?sync=ws://localhost:4200` to the URL of the example app (for example: `http://localhost:5173/?peer=ws://localhost:4200`), or by setting the `sync` parameter of the `<JazzProvider>` provider component in [./src/main.tsx](./src/main.tsx).

View File

@@ -1,9 +1,9 @@
import { useIframeHashRouter } from "hash-slash";
import { useAccount } from "jazz-react";
import { ID } from "jazz-tools";
import { CreateOrder } from "./CreateOrder.tsx";
import { EditOrder } from "./EditOrder.tsx";
import { Orders } from "./Orders.tsx";
import { useAccount } from "./main";
import { BubbleTeaOrder } from "./schema.ts";
function App() {

View File

@@ -1,10 +1,10 @@
import { useIframeHashRouter } from "hash-slash";
import { useAccount, useCoState } from "jazz-react";
import { ID } from "jazz-tools";
import { useState } from "react";
import { Errors } from "./Errors.tsx";
import { LinkToHome } from "./LinkToHome.tsx";
import { OrderForm } from "./OrderForm.tsx";
import { useAccount, useCoState } from "./main.tsx";
import {
BubbleTeaOrder,
DraftBubbleTeaOrder,

View File

@@ -1,4 +1,4 @@
import { useAccount } from "./main.tsx";
import { useAccount } from "jazz-react";
export function DraftIndicator() {
const { me } = useAccount({

View File

@@ -1,8 +1,8 @@
import { useCoState } from "jazz-react";
import { ID } from "jazz-tools";
import { LinkToHome } from "./LinkToHome.tsx";
import { OrderForm } from "./OrderForm.tsx";
import { OrderThumbnail } from "./OrderThumbnail.tsx";
import { useCoState } from "./main.tsx";
import { BubbleTeaOrder } from "./schema.ts";
export function EditOrder(props: { id: ID<BubbleTeaOrder> }) {

View File

@@ -1,6 +1,6 @@
import { useAccount } from "jazz-react";
import { DraftIndicator } from "./DraftIndicator.tsx";
import { OrderThumbnail } from "./OrderThumbnail.tsx";
import { useAccount } from "./main.tsx";
export function Orders() {
const { me } = useAccount({

View File

@@ -1,27 +1,22 @@
import { DemoAuthBasicUI, createJazzReactApp, useDemoAuth } from "jazz-react";
import { DemoAuthBasicUI, JazzProvider, useDemoAuth } from "jazz-react";
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import App from "./App.tsx";
import "./index.css";
import { JazzAccount } from "./schema.ts";
const Jazz = createJazzReactApp({
AccountSchema: JazzAccount,
});
export const { useAccount, useCoState } = Jazz;
function JazzAndAuth({ children }: { children: React.ReactNode }) {
const [auth, authState] = useDemoAuth();
return (
<>
<Jazz.Provider
<JazzProvider
auth={auth}
peer="wss://cloud.jazz.tools/?key=form-example@garden.co"
AccountSchema={JazzAccount}
>
{children}
</Jazz.Provider>
</JazzProvider>
{authState.state !== "signedIn" && (
<DemoAuthBasicUI appName="Form" state={authState} />
@@ -30,6 +25,12 @@ function JazzAndAuth({ children }: { children: React.ReactNode }) {
);
}
declare module "jazz-react" {
interface Register {
Account: JazzAccount;
}
}
createRoot(document.getElementById("root")!).render(
<StrictMode>
<JazzAndAuth>

View File

@@ -1,5 +1,5 @@
import { useAccount } from "jazz-react";
import ImageUpload from "./ImageUpload.tsx";
import { useAccount } from "./main";
function App() {
const { me, logOut } = useAccount();

View File

@@ -1,8 +1,7 @@
import { createImage } from "jazz-browser-media-images";
import { ProgressiveImg } from "jazz-react";
import { ProgressiveImg, useAccount } from "jazz-react";
import { ImageDefinition } from "jazz-tools";
import { ChangeEvent, useRef } from "react";
import { useAccount } from "./main.tsx";
function Image({ image }: { image: ImageDefinition }) {
return (

View File

@@ -1,27 +1,22 @@
import { DemoAuthBasicUI, createJazzReactApp, useDemoAuth } from "jazz-react";
import { DemoAuthBasicUI, JazzProvider, useDemoAuth } from "jazz-react";
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import App from "./App.tsx";
import "./index.css";
import { JazzAccount } from "./schema.ts";
const Jazz = createJazzReactApp({
AccountSchema: JazzAccount,
});
export const { useAccount, useCoState } = Jazz;
function JazzAndAuth({ children }: { children: React.ReactNode }) {
const [auth, authState] = useDemoAuth();
return (
<>
<Jazz.Provider
<JazzProvider
auth={auth}
peer="wss://cloud.jazz.tools/?key=image-upload-example@garden.co"
AccountSchema={JazzAccount}
>
{children}
</Jazz.Provider>
</JazzProvider>
{authState.state !== "signedIn" && (
<DemoAuthBasicUI appName="Image upload" state={authState} />
@@ -30,6 +25,12 @@ function JazzAndAuth({ children }: { children: React.ReactNode }) {
);
}
declare module "jazz-react" {
interface Register {
Account: JazzAccount;
}
}
createRoot(document.getElementById("root")!).render(
<StrictMode>
<JazzAndAuth>

View File

@@ -34,4 +34,4 @@ If you have feedback, let us know on [Discord](https://discord.gg/utDMjHYg42) or
By default, the example app uses [Jazz Cloud](https://jazz.tools/cloud) (`wss://cloud.jazz.tools`) - so cross-device use, invites and collaboration should just work.
You can also run a local sync server by running `npx cojson-simple-sync` and adding the query param `?sync=ws://localhost:4200` to the URL of the example app (for example: `http://localhost:5173/?peer=ws://localhost:4200`), or by setting the `sync` parameter of the `<Jazz.Provider>` provider component in [./src/2_main.tsx](./src/2_main.tsx).
You can also run a local sync server by running `npx cojson-simple-sync` and adding the query param `?sync=ws://localhost:4200` to the URL of the example app (for example: `http://localhost:5173/?peer=ws://localhost:4200`), or by setting the `sync` parameter of the `<JazzProvider>` provider component in [./src/2_main.tsx](./src/2_main.tsx).

View File

@@ -10,26 +10,20 @@ import { PlayerControls } from "./components/PlayerControls";
import "./index.css";
import { MusicaAccount } from "@/1_schema";
import { DemoAuthBasicUI, createJazzReactApp, useDemoAuth } from "jazz-react";
import { DemoAuthBasicUI, JazzProvider, useDemoAuth } from "jazz-react";
import { useUploadExampleData } from "./lib/useUploadExampleData";
/**
* Walkthrough: The top-level provider `<Jazz.Provider/>`
* Walkthrough: The top-level provider `<JazzProvider/>`
*
* This shows how to use the top-level provider `<Jazz.Provider/>`,
* This shows how to use the top-level provider `<JazzProvider/>`,
* which provides the rest of the app with a controlled account (used through `useAccount` later).
* Here we use `DemoAuth` which is great for prototyping you app without wasting time on figuring out
* the best way to do auth.
*
* `<Jazz.Provider/>` also runs our account migration
* `<JazzProvider/>` also runs our account migration
*/
const Jazz = createJazzReactApp({
AccountSchema: MusicaAccount,
});
export const { useAccount, useCoState, useAcceptInvite } = Jazz;
function Main() {
const mediaPlayer = useMediaPlayer();
@@ -70,18 +64,25 @@ function JazzAndAuth({ children }: { children: React.ReactNode }) {
return (
<>
<Jazz.Provider
<JazzProvider
storage={["singleTabOPFS", "indexedDB"]}
auth={auth}
peer={peer}
AccountSchema={MusicaAccount}
>
{children}
</Jazz.Provider>
</JazzProvider>
<DemoAuthBasicUI appName="Jazz Music Player" state={state} />
</>
);
}
declare module "jazz-react" {
interface Register {
Account: MusicaAccount;
}
}
ReactDOM.createRoot(document.getElementById("root")!).render(
<React.StrictMode>
<JazzAndAuth>

View File

@@ -1,9 +1,8 @@
import { useToast } from "@/hooks/use-toast";
import { createInviteLink } from "jazz-react";
import { createInviteLink, useAccount, useCoState } from "jazz-react";
import { ID } from "jazz-tools";
import { useNavigate, useParams } from "react-router";
import { Playlist } from "./1_schema";
import { useAccount, useCoState } from "./2_main";
import { createNewPlaylist, uploadMusicTracks } from "./4_actions";
import { MediaPlayer } from "./5_useMediaPlayer";
import { FileUploadButton } from "./components/FileUploadButton";

View File

@@ -1,9 +1,9 @@
import { MusicTrack, Playlist } from "@/1_schema";
import { usePlayMedia } from "@/lib/audio/usePlayMedia";
import { usePlayState } from "@/lib/audio/usePlayState";
import { useAccount } from "jazz-react";
import { FileStream, ID } from "jazz-tools";
import { useRef, useState } from "react";
import { useAccount } from "./2_main";
import { updateActivePlaylist, updateActiveTrack } from "./4_actions";
import { getNextTrack, getPrevTrack } from "./lib/getters";

View File

@@ -1,8 +1,8 @@
import { useAcceptInvite, useAccount } from "jazz-react";
import { ID } from "jazz-tools";
import { useCallback } from "react";
import { useNavigate } from "react-router-dom";
import { Playlist } from "./1_schema";
import { useAcceptInvite, useAccount } from "./2_main";
export function InvitePage() {
const navigate = useNavigate();

View File

@@ -1,4 +1,4 @@
import { useAccount } from "@/2_main";
import { useAccount } from "jazz-react";
import { Button } from "./ui/button";
export function LogoutButton() {

View File

@@ -1,5 +1,4 @@
import { MusicTrack, Playlist } from "@/1_schema";
import { useAccount, useCoState } from "@/2_main";
import { addTrackToPlaylist } from "@/4_actions";
import {
DropdownMenu,
@@ -8,6 +7,7 @@ import {
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { cn } from "@/lib/utils";
import { useAccount, useCoState } from "jazz-react";
import { ID } from "jazz-tools";
import { MoreHorizontal } from "lucide-react";
import { MusicTrackTitleInput } from "./MusicTrackTitleInput";

View File

@@ -1,6 +1,6 @@
import { MusicTrack } from "@/1_schema";
import { useCoState } from "@/2_main";
import { updateMusicTrackTitle } from "@/4_actions";
import { useCoState } from "jazz-react";
import { ID } from "jazz-tools";
import { ChangeEvent, useState } from "react";

View File

@@ -1,9 +1,9 @@
import { MusicTrack } from "@/1_schema";
import { useAccount, useCoState } from "@/2_main";
import { MediaPlayer } from "@/5_useMediaPlayer";
import { useMediaEndListener } from "@/lib/audio/useMediaEndListener";
import { usePlayState } from "@/lib/audio/usePlayState";
import { useKeyboardListener } from "@/lib/useKeyboardListener";
import { useAccount, useCoState } from "jazz-react";
import { Pause, Play, SkipBack, SkipForward } from "lucide-react";
import { Waveform } from "./Waveform";

View File

@@ -1,6 +1,6 @@
import { Playlist } from "@/1_schema";
import { useCoState } from "@/2_main";
import { updatePlaylistTitle } from "@/4_actions";
import { useCoState } from "jazz-react";
import { ID } from "jazz-tools";
import { ChangeEvent, useState } from "react";

View File

@@ -1,4 +1,4 @@
import { useAccount } from "@/2_main";
import { useAccount } from "jazz-react";
import { useNavigate, useParams } from "react-router";
export function SidePanel() {

View File

@@ -1,7 +1,7 @@
import { MusicTrack, MusicTrackWaveform } from "@/1_schema";
import { useCoState } from "@/2_main";
import { usePlayerCurrentTime } from "@/lib/audio/usePlayerCurrentTime";
import { cn } from "@/lib/utils";
import { useCoState } from "jazz-react";
export function Waveform(props: { track: MusicTrack; height: number }) {
const { track, height } = props;

View File

@@ -1,8 +1,8 @@
import { useAccount } from "jazz-react";
// eslint-disable-next-line react-compiler/react-compiler
/* eslint-disable react-hooks/exhaustive-deps */
import { useEffect } from "react";
import { MusicaAccount } from "../1_schema";
import { useAccount } from "../2_main";
import { uploadMusicTracks } from "../4_actions";
export function useUploadExampleData() {

View File

@@ -32,4 +32,4 @@ If you have feedback, let us know on [Discord](https://discord.gg/utDMjHYg42) or
By default, the example app uses [Jazz Cloud](https://jazz.tools/cloud) (`wss://cloud.jazz.tools`) - so cross-device use, invites and collaboration should just work.
You can also run a local sync server by running `npx cojson-simple-sync` and adding the query param `?sync=ws://localhost:4200` to the URL of the example app (for example: `http://localhost:5173/?peer=ws://localhost:4200`), or by setting the `sync` parameter of the `<Jazz.Provider>` provider component in [./src/main.tsx](./src/main.tsx).
You can also run a local sync server by running `npx cojson-simple-sync` and adding the query param `?sync=ws://localhost:4200` to the URL of the example app (for example: `http://localhost:5173/?peer=ws://localhost:4200`), or by setting the `sync` parameter of the `<JazzProvider>` provider component in [./src/main.tsx](./src/main.tsx).

View File

@@ -1,9 +1,9 @@
import { Button } from "@/components/Button.tsx";
import { useAcceptInvite, useAccount, useCoState } from "@/main.tsx";
import { EmployeeList } from "@/pages/EmployeeList.tsx";
import { EmployeeOnboading } from "@/pages/EmployeeOnboarding.tsx";
import { NewEmployee } from "@/pages/NewEmployee.tsx";
import { CoEmployee, EmployeeCoList } from "@/schema.ts";
import { useAcceptInvite, useAccount, useCoState } from "jazz-react";
import { ID } from "jazz-tools";
import { useEffect } from "react";
import {

View File

@@ -1,15 +1,10 @@
import App from "@/App.tsx";
import "@/index.css";
import { HRAccount } from "@/schema.ts";
import { DemoAuthBasicUI, createJazzReactApp, useDemoAuth } from "jazz-react";
import { DemoAuthBasicUI, JazzProvider, useDemoAuth } from "jazz-react";
import React from "react";
import ReactDOM from "react-dom/client";
const Jazz = createJazzReactApp({
AccountSchema: HRAccount,
});
export const { useAccount, useCoState, useAcceptInvite } = Jazz;
const peer =
(new URL(window.location.href).searchParams.get(
"peer",
@@ -20,9 +15,9 @@ function JazzAndAuth({ children }: { children: React.ReactNode }) {
const [auth, authState] = useDemoAuth();
return (
<>
<Jazz.Provider auth={auth} peer={peer}>
<JazzProvider AccountSchema={HRAccount} auth={auth} peer={peer}>
{children}
</Jazz.Provider>
</JazzProvider>
{authState.state !== "signedIn" && (
<DemoAuthBasicUI appName="Jazz Onboarding" state={authState} />
)}
@@ -30,6 +25,12 @@ function JazzAndAuth({ children }: { children: React.ReactNode }) {
);
}
declare module "jazz-react" {
interface Register {
Account: HRAccount;
}
}
ReactDOM.createRoot(document.getElementById("root")!).render(
<React.StrictMode>
<JazzAndAuth>

View File

@@ -1,8 +1,8 @@
import { NavLink } from "@/components/NavLink.tsx";
import { NavigateButton } from "@/components/NavigateBack.tsx";
import { Stack } from "@/components/Stack.tsx";
import { useCoState } from "@/main.tsx";
import { CoEmployee, EmployeeCoList } from "@/schema.ts";
import { useCoState } from "jazz-react";
import { ID } from "jazz-tools";
export function EmployeeList({

View File

@@ -2,8 +2,8 @@ import { Button } from "@/components/Button.tsx";
import { NavigateBack } from "@/components/NavigateBack.tsx";
import { Stack } from "@/components/Stack.tsx";
import { TextInput } from "@/components/TextInput.tsx";
import { useCoState } from "@/main.tsx";
import { createImage } from "jazz-browser-media-images";
import { useCoState } from "jazz-react";
import { ProgressiveImg, createInviteLink } from "jazz-react";
import { CoMap, ID } from "jazz-tools";
import { ChangeEvent, ReactNode, useCallback } from "react";

View File

@@ -2,7 +2,7 @@ import { Button } from "@/components/Button.tsx";
import { NavigateBack } from "@/components/NavigateBack.tsx";
import { Stack } from "@/components/Stack.tsx";
import { TextInput } from "@/components/TextInput.tsx";
import { useAccount, useCoState } from "@/main.tsx";
import { useAccount, useCoState } from "jazz-react";
import { Group, ID } from "jazz-tools";
import { useCallback, useState } from "react";
import { useNavigate } from "react-router-dom";

View File

@@ -37,4 +37,4 @@ If you have feedback, let us know on [Discord](https://discord.gg/utDMjHYg42) or
By default, the example app uses [Jazz Cloud](https://jazz.tools/cloud) (`wss://cloud.jazz.tools`) - so cross-device use, invites and collaboration should just work.
You can also run a local sync server by running `npx jazz-run sync` and adding the query param `?sync=ws://localhost:4200` to the URL of the example app (for example: `http://localhost:5173/?peer=ws://localhost:4200`), or by setting the `sync` parameter of the `<Jazz.Provider>` provider component in [./src/main.tsx](./src/main.tsx).
You can also run a local sync server by running `npx jazz-run sync` and adding the query param `?sync=ws://localhost:4200` to the URL of the example app (for example: `http://localhost:5173/?peer=ws://localhost:4200`), or by setting the `sync` parameter of the `<JazzProvider>` provider component in [./src/main.tsx](./src/main.tsx).

View File

@@ -1,6 +1,6 @@
import { useAcceptInvite, useAccount } from "jazz-react";
import { ID } from "jazz-tools";
import { useNavigate } from "react-router";
import { useAcceptInvite, useAccount } from "./main.tsx";
import { Organization } from "./schema.ts";
export function AcceptInvitePage() {

View File

@@ -1,7 +1,7 @@
import { useAccount } from "jazz-react";
import { Layout } from "./Layout.tsx";
import { CreateOrganization } from "./components/CreateOrganization.tsx";
import { Heading } from "./components/Heading.tsx";
import { useAccount } from "./main.tsx";
export function HomePage() {
const { me } = useAccount({

View File

@@ -1,5 +1,5 @@
import { useAccount } from "jazz-react";
import { UserIcon } from "lucide-react";
import { useAccount } from "./main.tsx";
export function Layout({ children }: { children: React.ReactNode }) {
const { me, logOut } = useAccount({

View File

@@ -1,3 +1,4 @@
import { useCoState } from "jazz-react";
import { ID } from "jazz-tools";
import { useParams } from "react-router";
import { Layout } from "./Layout.tsx";
@@ -5,7 +6,6 @@ import { CreateProject } from "./components/CreateProject.tsx";
import { Heading } from "./components/Heading.tsx";
import { InviteLink } from "./components/InviteLink.tsx";
import { OrganizationMembers } from "./components/OrganizationMembers.tsx";
import { useCoState } from "./main.tsx";
import { Organization } from "./schema.ts";
export function OrganizationPage() {

View File

@@ -1,7 +1,7 @@
import { useAccount, useCoState } from "jazz-react";
import { Group, ID } from "jazz-tools";
import { useState } from "react";
import { useNavigate } from "react-router";
import { useAccount, useCoState } from "../main.tsx";
import { DraftOrganization, ListOfProjects, Organization } from "../schema.ts";
import { Errors } from "./Errors.tsx";
import { OrganizationForm } from "./OrganizationForm.tsx";

View File

@@ -1,5 +1,5 @@
import { useCoState } from "jazz-react";
import { Account, Group, ID } from "jazz-tools";
import { useCoState } from "../main.tsx";
import { Organization } from "../schema.ts";
export function OrganizationMembers({

View File

@@ -1,8 +1,8 @@
import { useAccount } from "jazz-react";
import { ID } from "jazz-tools";
import { UsersIcon } from "lucide-react";
import { useEffect, useState } from "react";
import { useNavigate, useParams } from "react-router";
import { useAccount } from "../main.tsx";
import { Organization } from "../schema.ts";
export function OrganizationSelector({ className }: { className?: string }) {

View File

@@ -1,4 +1,4 @@
import { DemoAuthBasicUI, createJazzReactApp, useDemoAuth } from "jazz-react";
import { DemoAuthBasicUI, JazzProvider, useDemoAuth } from "jazz-react";
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import "./index.css";
@@ -8,11 +8,6 @@ import { HomePage } from "./HomePage.tsx";
import { OrganizationPage } from "./OrganizationPage.tsx";
import { JazzAccount } from "./schema.ts";
const Jazz = createJazzReactApp({
AccountSchema: JazzAccount,
});
export const { useAccount, useCoState, useAcceptInvite } = Jazz;
function Router() {
const router = createHashRouter([
{
@@ -37,12 +32,13 @@ function JazzAndAuth({ children }: { children: React.ReactNode }) {
return (
<>
<Jazz.Provider
<JazzProvider
AccountSchema={JazzAccount}
auth={auth}
peer="wss://cloud.jazz.tools/?key=organization-example@garden.co"
>
{children}
</Jazz.Provider>
</JazzProvider>
{authState.state !== "signedIn" && (
<DemoAuthBasicUI appName="Organization" state={authState} />
@@ -51,6 +47,12 @@ function JazzAndAuth({ children }: { children: React.ReactNode }) {
);
}
declare module "jazz-react" {
interface Register {
Account: JazzAccount;
}
}
createRoot(document.getElementById("root")!).render(
<StrictMode>
<JazzAndAuth>

View File

@@ -1,4 +1,4 @@
import { useAccount } from "./main";
import { useAccount } from "jazz-react";
function App() {
const { me, logOut } = useAccount();

View File

@@ -1,17 +1,9 @@
import {
PasskeyAuthBasicUI,
createJazzReactApp,
usePasskeyAuth,
} from "jazz-react";
import { JazzProvider, PasskeyAuthBasicUI, usePasskeyAuth } from "jazz-react";
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import App from "./App.tsx";
import "./index.css";
const Jazz = createJazzReactApp();
export const { useAccount, useCoState } = Jazz;
function JazzAndAuth({ children }: { children: React.ReactNode }) {
const [auth, state] = usePasskeyAuth({
appName: "Jazz Minimal Auth Passkey Example",
@@ -19,12 +11,12 @@ function JazzAndAuth({ children }: { children: React.ReactNode }) {
return (
<>
<Jazz.Provider
<JazzProvider
auth={auth}
peer="wss://cloud.jazz.tools/?key=minimal-auth-passkey-example@garden.co"
>
{children}
</Jazz.Provider>
</JazzProvider>
<PasskeyAuthBasicUI state={state} />
</>
);

View File

@@ -32,7 +32,7 @@ pnpm dev
- [`src/components`](./src/components/): UI components
- [`src/1_schema.ts`](./src/1_schema.ts): Jazz data model
- [`src/2_main.tsx`](./src/2_main.tsx): Main App component wrapped in `<Jazz.Provider>`
- [`src/2_main.tsx`](./src/2_main.tsx): Main App component wrapped in `<JazzProvider>`
- [`src/3_vault.tsx`](./src/3_vault.tsx): Password Manager Vault page
- [`src/4_actions.tsx`](./src/4_actions.tsx): Jazz specific actions
- [`src/5_App.tsx`](./src/5_App.tsx): App router - also handles invite links
@@ -44,7 +44,7 @@ pnpm dev
1. Define the data model with CoJSON: [`src/1_schema.ts`](./src/1_schema.ts)
2. Wrap the App with the top-level provider `<Jazz.Provider>`: [`src/2_main.tsx`](./src/2_main.tsx)
2. Wrap the App with the top-level provider `<JazzProvider>`: [`src/2_main.tsx`](./src/2_main.tsx)
3. Reactively render password items from folders inside a table, creating/sharing/deleting folders, creating/editing/deleting password items: [`src/3_vault.tsx`](./src/3_vault.tsx)
@@ -60,4 +60,4 @@ If you have feedback, let us know on [Discord](https://discord.gg/utDMjHYg42) or
By default, the example app uses [Jazz Cloud](https://jazz.tools/cloud) (`wss://cloud.jazz.tools`) - so cross-device use, invites and collaboration should just work.
You can also run a local sync server by running `npx cojson-simple-sync` and adding the query param `?sync=ws://localhost:4200` to the URL of the example app (for example: `http://localhost:5173/?peer=ws://localhost:4200`), or by setting the `sync` parameter of the `<Jazz.Provider>` provider component in [./src/2_main.tsx](./src/2_main.tsx).
You can also run a local sync server by running `npx cojson-simple-sync` and adding the query param `?sync=ws://localhost:4200` to the URL of the example app (for example: `http://localhost:5173/?peer=ws://localhost:4200`), or by setting the `sync` parameter of the `<JazzProvider>` provider component in [./src/2_main.tsx](./src/2_main.tsx).

View File

@@ -1,20 +1,10 @@
import {
PasskeyAuthBasicUI,
createJazzReactApp,
usePasskeyAuth,
} from "jazz-react";
import { JazzProvider, PasskeyAuthBasicUI, 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,
});
export const { useAccount, useCoState, useAcceptInvite } = Jazz;
function JazzAndAuth({ children }: { children: React.ReactNode }) {
const [auth, state] = usePasskeyAuth({
appName: "Jazz Password Manager",
@@ -22,17 +12,24 @@ function JazzAndAuth({ children }: { children: React.ReactNode }) {
return (
<>
<Jazz.Provider
<JazzProvider
AccountSchema={PasswordManagerAccount}
auth={auth}
peer="wss://cloud.jazz.tools/?key=password-manager-example-jazz@garden.co"
>
{children}
</Jazz.Provider>
</JazzProvider>
<PasskeyAuthBasicUI state={state} />
</>
);
}
declare module "jazz-react" {
interface Register {
Account: PasswordManagerAccount;
}
}
ReactDOM.createRoot(document.getElementById("root")!).render(
<React.StrictMode>
<JazzAndAuth>

View File

@@ -5,10 +5,10 @@ import InviteModal from "./components/invite-modal";
import NewItemModal from "./components/new-item-modal";
import Table from "./components/table";
import { useAccount, useCoState } from "jazz-react";
import { CoMapInit, Group, ID } from "jazz-tools";
import { useNavigate, useParams } from "react-router-dom";
import { Folder, FolderList, PasswordItem } from "./1_schema";
import { useAccount, useCoState } from "./2_main";
import {
addSharedFolder,
createFolder,

View File

@@ -1,7 +1,7 @@
import { useAcceptInvite } from "jazz-react";
import React from "react";
import { Navigate, RouterProvider, createHashRouter } from "react-router-dom";
import { Folder } from "./1_schema";
import { useAcceptInvite } from "./2_main";
import VaultPage from "./3_vault";
const App: React.FC = () => {

View File

@@ -35,4 +35,4 @@ If you have feedback, let us know on [Discord](https://discord.gg/utDMjHYg42) or
By default, the example app uses [Jazz Cloud](https://jazz.tools/cloud) (`wss://cloud.jazz.tools`) - so cross-device use, invites and collaboration should just work.
You can also run a local sync server by running `npx jazz-run sync` and adding the query param `?sync=ws://localhost:4200` to the URL of the example app (for example: `http://localhost:5173/?peer=ws://localhost:4200`), or by setting the `sync` parameter of the `<Jazz.Provider>` provider component in [./src/2_main.tsx](./src/2_main.tsx).
You can also run a local sync server by running `npx jazz-run sync` and adding the query param `?sync=ws://localhost:4200` to the URL of the example app (for example: `http://localhost:5173/?peer=ws://localhost:4200`), or by setting the `sync` parameter of the `<JazzProvider>` provider component in [./src/2_main.tsx](./src/2_main.tsx).

View File

@@ -8,7 +8,13 @@ import {
} from "react-router-dom";
import "./index.css";
import { DemoAuthBasicUI, createJazzReactApp, useDemoAuth } from "jazz-react";
import {
DemoAuthBasicUI,
JazzProvider,
useAcceptInvite,
useAccount,
useDemoAuth,
} from "jazz-react";
import { PetAccount, PetPost } from "./1_schema.ts";
import { NewPetPostForm } from "./3_NewPetPostForm.tsx";
@@ -25,32 +31,34 @@ const peer =
) as `ws://${string}`) ??
"wss://cloud.jazz.tools/?key=pets-example-jazz@garden.co";
/** Walkthrough: The top-level provider `<Jazz.Provider/>`
/** Walkthrough: The top-level provider `<JazzProvider/>`
*
* This shows how to use the top-level provider `<Jazz.Provider/>`,
* This shows how to use the top-level provider `<JazzProvider/>`,
* which provides the rest of the app with a `LocalNode` (used through `useJazz` later),
* based on `LocalAuth` that uses PassKeys (aka WebAuthn) to store a user's account secret
* - no backend needed. */
const appName = "Jazz Rate My Pet Example";
const Jazz = createJazzReactApp({ AccountSchema: PetAccount });
// eslint-disable-next-line react-refresh/only-export-components
export const { useAccount, useCoState, useAcceptInvite } = Jazz;
function JazzAndAuth({ children }: { children: React.ReactNode }) {
const [auth, authState] = useDemoAuth();
return (
<>
<Jazz.Provider auth={auth} peer={peer}>
<JazzProvider auth={auth} peer={peer} AccountSchema={PetAccount}>
{children}
</Jazz.Provider>
</JazzProvider>
<DemoAuthBasicUI appName={appName} state={authState} />
</>
);
}
declare module "jazz-react" {
interface Register {
Account: PetAccount;
}
}
ReactDOM.createRoot(document.getElementById("root")!).render(
<React.StrictMode>
<ThemeProvider>

View File

@@ -4,9 +4,9 @@ import { ChangeEvent, useCallback, useState } from "react";
import { useNavigate } from "react-router";
import { ProgressiveImg } from "jazz-react";
import { useAccount, useCoState } from "jazz-react";
import { CoMap, Group, ID, ImageDefinition, co } from "jazz-tools";
import { PetPost, PetReactions } from "./1_schema";
import { useAccount, useCoState } from "./2_main";
import { Button, Input } from "./basicComponents";
/** Walkthrough: TODO

View File

@@ -3,9 +3,9 @@ import { useParams } from "react-router";
import { PetPost, PetReactions, ReactionTypes } from "./1_schema";
import { ProgressiveImg } from "jazz-react";
import { useCoState } from "jazz-react";
import { ID } from "jazz-tools";
import uniqolor from "uniqolor";
import { useCoState } from "./2_main";
import { Button, Skeleton } from "./basicComponents";
import { ShareButton } from "./components/ShareButton";

View File

@@ -34,4 +34,4 @@ If you have feedback, let us know on [Discord](https://discord.gg/utDMjHYg42) or
By default, the example app uses [Jazz Cloud](https://jazz.tools/cloud) (`wss://cloud.jazz.tools`) - so cross-device use, invites and collaboration should just work.
You can also run a local sync server by running `npx jazz-run sync` and adding the query param `?sync=ws://localhost:4200` to the URL of the example app (for example: `http://localhost:5173/?peer=ws://localhost:4200`), or by setting the `sync` parameter of the `<Jazz.Provider>` provider component in [./src/main.tsx](./src/main.tsx).
You can also run a local sync server by running `npx jazz-run sync` and adding the query param `?sync=ws://localhost:4200` to the URL of the example app (for example: `http://localhost:5173/?peer=ws://localhost:4200`), or by setting the `sync` parameter of the `<JazzProvider>` provider component in [./src/main.tsx](./src/main.tsx).

View File

@@ -1,7 +1,7 @@
import { useIframeHashRouter } from "hash-slash";
import { useAccount } from "jazz-react";
import { Group, ID } from "jazz-tools";
import { ReactionsScreen } from "./ReactionsScreen.tsx";
import { useAccount } from "./main";
import { Reactions } from "./schema.ts";
function App() {

View File

@@ -1,5 +1,5 @@
import { useCoState } from "jazz-react";
import { ID } from "jazz-tools";
import { useCoState } from "./main.tsx";
import { ReactionType, ReactionTypes, Reactions } from "./schema.ts";
const reactionEmojiMap: {

View File

@@ -1,24 +1,20 @@
import { DemoAuthBasicUI, createJazzReactApp, useDemoAuth } from "jazz-react";
import { DemoAuthBasicUI, JazzProvider, useDemoAuth } from "jazz-react";
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import App from "./App.tsx";
import "./index.css";
const Jazz = createJazzReactApp();
export const { useAccount, useCoState } = Jazz;
function JazzAndAuth({ children }: { children: React.ReactNode }) {
const [auth, authState] = useDemoAuth();
return (
<>
<Jazz.Provider
<JazzProvider
auth={auth}
peer="wss://cloud.jazz.tools/?key=reactions-example@garden.co"
>
{children}
</Jazz.Provider>
</JazzProvider>
{authState.state !== "signedIn" && (
<DemoAuthBasicUI appName="Reactions" state={authState} />

View File

@@ -1,5 +0,0 @@
{
"name": "richtext",
"version": "0.0.0",
"private": true
}

View File

@@ -63,7 +63,7 @@ main {
</style>
<script setup lang="ts">
import { useAccount } from "./main";
import { useAccount } from "jazz-vue";
const { me, logOut } = useAccount();
</script>

View File

@@ -1,13 +1,15 @@
import { DemoAuthBasicUI, createJazzVueApp, useDemoAuth } from "jazz-vue";
import { DemoAuthBasicUI, JazzProvider, 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";
const Jazz = createJazzVueApp<ToDoAccount>({ AccountSchema: ToDoAccount });
export const { useAccount, useCoState } = Jazz;
const { JazzProvider } = Jazz;
declare module "jazz-vue" {
interface Register {
Account: ToDoAccount;
}
}
const RootComponent = defineComponent({
name: "RootComponent",
@@ -18,6 +20,7 @@ const RootComponent = defineComponent({
h(
JazzProvider,
{
AccountSchema: ToDoAccount,
auth: authMethod.value,
peer: "wss://cloud.jazz.tools/?key=vue-todo-example-jazz@garden.co",
},

View File

@@ -64,9 +64,9 @@
<script setup lang="ts">
import { Group, type ID } from "jazz-tools";
import { useAccount, useCoState } from "jazz-vue";
import { ref, toRaw, watch } from "vue";
import { computed } from "vue";
import { useAccount, useCoState } from "../main";
import { Folder, FolderList, ToDoItem, ToDoList } from "../schema";
const { me } = useAccount();

View File

@@ -61,4 +61,4 @@ If you have feedback, let us know on [Discord](https://discord.gg/utDMjHYg42) or
By default, the example app uses [Jazz Cloud](https://jazz.tools/cloud) (`wss://cloud.jazz.tools`) - so cross-device use, invites and collaboration should just work.
You can also run a local sync server by running `npx jazz-run sync` and adding the query param `?sync=ws://localhost:4200` to the URL of the example app (for example: `http://localhost:5173/?peer=ws://localhost:4200`), or by setting the `sync` parameter of the `<Jazz.Provider>` provider component in [./src/2_main.tsx](./src/2_main.tsx).
You can also run a local sync server by running `npx jazz-run sync` and adding the query param `?sync=ws://localhost:4200` to the URL of the example app (for example: `http://localhost:5173/?peer=ws://localhost:4200`), or by setting the `sync` parameter of the `<JazzProvider>` provider component in [./src/2_main.tsx](./src/2_main.tsx).

View File

@@ -7,8 +7,10 @@ import {
import "./index.css";
import {
JazzProvider,
PasskeyAuthBasicUI,
createJazzReactApp,
useAcceptInvite,
useAccount,
usePasskeyAuth,
} from "jazz-react";
@@ -23,40 +25,41 @@ import {
} from "./basicComponents/index.ts";
/**
* Walkthrough: The top-level provider `<Jazz.Provider/>`
* Walkthrough: The top-level provider `<JazzProvider/>`
*
* This shows how to use the top-level provider `<Jazz.Provider/>`,
* This shows how to use the top-level provider `<JazzProvider/>`,
* which provides the rest of the app with a controlled account (used through `useAccount` later).
* Here we use `PasskeyAuth`, which uses Passkeys (aka WebAuthn) to store a user's account secret
* - no backend needed.
*
* `<Jazz.Provider/>` also runs our account migration
* `<JazzProvider/>` also runs our account migration
*/
const appName = "Jazz Todo List Example";
const Jazz = createJazzReactApp<TodoAccount>({
AccountSchema: TodoAccount,
});
// eslint-disable-next-line react-refresh/only-export-components
export const { useAccount, useCoState, useAcceptInvite } = Jazz;
function JazzAndAuth({ children }: { children: React.ReactNode }) {
const [passkeyAuth, passKeyState] = usePasskeyAuth({ appName });
return (
<>
<Jazz.Provider
<JazzProvider
AccountSchema={TodoAccount}
auth={passkeyAuth}
peer="wss://cloud.jazz.tools/?key=todo-example-jazz@garden.co"
>
{children}
</Jazz.Provider>
</JazzProvider>
<PasskeyAuthBasicUI state={passKeyState} />
</>
);
}
declare module "jazz-react" {
interface Register {
Account: TodoAccount;
}
}
ReactDOM.createRoot(document.getElementById("root")!).render(
<React.StrictMode>
<ThemeProvider>
@@ -79,7 +82,7 @@ ReactDOM.createRoot(document.getElementById("root")!).render(
* - which can also contain invite links.
*/
export default function App() {
// logOut logs out the AuthProvider passed to `<Jazz.Provider/>` above.
// logOut logs out the AuthProvider passed to `<JazzProvider/>` above.
const { logOut } = useAccount();
const router = createHashRouter([

View File

@@ -4,9 +4,9 @@ import { ListOfTasks, TodoProject } from "./1_schema";
import { SubmittableInput } from "./basicComponents";
import { useAccount } from "jazz-react";
import { Group } from "jazz-tools";
import { useNavigate } from "react-router";
import { useAccount } from "./2_main";
export function NewProjectForm() {
// `me` represents the current user account, which will determine

View File

@@ -14,10 +14,10 @@ import {
TableRow,
} from "./basicComponents";
import { useCoState } from "jazz-react";
import { ID } from "jazz-tools";
import { useParams } from "react-router";
import uniqolor from "uniqolor";
import { useCoState } from "./2_main";
import { InviteButton } from "./components/InviteButton";
/** Walkthrough: Reactively rendering a todo project as a table,

View File

@@ -1,8 +1,8 @@
import { useAccount, useCoState } from "jazz-react";
import { Group, ID } from "jazz-tools";
import { useState } from "react";
import { IssueComponent } from "./Issue.tsx";
import { IssueVersionHistory } from "./IssueVersionHistory.tsx";
import { useAccount, useCoState } from "./main";
import { Issue } from "./schema";
function App() {
const { me, logOut } = useAccount();

View File

@@ -1,6 +1,6 @@
import { useCoState } from "jazz-react";
import { ID } from "jazz-tools";
import { useEffect, useMemo, useState } from "react";
import { useCoState } from "./main.tsx";
import { Issue } from "./schema.ts";
function DescriptionVersionHistory({ id }: { id: ID<Issue> }) {

View File

@@ -1,7 +1,7 @@
import { createInviteLink } from "jazz-react";
import { useCoState } from "jazz-react";
import { ID } from "jazz-tools";
import { IssueComponent } from "./Issue.tsx";
import { useCoState } from "./main.tsx";
import { Issue, Project } from "./schema.ts";
export function ProjectComponent({ projectID }: { projectID: ID<Project> }) {
const project = useCoState(Project, projectID, { issues: [{}] });

View File

@@ -1,24 +1,20 @@
import { DemoAuthBasicUI, createJazzReactApp, useDemoAuth } from "jazz-react";
import { DemoAuthBasicUI, JazzProvider, useDemoAuth } from "jazz-react";
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import App from "./App.tsx";
import "./index.css";
const Jazz = createJazzReactApp();
export const { useAccount, useCoState } = Jazz;
function JazzAndAuth({ children }: { children: React.ReactNode }) {
const [auth, authState] = useDemoAuth();
return (
<>
<Jazz.Provider
<JazzProvider
auth={auth}
peer="wss://cloud.jazz.tools/?key=version-history@garden.co"
>
{children}
</Jazz.Provider>
</JazzProvider>
{authState.state !== "signedIn" && (
<DemoAuthBasicUI appName="React + Demo Auth" state={authState} />

View File

@@ -56,6 +56,7 @@ const config = {
fontFamily: {
display: ["var(--font-manrope)"],
mono: ["var(--font-commit-mono)"],
sans: ["var(--font-inter)"],
},
fontSize: {
"2xs": ["0.75rem", { lineHeight: "1.25rem" }],

View File

@@ -5,5 +5,9 @@ export default function DocsLayout({
}: {
children: React.ReactNode;
}) {
return <Prose className="overflow-x-hidden lg:flex-1 py-8">{children}</Prose>;
return (
<Prose className="max-w-3xl mx-auto overflow-x-hidden lg:flex-1 py-8">
{children}
</Prose>
);
}

View File

@@ -92,7 +92,7 @@ function JazzAndAuth({ children }: { children: React.ReactNode }) {
return (
<>
{clerk.user && auth ? (
<Jazz.Provider auth={auth}></Jazz.Provider>
<JazzProvider auth={auth}></JazzProvider>
) : (
<SignInButton />
)}

View File

@@ -247,9 +247,32 @@ Let's not forget to update the `AccountSchema`.
<CodeGroup>
```ts
const Jazz = createJazzReactApp({ // old
AccountSchema: JazzAccount,
}); // old
import { JazzProvider } from "jazz-react"; // old
import { JazzAccount } from "./schema";
function JazzAndAuth({ children }: { children: React.ReactNode }) { // old
const [passkeyAuth, passKeyState] = usePasskeyAuth({ appName }); // old
return ( // old
<> // old
<JazzProvider // old
auth={passkeyAuth} // old
peer="wss://cloud.jazz.tools/?key=you@example.com" // old
AccountSchema={JazzAccount}
>// old
{children} // old
</JazzProvider> // old
<PasskeyAuthBasicUI state={passKeyState} /> // old
</> // old
); // old
} // old
// Register the Account schema so `useAccount` returns our custom `JazzAccount`
declare module "jazz-react" {
interface Register {
Account: JazzAccount;
}
}
```
</CodeGroup>

View File

@@ -82,43 +82,3 @@ useAcceptInvite({
});
```
</CodeGroup>
`useAcceptInvite` is exported from your Jazz app.
<ContentByFramework framework="react">
<CodeGroup>
```ts
const Jazz = createJazzReactApp();
export const { useAcceptInvite } = Jazz;
```
</CodeGroup>
</ContentByFramework>
<ContentByFramework framework="react-native">
<CodeGroup>
```ts
const Jazz = createJazzReactNativeApp();
export const { useAcceptInvite } = Jazz;
```
</CodeGroup>
</ContentByFramework>
<ContentByFramework framework="vue">
<CodeGroup>
```ts
const Jazz = createJazzVueApp();
export const { useAcceptInvite } = Jazz;
```
</CodeGroup>
</ContentByFramework>
<ContentByFramework framework="svelte">
<CodeGroup>
```ts
const Jazz = createJazzApp();
export const { useAcceptInvite } = Jazz;
```
</CodeGroup>
</ContentByFramework>
...more docs coming soon

View File

@@ -51,26 +51,24 @@ Collaborative Values (CoValues), build a UI and subscribe to changes, set permis
import App from "./App.tsx"; // old
import "./index.css"; // old
import {
createJazzReactApp,
JazzProvider,
useDemoAuth,
DemoAuthBasicUI,
} from "jazz-react";
// old
const Jazz = createJazzReactApp();
export const { useAccount, useCoState } = Jazz;
function JazzAndAuth({ children }: { children: React.ReactNode }) {
const [auth, authState] = useDemoAuth();
return (
<>
<Jazz.Provider
<JazzProvider
auth={auth}
// replace `you@example.com` with your email as a temporary API key
peer="wss://cloud.jazz.tools/?key=you@example.com"
>
{children}
</Jazz.Provider>
</JazzProvider>
<DemoAuthBasicUI appName="Circular" state={authState} />
</>
);
@@ -87,7 +85,7 @@ Collaborative Values (CoValues), build a UI and subscribe to changes, set permis
```
</CodeGroup>
This sets Jazz up, extracts app-specific hooks for later, and wraps our app in the provider.
This sets Jazz up and wraps our app in the provider.
{/* TODO: explain Auth */}
@@ -188,7 +186,7 @@ Now, finally, let's implement creating an issue:
import { useState } from "react"; // old
import { Issue } from "./schema"; // old
import { IssueComponent } from "./components/Issue.tsx"; // old
import { useAccount } from "./main";
import { useAccount } from "jazz-react";
// old
function App() {// old
const { me } = useAccount();
@@ -262,7 +260,7 @@ Let's modify `src/App.tsx`:
import { useState } from "react"; // old
import { Issue } from "./schema"; // old
import { IssueComponent } from "./components/Issue.tsx"; // old
import { useAccount, useCoState } from "./main";
import { useAccount, useCoState } from "jazz-react";
import { ID } from "jazz-tools"
// old
function App() { // old
@@ -411,7 +409,7 @@ So let's store the ID in the browser's URL and make sure our useState is in sync
import { useState } from "react"; // old
import { Issue } from "./schema"; // old
import { IssueComponent } from "./components/Issue.tsx"; // old
import { useAccount, useCoState } from "./main"; // old
import { useAccount, useCoState } from "jazz-react"; // old
import { ID } from "jazz-tools" // old
// old
function App() { // old
@@ -472,7 +470,7 @@ All we have to do is create a new group to own each new issue and add "everyone"
import { useState } from "react"; // old
import { Issue } from "./schema"; // old
import { IssueComponent } from "./components/Issue.tsx"; // old
import { useAccount, useCoState } from "./main"; // old
import { useAccount, useCoState } from "jazz-react"; // old
import { ID, Group } from "jazz-tools"
// old
function App() { // old
@@ -566,7 +564,7 @@ First, we'll change `App.tsx` to create and render `Project`s instead of `Issue`
import { useState } from "react"; // old
import { Project, ListOfIssues } from "./schema";
import { ProjectComponent } from "./components/Project.tsx";
import { useAccount } from "./main";
import { useAccount } from "jazz-react";
import { ID, Group } from "jazz-tools"
// old
function App() { // old
@@ -613,7 +611,7 @@ Create a new file `src/components/Project.tsx` and add the following:
import { ID } from "jazz-tools";
import { Project, Issue } from "../schema";
import { IssueComponent } from "./Issue.tsx";
import { useCoState } from "../main";
import { useCoState } from "jazz-react";
export function ProjectComponent({ projectID }: { projectID: ID<Project> }) {
const project = useCoState(Project, projectID);
@@ -664,7 +662,7 @@ But you can also take more precise control over loading by defining a minimum-de
import { ID } from "jazz-tools";// old
import { Project, Issue } from "../schema"; // old
import { IssueComponent } from "./Issue.tsx"; // old
import { useCoState } from "../main"; // old
import { useCoState } from "jazz-react"; // old
// old
export function ProjectComponent({ projectID }: { projectID: ID<Project> }) {// old
const project = useCoState(Project, projectID, { issues: [{}] });
@@ -733,7 +731,7 @@ Turns out, we're already mostly there! First, let's remove making the Project pu
import { useState } from "react"; // old
import { Project, ListOfIssues } from "./schema"; // old
import { ProjectComponent } from "./components/Project.tsx"; // old
import { useAccount } from "./main"; // old
import { useAccount } from "jazz-react"; // old
import { ID, Group } from "jazz-tools" // old
// old
function App() { // old
@@ -776,7 +774,7 @@ Now, inside ProjectComponent, let's add a button to invite guests (read-only) or
import { ID } from "jazz-tools"; // old
import { Project, Issue } from "../schema"; // old
import { IssueComponent } from "./Issue.tsx"; // old
import { useCoState } from "../main"; // old
import { useCoState } from "jazz-react"; // old
import { createInviteLink } from "jazz-react";
// old

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