Compare commits

...

20 Commits

Author SHA1 Message Date
Guido D'Orsi
6bee742b65 Merge pull request #1207 from garden-co/changeset-release/main
Version Packages
2025-01-18 00:26:30 +01:00
github-actions[bot]
23486d01b9 Version Packages 2025-01-17 23:23:34 +00:00
Guido D'Orsi
b761d5a730 Merge pull request #1215 from garden-co/fix/auth-issues
fix: improve error management on initial auth, fixed an infinite loop when migration fails
2025-01-18 00:22:06 +01:00
Guido D'Orsi
9181e74fc8 chore: add ts-ignore on an error flagged by some Typescript versions 2025-01-18 00:14:54 +01:00
Guido D'Orsi
5e83864f41 fix: improve error management on initial auth, fixed an infinite loop when migration fails 2025-01-18 00:12:46 +01:00
Guido D'Orsi
de5f2d6d5b Merge pull request #1213 from garden-co/fix/handle-unknown-covaule-types
perf: skip coValue content creation on access
2025-01-17 14:44:03 +01:00
Guido D'Orsi
4aa377dea7 chore: changeset 2025-01-17 14:42:05 +01:00
Guido D'Orsi
31ae73fe0e perf: skip coValue content creation on access 2025-01-17 12:49:24 +01:00
Guido D'Orsi
7a5adfc4dc Merge pull request #1212 from garden-co/fix/handle-unknown-covaule-types
feat: handle unknown coValue content instead of triggering an error
2025-01-17 12:23:50 +01:00
Guido D'Orsi
850e264912 feat: handle unknown coValue content instead of triggering an error 2025-01-17 12:02:32 +01:00
Anselm Eickhoff
aa81779ad8 Update page.tsx 2025-01-17 09:59:40 +00:00
Guido D'Orsi
72c97c0835 Merge pull request #1208 from garden-co/0.9.8-changelog
docs: add the 0.9.8 changelog
2025-01-14 18:35:21 +01:00
Guido D'Orsi
12809a6733 docs: add the 0.9.8 changelog 2025-01-14 17:21:51 +01:00
Guido D'Orsi
c55aeff98e docs: fix CoMap load & subscribe docs example 2025-01-14 16:56:47 +01:00
Guido D'Orsi
16b76e401c docs: fix jazz-tools tsDoc generation 2025-01-14 16:48:42 +01:00
Guido D'Orsi
d2470efd6f test: add a test to cover an indirect communication between nodes 2025-01-14 16:45:11 +01:00
pax
1a97b1b77c Merge pull request #1205 from garden-co/JAZZ-647/fix-image-handling-in-rn-chat-demo
Fix image handling in RN Chat Demo
2025-01-14 17:43:54 +02:00
pax-k
f76274c19a chore: changeset 2025-01-14 15:15:59 +02:00
pax-k
cb1b602255 Merge remote-tracking branch 'upstream/main' into JAZZ-647/fix-image-handling-in-rn-chat-demo 2025-01-14 15:14:30 +02:00
pax-k
a728dbf632 fix: image handling in react-native 2025-01-14 15:14:06 +02:00
110 changed files with 1036 additions and 487 deletions

View File

@@ -1,5 +1,17 @@
# chat-rn-clerk
## 1.0.51
### Patch Changes
- f76274c: Fix image handling in react-native
- Updated dependencies [f76274c]
- Updated dependencies [5e83864]
- jazz-react-native@0.9.10
- jazz-tools@0.9.10
- jazz-react-native-auth-clerk@0.9.10
- jazz-react-native-media-images@0.9.10
## 1.0.50
### Patch Changes

View File

