Compare commits

...

25 Commits

Author SHA1 Message Date
Guido D'Orsi
d4d6cb3307 Merge pull request #2354 from garden-co/changeset-release/main
Version Packages
2025-05-23 20:01:42 +02:00
github-actions[bot]
9565cdf323 Version Packages 2025-05-23 18:01:27 +00:00
Guido D'Orsi
dfb21ff0f2 fix: add missing deps for sqlite and secure storage 2025-05-23 19:59:08 +02:00
Guido D'Orsi
98d697fafb fix: remove react and react-native dev dependencies 2025-05-23 19:50:54 +02:00
Guido D'Orsi
9150d53f90 Merge pull request #2353 from garden-co/changeset-release/main
Version Packages
2025-05-23 19:46:39 +02:00
github-actions[bot]
ac7ecc278c Version Packages 2025-05-23 17:46:11 +00:00
Guido D'Orsi
99595bc7e3 fix: remove React Native specific steps only for chat-rn-expo 2025-05-23 19:42:45 +02:00
Guido D'Orsi
f5bae09679 fix: remove React Native specific steps as not required anymore 2025-05-23 19:40:51 +02:00
Guido D'Orsi
a7b9ae0b76 Merge pull request #2350 from garden-co/changeset-release/main
Version Packages
2025-05-23 19:24:34 +02:00
github-actions[bot]
196efcf48e Version Packages 2025-05-23 17:23:15 +00:00
Guido D'Orsi
153aa972b3 Merge pull request #2351 from garden-co/fix/chat-rn-expo
fix: fix chat-rn-expo example app
2025-05-23 19:20:25 +02:00
Guido D'Orsi
4508524f77 feat: rename demo to minimal, change React Native template to minimal auth 2025-05-23 19:20:05 +02:00
Guido D'Orsi
e7e9062dff test: disable the chat navigation step on RN expo 2025-05-23 18:44:03 +02:00
Guido D'Orsi
65e8d135c1 fix: React 19 upgrade type fixes 2025-05-23 18:36:54 +02:00
Meg Culotta
0b8e84e22d Merge pull request #2352 from garden-co/feat/2345-add-example-links-to-readmes
Add URL's to live demos in all readme files in examples
2025-05-23 11:15:46 -05:00
Margaret Culotta
7b51e38cf6 Add all other examples 2025-05-23 11:11:57 -05:00
Margaret Culotta
fcc2cbdc93 Add URL's to live demos in all readme files in examples 2025-05-23 11:09:00 -05:00
Guido D'Orsi
5aa13b5afc feat: upgrade to React 19 2025-05-23 17:53:49 +02:00
Guido D'Orsi
dc746a2fc9 chore: changeset 2025-05-23 17:36:38 +02:00
Guido D'Orsi
ca39bae001 fix: fix chat-rn-expo when used as template 2025-05-23 17:35:49 +02:00
Guido D'Orsi
020b12fa32 fix: correct definition of react in peerDependencies 2025-05-23 17:33:26 +02:00
Guido D'Orsi
bfea02c229 Merge pull request #2348 from garden-co/feat/deprecate-with-helpers
fix: deprecate withHelpers
2025-05-23 14:45:01 +02:00
Guido D'Orsi
74e6495beb Merge pull request #2349 from garden-co/feat/default-catch
feat: add shallow support for default/catch
2025-05-23 14:40:01 +02:00
Guido D'Orsi
3fe683206a feat: add shallow support for default/catch 2025-05-23 14:37:15 +02:00
Guido D'Orsi
f869d9a4dd fix: deprecate withHelpers 2025-05-23 14:30:52 +02:00
167 changed files with 2813 additions and 3376 deletions

View File

@@ -1,5 +1,19 @@
# betterauth
## 0.1.14
### Patch Changes
- Updated dependencies [dc746a2]
- Updated dependencies [f869d9a]
- Updated dependencies [3fe6832]
- jazz-react-auth-betterauth@0.14.10
- jazz-inspector@0.14.10
- jazz-react@0.14.10
- jazz-tools@0.14.10
- jazz-betterauth-server-plugin@0.14.10
- jazz-betterauth-client-plugin@0.14.10
## 0.1.13
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "betterauth",
"version": "0.1.13",
"version": "0.1.14",
"private": true,
"type": "module",
"scripts": {

View File

@@ -1,5 +1,23 @@
# chat-rn-expo-clerk
## 1.0.134
### Patch Changes
- Updated dependencies [98d697f]
- jazz-expo@0.14.11
## 1.0.133
### Patch Changes
- Updated dependencies [dc746a2]
- Updated dependencies [f869d9a]
- Updated dependencies [3fe6832]
- jazz-react-native-media-images@0.14.10
- jazz-tools@0.14.10
- jazz-expo@0.14.10
## 1.0.132
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "chat-rn-expo-clerk",
"main": "index.js",
"version": "1.0.132",
"version": "1.0.134",
"scripts": {
"build": "expo export -p ios",
"start": "expo start",

View File

@@ -7,8 +7,10 @@ node_modules/
.expo/
dist/
web-build/
expo-env.d.ts
# Native
.kotlin/
*.orig.*
*.jks
*.p8
@@ -33,6 +35,5 @@ yarn-error.*
# typescript
*.tsbuildinfo
ios
android
android/
ios/

File diff suppressed because it is too large Load Diff

View File

@@ -1,24 +0,0 @@
# 🎷 Jazz + Expo + `react-navigation` + Demo Auth
## 🚀 How to Run
### 1. Inside the Workspace Root
First, install dependencies and build the project:
```bash
pnpm i
pnpm run build
```
### 2. Inside the `examples/chat-rn-expo` Directory
Next, navigate to the specific example project and run the following commands:
```bash
pnpm expo prebuild
pnpx pod-install
pnpm expo run:ios
```
This will set up and launch the app on iOS. For Android, you can replace the last command with `pnpm expo run:android`.

View File

@@ -1,55 +0,0 @@
const { withBuildProperties } = require("expo-build-properties");
const { withDangerousMod } = require("@expo/config-plugins");
const fs = require("fs/promises");
const path = require("path");
/**
* https://github.com/mrousavy/nitro/issues/422#issuecomment-2545988256
*/
function withCustomIosMod(config) {
// Use expo-build-properties to bump iOS deployment target
config = withBuildProperties(config, { ios: { deploymentTarget: "16.0" } });
// Patch the generated Podfile fallback to ensure platform is always 16.0
config = withDangerousMod(config, [
"ios",
async (modConfig) => {
const podfilePath = path.join(
modConfig.modRequest.platformProjectRoot,
"Podfile",
);
let contents = await fs.readFile(podfilePath, "utf-8");
// Check if the IPHONEOS_DEPLOYMENT_TARGET setting is already present
// We search for the key being assigned, e.g., config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] =
const deploymentTargetSettingExists =
/\.build_settings\s*\[\s*['"]IPHONEOS_DEPLOYMENT_TARGET['"]\s*\]\s*=/.test(
contents,
);
if (!deploymentTargetSettingExists) {
// IPHONEOS_DEPLOYMENT_TARGET setting not found, proceed to add it.
contents = contents.replace(
/(post_install\s+do\s+\|installer\|[\s\S]*?)(\r?\n\s end\s*)$/m,
`$1
# Expo Build Properties: force deployment target
# https://github.com/mrousavy/nitro/issues/422#issuecomment-2545988256
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '16.0'
end
end
$2`,
);
}
await fs.writeFile(podfilePath, contents);
return modConfig;
},
]);
return config;
}
module.exports = ({ config }) => {
return withCustomIosMod(config);
};

View File

@@ -1,39 +1,32 @@
{
"expo": {
"name": "jazz-chat-rn-expo",
"scheme": "jazz-chat-rn-expo",
"slug": "jazz-chat-rn-expo",
"name": "chat-rn-expo",
"slug": "chat-rn-expo",
"version": "1.0.0",
"orientation": "portrait",
"icon": "./assets/icon.png",
"userInterfaceStyle": "light",
"newArchEnabled": true,
"splash": {
"image": "./assets/splash.png",
"image": "./assets/splash-icon.png",
"resizeMode": "contain",
"backgroundColor": "#ffffff"
},
"ios": {
"supportsTablet": true,
"bundleIdentifier": "com.jazz.chatrn"
"bundleIdentifier": "com.anonymous.chatrnexpo"
},
"android": {
"adaptiveIcon": {
"foregroundImage": "./assets/adaptive-icon.png",
"backgroundColor": "#ffffff"
},
"package": "com.jazz.chatrn"
"edgeToEdgeEnabled": true,
"package": "com.anonymous.chatrnexpo"
},
"plugins": [
"expo-secure-store",
"expo-sqlite",
"expo-build-properties",
"expo-web-browser"
],
"extra": {
"eas": {
"projectId": "e0e61872-1906-4c84-b9d8-9be77355cad0"
}
"web": {
"favicon": "./assets/favicon.png"
},
"owner": "paxx"
"plugins": ["expo-secure-store", "expo-sqlite"]
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

View File

@@ -1,9 +0,0 @@
module.exports = function (api) {
api.cache(true);
return {
presets: [
["babel-preset-expo", { jsxImportSource: "nativewind" }],
"nativewind/babel",
],
};
};

View File

@@ -1,27 +0,0 @@
{
"cli": {
"version": ">= 12.5.1",
"appVersionSource": "remote"
},
"build": {
"development": {
"developmentClient": true,
"distribution": "internal"
},
"ios-simulator": {
"extends": "development",
"ios": {
"simulator": true
}
},
"preview": {
"distribution": "internal"
},
"production": {
"autoIncrement": true
}
},
"submit": {
"production": {}
}
}

View File

@@ -1,3 +0,0 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

View File

@@ -1,4 +0,0 @@
import "./polyfills";
import { registerRootComponent } from "expo";
import App from "./src/App";
registerRootComponent(App);

View File

@@ -0,0 +1,9 @@
import { registerRootComponent } from "expo";
import "./polyfills";
import App from "./src/App";
// registerRootComponent calls AppRegistry.registerComponent('main', () => App);
// It also ensures that whether you load the app in Expo Go or in a native build,
// the environment is set up appropriately
registerRootComponent(App);

View File

@@ -1,35 +0,0 @@
// Learn more https://docs.expo.dev/guides/monorepos
const { getDefaultConfig } = require("expo/metro-config");
const { withNativeWind } = require("nativewind/metro");
const { FileStore } = require("metro-cache");
const path = require("path");
// eslint-disable-next-line no-undef
const projectRoot = __dirname;
const workspaceRoot = path.resolve(projectRoot, "../..");
const config = getDefaultConfig(projectRoot, { isCSSEnabled: true });
// Since we are using pnpm, we have to setup the monorepo manually for Metro
// #1 - Watch all files in the monorepo
config.watchFolders = [workspaceRoot];
// #2 - Try resolving with project modules first, then workspace modules
config.resolver.nodeModulesPaths = [
path.resolve(projectRoot, "node_modules"),
path.resolve(workspaceRoot, "node_modules"),
];
config.resolver.sourceExts = ["mjs", "js", "json", "ts", "tsx"];
config.resolver.requireCycleIgnorePatterns = [
/(^|\/|\\)node_modules($|\/|\\)/,
/(^|\/|\\)packages($|\/|\\)/,
];
// Use turborepo to restore the cache when possible
config.cacheStores = [
new FileStore({
root: path.join(projectRoot, "node_modules", ".cache", "metro"),
}),
];
// module.exports = config;
module.exports = withNativeWind(config, { input: "./global.css" });

View File

@@ -1 +0,0 @@
/// <reference types="nativewind/types" />

View File

@@ -1,53 +1,35 @@
{
"name": "chat-rn-expo",
"version": "1.0.119",
"main": "index.js",
"version": "1.0.2",
"main": "index.ts",
"scripts": {
"build": "tsc --noEmit && expo export -p ios",
"build": "expo prebuild",
"start": "expo start",
"format-and-lint": "biome check .",
"format-and-lint:fix": "biome check . --write",
"android": "expo run:android",
"ios": "expo prebuild && pnpx pod-install && expo run:ios",
"ios": "expo run:ios",
"web": "expo start --web"
},
"dependencies": {
"@azure/core-asynciterator-polyfill": "^1.0.2",
"@bacons/text-decoder": "0.0.0",
"@craftzdog/react-native-buffer": "6.0.5",
"@bacons/text-decoder": "^0.0.0",
"@craftzdog/react-native-buffer": "^6.0.5",
"@react-native-community/netinfo": "11.4.1",
"@react-navigation/native": "7.0.19",
"@react-navigation/native-stack": "7.2.1",
"clsx": "^2.0.0",
"expo": "53.0.8",
"expo-build-properties": "~0.14.6",
"expo-clipboard": "~7.1.4",
"expo-constants": "~17.1.6",
"expo-dev-client": "~5.1.8",
"expo-linking": "~7.1.4",
"expo": "~53.0.9",
"expo-clipboard": "^7.1.4",
"expo-secure-store": "~14.2.3",
"expo-sqlite": "15.2.9",
"expo-sqlite": "~15.2.10",
"expo-status-bar": "~2.2.3",
"expo-web-browser": "~14.1.6",
"jazz-expo": "workspace:*",
"jazz-tools": "workspace:*",
"nativewind": "^4.1.21",
"react": "19.0.0",
"react-dom": "19.0.0",
"react-native": "0.79.2",
"react-native-get-random-values": "^1.11.0",
"react-native-safe-area-context": "5.4.0",
"react-native-screens": "4.10.0",
"react-native-nitro-modules": "0.25.2",
"react-native-quick-crypto": "1.0.0-beta.15",
"react-native-url-polyfill": "^2.0.0",
"readable-stream": "4.7.0"
"readable-stream": "^4.7.0"
},
"devDependencies": {
"@babel/core": "^7.25.2",
"@types/react": "~19.0.14",
"tailwindcss": "^3.4.17",
"typescript": "5.8.3"
"@types/react": "~19.0.10",
"typescript": "~5.8.3"
},
"private": true
}

View File

@@ -1,74 +1,18 @@
import "../global.css";
import {
NavigationContainer,
useNavigationContainerRef,
} from "@react-navigation/native";
import { createNativeStackNavigator } from "@react-navigation/native-stack";
import * as Linking from "expo-linking";
import { RNQuickCrypto } from "jazz-expo/crypto";
import React, { StrictMode, useEffect, useState } from "react";
import HandleInviteScreen from "./invite";
import { JazzProvider } from "jazz-expo";
import React, { StrictMode } from "react";
import { apiKey } from "./apiKey";
import ChatScreen from "./chat";
const Stack = createNativeStackNavigator();
const prefix = Linking.createURL("/");
const linking = {
prefixes: [prefix],
config: {
screens: {
HandleInviteScreen: {
path: "router/invite/:valueHint?/:valueID/:inviteSecret",
},
},
},
};
function App() {
const [initialRoute, setInitialRoute] = useState<
"ChatScreen" | "HandleInviteScreen"
>("ChatScreen");
const navigationRef = useNavigationContainerRef();
useEffect(() => {
Linking.getInitialURL().then((url) => {
if (url) {
if (url && url.includes("invite")) {
setInitialRoute("HandleInviteScreen");
}
}
});
}, []);
export default function App() {
return (
<StrictMode>
<JazzProvider
CryptoProvider={RNQuickCrypto}
sync={{
peer: `wss://cloud.jazz.tools/?key=${apiKey}`,
}}
>
<NavigationContainer linking={linking} ref={navigationRef}>
<Stack.Navigator initialRouteName={initialRoute}>
<Stack.Screen
options={{ title: "Jazz Chat" }}
name="ChatScreen"
// @ts-ignore
component={ChatScreen}
/>
<Stack.Screen
name="HandleInviteScreen"
component={HandleInviteScreen}
/>
</Stack.Navigator>
</NavigationContainer>
<ChatScreen />
</JazzProvider>
</StrictMode>
);
}
export default App;

View File

@@ -1,7 +1,6 @@
import clsx from "clsx";
import * as Clipboard from "expo-clipboard";
import { Group, ID, Loaded, Profile } from "jazz-tools";
import { useEffect, useState } from "react";
import { Account, Group } from "jazz-tools";
import { useState } from "react";
import React, {
Button,
FlatList,
@@ -12,54 +11,38 @@ import React, {
TouchableOpacity,
View,
Alert,
StyleSheet,
} from "react-native";
import { useAccount, useCoState } from "jazz-expo";
import { Chat, Message } from "./schema";
export default function ChatScreen({ navigation }: { navigation: any }) {
const { me, logOut } = useAccount();
export default function ChatScreen() {
const { me, logOut } = useAccount(Account, { resolve: { profile: true } });
const [chatId, setChatId] = useState<string>();
const [chatIdInput, setChatIdInput] = useState<string>();
const loadedChat = useCoState(Chat, chatId, { resolve: { $each: true } });
const [message, setMessage] = useState("");
const profile = useCoState(Profile, me._refs.profile?.id, {});
function handleLogOut() {
setChatId(undefined);
logOut();
}
useEffect(() => {
navigation.setOptions({
headerRight: () => <Button onPress={handleLogOut} title="Logout" />,
headerLeft: () =>
loadedChat ? (
<Button
onPress={() => {
if (loadedChat?.id) {
Clipboard.setStringAsync(
`https://chat.jazz.tools/#/chat/${loadedChat.id}`,
);
Alert.alert("Copied to clipboard", `Chat ID: ${loadedChat.id}`);
}
}}
title="Share"
/>
) : null,
});
}, [navigation, loadedChat]);
const createChat = () => {
const group = Group.create({ owner: me });
const group = Group.create();
group.addMember("everyone", "writer");
const chat = Chat.create([], { owner: group });
const chat = Chat.create([], group);
setChatId(chat.id);
};
const joinChat = () => {
if (chatIdInput) {
setChatId(chatIdInput);
if (chatIdInput.startsWith("https://chat.jazz.tools/#/chat/")) {
setChatId(chatIdInput.split("/").pop());
} else {
setChatId(chatIdInput);
}
} else {
Alert.alert("Error", "Chat ID cannot be empty.");
}
@@ -75,41 +58,28 @@ export default function ChatScreen({ navigation }: { navigation: any }) {
}
};
const renderMessageItem = ({ item }: { item: Loaded<typeof Message> }) => {
const renderMessageItem = ({ item }: { item: Message }) => {
const isMe = item._edits?.text?.by?.isMe;
return (
<View
className={clsx(
`rounded-lg p-1 px-1.5 max-w-[80%] `,
isMe ? `bg-gray-200 self-end text-right` : `bg-gray-300 self-start `,
)}
style={[
styles.messageContainer,
isMe ? styles.myMessage : styles.otherMessage,
]}
>
{!isMe ? (
<Text
className={clsx(
`text-xs text-gray-500`,
isMe ? "text-right" : "text-left",
)}
style={[
styles.messageSender,
{ textAlign: isMe ? "right" : "left" },
]}
>
{item?._edits?.text?.by?.profile?.name}
</Text>
) : null}
<View
className={clsx(
"flex relative items-end justify-between",
isMe ? "flex-row" : "flex-row",
)}
>
<Text className={clsx(`text-black text-md max-w-[85%]`)}>
{item.text}
</Text>
<Text
className={clsx(
"text-[10px] text-gray-500 text-right ml-2",
!isMe ? "mt-2" : "mt-1",
)}
>
<View style={styles.messageContent}>
<Text style={styles.messageText}>{item.text}</Text>
<Text style={[styles.messageTime, { marginTop: !isMe ? 8 : 4 }]}>
{item?._edits?.text?.madeAt?.getHours().toString().padStart(2, "0")}
:
{item?._edits?.text?.madeAt
@@ -123,31 +93,28 @@ export default function ChatScreen({ navigation }: { navigation: any }) {
};
return (
<View className="flex flex-col h-full">
<View style={styles.container}>
{!loadedChat ? (
<View className="flex flex-col h-full items-center justify-center">
<Text className="text-m font-bold mb-6">Username</Text>
<View style={styles.welcomeContainer}>
<Text style={styles.usernameTitle}>Username</Text>
<TextInput
className="rounded h-12 p-2 mb-12 w-40 border border-gray-200 block"
value={profile?.name ?? ""}
style={styles.usernameInput}
value={me?.profile.name ?? ""}
onChangeText={(value) => {
if (profile) {
profile.name = value;
if (me?.profile) {
me.profile.name = value;
}
}}
textAlignVertical="center"
onSubmitEditing={sendMessage}
testID="username-input"
/>
<TouchableOpacity
onPress={createChat}
className="bg-blue-500 p-4 rounded-md"
>
<Text className="text-white font-semibold">Start new chat</Text>
<TouchableOpacity onPress={createChat} style={styles.newChatButton}>
<Text style={styles.newChatButtonText}>Start new chat</Text>
</TouchableOpacity>
<Text className="text-m font-bold mt-6">Join existing chat</Text>
<Text style={styles.joinChatTitle}>Join existing chat</Text>
<TextInput
className="rounded h-12 p-2 m-2 mt-4 w-80 border border-gray-200 block"
style={styles.chatIdInput}
placeholder="Chat ID"
value={chatIdInput ?? ""}
onChangeText={(value) => {
@@ -161,22 +128,38 @@ export default function ChatScreen({ navigation }: { navigation: any }) {
}}
testID="chat-id-input"
/>
<TouchableOpacity
onPress={joinChat}
className="bg-green-500 p-4 rounded-md"
>
<Text className="text-white font-semibold">Join chat</Text>
<TouchableOpacity onPress={joinChat} style={styles.joinChatButton}>
<Text style={styles.newChatButtonText}>Join chat</Text>
</TouchableOpacity>
</View>
) : (
<>
<View style={styles.chatHeader}>
<Button
onPress={() => {
if (loadedChat?.id) {
Clipboard.setStringAsync(
`https://chat.jazz.tools/#/chat/${loadedChat.id}`,
);
Alert.alert(
"Copied to clipboard",
`Chat ID: ${loadedChat.id}`,
);
}
}}
title="Share"
/>
<Text style={{ fontWeight: "bold", fontSize: 18 }}>Jazz chat</Text>
<Button onPress={handleLogOut} title="Logout" />
</View>
<FlatList
contentContainerStyle={{
flexGrow: 1,
gap: 6,
padding: 8,
justifyContent: "flex-end",
}}
className="flex"
style={styles.messageList}
data={loadedChat}
keyExtractor={(item) => item.id}
renderItem={renderMessageItem}
@@ -185,11 +168,11 @@ export default function ChatScreen({ navigation }: { navigation: any }) {
<KeyboardAvoidingView
keyboardVerticalOffset={110}
behavior="padding"
className="p-3 bg-white border-t border-gray-300"
style={styles.inputContainer}
>
<SafeAreaView className="flex flex-row items-center gap-2">
<SafeAreaView style={styles.inputRow}>
<TextInput
className="rounded-full h-8 py-0 px-2 border border-gray-200 block flex-1"
style={styles.messageInput}
value={message}
onChangeText={setMessage}
placeholder="Type a message..."
@@ -199,7 +182,7 @@ export default function ChatScreen({ navigation }: { navigation: any }) {
/>
<TouchableOpacity
onPress={sendMessage}
className="bg-gray-300 text-white rounded-full h-8 w-8 items-center justify-center"
style={styles.sendButton}
testID="send-button"
>
<Text></Text>
@@ -211,3 +194,133 @@ export default function ChatScreen({ navigation }: { navigation: any }) {
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: "column",
height: "100%",
},
chatHeader: {
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center",
padding: 8,
paddingTop: 48,
backgroundColor: "#f0f0f0",
},
welcomeContainer: {
flex: 1,
flexDirection: "column",
height: "100%",
alignItems: "center",
justifyContent: "center",
},
usernameTitle: {
fontSize: 16,
fontWeight: "bold",
marginBottom: 24,
},
usernameInput: {
borderRadius: 4,
height: 48,
padding: 8,
marginBottom: 48,
width: 160,
borderWidth: 1,
borderColor: "#e5e5e5",
},
newChatButton: {
backgroundColor: "#3b82f6",
padding: 16,
borderRadius: 6,
},
newChatButtonText: {
color: "white",
fontWeight: "600",
},
joinChatTitle: {
fontSize: 16,
fontWeight: "bold",
marginTop: 24,
},
chatIdInput: {
borderRadius: 4,
height: 48,
padding: 8,
margin: 8,
marginTop: 16,
width: 320,
borderWidth: 1,
borderColor: "#e5e5e5",
},
joinChatButton: {
backgroundColor: "#22c55e",
padding: 16,
borderRadius: 6,
},
messageList: {
display: "flex",
},
messageContainer: {
borderRadius: 8,
padding: 4,
paddingHorizontal: 6,
maxWidth: "80%",
},
myMessage: {
backgroundColor: "#e5e5e5",
alignSelf: "flex-end",
},
otherMessage: {
backgroundColor: "#d4d4d4",
alignSelf: "flex-start",
},
messageSender: {
fontSize: 12,
color: "#6b7280",
},
messageContent: {
flexDirection: "row",
alignItems: "flex-end",
justifyContent: "space-between",
},
messageText: {
color: "black",
fontSize: 16,
maxWidth: "85%",
},
messageTime: {
fontSize: 10,
color: "#6b7280",
marginLeft: 8,
},
inputContainer: {
padding: 12,
backgroundColor: "white",
borderTopWidth: 1,
borderTopColor: "#d4d4d4",
},
inputRow: {
flexDirection: "row",
alignItems: "center",
gap: 8,
},
messageInput: {
borderRadius: 9999,
height: 32,
paddingVertical: 0,
paddingHorizontal: 8,
borderWidth: 1,
borderColor: "#e5e5e5",
flex: 1,
},
sendButton: {
backgroundColor: "#d4d4d4",
borderRadius: 9999,
height: 32,
width: 32,
alignItems: "center",
justifyContent: "center",
},
});

View File

@@ -1,18 +0,0 @@
import { useAcceptInvite } from "jazz-expo";
import React, { Text } from "react-native";
import { Chat } from "./schema";
export default function HandleInviteScreen({
navigation,
}: {
navigation: any;
}) {
useAcceptInvite({
invitedObjectSchema: Chat,
onAccept: async (chatId) => {
navigation.navigate("ChatScreen", { chatId });
},
});
return <Text>Accepting invite...</Text>;
}

View File

@@ -3,5 +3,7 @@ import { co, z } from "jazz-tools";
export const Message = co.map({
text: z.string(),
});
export type Message = co.loaded<typeof Message>;
export const Chat = co.list(Message);
export type Chat = co.loaded<typeof Chat>;

View File

@@ -1,14 +0,0 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
// NOTE: Update this to include the paths to all of your component files.
content: [
"./app/**/*.{js,jsx,ts,tsx}",
"./components/**/*.{js,jsx,ts,tsx}",
"./src/**/*.{js,jsx,ts,tsx}",
],
presets: [require("nativewind/preset")],
theme: {
extend: {},
},
plugins: [],
};

View File

@@ -8,10 +8,7 @@ appId: com.jazz.chatrn
# - assertVisible: "Reload"
# - tapOn: "Reload"
# login
- assertVisible: "Logout"
- tapOn: "Logout"
- assertVisible: "Anonymous user"
- assertVisible: "Username"
- runFlow:
label: "Erase existing username"
file: erase_text.yml
@@ -43,12 +40,13 @@ appId: com.jazz.chatrn
# logout
- tapOn: "Logout"
- assertVisible: "Username"
- assertVisible: "Anonymous user"
# join chat
- tapOn:
id: "chat-id-input"
- inputText: "co_zFs6KFyhxPw4xtw83tcEMzeHUNv" # Use a static id because maestro doesn't have access to the system clipboard
- tapOn: "Join chat"
- assertVisible: "boorad"
- assertVisible: "bro, low key, it do be like that tho"
# - tapOn:
# id: "chat-id-input"
# - inputText: "co_zFs6KFyhxPw4xtw83tcEMzeHUNv" # Use a static id because maestro doesn't have access to the system clipboard
# - tapOn: "Join chat"
# - assertVisible: "boorad"
# - assertVisible: "bro, low key, it do be like that tho"

View File

@@ -3,14 +3,14 @@
# This script is necessary, because unlike ios, the android emulator action
# accepts a script, runs it as your tests, then terminates.
set -e
# set -e
# build and install the app
echo "Building and installing Android app."
echo "If it fails, its output will be in artifact: android-install.log..."
cd ./android/
./gradlew installRelease >> ~/output/android-install.log 2>&1
cd ..
# # build and install the app
# echo "Building and installing Android app."
# echo "If it fails, its output will be in artifact: android-install.log..."
# cd ./android/
# ./gradlew installRelease >> ~/output/android-install.log 2>&1
# cd ..
# run the e2e tests
export PATH="$PATH":"$HOME/.maestro/bin"

View File

@@ -1,8 +1,6 @@
{
"extends": "expo/tsconfig.base",
"compilerOptions": {
"strict": true,
"moduleResolution": "bundler"
},
"exclude": ["src/tests"]
"strict": true
}
}

View File

@@ -1,5 +1,22 @@
# chat-rn
## 1.0.129
### Patch Changes
- Updated dependencies [98d697f]
- jazz-react-native@0.14.11
## 1.0.128
### Patch Changes
- Updated dependencies [dc746a2]
- Updated dependencies [f869d9a]
- Updated dependencies [3fe6832]
- jazz-react-native@0.14.10
- jazz-tools@0.14.10
## 1.0.127
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "chat-rn",
"version": "1.0.127",
"version": "1.0.129",
"main": "index.js",
"scripts": {
"android": "react-native run-android",
@@ -23,7 +23,7 @@
"cojson-transport-ws": "workspace:*",
"jazz-react-native": "workspace:*",
"jazz-tools": "workspace:*",
"react": "18.3.1",
"react": "19.0.0",
"react-native": "0.79.2",
"react-native-get-random-values": "^1.11.0",
"react-native-mmkv": "^3.2.0",

View File

@@ -1,5 +1,16 @@
# chat-vue
## 0.0.111
### Patch Changes
- Updated dependencies [dc746a2]
- Updated dependencies [f869d9a]
- Updated dependencies [3fe6832]
- jazz-tools@0.14.10
- jazz-browser@0.14.10
- jazz-vue@0.14.10
## 0.0.110
### Patch Changes

View File

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

View File

@@ -1,5 +1,17 @@
# jazz-example-chat
## 0.0.209
### Patch Changes
- Updated dependencies [dc746a2]
- Updated dependencies [f869d9a]
- Updated dependencies [3fe6832]
- jazz-inspector@0.14.10
- hash-slash@0.2.3
- jazz-react@0.14.10
- jazz-tools@0.14.10
## 0.0.208
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "jazz-example-chat",
"private": true,
"version": "0.0.208",
"version": "0.0.209",
"type": "module",
"scripts": {
"dev": "vite",
@@ -19,14 +19,14 @@
"jazz-react": "workspace:*",
"jazz-tools": "workspace:*",
"lucide-react": "^0.274.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react": "19.0.0",
"react-dom": "19.0.0",
"zod": "4.0.0-beta.20250505T012514"
},
"devDependencies": {
"@playwright/test": "^1.50.1",
"@types/react": "^18.3.12",
"@types/react-dom": "^18.3.1",
"@types/react": "19.0.0",
"@types/react-dom": "19.0.0",
"@vitejs/plugin-react-swc": "^3.3.2",
"autoprefixer": "^10.4.20",
"is-ci": "^3.0.1",

View File

@@ -1,5 +1,16 @@
# minimal-auth-clerk
## 0.0.108
### Patch Changes
- Updated dependencies [dc746a2]
- Updated dependencies [f869d9a]
- Updated dependencies [3fe6832]
- jazz-react-auth-clerk@0.14.10
- jazz-react@0.14.10
- jazz-tools@0.14.10
## 0.0.107
### Patch Changes

View File

@@ -2,7 +2,7 @@
This is an example of how to use clerk authentication with Jazz.
Live version: https://clerk-demo.jazz.tools
Live version: [https://clerk-demo.jazz.tools](https://clerk-demo.jazz.tools)
## Getting started

View File

@@ -1,7 +1,7 @@
{
"name": "clerk",
"private": true,
"version": "0.0.107",
"version": "0.0.108",
"type": "module",
"scripts": {
"dev": "vite",
@@ -17,14 +17,14 @@
"jazz-react": "workspace:*",
"jazz-react-auth-clerk": "workspace:*",
"jazz-tools": "workspace:*",
"react": "^18.3.1",
"react-dom": "^18.3.1"
"react": "19.0.0",
"react-dom": "19.0.0"
},
"devDependencies": {
"@playwright/test": "^1.50.1",
"@biomejs/biome": "1.9.4",
"@types/react": "^18.3.12",
"@types/react-dom": "^18.3.1",
"@types/react": "19.0.0",
"@types/react-dom": "19.0.0",
"@vitejs/plugin-react": "^4.3.3",
"globals": "^15.11.0",
"typescript": "5.6.2",

View File

@@ -4,6 +4,7 @@ import { createRoot } from "react-dom/client";
import App from "./App.tsx";
import "./index.css";
import { JazzProviderWithClerk } from "jazz-react-auth-clerk";
import { ReactNode } from "react";
import { apiKey } from "./apiKey";
// Import your publishable key
@@ -13,7 +14,7 @@ if (!PUBLISHABLE_KEY) {
throw new Error("Add your Clerk publishable key to the .env.local file");
}
function JazzProvider({ children }: { children: React.ReactNode }) {
function JazzProvider({ children }: { children: ReactNode }) {
const clerk = useClerk();
return (

View File

@@ -1,5 +1,16 @@
# file-share-svelte
## 0.0.93
### Patch Changes
- Updated dependencies [dc746a2]
- Updated dependencies [f869d9a]
- Updated dependencies [3fe6832]
- jazz-tools@0.14.10
- jazz-inspector-element@0.14.10
- jazz-svelte@0.14.10
## 0.0.92
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "file-share-svelte",
"version": "0.0.92",
"version": "0.0.93",
"private": true,
"type": "module",
"scripts": {

View File

@@ -1,5 +1,16 @@
# jazz-tailwind-demo-auth-starter
## 0.0.48
### Patch Changes
- Updated dependencies [dc746a2]
- Updated dependencies [f869d9a]
- Updated dependencies [3fe6832]
- jazz-inspector@0.14.10
- jazz-react@0.14.10
- jazz-tools@0.14.10
## 0.0.47
### Patch Changes

View File

@@ -2,7 +2,7 @@
This is an example of how to upload and render images with Jazz.
Live version: https://file-upload-demo.jazz.tools
Live version: [https://file-upload-demo.jazz.tools](https://file-upload-demo.jazz.tools)
## Getting started

View File

@@ -1,7 +1,7 @@
{
"name": "filestream",
"private": true,
"version": "0.0.47",
"version": "0.0.48",
"type": "module",
"scripts": {
"dev": "vite",
@@ -14,13 +14,13 @@
"jazz-react": "workspace:*",
"jazz-tools": "workspace:*",
"jazz-inspector": "workspace:*",
"react": "^18.3.1",
"react-dom": "^18.3.1"
"react": "19.0.0",
"react-dom": "19.0.0"
},
"devDependencies": {
"@biomejs/biome": "1.9.4",
"@types/react": "^18.3.12",
"@types/react-dom": "^18.3.1",
"@types/react": "19.0.0",
"@types/react-dom": "19.0.0",
"@vitejs/plugin-react": "^4.3.3",
"autoprefixer": "^10.4.20",
"globals": "^15.11.0",

View File

@@ -1,5 +1,16 @@
# form
## 0.1.49
### Patch Changes
- Updated dependencies [dc746a2]
- Updated dependencies [f869d9a]
- Updated dependencies [3fe6832]
- hash-slash@0.2.3
- jazz-react@0.14.10
- jazz-tools@0.14.10
## 0.1.48
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "form",
"private": true,
"version": "0.1.48",
"version": "0.1.49",
"type": "module",
"scripts": {
"dev": "vite",
@@ -14,15 +14,15 @@
"hash-slash": "workspace:*",
"jazz-react": "workspace:*",
"jazz-tools": "workspace:*",
"react": "^18.3.1",
"react-dom": "^18.3.1"
"react": "19.0.0",
"react-dom": "19.0.0"
},
"devDependencies": {
"@biomejs/biome": "1.9.4",
"@playwright/test": "^1.50.1",
"@tailwindcss/forms": "^0.5.9",
"@types/react": "^18.3.12",
"@types/react-dom": "^18.3.1",
"@types/react": "19.0.0",
"@types/react-dom": "19.0.0",
"@vitejs/plugin-react": "^4.3.3",
"autoprefixer": "^10.4.20",
"globals": "^15.11.0",

View File

@@ -1,5 +1,15 @@
# image-upload
## 0.0.105
### Patch Changes
- Updated dependencies [dc746a2]
- Updated dependencies [f869d9a]
- Updated dependencies [3fe6832]
- jazz-react@0.14.10
- jazz-tools@0.14.10
## 0.0.104
### Patch Changes

View File

@@ -2,7 +2,7 @@
This is an example of how to upload and render images with Jazz.
Live version: https://image-upload-demo.jazz.tools
Live version: [https://image-upload-demo.jazz.tools](https://image-upload-demo.jazz.tools)
## Getting started

View File

@@ -1,7 +1,7 @@
{
"name": "image-upload",
"private": true,
"version": "0.0.104",
"version": "0.0.105",
"type": "module",
"scripts": {
"dev": "vite",
@@ -13,13 +13,13 @@
"dependencies": {
"jazz-react": "workspace:*",
"jazz-tools": "workspace:*",
"react": "^18.3.1",
"react-dom": "^18.3.1"
"react": "19.0.0",
"react-dom": "19.0.0"
},
"devDependencies": {
"@biomejs/biome": "1.9.4",
"@types/react": "^18.3.12",
"@types/react-dom": "^18.3.1",
"@types/react": "19.0.0",
"@types/react-dom": "19.0.0",
"@vitejs/plugin-react": "^4.3.3",
"globals": "^15.11.0",
"typescript": "5.6.2",

View File

@@ -1,5 +1,13 @@
# jazz-example-inspector
## 0.0.158
### Patch Changes
- Updated dependencies [dc746a2]
- jazz-inspector@0.14.10
- hash-slash@0.2.3
## 0.0.157
### Patch Changes

View File

@@ -1,6 +1,6 @@
# Jazz Inspector
Live address: https://inspector.jazz.tools
Live address: [https://inspector.jazz.tools](https://inspector.jazz.tools)
Use this to visually inspect a Jazz account or other CoValue.

View File

@@ -1,7 +1,7 @@
{
"name": "jazz-inspector-app",
"private": true,
"version": "0.0.157",
"version": "0.0.158",
"type": "module",
"scripts": {
"dev": "vite",
@@ -17,15 +17,15 @@
"cojson-transport-ws": "workspace:*",
"hash-slash": "workspace:*",
"lucide-react": "^0.274.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react": "19.0.0",
"react-dom": "19.0.0",
"react-router": "^6.16.0",
"react-router-dom": "^6.16.0",
"react-use": "^17.4.0"
},
"devDependencies": {
"@types/react": "^18.3.12",
"@types/react-dom": "^18.3.1",
"@types/react": "19.0.0",
"@types/react-dom": "19.0.0",
"@vitejs/plugin-react-swc": "^3.3.2",
"autoprefixer": "^10.4.20",
"postcss": "^8.4.27",

View File

@@ -27,15 +27,15 @@
"jazz-react": "workspace:*",
"jazz-tools": "workspace:*",
"lucide-react": "^0.485.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react": "19.0.0",
"react-dom": "19.0.0",
"tailwind-merge": "^3.0.2",
"tailwindcss": "^4.0.17",
"tw-animate-css": "^1.2.5"
},
"devDependencies": {
"@types/react": "^18.3.12",
"@types/react-dom": "^18.3.1",
"@types/react": "19.0.0",
"@types/react-dom": "19.0.0",
"@vitejs/plugin-react": "^4.3.4",
"jazz-run": "workspace:*",
"npm-run-all": "^4.1.5",

View File

@@ -1,5 +1,15 @@
# multi-cursors
## 0.0.101
### Patch Changes
- Updated dependencies [dc746a2]
- Updated dependencies [f869d9a]
- Updated dependencies [3fe6832]
- jazz-react@0.14.10
- jazz-tools@0.14.10
## 0.0.100
### Patch Changes

View File

@@ -1,6 +1,7 @@
# Jazz Multi-Cursors Example
Track user presence on a canvas with multiple cursors and out of bounds indicators.
Live version: [https://multi-cursors-demo.jazz.tools/](https://multi-cursors-demo.jazz.tools/)
## Getting started

View File

@@ -1,7 +1,7 @@
{
"name": "multi-cursors",
"private": true,
"version": "0.0.100",
"version": "0.0.101",
"type": "module",
"scripts": {
"dev": "vite",
@@ -15,14 +15,14 @@
"@react-spring/web": "^9.7.5",
"jazz-react": "workspace:*",
"jazz-tools": "workspace:*",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react": "19.0.0",
"react-dom": "19.0.0",
"zod": "3.25.0-beta.20250518T002810"
},
"devDependencies": {
"@biomejs/biome": "1.9.4",
"@types/react": "^18.3.12",
"@types/react-dom": "^18.3.1",
"@types/react": "19.0.0",
"@types/react-dom": "19.0.0",
"@vitejs/plugin-react": "^4.3.3",
"autoprefixer": "^10.4.20",
"globals": "^15.11.0",

View File

@@ -78,6 +78,7 @@ export function Cursor({
return (
<>
{/* @ts-expect-error - TODO: invalid after the React 19 upgrade */}
<animated.g
transform={to(
[springs.x, springs.y],
@@ -113,6 +114,7 @@ export function Cursor({
isOutOfBounds={isStrictlyOutOfBounds}
/>
{isStrictlyOutOfBounds ? (
// @ts-expect-error - TODO: invalid after the React 19 upgrade
<animated.g
transform={to(
[intersectionSprings.x, intersectionSprings.y],

View File

@@ -52,6 +52,7 @@ export function CursorLabel({
return (
<>
{/* @ts-expect-error - TODO: invalid after the React 19 upgrade */}
<animated.text
ref={textRef}
x={to([labelSprings.x], (x) => x)}

View File

@@ -1,5 +1,16 @@
# multiauth
## 0.0.49
### Patch Changes
- Updated dependencies [dc746a2]
- Updated dependencies [f869d9a]
- Updated dependencies [3fe6832]
- jazz-react-auth-clerk@0.14.10
- jazz-react@0.14.10
- jazz-tools@0.14.10
## 0.0.48
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "multiauth",
"private": true,
"version": "0.0.48",
"version": "0.0.49",
"type": "module",
"scripts": {
"dev": "vite",
@@ -15,13 +15,13 @@
"jazz-react": "workspace:*",
"jazz-react-auth-clerk": "workspace:*",
"jazz-tools": "workspace:*",
"react": "^18.3.1",
"react-dom": "^18.3.1"
"react": "19.0.0",
"react-dom": "19.0.0"
},
"devDependencies": {
"@biomejs/biome": "1.9.4",
"@types/react": "^18.3.12",
"@types/react-dom": "^18.3.1",
"@types/react": "19.0.0",
"@types/react-dom": "19.0.0",
"@vitejs/plugin-react": "^4.3.3",
"globals": "^15.11.0",
"typescript": "5.6.2",

View File

@@ -1,5 +1,16 @@
# jazz-example-musicplayer
## 0.0.130
### Patch Changes
- Updated dependencies [dc746a2]
- Updated dependencies [f869d9a]
- Updated dependencies [3fe6832]
- jazz-inspector@0.14.10
- jazz-react@0.14.10
- jazz-tools@0.14.10
## 0.0.129
### Patch Changes

View File

@@ -1,6 +1,6 @@
# Music player example with Jazz and React
Live version: https://music-demo.jazz.tools
Live version: [https://music-demo.jazz.tools](https://music-demo.jazz.tools)
## Getting started

View File

@@ -1,7 +1,7 @@
{
"name": "jazz-example-music-player",
"private": true,
"version": "0.0.129",
"version": "0.0.130",
"type": "module",
"scripts": {
"dev": "vite",
@@ -25,8 +25,8 @@
"jazz-react": "workspace:*",
"jazz-tools": "workspace:*",
"lucide-react": "^0.274.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react": "19.0.0",
"react-dom": "19.0.0",
"react-router": "^6.16.0",
"react-router-dom": "^6.16.0",
"tailwind-merge": "^1.14.0",
@@ -34,8 +34,8 @@
},
"devDependencies": {
"@playwright/test": "^1.50.1",
"@types/react": "^18.3.12",
"@types/react-dom": "^18.3.1",
"@types/react": "19.0.0",
"@types/react-dom": "19.0.0",
"@vitejs/plugin-react-swc": "^3.3.2",
"autoprefixer": "^10.4.20",
"postcss": "^8.4.27",

View File

@@ -4,7 +4,7 @@ import { useAudioManager } from "./AudioManager";
export function usePlayMedia() {
const audioManager = useAudioManager();
const previousMediaLoad = useRef<Promise<unknown>>();
const previousMediaLoad = useRef<Promise<unknown> | undefined>(undefined);
async function playMedia(file: Blob) {
// Wait for the previous load to finish

View File

@@ -1,5 +1,15 @@
# organization
## 0.0.101
### Patch Changes
- Updated dependencies [dc746a2]
- Updated dependencies [f869d9a]
- Updated dependencies [3fe6832]
- jazz-react@0.14.10
- jazz-tools@0.14.10
## 0.0.100
### Patch Changes

View File

@@ -2,7 +2,7 @@
This is an example of how to share a set of data between users through a CoMap called Organization.
Different apps have different names for this concept, such as "teams" or "workspaces".
Live version: [https://jazz-organization.vercel.app/](https://jazz-organization.vercel.app/)
Refer to the [documentation](https://jazz.tools/docs/react/design-patterns/organization) for more information.
## Getting started

View File

@@ -1,7 +1,7 @@
{
"name": "organization",
"private": true,
"version": "0.0.100",
"version": "0.0.101",
"type": "module",
"scripts": {
"dev": "vite",
@@ -16,8 +16,8 @@
"jazz-react": "workspace:*",
"jazz-tools": "workspace:*",
"lucide-react": "^0.274.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react": "19.0.0",
"react-dom": "19.0.0",
"react-router": "^6.16.0",
"react-router-dom": "^6.16.0"
},
@@ -25,8 +25,8 @@
"@playwright/test": "^1.50.1",
"@biomejs/biome": "1.9.4",
"@tailwindcss/forms": "^0.5.9",
"@types/react": "^18.3.12",
"@types/react-dom": "^18.3.1",
"@types/react": "19.0.0",
"@types/react-dom": "19.0.0",
"@vitejs/plugin-react": "^4.3.3",
"autoprefixer": "^10.4.20",
"globals": "^15.11.0",

View File

@@ -1,5 +1,15 @@
# passkey-svelte
## 0.0.97
### Patch Changes
- Updated dependencies [dc746a2]
- Updated dependencies [f869d9a]
- Updated dependencies [3fe6832]
- jazz-tools@0.14.10
- jazz-svelte@0.14.10
## 0.0.96
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "passkey-svelte",
"version": "0.0.96",
"version": "0.0.97",
"type": "module",
"private": true,
"scripts": {

View File

@@ -1,5 +1,15 @@
# minimal-auth-passkey
## 0.0.106
### Patch Changes
- Updated dependencies [dc746a2]
- Updated dependencies [f869d9a]
- Updated dependencies [3fe6832]
- jazz-react@0.14.10
- jazz-tools@0.14.10
## 0.0.105
### Patch Changes

View File

@@ -2,7 +2,7 @@
This is an example of how to use passkey authentication with Jazz.
Live version: https://passkey-demo.jazz.tools
Live version: [https://passkey-demo.jazz.tools](https://passkey-demo.jazz.tools)
## Getting started

View File

@@ -1,7 +1,7 @@
{
"name": "passkey",
"private": true,
"version": "0.0.105",
"version": "0.0.106",
"type": "module",
"scripts": {
"dev": "vite",
@@ -13,13 +13,13 @@
"dependencies": {
"jazz-react": "workspace:*",
"jazz-tools": "workspace:*",
"react": "^18.3.1",
"react-dom": "^18.3.1"
"react": "19.0.0",
"react-dom": "19.0.0"
},
"devDependencies": {
"@biomejs/biome": "1.9.4",
"@types/react": "^18.3.12",
"@types/react-dom": "^18.3.1",
"@types/react": "19.0.0",
"@types/react-dom": "19.0.0",
"@vitejs/plugin-react": "^4.3.3",
"globals": "^15.11.0",
"typescript": "5.6.2",

View File

@@ -1,5 +1,15 @@
# passphrase
## 0.0.103
### Patch Changes
- Updated dependencies [dc746a2]
- Updated dependencies [f869d9a]
- Updated dependencies [3fe6832]
- jazz-react@0.14.10
- jazz-tools@0.14.10
## 0.0.102
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "passphrase",
"private": true,
"version": "0.0.102",
"version": "0.0.103",
"type": "module",
"scripts": {
"dev": "vite",
@@ -13,13 +13,13 @@
"dependencies": {
"jazz-react": "workspace:*",
"jazz-tools": "workspace:*",
"react": "^18.3.1",
"react-dom": "^18.3.1"
"react": "19.0.0",
"react-dom": "19.0.0"
},
"devDependencies": {
"@biomejs/biome": "1.9.4",
"@types/react": "^18.3.12",
"@types/react-dom": "^18.3.1",
"@types/react": "19.0.0",
"@types/react-dom": "19.0.0",
"@vitejs/plugin-react": "^4.3.3",
"globals": "^15.11.0",
"typescript": "5.6.2",

View File

@@ -1,5 +1,15 @@
# jazz-password-manager
## 0.0.127
### Patch Changes
- Updated dependencies [dc746a2]
- Updated dependencies [f869d9a]
- Updated dependencies [3fe6832]
- jazz-react@0.14.10
- jazz-tools@0.14.10
## 0.0.126
### Patch Changes

View File

@@ -1,6 +1,6 @@
# Password manager example with Jazz and React
Live version: https://passwords-demo.jazz.tools
Live version: [https://passwords-demo.jazz.tools](https://passwords-demo.jazz.tools)
![Password Manager Screenshot](demo.png "Screenshot")

View File

@@ -1,7 +1,7 @@
{
"name": "jazz-password-manager",
"private": true,
"version": "0.0.126",
"version": "0.0.127",
"type": "module",
"scripts": {
"dev": "vite",
@@ -14,14 +14,14 @@
"dependencies": {
"jazz-react": "workspace:*",
"jazz-tools": "workspace:*",
"react": "18.3.1",
"react-dom": "18.3.1",
"react": "19.0.0",
"react-dom": "19.0.0",
"react-hook-form": "^7.41.5",
"react-router-dom": "^6.16.0"
},
"devDependencies": {
"@types/react": "^18.3.12",
"@types/react-dom": "^18.3.1",
"@types/react": "19.0.0",
"@types/react-dom": "19.0.0",
"@vitejs/plugin-react": "^4.3.3",
"@vitejs/plugin-react-swc": "^3.3.2",
"autoprefixer": "^10.4.20",

View File

@@ -5,8 +5,8 @@ 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 { Loaded, co } from "jazz-tools";
import { useAccount } from "jazz-react";
import { Loaded } from "jazz-tools";
import { useNavigate, useParams } from "react-router-dom";
import { Folder, PasswordItem, PasswordManagerAccount } from "./1_schema";
import {
@@ -20,7 +20,19 @@ import { Alert, AlertDescription } from "./components/alert";
import { PasswordItemFormValues } from "./types";
const VaultPage: React.FC = () => {
const { me, logOut } = useAccount(PasswordManagerAccount);
const { me, logOut } = useAccount(PasswordManagerAccount, {
resolve: {
root: {
folders: {
$each: {
items: {
$each: true,
},
},
},
},
},
});
const sharedFolderId = useParams<{ sharedFolderId: string }>().sharedFolderId;
const navigate = useNavigate();
@@ -28,6 +40,8 @@ const VaultPage: React.FC = () => {
useEffect(() => {
if (!sharedFolderId) return;
const me = PasswordManagerAccount.getMe();
addSharedFolder(sharedFolderId, me).then(() => {
navigate("/vault");
});
@@ -36,17 +50,13 @@ const VaultPage: React.FC = () => {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
const items = me.root?.folders?.flatMap(
const items = me?.root.folders.flatMap(
(folder) =>
folder?.items?.filter(
(item): item is Exclude<typeof item, null> => !!item,
) || [],
);
const folders = useCoState(co.list(Folder), me.root?._refs.folders?.id, {
resolve: {
$each: { items: { $each: true } },
},
});
const folders = me?.root.folders;
const [selectedFolder, setSelectedFolder] = useState<
Loaded<typeof Folder> | undefined
@@ -95,6 +105,7 @@ const VaultPage: React.FC = () => {
};
const handleCreateFolder = async () => {
if (!me) return;
if (newFolderName) {
try {
const newFolder = createFolder(newFolderName, me);
@@ -108,18 +119,20 @@ const VaultPage: React.FC = () => {
};
const handleDeleteFolder = async () => {
if (!me) return;
try {
const selectedFolderIndex = me.root?.folders?.findIndex(
const selectedFolderIndex = me.root.folders.findIndex(
(folder) => folder?.id === selectedFolder?.id,
);
if (selectedFolderIndex !== undefined && selectedFolderIndex > -1)
me.root?.folders?.splice(selectedFolderIndex, 1);
me.root.folders.splice(selectedFolderIndex, 1);
} catch (err) {
setError("Failed to create folder. Please try again.");
}
};
const handleLogout = async () => {
if (!me) return;
try {
logOut();
} catch (err) {
@@ -141,14 +154,14 @@ const VaultPage: React.FC = () => {
</Button>
<Button
onClick={() => setEditingItem(item)}
disabled={!me.canWrite(item)}
disabled={!me?.canWrite(item)}
>
Edit
</Button>
<Button
onClick={() => handleDeleteItem(item)}
variant="danger"
disabled={!me.canWrite(item)}
disabled={!me?.canWrite(item)}
>
Delete
</Button>
@@ -209,13 +222,13 @@ const VaultPage: React.FC = () => {
<div className="flex gap-2">
<Button
onClick={() => setIsNewItemModalOpen(true)}
disabled={!selectedFolder || !me.canWrite(selectedFolder)}
disabled={!selectedFolder || !me?.canWrite(selectedFolder)}
>
New Item
</Button>
<Button
onClick={() => setIsInviteModalOpen(true)}
disabled={!selectedFolder || !me.canWrite(selectedFolder)}
disabled={!selectedFolder || !me?.canWrite(selectedFolder)}
>
Share Folder
</Button>

View File

@@ -1,5 +1,15 @@
# jazz-example-pets
## 0.0.225
### Patch Changes
- Updated dependencies [dc746a2]
- Updated dependencies [f869d9a]
- Updated dependencies [3fe6832]
- jazz-react@0.14.10
- jazz-tools@0.14.10
## 0.0.224
### Patch Changes

View File

@@ -1,6 +1,6 @@
# Rate My Pets example with Jazz and React
Live version: https://pets-demo.jazz.tools/
Live version: [https://pets-demo.jazz.tools/](https://pets-demo.jazz.tools/)
## Getting started

View File

@@ -1,7 +1,7 @@
{
"name": "jazz-example-pets",
"private": true,
"version": "0.0.224",
"version": "0.0.225",
"type": "module",
"scripts": {
"dev": "vite",
@@ -23,8 +23,8 @@
"jazz-tools": "workspace:*",
"lucide-react": "^0.274.0",
"qrcode": "^1.5.3",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react": "19.0.0",
"react-dom": "19.0.0",
"react-router": "^6.16.0",
"react-router-dom": "^6.16.0",
"tailwind-merge": "^1.14.0",
@@ -35,8 +35,8 @@
"@playwright/test": "^1.50.1",
"@types/node": "^22.5.1",
"@types/qrcode": "^1.5.1",
"@types/react": "^18.3.12",
"@types/react-dom": "^18.3.1",
"@types/react": "19.0.0",
"@types/react-dom": "19.0.0",
"@vitejs/plugin-react-swc": "^3.3.2",
"autoprefixer": "^10.4.20",
"is-ci": "^3.0.1",

View File

@@ -1,5 +1,16 @@
# reactions
## 0.0.105
### Patch Changes
- Updated dependencies [dc746a2]
- Updated dependencies [f869d9a]
- Updated dependencies [3fe6832]
- hash-slash@0.2.3
- jazz-react@0.14.10
- jazz-tools@0.14.10
## 0.0.104
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "reactions",
"private": true,
"version": "0.0.104",
"version": "0.0.105",
"type": "module",
"scripts": {
"dev": "vite",
@@ -14,13 +14,13 @@
"hash-slash": "workspace:*",
"jazz-react": "workspace:*",
"jazz-tools": "workspace:*",
"react": "^18.3.1",
"react-dom": "^18.3.1"
"react": "19.0.0",
"react-dom": "19.0.0"
},
"devDependencies": {
"@biomejs/biome": "1.9.4",
"@types/react": "^18.3.12",
"@types/react-dom": "^18.3.1",
"@types/react": "19.0.0",
"@types/react-dom": "19.0.0",
"@vitejs/plugin-react": "^4.3.3",
"globals": "^15.11.0",
"typescript": "5.6.2",

View File

@@ -1,5 +1,16 @@
# richtext-tiptap
## 0.1.18
### Patch Changes
- Updated dependencies [dc746a2]
- Updated dependencies [f869d9a]
- Updated dependencies [3fe6832]
- jazz-react@0.14.10
- jazz-tools@0.14.10
- jazz-richtext-tiptap@0.1.18
## 0.1.17
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "richtext-tiptap",
"private": true,
"version": "0.1.17",
"version": "0.1.18",
"type": "module",
"scripts": {
"dev": "vite",
@@ -25,14 +25,14 @@
"jazz-richtext-tiptap": "workspace:*",
"jazz-tools": "workspace:*",
"lucide-react": "^0.509.0",
"react": "18.3.1",
"react-dom": "18.3.1"
"react": "19.0.0",
"react-dom": "19.0.0"
},
"devDependencies": {
"@biomejs/biome": "1.9.4",
"@playwright/test": "^1.50.1",
"@types/react": "~18.3.12",
"@types/react-dom": "^18.3.1",
"@types/react": "19.0.0",
"@types/react-dom": "19.0.0",
"@vitejs/plugin-react": "^4.3.3",
"autoprefixer": "^10.4.20",
"globals": "^15.11.0",

View File

@@ -1,5 +1,16 @@
# richtext
## 0.0.95
### Patch Changes
- Updated dependencies [dc746a2]
- Updated dependencies [f869d9a]
- Updated dependencies [3fe6832]
- jazz-react@0.14.10
- jazz-tools@0.14.10
- jazz-richtext-prosemirror@0.1.29
## 0.0.94
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "richtext",
"private": true,
"version": "0.0.94",
"version": "0.0.95",
"type": "module",
"scripts": {
"dev": "vite",
@@ -22,14 +22,14 @@
"prosemirror-schema-list": "^1.5.1",
"prosemirror-state": "^1.4.3",
"prosemirror-view": "^1.39.1",
"react": "18.3.1",
"react-dom": "18.3.1"
"react": "19.0.0",
"react-dom": "19.0.0"
},
"devDependencies": {
"@biomejs/biome": "1.9.4",
"@playwright/test": "^1.50.1",
"@types/react": "~18.3.12",
"@types/react-dom": "^18.3.1",
"@types/react": "19.0.0",
"@types/react-dom": "19.0.0",
"@vitejs/plugin-react": "^4.3.3",
"autoprefixer": "^10.4.20",
"globals": "^15.11.0",

View File

@@ -1,5 +1,16 @@
# todo-vue
## 0.0.109
### Patch Changes
- Updated dependencies [dc746a2]
- Updated dependencies [f869d9a]
- Updated dependencies [3fe6832]
- jazz-tools@0.14.10
- jazz-browser@0.14.10
- jazz-vue@0.14.10
## 0.0.108
### Patch Changes

View File

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

View File

@@ -1,5 +1,15 @@
# jazz-example-todo
## 0.0.224
### Patch Changes
- Updated dependencies [dc746a2]
- Updated dependencies [f869d9a]
- Updated dependencies [3fe6832]
- jazz-react@0.14.10
- jazz-tools@0.14.10
## 0.0.223
### Patch Changes

View File

@@ -1,6 +1,6 @@
# Todo list example with Jazz and React
Live version: https://todo-demo.jazz.tools/
Live version: [https://todo-demo.jazz.tools/](https://todo-demo.jazz.tools/)
## Getting started

View File

@@ -1,7 +1,7 @@
{
"name": "jazz-example-todo",
"private": true,
"version": "0.0.223",
"version": "0.0.224",
"type": "module",
"scripts": {
"dev": "vite",
@@ -21,8 +21,8 @@
"jazz-tools": "workspace:*",
"lucide-react": "^0.274.0",
"qrcode": "^1.5.3",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react": "19.0.0",
"react-dom": "19.0.0",
"react-router": "^6.16.0",
"react-router-dom": "^6.16.0",
"tailwind-merge": "^1.14.0",
@@ -31,8 +31,8 @@
},
"devDependencies": {
"@types/qrcode": "^1.5.1",
"@types/react": "^18.3.12",
"@types/react-dom": "^18.3.1",
"@types/react": "19.0.0",
"@types/react-dom": "19.0.0",
"@vitejs/plugin-react-swc": "^3.3.2",
"autoprefixer": "^10.4.20",
"postcss": "^8.4.27",

View File

@@ -1,5 +1,16 @@
# version-history
## 0.0.103
### Patch Changes
- Updated dependencies [dc746a2]
- Updated dependencies [f869d9a]
- Updated dependencies [3fe6832]
- jazz-inspector@0.14.10
- jazz-react@0.14.10
- jazz-tools@0.14.10
## 0.0.102
### Patch Changes

View File

@@ -1,6 +1,7 @@
# Jazz Version History Example
A minimal example showing how to use Jazz's built-in version history to show and restore changes.
Live Version: [https://jazz-version-history.vercel.app/](https://jazz-version-history.vercel.app/)
## Getting started

View File

@@ -1,7 +1,7 @@
{
"name": "version-history",
"private": true,
"version": "0.0.102",
"version": "0.0.103",
"type": "module",
"scripts": {
"dev": "vite",
@@ -15,14 +15,14 @@
"jazz-inspector": "workspace:*",
"jazz-react": "workspace:*",
"jazz-tools": "workspace:*",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react": "19.0.0",
"react-dom": "19.0.0",
"tailwindcss": "^3.4.17"
},
"devDependencies": {
"@biomejs/biome": "1.9.4",
"@types/react": "^18.3.12",
"@types/react-dom": "^18.3.1",
"@types/react": "19.0.0",
"@types/react-dom": "19.0.0",
"@vitejs/plugin-react": "^4.3.3",
"globals": "^15.11.0",
"typescript": "5.6.2",

View File

@@ -382,9 +382,7 @@ const Person = co.map({
### Helper methods
You can use the `withHelpers` method on CoValue schemas to add helper functions to the schema itself.
These typically take a parameter of a loaded CoValue of the schema.
You should define helper methods of CoValue schemas separately, in standalone functions.
<CodeGroup>
```ts twoslash
@@ -398,15 +396,16 @@ const Person = co.map({
firstName: z.string(),
lastName: z.string(),
dateOfBirth: z.date(),
}).withHelpers((Self) => ({
fullName(person: Loaded<typeof Self>) {
return `${person.firstName} ${person.lastName}`;
},
})
type Person = co.loaded<typeof Person>;
ageAsOf(person: Loaded<typeof Self>, date: Date) {
return differenceInYears(date, person.dateOfBirth);
}
}));
export function getPersonFullName(person: Person) {
return `${person.firstName} ${person.lastName}`;
}
export function getPersonAgeAsOf(person: Person, date: Date) {
return differenceInYears(date, person.dateOfBirth);
}
const person = Person.create({
firstName: "John",
@@ -414,7 +413,7 @@ const person = Person.create({
dateOfBirth: new Date("1990-01-01"),
});
const fullName = Person.fullName(person);
const age = Person.ageAsOf(person, new Date());
const fullName = getPersonFullName(person);
const age = getPersonAgeAsOf(person, new Date());
```
</CodeGroup>

View File

@@ -318,7 +318,7 @@ project.coordinator = undefined; // Remove the reference
#### Helper methods
You can add helper methods to your CoMap schema to make it more useful:
You should define helper methods of CoValue schemas separately, in standalone functions:
<CodeGroup>
```ts twoslash
@@ -331,26 +331,27 @@ const Project = co.map({
name: z.string(),
startDate: z.date(),
endDate: z.optional(z.date()),
}).withHelpers((Self) => ({
isActive(project: Loaded<typeof Self>) {
const now = new Date();
return now >= project.startDate && (!project.endDate || now <= project.endDate);
},
});
type Project = co.loaded<typeof Project>;
formatDuration(project: Loaded<typeof Self>, format: "short" | "full") {
const start = project.startDate.toLocaleDateString();
if (!project.endDate) {
return format === "full"
export function isProjectActive(project: Project) {
const now = new Date();
return now >= project.startDate && (!project.endDate || now <= project.endDate);
}
export function formatProjectDuration(project: Project, format: "short" | "full") {
const start = project.startDate.toLocaleDateString();
if (!project.endDate) {
return format === "full"
? `Started on ${start}, ongoing`
: `From ${start}`;
}
const end = project.endDate.toLocaleDateString();
return format === "full"
? `From ${start} to ${end}`
: `${(project.endDate.getTime() - project.startDate.getTime()) / 86400000} days`;
}
}));
const end = project.endDate.toLocaleDateString();
return format === "full"
? `From ${start} to ${end}`
: `${(project.endDate.getTime() - project.startDate.getTime()) / 86400000} days`;
}
const project = Project.create({
name: "My project",
@@ -358,7 +359,7 @@ const project = Project.create({
endDate: new Date("2025-04-04"),
});
console.log(Project.isActive(project)); // false
console.log(Project.formatDuration(project, "short")); // "3 days"
console.log(isProjectActive(project)); // false
console.log(formatProjectDuration(project, "short")); // "3 days"
```
</CodeGroup>

View File

@@ -48,9 +48,12 @@
"ignoreMissing": ["@babel/*", "expo-modules-*", "typescript"]
},
"overrides": {
"react": "18.3.1",
"react-dom": "18.3.1",
"@types/react": "19.0.0",
"@types/react-dom": "19.0.0",
"react": "19.0.0",
"react-dom": "19.0.0",
"esbuild": "0.24.0"
},
"patchedDependencies": {
"expo-router": "patches/expo-router.patch"

View File

@@ -1,5 +1,17 @@
# create-jazz-app
## 0.1.20
### Patch Changes
- f5bae09: Remove React Native specific steps as not required anymore
## 0.1.19
### Patch Changes
- 4508524: Rename demo to minimal, change React Native template to minimal auth
## 0.1.18
### Patch Changes

View File

@@ -5,7 +5,7 @@
"types": "src/index.ts",
"type": "module",
"license": "MIT",
"version": "0.1.18",
"version": "0.1.20",
"bin": {
"create-jazz-app": "./dist/index.js"
},

View File

@@ -2,7 +2,7 @@ export type Environment = "browser" | "mobile";
export type Engine = "browser" | "mobile" | "nodejs" | "deno" | "bun";
export type Framework = "react" | "vue" | "svelte" | "rn";
export type AuthMethod =
| "demo"
| "minimal"
| "passkey"
| "passphrase"
| "clerk"
@@ -58,14 +58,14 @@ export type ValidAuth<
export const configMap: ConfigStructure = {
browser: {
browser: {
react: { auth: ["demo", "passkey", "passphrase", "clerk"] },
vue: { auth: ["demo"] },
react: { auth: ["minimal", "passkey", "passphrase", "clerk"] },
vue: { auth: ["minimal"] },
svelte: { auth: ["passkey"] },
},
},
mobile: {
mobile: {
rn: { auth: ["demo", "clerk"] },
rn: { auth: ["minimal"] },
},
},
};
@@ -98,8 +98,8 @@ export const frameworkToAuthExamples: Partial<
repo: "garden-co/jazz/examples/clerk",
platform: PLATFORM.WEB,
},
"vue-demo-auth": {
name: "Demo auth",
"vue-minimal-auth": {
name: "Anonymous auth",
repo: "garden-co/jazz/examples/todo-vue",
platform: PLATFORM.WEB,
},
@@ -108,9 +108,9 @@ export const frameworkToAuthExamples: Partial<
repo: "garden-co/jazz/examples/passkey-svelte",
platform: PLATFORM.WEB,
},
"rn-clerk-auth": {
name: "Clerk auth",
repo: "garden-co/jazz/examples/chat-rn-expo-clerk",
"rn-minimal-auth": {
name: "Anonymous auth",
repo: "garden-co/jazz/examples/chat-rn-expo",
platform: PLATFORM.REACT_NATIVE,
},
};

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