@@ -37,7 +37,13 @@
],
"expo-secure-store",
"expo-font",
"expo-router"
"expo-router",
[
"expo-image-picker",
{
"photosPermission": "The app accesses your photos to let you share them with your friends."
}
]
],
"extra": {
"eas": {

View File

@@ -2,8 +2,11 @@ import { Chat, Message } from "@/src/schema";
import { useNavigation } from "@react-navigation/native";
import clsx from "clsx";
import * as Clipboard from "expo-clipboard";
import * as ImagePicker from "expo-image-picker";
import { useLocalSearchParams } from "expo-router";
import { useAccount, useCoState } from "jazz-react-native";
import { ProgressiveImg } from "jazz-react-native";
import { createImage } from "jazz-react-native-media-images";
import { Group, ID } from "jazz-tools";
import { useEffect, useLayoutEffect, useState } from "react";
import React, {
@@ -16,6 +19,8 @@ import React, {
KeyboardAvoidingView,
TextInput,
Button,
Image,
ActivityIndicator,
} from "react-native";
export default function Conversation() {
@@ -25,6 +30,7 @@ export default function Conversation() {
const [message, setMessage] = useState("");
const loadedChat = useCoState(Chat, chat?.id, [{}]);
const navigation = useNavigation();
const [isUploading, setIsUploading] = useState(false);
useEffect(() => {
if (chat) return;
@@ -81,6 +87,32 @@ export default function Conversation() {
}
};
const handleImageUpload = async () => {
try {
const result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.Images,
base64: true,
quality: 0.7,
});
if (!result.canceled && result.assets[0].base64 && chat) {
setIsUploading(true);
const base64Uri = `data:image/jpeg;base64,${result.assets[0].base64}`;
const image = await createImage(base64Uri, {
owner: chat._owner,
maxSize: 2048,
});
chat.push(Message.create({ text: "", image }, { owner: chat._owner }));
}
} catch (error) {
Alert.alert("Error", "Failed to upload image");
} finally {
setIsUploading(false);
}
};
const renderMessageItem = ({ item }: { item: Message }) => {
const isMe = item._edits.text.by?.isMe;
return (
@@ -106,14 +138,27 @@ export default function Conversation() {
isMe ? "flex-row" : "flex-row",
)}
>
<Text
className={clsx(
!isMe ? "text-black" : "text-gray-200",
`text-md max-w-[85%]`,
)}
>
{item.text}
</Text>
{item.image && (
<ProgressiveImg image={item.image} maxWidth={1024}>
{({ src, res, originalSize }) => (
<Image
source={{ uri: src }}
className="w-48 h-48 rounded-lg mb-2"
resizeMode="cover"
/>
)}
</ProgressiveImg>
)}
{item.text && (
<Text
className={clsx(
!isMe ? "text-black" : "text-gray-200",
`text-md max-w-[85%]`,
)}
>
{item.text}
</Text>
)}
<Text
className={clsx(
"text-[10px] text-right ml-2",
@@ -147,6 +192,17 @@ export default function Conversation() {
className="p-3 bg-white border-t border-gray-300"
>
<SafeAreaView className="flex-row items-center gap-2">
<TouchableOpacity
onPress={handleImageUpload}
disabled={isUploading}
className="h-10 w-10 items-center justify-center"
>
{isUploading ? (
<ActivityIndicator size="small" color="#0000ff" />
) : (
<Text className="text-2xl">🖼</Text>
)}
</TouchableOpacity>
<TextInput
className="flex-1 rounded-full h-10 px-4 bg-gray-100 border border-gray-300 focus:border-blue-500 focus:bg-white"
value={message}

View File

@@ -1,7 +1,7 @@
{
"name": "chat-rn-clerk",
"main": "index.js",
"version": "1.0.50",
"version": "1.0.51",
"scripts": {
"build": "expo export -p ios",
"start": "expo start",
@@ -35,6 +35,7 @@
"expo-dev-client": "~5.0.5",
"expo-file-system": "^18.0.4",
"expo-font": "~13.0.1",
"expo-image-picker": "~16.0.4",
"expo-linking": "~7.0.3",
"expo-router": "~4.0.11",
"expo-secure-store": "~14.0.0",

View File

@@ -1,7 +1,8 @@
import { CoList, CoMap, co } from "jazz-tools";
import { CoList, CoMap, ImageDefinition, co } from "jazz-tools";
export class Message extends CoMap {
text = co.string;
image = co.optional.ref(ImageDefinition);
}
export class Chat extends CoList.Of(co.ref(Message)) {}

View File

@@ -1,5 +1,14 @@
# chat-rn
## 1.0.48
### Patch Changes
- Updated dependencies [f76274c]
- Updated dependencies [5e83864]
- jazz-react-native@0.9.10
- jazz-tools@0.9.10
## 1.0.47
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "chat-rn",
"version": "1.0.47",
"version": "1.0.48",
"main": "index.js",
"scripts": {
"build": "expo export -p ios",

View File

@@ -1,5 +1,14 @@
# chat-vue
## 0.0.35
### Patch Changes
- Updated dependencies [5e83864]
- jazz-tools@0.9.10
- jazz-browser@0.9.10
- jazz-vue@0.9.10
## 0.0.34
### Patch Changes

View File

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

View File

@@ -1,5 +1,15 @@
# jazz-example-chat
## 0.0.131
### Patch Changes
- f76274c: Fix image handling in react-native
- Updated dependencies [5e83864]
- jazz-react@0.9.10
- jazz-tools@0.9.10
- jazz-browser-media-images@0.9.10
## 0.0.130
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "jazz-example-chat",
"private": true,
"version": "0.0.130",
"version": "0.0.131",
"type": "module",
"scripts": {
"dev": "vite",

View File

@@ -35,7 +35,7 @@ export function ChatScreen(props: { chatID: ID<Chat> }) {
return;
}
createImage(file).then((image) => {
createImage(file, { owner: chat._owner }).then((image) => {
chat.push(Message.create({ text: file.name, image: image }, chat._owner));
});
};

View File

@@ -1,5 +1,14 @@
# minimal-auth-clerk
## 0.0.30
### Patch Changes
- Updated dependencies [5e83864]
- jazz-react@0.9.10
- jazz-tools@0.9.10
- jazz-react-auth-clerk@0.9.10
## 0.0.29
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "clerk",
"private": true,
"version": "0.0.29",
"version": "0.0.30",
"type": "module",
"scripts": {
"dev": "vite",
@@ -13,7 +13,7 @@
"dependencies": {
"@clerk/clerk-react": "^5.4.1",
"jazz-react": "workspace:*",
"jazz-react-auth-clerk": "workspace:0.9.9",
"jazz-react-auth-clerk": "workspace:0.9.10",
"jazz-tools": "workspace:*",
"react": "^18.3.1",
"react-dom": "^18.3.1"

View File

@@ -1,5 +1,13 @@
# file-share-svelte
## 0.0.15
### Patch Changes
- Updated dependencies [5e83864]
- jazz-tools@0.9.10
- jazz-svelte@0.9.10
## 0.0.14
### Patch Changes

View File

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

View File

@@ -1,5 +1,14 @@
# form
## 0.0.26
### Patch Changes
- Updated dependencies [5e83864]
- jazz-react@0.9.10
- jazz-tools@0.9.10
- jazz-browser-media-images@0.9.10
## 0.0.25
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "form",
"private": true,
"version": "0.0.25",
"version": "0.0.26",
"type": "module",
"scripts": {
"dev": "vite",

View File

@@ -1,5 +1,14 @@
# image-upload
## 0.0.28
### Patch Changes
- Updated dependencies [5e83864]
- jazz-react@0.9.10
- jazz-tools@0.9.10
- jazz-browser-media-images@0.9.10
## 0.0.27
### Patch Changes

View File

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

View File

@@ -1,5 +1,13 @@
# jazz-example-inspector
## 0.0.95
### Patch Changes
- Updated dependencies [4aa377d]
- cojson@0.9.10
- cojson-transport-ws@0.9.10
## 0.0.94
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "jazz-inspector",
"private": true,
"version": "0.0.94",
"version": "0.0.95",
"type": "module",
"scripts": {
"dev": "vite",
@@ -16,8 +16,8 @@
"@radix-ui/react-toast": "^1.1.4",
"class-variance-authority": "^0.7.0",
"clsx": "^2.0.0",
"cojson": "workspace:0.9.9",
"cojson-transport-ws": "workspace:0.9.9",
"cojson": "workspace:0.9.10",
"cojson-transport-ws": "workspace:0.9.10",
"hash-slash": "workspace:0.2.1",
"lucide-react": "^0.274.0",
"qrcode": "^1.5.3",

View File

@@ -1,5 +1,13 @@
# jazz-example-musicplayer
## 0.0.51
### Patch Changes
- Updated dependencies [5e83864]
- jazz-react@0.9.10
- jazz-tools@0.9.10
## 0.0.50
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "jazz-example-music-player",
"private": true,
"version": "0.0.50",
"version": "0.0.51",
"type": "module",
"scripts": {
"dev": "vite",
@@ -18,8 +18,8 @@
"@radix-ui/react-toast": "^1.1.4",
"class-variance-authority": "^0.7.0",
"clsx": "^2.0.0",
"jazz-react": "workspace:0.9.9",
"jazz-tools": "workspace:0.9.9",
"jazz-react": "workspace:0.9.10",
"jazz-tools": "workspace:0.9.10",
"lucide-react": "^0.274.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",

View File

@@ -1,5 +1,14 @@
# jazz-example-onboarding
## 0.0.32
### Patch Changes
- Updated dependencies [5e83864]
- jazz-react@0.9.10
- jazz-tools@0.9.10
- jazz-browser-media-images@0.9.10
## 0.0.31
### Patch Changes

View File

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

View File

@@ -1,5 +1,13 @@
# organization
## 0.0.24
### Patch Changes
- Updated dependencies [5e83864]
- jazz-react@0.9.10
- jazz-tools@0.9.10
## 0.0.23
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "organization",
"private": true,
"version": "0.0.23",
"version": "0.0.24",
"type": "module",
"scripts": {
"dev": "vite",

View File

@@ -1,5 +1,11 @@
# passkey-svelte
## 0.0.19
### Patch Changes
- jazz-svelte@0.9.10
## 0.0.18
### Patch Changes

View File

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

View File

@@ -1,5 +1,13 @@
# minimal-auth-passkey
## 0.0.29
### Patch Changes
- Updated dependencies [5e83864]
- jazz-react@0.9.10
- jazz-tools@0.9.10
## 0.0.28
### Patch Changes

View File

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

View File

@@ -1,5 +1,13 @@
# jazz-password-manager
## 0.0.50
### Patch Changes
- Updated dependencies [5e83864]
- jazz-react@0.9.10
- jazz-tools@0.9.10
## 0.0.49
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "jazz-password-manager",
"private": true,
"version": "0.0.49",
"version": "0.0.50",
"type": "module",
"scripts": {
"dev": "vite",
@@ -12,8 +12,8 @@
"clean-install": "rm -rf node_modules pnpm-lock.yaml && pnpm install"
},
"dependencies": {
"jazz-react": "workspace:0.9.9",
"jazz-tools": "workspace:0.9.9",
"jazz-react": "workspace:0.9.10",
"jazz-tools": "workspace:0.9.10",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-hook-form": "^7.41.5",

View File

@@ -1,5 +1,14 @@
# jazz-example-pets
## 0.0.148
### Patch Changes
- Updated dependencies [5e83864]
- jazz-react@0.9.10
- jazz-tools@0.9.10
- jazz-browser-media-images@0.9.10
## 0.0.147
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "jazz-example-pets",
"private": true,
"version": "0.0.147",
"version": "0.0.148",
"type": "module",
"scripts": {
"dev": "vite",
@@ -19,9 +19,9 @@
"@radix-ui/react-toast": "^1.1.4",
"class-variance-authority": "^0.7.0",
"clsx": "^2.0.0",
"jazz-browser-media-images": "workspace:0.9.9",
"jazz-react": "workspace:0.9.9",
"jazz-tools": "workspace:0.9.9",
"jazz-browser-media-images": "workspace:0.9.10",
"jazz-react": "workspace:0.9.10",
"jazz-tools": "workspace:0.9.10",
"lucide-react": "^0.274.0",
"qrcode": "^1.5.3",
"react": "^18.3.1",
@@ -41,7 +41,7 @@
"@vitejs/plugin-react-swc": "^3.3.2",
"autoprefixer": "^10.4.20",
"is-ci": "^3.0.1",
"jazz-run": "workspace:0.9.9",
"jazz-run": "workspace:0.9.10",
"postcss": "^8.4.27",
"tailwindcss": "^3.4.15",
"typescript": "~5.6.2",

View File

@@ -1,5 +1,14 @@
# reactions
## 0.0.28
### Patch Changes
- Updated dependencies [5e83864]
- jazz-react@0.9.10
- jazz-tools@0.9.10
- jazz-browser-media-images@0.9.10
## 0.0.27
### Patch Changes

View File

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

View File

@@ -1,5 +1,14 @@
# todo-vue
## 0.0.33
### Patch Changes
- Updated dependencies [5e83864]
- jazz-tools@0.9.10
- jazz-browser@0.9.10
- jazz-vue@0.9.10
## 0.0.32
### Patch Changes

View File

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

View File

@@ -1,5 +1,13 @@
# jazz-example-todo
## 0.0.147
### Patch Changes
- Updated dependencies [5e83864]
- jazz-react@0.9.10
- jazz-tools@0.9.10
## 0.0.146
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "jazz-example-todo",
"private": true,
"version": "0.0.146",
"version": "0.0.147",
"type": "module",
"scripts": {
"dev": "vite",
@@ -16,8 +16,8 @@
"@radix-ui/react-toast": "^1.1.4",
"class-variance-authority": "^0.7.0",
"clsx": "^2.0.0",
"jazz-react": "workspace:0.9.9",
"jazz-tools": "workspace:0.9.9",
"jazz-react": "workspace:0.9.10",
"jazz-tools": "workspace:0.9.10",
"lucide-react": "^0.274.0",
"qrcode": "^1.5.3",
"react": "^18.3.1",

View File

@@ -1,5 +1,13 @@
# version-history
## 0.0.25
### Patch Changes
- Updated dependencies [5e83864]
- jazz-react@0.9.10
- jazz-tools@0.9.10
## 0.0.24
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "version-history",
"private": true,
"version": "0.0.24",
"version": "0.0.25",
"type": "module",
"scripts": {
"dev": "vite",

View File

@@ -61,14 +61,6 @@ const team: Array<TeamMember> = [
location: "Portsmouth, UK ",
github: "bensleveritt",
},
{
name: "Marina Orlova",
titles: ["Full-Stack Dev"],
location: "Tarragona, Spain ",
linkedin: "marina-orlova-52a34394",
github: "marinoska",
image: "marina.jpeg",
},
{
name: "Giordano Ricci",
titles: ["Full-Stack Dev", "DevOps"],

View File

@@ -240,24 +240,77 @@ In the demos, you'll find details on:
### Working with Images
To work with images in Jazz, import the `createImage` function from [`jazz-react-native-media-images`](https://github.com/garden-co/jazz/tree/main/packages/jazz-react-native-media-images).
Jazz provides a complete solution for handling images in React Native, including uploading, processing, and displaying them. Here's how to work with images:
#### Uploading Images
To upload images, use the `createImage` function from `jazz-react-native-media-images`. This function handles image processing and creates an `ImageDefinition` that can be stored in your Jazz covalues:
<CodeGroup>
```tsx
import { createImage } from "jazz-react-native-media-images";
import * as ImagePicker from 'expo-image-picker';
const base64ImageDataURI = "data:image/png;base64,...";
// Example: Image upload from device library
const handleImageUpload = async () => {
try {
const result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.Images,
base64: true, // Important: We need base64 data
quality: 0.7,
});
const image = await createImage(base64ImageDataURI, {
owner: newPetPost._owner,
maxSize: 2048, // optional: specify maximum image size
});
if (!result.canceled && result.assets[0].base64) {
const base64Uri = `data:image/jpeg;base64,${result.assets[0].base64}`;
someCovalue.image = image;
const image = await createImage(base64Uri, {
owner: someCovalue._owner, // Set appropriate owner
maxSize: 2048, // Optional: limit maximum image size
});
// Store the image in your covalue
someCovalue.image = image;
}
} catch (error) {
console.error('Failed to upload image:', error);
}
};
```
</CodeGroup>
For a complete implementation, please refer to [this](https://github.com/garden-co/jazz/blob/main/examples/pets/src/3_NewPetPostForm.tsx) demo.
#### Displaying Images
To display images, use the `ProgressiveImg` component from `jazz-react-native`. This component handles both images uploaded from React Native and desktop browsers:
<CodeGroup>
```tsx
import { ProgressiveImg } from "jazz-react-native";
import { Image } from "react-native";
// Inside your render function:
<ProgressiveImg image={someCovalue.image} maxWidth={1024}>
{({ src, res, originalSize }) => (
<Image
source={{ uri: src }}
style={{
width: 300, // Adjust size as needed
height: 300,
borderRadius: 8,
}}
resizeMode="cover"
/>
)}
</ProgressiveImg>
```
</CodeGroup>
The `ProgressiveImg` component:
- Automatically handles different image formats
- Provides progressive loading with placeholder images
- Supports different resolutions based on the `maxWidth` prop
- Works seamlessly with React Native's `Image` component
For a complete implementation example, see the [Chat Example](https://github.com/garden-co/jazz/blob/main/examples/chat-rn-clerk/app/chat/[chatId].tsx).
### Running your app

View File

@@ -0,0 +1,74 @@
import { ContentByFramework, CodeGroup } from '@/components/forMdx'
export const metadata = { title: "Upgrade to Jazz 0.9.0" };
# Jazz 0.9.8 - Without me!
<h2 className="not-prose text-sm text-stone-600 dark:text-stone-400 mb-5 pb-2 border-b">
14 January 2025
</h2>
<div>
We have simplified the API to make the "me" value always optional!
This removes the need of using `useAccount` like the 90% of the time!
</div>
<CodeGroup>
{/* prettier-ignore */}
```ts
import { useState } from "react";
import { Issue } from "./schema";
import { IssueComponent } from "./components/Issue.tsx";
function App() {
const [issue, setIssue] = useState<Issue>();
const createIssue = () => {
setIssue(Issue.create(
{
title: "Buy terrarium",
description: "Make sure it's big enough for 10 snails.",
estimate: 5,
status: "backlog",
}, // The owner defaults now to a group managed by the current user!
));
};
if (issue) {
return <IssueComponent issue={issue} />;
} else {
return <button onClick={createIssue}>Create Issue</button>;
}
}
```
</CodeGroup>
<div>
This also applies to the load API:
</div>
<CodeGroup>
{/* prettier-ignore */}
```ts
const issue = Issue.load(issueId, {})
```
</CodeGroup>
<div>
And `Group.create`:
</div>
<CodeGroup>
{/* prettier-ignore */}
```tsx
const group = Group.create()
const sharedIssue = Issue.create(payload, group)
group.addMember('everyone', 'reader')
```
</CodeGroup>
<div>
Everything is backward compatible, so no upgrade steps are required.
With this Jazz API becomes way more lean and more is coming!
</div>

View File

@@ -13,7 +13,9 @@ export function DocNav({ className }: { className?: string }) {
return {
...headerItem,
items: headerItem.items
.filter((item) => !item.framework || item.framework === framework)
.filter(
(item) => !("framework" in item) || item.framework === framework,
)
.map((item) => {
if (!item.href?.startsWith("/docs")) return item;

View File

@@ -3,8 +3,7 @@ import { Application } from "typedoc";
for (const { packageName, entryPoint, tsconfig, typedocOptions } of [
{
packageName: "jazz-tools",
entryPoint: "index.web.ts",
tsconfig: "tsconfig.web.json",
entryPoint: "exports.ts",
},
{
packageName: "jazz-react",

View File

@@ -50,16 +50,27 @@ export const docNavigationItems = [
href: "/docs/project-setup/server-side",
done: 80,
},
],
},
{
name: "Updates",
items: [
{
// upgrade guides
name: "Enable local persistence",
name: "Jazz 0.9.8 - Without me!",
href: "/docs/upgrade/0-9-8",
done: 100,
},
{
// upgrade guides
name: "Jazz 0.9.2 - Local persistence on React Native",
href: "/docs/upgrade/react-native-local-persistence",
done: 100,
framework: "react-native",
},
{
// upgrade guides
name: "Upgrade to Jazz 0.9.0",
name: "Jazz 0.9.0 - Upgrade guide",
href: "/docs/upgrade/0-9-0",
done: 100,
},

View File

@@ -1,5 +1,13 @@
# cojson-storage-indexeddb
## 0.9.10
### Patch Changes
- Updated dependencies [4aa377d]
- cojson@0.9.10
- cojson-storage@0.9.10
## 0.9.9
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "cojson-storage-indexeddb",
"version": "0.9.9",
"version": "0.9.10",
"main": "dist/index.js",
"type": "module",
"types": "src/index.ts",

View File

@@ -1,5 +1,13 @@
# cojson-storage-sqlite
## 0.8.53
### Patch Changes
- Updated dependencies [4aa377d]
- cojson@0.9.10
- cojson-storage@0.9.10
## 0.8.52
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "cojson-storage-rn-sqlite",
"type": "module",
"version": "0.8.52",
"version": "0.8.53",
"main": "dist/index.js",
"types": "src/index.ts",
"license": "MIT",

View File

@@ -1,5 +1,13 @@
# cojson-storage-sqlite
## 0.9.10
### Patch Changes
- Updated dependencies [4aa377d]
- cojson@0.9.10
- cojson-storage@0.9.10
## 0.9.9
### Patch Changes

View File

@@ -1,13 +1,13 @@
{
"name": "cojson-storage-sqlite",
"type": "module",
"version": "0.9.9",
"version": "0.9.10",
"main": "dist/index.js",
"types": "src/index.ts",
"license": "MIT",
"dependencies": {
"better-sqlite3": "^11.7.0",
"cojson": "workspace:0.9.9",
"cojson": "workspace:0.9.10",
"cojson-storage": "workspace:*"
},
"devDependencies": {

View File

@@ -1,5 +1,12 @@
# cojson-storage
## 0.9.10
### Patch Changes
- Updated dependencies [4aa377d]
- cojson@0.9.10
## 0.9.9
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "cojson-storage",
"version": "0.9.9",
"version": "0.9.10",
"main": "dist/index.js",
"type": "module",
"types": "src/index.ts",

View File

@@ -1,5 +1,12 @@
# cojson-transport-nodejs-ws
## 0.9.10
### Patch Changes
- Updated dependencies [4aa377d]
- cojson@0.9.10
## 0.9.9
### Patch Changes

View File

@@ -1,12 +1,12 @@
{
"name": "cojson-transport-ws",
"type": "module",
"version": "0.9.9",
"version": "0.9.10",
"main": "dist/index.js",
"types": "src/index.ts",
"license": "MIT",
"dependencies": {
"cojson": "workspace:0.9.9",
"cojson": "workspace:0.9.10",
"typescript": "~5.6.2"
},
"scripts": {

View File

@@ -1,5 +1,11 @@
# cojson
## 0.9.10
### Patch Changes
- 4aa377d: Handle unkown coValue content type and optimize content access
## 0.9.9
### Patch Changes

View File

@@ -24,7 +24,7 @@
},
"type": "module",
"license": "MIT",
"version": "0.9.9",
"version": "0.9.10",
"devDependencies": {
"@opentelemetry/sdk-metrics": "^1.29.0",
"@types/jest": "^29.5.3",

View File

@@ -35,6 +35,43 @@ export interface RawCoValue {
subscribe(listener: (coValue: this) => void): () => void;
}
export class RawUnknownCoValue implements RawCoValue {
id: CoID<this>;
core: CoValueCore;
constructor(core: CoValueCore) {
this.id = core.id as CoID<this>;
this.core = core;
}
get type() {
return this.core.header.type;
}
get headerMeta() {
return this.core.header.meta as JsonObject;
}
/** @category 6. Meta */
get group(): RawGroup {
return this.core.getGroup();
}
toJSON() {
return {};
}
atTime() {
return this;
}
subscribe(listener: (value: this) => void): () => void {
return this.core.subscribe((content) => {
listener(content as this);
});
}
}
export type AnyRawCoValue =
| RawCoMap
| RawGroup

View File

@@ -126,10 +126,7 @@ export class CoValueCore {
.expectCoValueLoaded(header.ruleset.group)
.subscribe((_groupUpdate) => {
this._cachedContent = undefined;
const newContent = this.getCurrentContent();
for (const listener of this.listeners) {
listener(newContent);
}
this.notifyUpdate("immediate");
});
}
}
@@ -244,11 +241,6 @@ export class CoValueCore {
signerID,
} satisfies InvalidSignatureError);
}
// const afterVerify = performance.now();
// console.log(
// "Verify took",
// afterVerify - beforeVerify
// );
this.doAddTransactions(
sessionID,
@@ -263,138 +255,6 @@ export class CoValueCore {
});
}
/*tryAddTransactionsAsync(
sessionID: SessionID,
newTransactions: Transaction[],
givenExpectedNewHash: Hash | undefined,
newSignature: Signature,
): ResultAsync<true, TryAddTransactionsError> {
const currentAsyncAddTransaction = this._currentAsyncAddTransaction;
let maybeAwaitPrevious:
| ResultAsync<void, TryAddTransactionsError>
| undefined;
let thisDone = () => {};
if (currentAsyncAddTransaction) {
// eslint-disable-next-line neverthrow/must-use-result
maybeAwaitPrevious = ResultAsync.fromSafePromise(
currentAsyncAddTransaction,
);
} else {
// eslint-disable-next-line neverthrow/must-use-result
maybeAwaitPrevious = ResultAsync.fromSafePromise(Promise.resolve());
this._currentAsyncAddTransaction = new Promise((resolve) => {
thisDone = resolve;
});
}
return maybeAwaitPrevious
.andThen((_previousDone) =>
this.node
.resolveAccountAgentAsync(
accountOrAgentIDfromSessionID(sessionID),
"Expected to know signer of transaction",
)
.andThen((agent) => {
const signerID = this.crypto.getAgentSignerID(agent);
const nTxBefore =
this.sessionLogs.get(sessionID)?.transactions
.length ?? 0;
// const beforeHash = performance.now();
return ResultAsync.fromSafePromise(
this.expectedNewHashAfterAsync(
sessionID,
newTransactions,
),
).andThen(({ expectedNewHash, newStreamingHash }) => {
// const afterHash = performance.now();
// console.log(
// "Hashing took",
// afterHash - beforeHash
// );
const nTxAfter =
this.sessionLogs.get(sessionID)?.transactions
.length ?? 0;
if (nTxAfter !== nTxBefore) {
const newTransactionLengthBefore =
newTransactions.length;
newTransactions = newTransactions.slice(
nTxAfter - nTxBefore,
);
console.warn(
"Transactions changed while async hashing",
{
nTxBefore,
nTxAfter,
newTransactionLengthBefore,
remainingNewTransactions:
newTransactions.length,
},
);
}
if (
givenExpectedNewHash &&
givenExpectedNewHash !== expectedNewHash
) {
return err({
type: "InvalidHash",
id: this.id,
expectedNewHash,
givenExpectedNewHash,
} satisfies InvalidHashError);
}
performance.mark("verifyStart" + this.id);
if (
!this.crypto.verify(
newSignature,
expectedNewHash,
signerID,
)
) {
return err({
type: "InvalidSignature",
id: this.id,
newSignature,
sessionID,
signerID,
} satisfies InvalidSignatureError);
}
performance.mark("verifyEnd" + this.id);
performance.measure(
"verify" + this.id,
"verifyStart" + this.id,
"verifyEnd" + this.id,
);
this.doAddTransactions(
sessionID,
newTransactions,
newSignature,
expectedNewHash,
newStreamingHash,
"deferred",
);
return ok(true as const);
});
}),
)
.map((trueResult) => {
thisDone();
return trueResult;
})
.mapErr((err) => {
thisDone();
return err;
});
}*/
private doAddTransactions(
sessionID: SessionID,
newTransactions: Transaction[],
@@ -432,12 +292,6 @@ export class CoValueCore {
);
if (sizeOfTxsSinceLastInbetweenSignature > MAX_RECOMMENDED_TX_SIZE) {
// console.log(
// "Saving inbetween signature for tx ",
// sessionID,
// transactions.length - 1,
// sizeOfTxsSinceLastInbetweenSignature
// );
signatureAfter[transactions.length - 1] = newSignature;
}
@@ -463,34 +317,40 @@ export class CoValueCore {
this._cachedDependentOn = undefined;
this._cachedNewContentSinceEmpty = undefined;
if (this.listeners.size > 0) {
if (notifyMode === "immediate") {
const content = this.getCurrentContent();
for (const listener of this.listeners) {
listener(content);
}
} else {
if (!this.nextDeferredNotify) {
this.nextDeferredNotify = new Promise((resolve) => {
setTimeout(() => {
this.nextDeferredNotify = undefined;
this.deferredUpdates = 0;
const content = this.getCurrentContent();
for (const listener of this.listeners) {
listener(content);
}
resolve();
}, 0);
});
}
this.deferredUpdates++;
}
}
this.notifyUpdate(notifyMode);
}
deferredUpdates = 0;
nextDeferredNotify: Promise<void> | undefined;
notifyUpdate(notifyMode: "immediate" | "deferred") {
if (this.listeners.size === 0) {
return;
}
if (notifyMode === "immediate") {
const content = this.getCurrentContent();
for (const listener of this.listeners) {
listener(content);
}
} else {
if (!this.nextDeferredNotify) {
this.nextDeferredNotify = new Promise((resolve) => {
setTimeout(() => {
this.nextDeferredNotify = undefined;
this.deferredUpdates = 0;
const content = this.getCurrentContent();
for (const listener of this.listeners) {
listener(content);
}
resolve();
}, 0);
});
}
this.deferredUpdates++;
}
}
subscribe(listener: (content?: RawCoValue) => void): () => void {
this.listeners.add(listener);
listener(this.getCurrentContent());

View File

@@ -1,3 +1,4 @@
import { RawUnknownCoValue } from "./coValue.js";
import type { CoValueCore } from "./coValueCore.js";
import { RawAccount, RawControlledAccount } from "./coValues/account.js";
import { RawCoList } from "./coValues/coList.js";
@@ -38,6 +39,6 @@ export function coreToCoValue(
return new RawCoStream(core);
}
} else {
throw new Error(`Unknown coValue type ${core.header.type}`);
return new RawUnknownCoValue(core);
}
}

View File

@@ -1,11 +1,14 @@
import { expect, test, vi } from "vitest";
import { Transaction } from "../coValueCore.js";
import { CoValueCore, Transaction } from "../coValueCore.js";
import { MapOpPayload } from "../coValues/coMap.js";
import { WasmCrypto } from "../crypto/WasmCrypto.js";
import { stableStringify } from "../jsonStringify.js";
import { LocalNode } from "../localNode.js";
import { Role } from "../permissions.js";
import { randomAnonymousAccountAndSessionID } from "./testUtils.js";
import {
createTestNode,
randomAnonymousAccountAndSessionID,
} from "./testUtils.js";
const Crypto = await WasmCrypto.create();
@@ -191,3 +194,30 @@ test("New transactions in a group correctly update owned values, including subsc
expect(map.core.getValidSortedTransactions().length).toBe(0);
});
test("creating a coValue with a group should't trigger automatically a content creation (performance)", () => {
const node = createTestNode();
const group = node.createGroup();
const getCurrentContentSpy = vi.spyOn(
CoValueCore.prototype,
"getCurrentContent",
);
const groupSpy = vi.spyOn(group.core, "getCurrentContent");
getCurrentContentSpy.mockClear();
node.createCoValue({
type: "comap",
ruleset: { type: "ownedByGroup", group: group.id },
meta: null,
...Crypto.createdNowUnique(),
});
// It's called once for the group and never for the coValue
expect(getCurrentContentSpy).toHaveBeenCalledTimes(1);
expect(groupSpy).toHaveBeenCalledTimes(1);
getCurrentContentSpy.mockRestore();
});

View File

@@ -12,8 +12,10 @@ import { connectedPeers, newQueuePair } from "../streamUtils.js";
import type { SyncMessage } from "../sync.js";
import {
blockMessageTypeOnOutgoingPeer,
connectTwoPeers,
createTestMetricReader,
createTestNode,
loadCoValueOrFail,
randomAnonymousAccountAndSessionID,
tearDownTestMetricReader,
waitFor,
@@ -1645,6 +1647,28 @@ function createTwoConnectedNodes() {
};
}
test("a value created on one node can be loaded on anotehr node even if not directly connected", async () => {
const userA = createTestNode();
const userB = createTestNode();
const serverA = createTestNode();
const serverB = createTestNode();
const core = createTestNode();
connectTwoPeers(userA, serverA, "client", "server");
connectTwoPeers(userB, serverB, "client", "server");
connectTwoPeers(serverA, core, "client", "server");
connectTwoPeers(serverB, core, "client", "server");
const group = userA.createGroup();
const map = group.createMap();
map.set("key1", "value1", "trusting");
await map.core.waitForSync();
const mapOnUserB = await loadCoValueOrFail(userB, map.id);
expect(mapOnUserB.get("key1")).toBe("value1");
});
describe("SyncManager - knownStates vs optimisticKnownStates", () => {
test("knownStates and optimisticKnownStates are the same when the coValue is fully synced", async () => {
const { client, jazzCloud } = createTwoConnectedNodes();
@@ -1961,6 +1985,25 @@ describe("waitForSyncWithPeer", () => {
});
});
test("Should not crash when syncing an unknown coValue type", async () => {
const { client, jazzCloud } = createTwoConnectedNodes();
const coValue = client.createCoValue({
type: "ooops" as any,
ruleset: { type: "unsafeAllowAll" },
meta: null,
...Crypto.createdNowUnique(),
});
await coValue.waitForSync();
const coValueOnTheOtherNode = await loadCoValueOrFail(
jazzCloud,
coValue.getCurrentContent().id,
);
expect(coValueOnTheOtherNode.id).toBe(coValue.id);
});
describe("metrics", () => {
afterEach(() => {
tearDownTestMetricReader();

View File

@@ -33,6 +33,25 @@ export function createTestNode() {
return new LocalNode(admin, session, Crypto);
}
export function connectTwoPeers(
a: LocalNode,
b: LocalNode,
aRole: "client" | "server",
bRole: "client" | "server",
) {
const [aAsPeer, bAsPeer] = connectedPeers(
"peer:" + a.account.id,
"peer:" + b.account.id,
{
peer1role: aRole,
peer2role: bRole,
},
);
a.syncManager.addPeer(bAsPeer);
b.syncManager.addPeer(aAsPeer);
}
export async function createTwoConnectedNodes(
node1Role: Peer["role"],
node2Role: Peer["role"],

View File

@@ -1,5 +1,15 @@
# jazz-browser-media-images
## 0.9.10
### Patch Changes
- Updated dependencies [4aa377d]
- Updated dependencies [5e83864]
- cojson@0.9.10
- jazz-tools@0.9.10
- jazz-browser@0.9.10
## 0.9.9
### Patch Changes

View File

@@ -1,14 +1,14 @@
{
"name": "jazz-browser-auth-clerk",
"version": "0.9.9",
"version": "0.9.10",
"type": "module",
"main": "dist/index.js",
"types": "src/index.ts",
"license": "MIT",
"dependencies": {
"cojson": "workspace:0.9.9",
"jazz-browser": "workspace:0.9.9",
"jazz-tools": "workspace:0.9.9"
"cojson": "workspace:0.9.10",
"jazz-browser": "workspace:0.9.10",
"jazz-tools": "workspace:0.9.10"
},
"scripts": {
"format-and-lint": "biome check .",

View File

@@ -1,5 +1,13 @@
# jazz-browser-media-images
## 0.9.10
### Patch Changes
- Updated dependencies [5e83864]
- jazz-tools@0.9.10
- jazz-browser@0.9.10
## 0.9.9
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "jazz-browser-media-images",
"version": "0.9.9",
"version": "0.9.10",
"type": "module",
"main": "dist/index.js",
"types": "src/index.ts",
@@ -8,8 +8,8 @@
"dependencies": {
"@types/image-blob-reduce": "^4.1.1",
"image-blob-reduce": "^4.1.0",
"jazz-browser": "workspace:0.9.9",
"jazz-tools": "workspace:0.9.9",
"jazz-browser": "workspace:0.9.10",
"jazz-tools": "workspace:0.9.10",
"pica": "^9.0.1",
"typescript": "~5.6.2"
},

View File

@@ -1,5 +1,16 @@
# jazz-browser
## 0.9.10
### Patch Changes
- Updated dependencies [4aa377d]
- Updated dependencies [5e83864]
- cojson@0.9.10
- jazz-tools@0.9.10
- cojson-storage-indexeddb@0.9.10
- cojson-transport-ws@0.9.10
## 0.9.9
### Patch Changes

View File

@@ -1,16 +1,16 @@
{
"name": "jazz-browser",
"version": "0.9.9",
"version": "0.9.10",
"type": "module",
"main": "dist/index.js",
"types": "src/index.ts",
"license": "MIT",
"dependencies": {
"@scure/bip39": "^1.3.0",
"cojson": "workspace:0.9.9",
"cojson-storage-indexeddb": "workspace:0.9.9",
"cojson-transport-ws": "workspace:0.9.9",
"jazz-tools": "workspace:0.9.9",
"cojson": "workspace:0.9.10",
"cojson-storage-indexeddb": "workspace:0.9.10",
"cojson-transport-ws": "workspace:0.9.10",
"jazz-tools": "workspace:0.9.10",
"typescript": "~5.6.2"
},
"scripts": {

View File

@@ -1,5 +1,15 @@
# jazz-autosub
## 0.9.10
### Patch Changes
- Updated dependencies [4aa377d]
- Updated dependencies [5e83864]
- cojson@0.9.10
- jazz-tools@0.9.10
- cojson-transport-ws@0.9.10
## 0.9.9
### Patch Changes

View File

@@ -5,11 +5,11 @@
"types": "src/index.ts",
"type": "module",
"license": "MIT",
"version": "0.9.9",
"version": "0.9.10",
"dependencies": {
"cojson": "workspace:0.9.9",
"cojson-transport-ws": "workspace:0.9.9",
"jazz-tools": "workspace:0.9.9",
"cojson": "workspace:0.9.10",
"cojson-transport-ws": "workspace:0.9.10",
"jazz-tools": "workspace:0.9.10",
"ws": "^8.14.2"
},
"devDependencies": {

View File

@@ -1,5 +1,16 @@
# jazz-browser-media-images
## 0.9.10
### Patch Changes
- Updated dependencies [4aa377d]
- Updated dependencies [5e83864]
- cojson@0.9.10
- jazz-react@0.9.10
- jazz-tools@0.9.10
- jazz-browser-auth-clerk@0.9.10
## 0.9.9
### Patch Changes

View File

@@ -1,15 +1,15 @@
{
"name": "jazz-react-auth-clerk",
"version": "0.9.9",
"version": "0.9.10",
"type": "module",
"main": "dist/index.js",
"types": "src/index.tsx",
"license": "MIT",
"dependencies": {
"cojson": "workspace:0.9.9",
"jazz-browser-auth-clerk": "workspace:0.9.9",
"jazz-react": "workspace:0.9.9",
"jazz-tools": "workspace:0.9.9"
"cojson": "workspace:0.9.10",
"jazz-browser-auth-clerk": "workspace:0.9.10",
"jazz-react": "workspace:0.9.10",
"jazz-tools": "workspace:0.9.10"
},
"peerDependencies": {
"react": "^18.2.0"

View File

@@ -1,5 +1,14 @@
# jazz-react-core
## 0.8.51
### Patch Changes
- Updated dependencies [4aa377d]
- Updated dependencies [5e83864]
- cojson@0.9.10
- jazz-tools@0.9.10
## 0.8.50
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "jazz-react-core",
"version": "0.8.50",
"version": "0.8.51",
"type": "module",
"main": "dist/index.js",
"types": "src/index.ts",

View File

@@ -1,5 +1,16 @@
# jazz-react-native-auth-clerk
## 0.9.10
### Patch Changes
- Updated dependencies [4aa377d]
- Updated dependencies [f76274c]
- Updated dependencies [5e83864]
- cojson@0.9.10
- jazz-react-native@0.9.10
- jazz-tools@0.9.10
## 0.9.9
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "jazz-react-native-auth-clerk",
"version": "0.9.9",
"version": "0.9.10",
"type": "module",
"main": "dist/index.js",
"types": "src/index.ts",

View File

@@ -1,5 +1,12 @@
# jazz-browser-media-images
## 0.9.10
### Patch Changes
- Updated dependencies [5e83864]
- jazz-tools@0.9.10
## 0.9.9
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "jazz-react-native-media-images",
"version": "0.9.9",
"version": "0.9.10",
"type": "module",
"main": "dist/index.js",
"types": "src/index.ts",

View File

@@ -1,5 +1,19 @@
# jazz-browser
## 0.9.10
### Patch Changes
- f76274c: Fix image handling in react-native
- 5e83864: Improve error management on initial auth, fixed an infinite loop when migration fails
- Updated dependencies [4aa377d]
- Updated dependencies [5e83864]
- cojson@0.9.10
- jazz-tools@0.9.10
- cojson-storage-rn-sqlite@0.8.53
- cojson-transport-ws@0.9.10
- jazz-react-core@0.8.51
## 0.9.9
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "jazz-react-native",
"version": "0.9.9",
"version": "0.9.10",
"type": "module",
"main": "./dist/index.js",
"module": "./dist/index.js",

View File

@@ -2,5 +2,6 @@ export * from "./provider.js";
export * from "./auth/auth.js";
export * from "./storage/kv-store-context.js";
export * from "./hooks.js";
export * from "./media.js";
export { parseInviteLink, createInviteLink, setupKvStore } from "./platform.js";

View File

@@ -18,19 +18,40 @@ export function useProgressiveImg({
if (!image) return;
const unsub = image.subscribe({}, (update) => {
const highestRes = update?.highestResAvailable({ maxWidth });
if (highestRes) {
if (highestRes.res !== lastHighestRes) {
lastHighestRes = highestRes.res;
const blob = highestRes.stream.toBlob();
if (blob) {
const blobURI = URL.createObjectURL(blob);
setCurrent({ src: blobURI, res: highestRes.res });
return () => {
setTimeout(() => URL.revokeObjectURL(blobURI), 200);
};
}
if (highestRes && highestRes.res !== lastHighestRes) {
lastHighestRes = highestRes.res;
// use the base64 data directly
const chunks = highestRes.stream.getChunks();
if (chunks?.chunks && chunks.chunks.length > 0) {
// convert chunks to base64
const totalLength = chunks.chunks.reduce(
(acc, chunk) => acc + chunk.length,
0,
);
const combinedArray = new Uint8Array(totalLength);
let offset = 0;
chunks.chunks.forEach((chunk) => {
combinedArray.set(chunk, offset);
offset += chunk.length;
});
// Create data URL
const base64 = Buffer.from(combinedArray).toString("base64");
const dataUrl = `data:${chunks.mimeType};base64,${base64}`;
setCurrent({
src: dataUrl,
res: highestRes.res,
});
} else {
// Fallback to placeholder if chunks aren't available
console.warn("No chunks available for image", image.id);
setCurrent({
src: update?.placeholderDataURL,
res: "placeholder",
});
}
} else {
} else if (!highestRes) {
setCurrent({
src: update?.placeholderDataURL,
res: "placeholder",

View File

@@ -96,6 +96,10 @@ export function JazzProvider<Acc extends Account = RegisteredAccount>({
const promise = createContext();
promise.catch((e) => {
console.error("Error creating Jazz context", e);
});
// In development mode we don't return a cleanup function because otherwise
// the double effect execution would mark the context as done immediately.
if (process.env.NODE_ENV === "development") {

View File

@@ -1,5 +1,17 @@
# jazz-react
## 0.9.10
### Patch Changes
- 5e83864: Improve error management on initial auth, fixed an infinite loop when migration fails
- Updated dependencies [4aa377d]
- Updated dependencies [5e83864]
- cojson@0.9.10
- jazz-tools@0.9.10
- jazz-browser@0.9.10
- jazz-react-core@0.8.51
## 0.9.9
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "jazz-react",
"version": "0.9.9",
"version": "0.9.10",
"type": "module",
"main": "dist/index.js",
"types": "src/index.ts",
@@ -17,9 +17,9 @@
},
"dependencies": {
"@scure/bip39": "^1.3.0",
"cojson": "workspace:0.9.9",
"jazz-browser": "workspace:0.9.9",
"jazz-tools": "workspace:0.9.9",
"cojson": "workspace:0.9.10",
"jazz-browser": "workspace:0.9.10",
"jazz-tools": "workspace:0.9.10",
"jazz-react-core": "workspace:*"
},
"devDependencies": {

View File

@@ -94,6 +94,10 @@ export function JazzProvider<Acc extends Account = RegisteredAccount>({
const promise = createContext();
promise.catch((e) => {
console.error("Error creating Jazz context", e);
});
// In development mode we don't return a cleanup function because otherwise
// the double effect execution would mark the context as done immediately.
if (process.env.NODE_ENV === "development") {

View File

@@ -1,5 +1,16 @@
# jazz-run
## 0.9.10
### Patch Changes
- Updated dependencies [4aa377d]
- Updated dependencies [5e83864]
- cojson@0.9.10
- jazz-tools@0.9.10
- cojson-storage-sqlite@0.9.10
- cojson-transport-ws@0.9.10
## 0.9.9
### Patch Changes

View File

@@ -3,7 +3,7 @@
"bin": "./dist/index.js",
"type": "module",
"license": "MIT",
"version": "0.9.9",
"version": "0.9.10",
"exports": {
"./startSyncServer": {
"import": "./dist/startSyncServer.js",
@@ -28,11 +28,11 @@
"@effect/printer-ansi": "^0.34.5",
"@effect/schema": "^0.71.1",
"@effect/typeclass": "^0.25.5",
"cojson": "workspace:0.9.9",
"cojson-storage-sqlite": "workspace:0.9.9",
"cojson-transport-ws": "workspace:0.9.9",
"cojson": "workspace:0.9.10",
"cojson-storage-sqlite": "workspace:0.9.10",
"cojson-transport-ws": "workspace:0.9.10",
"effect": "^3.6.5",
"jazz-tools": "workspace:0.9.9",
"jazz-tools": "workspace:0.9.10",
"ws": "^8.14.2"
},
"devDependencies": {

View File

@@ -1,5 +1,15 @@
# jazz-svelte
## 0.9.10
### Patch Changes
- Updated dependencies [4aa377d]
- Updated dependencies [5e83864]
- cojson@0.9.10
- jazz-tools@0.9.10
- jazz-browser@0.9.10
## 0.9.9
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "jazz-svelte",
"version": "0.9.9",
"version": "0.9.10",
"scripts": {
"dev": "vite dev",
"build": "vite build && npm run package",

View File

@@ -1,5 +1,13 @@
# jazz-tools
## 0.9.10
### Patch Changes
- 5e83864: Improve error management on initial auth, fixed an infinite loop when migration fails
- Updated dependencies [4aa377d]
- cojson@0.9.10
## 0.9.9
### Patch Changes

View File

@@ -23,7 +23,7 @@
},
"type": "module",
"license": "MIT",
"version": "0.9.9",
"version": "0.9.10",
"dependencies": {
"cojson": "workspace:*"
},

View File

@@ -426,7 +426,6 @@ export class CoMap extends CoValueBase implements CoValue {
* ```ts
* const person = await Person.load(
* "co_zdsMhHtfG6VNKt7RqPUPvUtN2Ax",
* me,
* { pet: {} }
* );
* ```
@@ -473,7 +472,6 @@ export class CoMap extends CoValueBase implements CoValue {
* ```ts
* const unsub = Person.subscribe(
* "co_zdsMhHtfG6VNKt7RqPUPvUtN2Ax",
* me,
* { pet: {} },
* (person) => console.log(person)
* );

View File

@@ -117,22 +117,6 @@ export class CoPlainText extends String implements CoValue {
/**
* Load a `CoPlainText` with a given ID, as a given account.
*
* `depth` specifies which (if any) fields that reference other CoValues to load as well before resolving.
* The `DeeplyLoaded` return type guarantees that corresponding referenced CoValues are loaded to the specified depth.
*
* You can pass `[]` or `{}` for shallowly loading only this CoPlainText, or `{ fieldA: depthA, fieldB: depthB }` for recursively loading referenced CoValues.
*
* Check out the `load` methods on `CoMap`/`CoList`/`CoStream`/`Group`/`Account` to see which depth structures are valid to nest.
*
* @example
* ```ts
* const person = await Person.load(
* "co_zdsMhHtfG6VNKt7RqPUPvUtN2Ax",
* me,
* { pet: {} }
* );
* ```
*
* @category Subscription & Loading
*/
static load<T extends CoPlainText>(
@@ -162,27 +146,12 @@ export class CoPlainText extends String implements CoValue {
*
* Automatically also subscribes to updates to all referenced/nested CoValues as soon as they are accessed in the listener.
*
* `depth` specifies which (if any) fields that reference other CoValues to load as well before calling `listener` for the first time.
* The `DeeplyLoaded` return type guarantees that corresponding referenced CoValues are loaded to the specified depth.
*
* You can pass `[]` or `{}` for shallowly loading only this CoMap, or `{ fieldA: depthA, fieldB: depthB }` for recursively loading referenced CoValues.
*
* Check out the `load` methods on `CoMap`/`CoList`/`CoStream`/`Group`/`Account` to see which depth structures are valid to nest.
*
* Returns an unsubscribe function that you should call when you no longer need updates.
*
* Also see the `useCoState` hook to reactively subscribe to a CoValue in a React component.
*
* @example
* ```ts
* const unsub = Person.subscribe(
* "co_zdsMhHtfG6VNKt7RqPUPvUtN2Ax",
* me,
* { pet: {} },
* (person) => console.log(person)
* );
* ```
*
* @category Subscription & Loading
*/
static subscribe<T extends CoPlainText>(

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