Compare commits
114 Commits
feat/react
...
perf/linke
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5a00fe0862 | ||
|
|
3db07f541f | ||
|
|
0db2e60d09 | ||
|
|
f122147f03 | ||
|
|
4e1bcde8b2 | ||
|
|
eaef418151 | ||
|
|
8d17b192d0 | ||
|
|
9a56bb3d25 | ||
|
|
b6c6a0ae64 | ||
|
|
e000774b3b | ||
|
|
6f6cf23bc8 | ||
|
|
77a718656c | ||
|
|
6c86c4f7ee | ||
|
|
72508332fb | ||
|
|
0ac88b4c80 | ||
|
|
11460b6f9f | ||
|
|
71b93909e6 | ||
|
|
26646cde0c | ||
|
|
4033e95a50 | ||
|
|
f379fcc176 | ||
|
|
66d59b31d5 | ||
|
|
1e6da19d5e | ||
|
|
d6ea4d4662 | ||
|
|
84b5dd8a0b | ||
|
|
c730016572 | ||
|
|
7677ca5240 | ||
|
|
cffe482f75 | ||
|
|
a140f555ba | ||
|
|
10de4b6fc9 | ||
|
|
2433344778 | ||
|
|
4c01459942 | ||
|
|
8dacdd6e2f | ||
|
|
5b0580bfda | ||
|
|
2bed7e845d | ||
|
|
76976026b7 | ||
|
|
10ea8fbf88 | ||
|
|
bd86b159b9 | ||
|
|
c4f5241818 | ||
|
|
181f433477 | ||
|
|
3897a7e137 | ||
|
|
5082ecef3f | ||
|
|
268e433870 | ||
|
|
6c185160c5 | ||
|
|
d18323b74a | ||
|
|
edd91791c9 | ||
|
|
958b13c050 | ||
|
|
bbe140f7be | ||
|
|
1625f82ab7 | ||
|
|
843f729a62 | ||
|
|
cc4631bb42 | ||
|
|
3665ef0088 | ||
|
|
e13039818e | ||
|
|
2e79487982 | ||
|
|
fc2c045a8d | ||
|
|
69bb94be06 | ||
|
|
228c8fa796 | ||
|
|
a34b850824 | ||
|
|
96d518bb97 | ||
|
|
8355f5674d | ||
|
|
5c1d04ee88 | ||
|
|
2ef98d01b0 | ||
|
|
15a86a3014 | ||
|
|
9c49704cf9 | ||
|
|
44f0d8d5c7 | ||
|
|
d7af97d63f | ||
|
|
9d0c9dc6ea | ||
|
|
2c3761c8e8 | ||
|
|
c91bcf9745 | ||
|
|
c1db6e087a | ||
|
|
9d8cc194e0 | ||
|
|
3b189e4def | ||
|
|
7fe50922cc | ||
|
|
b04e2be665 | ||
|
|
80b1535cdf | ||
|
|
3d882f0442 | ||
|
|
f61d568c9d | ||
|
|
6dd02d289c | ||
|
|
33a4944ba3 | ||
|
|
e367b6056d | ||
|
|
f3f56b9be0 | ||
|
|
4cae6bad34 | ||
|
|
17f2ef57de | ||
|
|
3a4d111a37 | ||
|
|
1e18c7f5fc | ||
|
|
8c7a6b27ed | ||
|
|
91f96e1188 | ||
|
|
28dac10723 | ||
|
|
9cb11e38dd | ||
|
|
f3e4bacb33 | ||
|
|
626d43f07b | ||
|
|
1f5d073035 | ||
|
|
a3b607e799 | ||
|
|
8fb93502af | ||
|
|
36774122e0 | ||
|
|
a6923128c1 | ||
|
|
706ca62feb | ||
|
|
01523dcca3 | ||
|
|
77f039b561 | ||
|
|
d661ba77be | ||
|
|
f8fbc59b6f | ||
|
|
cce0d22007 | ||
|
|
e3ff76e9cb | ||
|
|
4cbf71bff7 | ||
|
|
ceb060243a | ||
|
|
a70bebb96a | ||
|
|
b3b2507c35 | ||
|
|
6a8fa16b49 | ||
|
|
1f08807701 | ||
|
|
ba4a7f6170 | ||
|
|
a2854e3602 | ||
|
|
4ea87dc494 | ||
|
|
d8c87c5314 | ||
|
|
46f624a12e | ||
|
|
86ce770f38 |
5
.changeset/breezy-rings-beam.md
Normal file
5
.changeset/breezy-rings-beam.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"cojson": patch
|
||||
---
|
||||
|
||||
Re-introducing linked lists on PriorityBasedMessageQueue
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
"cojson": patch
|
||||
---
|
||||
|
||||
Performance: optimize Group.roleOf getter and made the transactions validation incremental for CoMap and CoFeed
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
"jazz-react": patch
|
||||
---
|
||||
|
||||
Re-export createImage from jazz-browser-media-images
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
"cojson": patch
|
||||
---
|
||||
|
||||
Throw an error when the user tries to load an invalid or undefined id
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
"jazz-tools": patch
|
||||
---
|
||||
|
||||
Export CoFeedEntry type
|
||||
@@ -1,5 +1,38 @@
|
||||
# chat-rn-clerk
|
||||
|
||||
## 1.0.90
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [01523dc]
|
||||
- Updated dependencies [4ea87dc]
|
||||
- Updated dependencies [1e6da19]
|
||||
- Updated dependencies [b6c6a0a]
|
||||
- jazz-tools@0.12.0
|
||||
- jazz-react-native@0.12.0
|
||||
- jazz-react-native-auth-clerk@0.12.0
|
||||
- jazz-react-native-media-images@0.12.0
|
||||
|
||||
## 1.0.89
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react-native@0.11.8
|
||||
- jazz-react-native-auth-clerk@0.11.8
|
||||
- jazz-tools@0.11.8
|
||||
- jazz-react-native-media-images@0.11.8
|
||||
|
||||
## 1.0.88
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [a140f55]
|
||||
- Updated dependencies [2b0d1b0]
|
||||
- jazz-tools@0.11.7
|
||||
- jazz-react-native@0.11.7
|
||||
- jazz-react-native-auth-clerk@0.11.7
|
||||
- jazz-react-native-media-images@0.11.7
|
||||
|
||||
## 1.0.87
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -28,7 +28,7 @@ export default function Conversation() {
|
||||
const { me } = useAccount();
|
||||
const [chat, setChat] = useState<Chat>();
|
||||
const [message, setMessage] = useState("");
|
||||
const loadedChat = useCoState(Chat, chat?.id, [{}]);
|
||||
const loadedChat = useCoState(Chat, chat?.id, { resolve: { $each: true } });
|
||||
const navigation = useNavigation();
|
||||
const [isUploading, setIsUploading] = useState(false);
|
||||
|
||||
@@ -71,7 +71,7 @@ export default function Conversation() {
|
||||
|
||||
const loadChat = async (chatId: ID<Chat>) => {
|
||||
try {
|
||||
const chat = await Chat.load(chatId, me, []);
|
||||
const chat = await Chat.load(chatId, me);
|
||||
setChat(chat);
|
||||
} catch (error) {
|
||||
console.log("Error loading chat", error);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "chat-rn-clerk",
|
||||
"main": "index.js",
|
||||
"version": "1.0.87",
|
||||
"version": "1.0.90",
|
||||
"scripts": {
|
||||
"build": "expo export -p ios",
|
||||
"start": "expo start",
|
||||
|
||||
@@ -1,5 +1,32 @@
|
||||
# chat-rn
|
||||
|
||||
## 1.0.86
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [01523dc]
|
||||
- Updated dependencies [4ea87dc]
|
||||
- Updated dependencies [1e6da19]
|
||||
- Updated dependencies [b6c6a0a]
|
||||
- jazz-tools@0.12.0
|
||||
- jazz-react-native@0.12.0
|
||||
|
||||
## 1.0.85
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react-native@0.11.8
|
||||
- jazz-tools@0.11.8
|
||||
|
||||
## 1.0.84
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [a140f55]
|
||||
- Updated dependencies [2b0d1b0]
|
||||
- jazz-tools@0.11.7
|
||||
- jazz-react-native@0.11.7
|
||||
|
||||
## 1.0.83
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "chat-rn",
|
||||
"version": "1.0.83",
|
||||
"version": "1.0.86",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"build": "expo export -p ios",
|
||||
|
||||
@@ -20,7 +20,7 @@ import { Chat, Message } from "./schema";
|
||||
export default function ChatScreen({ navigation }: { navigation: any }) {
|
||||
const { me, logOut } = useAccount();
|
||||
const [chatId, setChatId] = useState<ID<Chat>>();
|
||||
const loadedChat = useCoState(Chat, chatId, [{}]);
|
||||
const loadedChat = useCoState(Chat, chatId, { resolve: { $each: true } });
|
||||
const [message, setMessage] = useState("");
|
||||
const profile = useCoState(Profile, me._refs.profile?.id, {});
|
||||
|
||||
|
||||
@@ -1,5 +1,36 @@
|
||||
# chat-vue
|
||||
|
||||
## 0.0.71
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [01523dc]
|
||||
- Updated dependencies [4ea87dc]
|
||||
- Updated dependencies [1e6da19]
|
||||
- Updated dependencies [b6c6a0a]
|
||||
- Updated dependencies [4c01459]
|
||||
- jazz-tools@0.12.0
|
||||
- jazz-vue@0.12.0
|
||||
- jazz-browser@0.12.0
|
||||
|
||||
## 0.0.70
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-browser@0.11.8
|
||||
- jazz-tools@0.11.8
|
||||
- jazz-vue@0.11.8
|
||||
|
||||
## 0.0.69
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [a140f55]
|
||||
- Updated dependencies [2b0d1b0]
|
||||
- jazz-tools@0.11.7
|
||||
- jazz-browser@0.11.7
|
||||
- jazz-vue@0.11.7
|
||||
|
||||
## 0.0.68
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "chat-vue",
|
||||
"version": "0.0.68",
|
||||
"version": "0.0.71",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
|
||||
@@ -49,7 +49,7 @@ export default defineComponent({
|
||||
},
|
||||
},
|
||||
setup(props) {
|
||||
const chat = useCoState(Chat, props.chatId, [{}]);
|
||||
const chat = useCoState(Chat, props.chatId, { resolve: { $each: true } });
|
||||
const showNLastMessages = ref(30);
|
||||
|
||||
const displayedMessages = computed(() => {
|
||||
|
||||
@@ -1,5 +1,39 @@
|
||||
# jazz-example-chat
|
||||
|
||||
## 0.0.168
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [01523dc]
|
||||
- Updated dependencies [4ea87dc]
|
||||
- Updated dependencies [1e6da19]
|
||||
- Updated dependencies [b6c6a0a]
|
||||
- Updated dependencies [9a56bb3]
|
||||
- jazz-tools@0.12.0
|
||||
- jazz-inspector@0.12.0
|
||||
- jazz-react@0.12.0
|
||||
|
||||
## 0.0.167
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [71b9390]
|
||||
- jazz-inspector@0.11.8
|
||||
- jazz-react@0.11.8
|
||||
- jazz-tools@0.11.8
|
||||
|
||||
## 0.0.166
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [2c3761c]
|
||||
- Updated dependencies [a140f55]
|
||||
- Updated dependencies [4019918]
|
||||
- Updated dependencies [2b0d1b0]
|
||||
- jazz-inspector@0.11.7
|
||||
- jazz-tools@0.11.7
|
||||
- jazz-react@0.11.7
|
||||
|
||||
## 0.0.165
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "jazz-example-chat",
|
||||
"private": true,
|
||||
"version": "0.0.165",
|
||||
"version": "0.0.168",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
||||
@@ -16,8 +16,8 @@ import {
|
||||
} from "./ui.tsx";
|
||||
|
||||
export function ChatScreen(props: { chatID: ID<Chat> }) {
|
||||
const chat = useCoState(Chat, props.chatID, { resolve: { $each: true } });
|
||||
const account = useAccount();
|
||||
const chat = useCoState(Chat, props.chatID, [{}]);
|
||||
const [showNLastMessages, setShowNLastMessages] = useState(30);
|
||||
|
||||
if (!chat)
|
||||
|
||||
@@ -1,5 +1,36 @@
|
||||
# minimal-auth-clerk
|
||||
|
||||
## 0.0.67
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [01523dc]
|
||||
- Updated dependencies [4ea87dc]
|
||||
- Updated dependencies [1e6da19]
|
||||
- Updated dependencies [b6c6a0a]
|
||||
- jazz-tools@0.12.0
|
||||
- jazz-react@0.12.0
|
||||
- jazz-react-auth-clerk@0.12.0
|
||||
|
||||
## 0.0.66
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react@0.11.8
|
||||
- jazz-react-auth-clerk@0.11.8
|
||||
- jazz-tools@0.11.8
|
||||
|
||||
## 0.0.65
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [a140f55]
|
||||
- Updated dependencies [4019918]
|
||||
- Updated dependencies [2b0d1b0]
|
||||
- jazz-tools@0.11.7
|
||||
- jazz-react@0.11.7
|
||||
- jazz-react-auth-clerk@0.11.7
|
||||
|
||||
## 0.0.64
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "clerk",
|
||||
"private": true,
|
||||
"version": "0.0.64",
|
||||
"version": "0.0.67",
|
||||
"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.11.6",
|
||||
"jazz-react-auth-clerk": "workspace:0.12.0",
|
||||
"jazz-tools": "workspace:*",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1"
|
||||
|
||||
@@ -1,5 +1,32 @@
|
||||
# file-share-svelte
|
||||
|
||||
## 0.0.51
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [01523dc]
|
||||
- Updated dependencies [4ea87dc]
|
||||
- Updated dependencies [1e6da19]
|
||||
- Updated dependencies [b6c6a0a]
|
||||
- jazz-tools@0.12.0
|
||||
- jazz-svelte@0.12.0
|
||||
|
||||
## 0.0.50
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-svelte@0.11.8
|
||||
- jazz-tools@0.11.8
|
||||
|
||||
## 0.0.49
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [a140f55]
|
||||
- Updated dependencies [2b0d1b0]
|
||||
- jazz-tools@0.11.7
|
||||
- jazz-svelte@0.11.7
|
||||
|
||||
## 0.0.48
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "file-share-svelte",
|
||||
"version": "0.0.48",
|
||||
"version": "0.0.51",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
|
||||
@@ -1,5 +1,33 @@
|
||||
# jazz-tailwind-demo-auth-starter
|
||||
|
||||
## 0.0.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [01523dc]
|
||||
- Updated dependencies [4ea87dc]
|
||||
- Updated dependencies [1e6da19]
|
||||
- Updated dependencies [b6c6a0a]
|
||||
- jazz-tools@0.12.0
|
||||
- jazz-react@0.12.0
|
||||
|
||||
## 0.0.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react@0.11.8
|
||||
- jazz-tools@0.11.8
|
||||
|
||||
## 0.0.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [a140f55]
|
||||
- Updated dependencies [4019918]
|
||||
- Updated dependencies [2b0d1b0]
|
||||
- jazz-tools@0.11.7
|
||||
- jazz-react@0.11.7
|
||||
|
||||
## 0.0.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "filestream",
|
||||
"private": true,
|
||||
"version": "0.0.4",
|
||||
"version": "0.0.7",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
||||
@@ -1,5 +1,33 @@
|
||||
# form
|
||||
|
||||
## 0.1.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [01523dc]
|
||||
- Updated dependencies [4ea87dc]
|
||||
- Updated dependencies [1e6da19]
|
||||
- Updated dependencies [b6c6a0a]
|
||||
- jazz-tools@0.12.0
|
||||
- jazz-react@0.12.0
|
||||
|
||||
## 0.1.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react@0.11.8
|
||||
- jazz-tools@0.11.8
|
||||
|
||||
## 0.1.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [a140f55]
|
||||
- Updated dependencies [4019918]
|
||||
- Updated dependencies [2b0d1b0]
|
||||
- jazz-tools@0.11.7
|
||||
- jazz-react@0.11.7
|
||||
|
||||
## 0.1.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "form",
|
||||
"private": true,
|
||||
"version": "0.1.6",
|
||||
"version": "0.1.9",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
||||
@@ -12,7 +12,9 @@ import {
|
||||
} from "./schema.ts";
|
||||
|
||||
export function CreateOrder() {
|
||||
const { me } = useAccount({ root: { draft: {}, orders: [] } });
|
||||
const { me } = useAccount({
|
||||
resolve: { root: { draft: true, orders: true } },
|
||||
});
|
||||
const router = useIframeHashRouter();
|
||||
const [errors, setErrors] = useState<string[]>([]);
|
||||
|
||||
@@ -60,7 +62,7 @@ function CreateOrderForm({
|
||||
onSave: (draft: DraftBubbleTeaOrder) => void;
|
||||
}) {
|
||||
const draft = useCoState(DraftBubbleTeaOrder, id, {
|
||||
addOns: [],
|
||||
resolve: { addOns: true },
|
||||
});
|
||||
|
||||
if (!draft) return;
|
||||
|
||||
@@ -2,7 +2,7 @@ import { useAccount } from "jazz-react";
|
||||
|
||||
export function DraftIndicator() {
|
||||
const { me } = useAccount({
|
||||
root: { draft: {} },
|
||||
resolve: { root: { draft: true } },
|
||||
});
|
||||
|
||||
if (me?.root.draft?.hasChanges) {
|
||||
|
||||
@@ -6,7 +6,7 @@ import { OrderThumbnail } from "./OrderThumbnail.tsx";
|
||||
import { BubbleTeaOrder } from "./schema.ts";
|
||||
|
||||
export function EditOrder(props: { id: ID<BubbleTeaOrder> }) {
|
||||
const order = useCoState(BubbleTeaOrder, props.id, []);
|
||||
const order = useCoState(BubbleTeaOrder, props.id);
|
||||
|
||||
if (!order) return;
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import { OrderThumbnail } from "./OrderThumbnail.tsx";
|
||||
|
||||
export function Orders() {
|
||||
const { me } = useAccount({
|
||||
root: { orders: [] },
|
||||
resolve: { root: { orders: true } },
|
||||
});
|
||||
|
||||
return (
|
||||
|
||||
@@ -1,5 +1,33 @@
|
||||
# image-upload
|
||||
|
||||
## 0.0.65
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [01523dc]
|
||||
- Updated dependencies [4ea87dc]
|
||||
- Updated dependencies [1e6da19]
|
||||
- Updated dependencies [b6c6a0a]
|
||||
- jazz-tools@0.12.0
|
||||
- jazz-react@0.12.0
|
||||
|
||||
## 0.0.64
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react@0.11.8
|
||||
- jazz-tools@0.11.8
|
||||
|
||||
## 0.0.63
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [a140f55]
|
||||
- Updated dependencies [4019918]
|
||||
- Updated dependencies [2b0d1b0]
|
||||
- jazz-tools@0.11.7
|
||||
- jazz-react@0.11.7
|
||||
|
||||
## 0.0.62
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "image-upload",
|
||||
"private": true,
|
||||
"version": "0.0.62",
|
||||
"version": "0.0.65",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
||||
@@ -1,5 +1,39 @@
|
||||
# jazz-example-inspector
|
||||
|
||||
## 0.0.118
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [01523dc]
|
||||
- Updated dependencies [01523dc]
|
||||
- Updated dependencies [9a56bb3]
|
||||
- cojson@0.12.0
|
||||
- jazz-inspector@0.12.0
|
||||
- cojson-transport-ws@0.12.0
|
||||
|
||||
## 0.0.117
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [71b9390]
|
||||
- Updated dependencies [6c86c4f]
|
||||
- Updated dependencies [9d0c9dc]
|
||||
- jazz-inspector@0.11.8
|
||||
- cojson@0.11.8
|
||||
- cojson-transport-ws@0.11.8
|
||||
|
||||
## 0.0.116
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 2c3761c: fix: CoFeed and FileStream are showing as CoStream
|
||||
- Updated dependencies [2c3761c]
|
||||
- Updated dependencies [2b94bc8]
|
||||
- Updated dependencies [2957362]
|
||||
- jazz-inspector@0.11.7
|
||||
- cojson@0.11.7
|
||||
- cojson-transport-ws@0.11.7
|
||||
|
||||
## 0.0.115
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "jazz-inspector-app",
|
||||
"private": true,
|
||||
"version": "0.0.115",
|
||||
"version": "0.0.118",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
@@ -13,8 +13,8 @@
|
||||
"dependencies": {
|
||||
"jazz-inspector": "workspace:*",
|
||||
"clsx": "^2.0.0",
|
||||
"cojson": "workspace:0.11.6",
|
||||
"cojson-transport-ws": "workspace:0.11.6",
|
||||
"cojson": "workspace:0.12.0",
|
||||
"cojson-transport-ws": "workspace:0.12.0",
|
||||
"hash-slash": "workspace:0.2.2",
|
||||
"lucide-react": "^0.274.0",
|
||||
"react": "^18.3.1",
|
||||
|
||||
@@ -17,9 +17,9 @@ import {
|
||||
PageStack,
|
||||
Select,
|
||||
} from "jazz-inspector";
|
||||
import { resolveCoValue, useResolvedCoValue } from "jazz-inspector";
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { usePagePath } from "./use-page-path";
|
||||
import { resolveCoValue, useResolvedCoValue } from "./use-resolve-covalue";
|
||||
|
||||
interface Account {
|
||||
id: CoID<RawAccount>;
|
||||
|
||||
@@ -1,216 +0,0 @@
|
||||
import { CoID, LocalNode, RawBinaryCoStream, RawCoValue } from "cojson";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
export type CoJsonType = "comap" | "costream" | "colist";
|
||||
export type ExtendedCoJsonType = "image" | "record" | "account" | "group";
|
||||
|
||||
type JSON = string | number | boolean | null | JSON[] | { [key: string]: JSON };
|
||||
type JSONObject = { [key: string]: JSON };
|
||||
|
||||
type ResolvedImageDefinition = {
|
||||
originalSize: [number, number];
|
||||
placeholderDataURL?: string;
|
||||
[res: `${number}x${number}`]: RawBinaryCoStream["id"];
|
||||
};
|
||||
|
||||
// Type guard for browser image
|
||||
export const isBrowserImage = (
|
||||
coValue: JSONObject,
|
||||
): coValue is ResolvedImageDefinition => {
|
||||
return "originalSize" in coValue && "placeholderDataURL" in coValue;
|
||||
};
|
||||
|
||||
export type ResolvedGroup = {
|
||||
readKey: string;
|
||||
[key: string]: JSON;
|
||||
};
|
||||
|
||||
export const isGroup = (coValue: JSONObject): coValue is ResolvedGroup => {
|
||||
return "readKey" in coValue;
|
||||
};
|
||||
|
||||
export type ResolvedAccount = {
|
||||
profile: {
|
||||
name: string;
|
||||
};
|
||||
[key: string]: JSON;
|
||||
};
|
||||
|
||||
export const isAccount = (coValue: JSONObject): coValue is ResolvedAccount => {
|
||||
return isGroup(coValue) && "profile" in coValue;
|
||||
};
|
||||
|
||||
export async function resolveCoValue(
|
||||
coValueId: CoID<RawCoValue>,
|
||||
node: LocalNode,
|
||||
): Promise<
|
||||
| {
|
||||
value: RawCoValue;
|
||||
snapshot: JSONObject;
|
||||
type: CoJsonType | null;
|
||||
extendedType: ExtendedCoJsonType | undefined;
|
||||
}
|
||||
| {
|
||||
value: undefined;
|
||||
snapshot: "unavailable";
|
||||
type: null;
|
||||
extendedType: undefined;
|
||||
}
|
||||
> {
|
||||
const value = await node.load(coValueId);
|
||||
|
||||
if (value === "unavailable") {
|
||||
return {
|
||||
value: undefined,
|
||||
snapshot: "unavailable",
|
||||
type: null,
|
||||
extendedType: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
const snapshot = value.toJSON() as JSONObject;
|
||||
const type = value.type as CoJsonType;
|
||||
|
||||
// Determine extended type
|
||||
let extendedType: ExtendedCoJsonType | undefined;
|
||||
|
||||
if (type === "comap") {
|
||||
if (isBrowserImage(snapshot)) {
|
||||
extendedType = "image";
|
||||
} else if (isAccount(snapshot)) {
|
||||
extendedType = "account";
|
||||
} else if (isGroup(snapshot)) {
|
||||
extendedType = "group";
|
||||
} else {
|
||||
// This check is a bit of a hack
|
||||
// There might be a better way to do this
|
||||
const children = Object.values(snapshot).slice(0, 10);
|
||||
if (
|
||||
children.every((c) => typeof c === "string" && c.startsWith("co_")) &&
|
||||
children.length > 3
|
||||
) {
|
||||
extendedType = "record";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
value,
|
||||
snapshot,
|
||||
type,
|
||||
extendedType,
|
||||
};
|
||||
}
|
||||
|
||||
function subscribeToCoValue(
|
||||
coValueId: CoID<RawCoValue>,
|
||||
node: LocalNode,
|
||||
callback: (result: Awaited<ReturnType<typeof resolveCoValue>>) => void,
|
||||
) {
|
||||
return node.subscribe(coValueId, (value) => {
|
||||
if (value === "unavailable") {
|
||||
callback({
|
||||
value: undefined,
|
||||
snapshot: "unavailable",
|
||||
type: null,
|
||||
extendedType: undefined,
|
||||
});
|
||||
} else {
|
||||
const snapshot = value.toJSON() as JSONObject;
|
||||
const type = value.type as CoJsonType;
|
||||
let extendedType: ExtendedCoJsonType | undefined;
|
||||
|
||||
if (type === "comap") {
|
||||
if (isBrowserImage(snapshot)) {
|
||||
extendedType = "image";
|
||||
} else if (isAccount(snapshot)) {
|
||||
extendedType = "account";
|
||||
} else if (isGroup(snapshot)) {
|
||||
extendedType = "group";
|
||||
} else {
|
||||
const children = Object.values(snapshot).slice(0, 10);
|
||||
if (
|
||||
children.every(
|
||||
(c) => typeof c === "string" && c.startsWith("co_"),
|
||||
) &&
|
||||
children.length > 3
|
||||
) {
|
||||
extendedType = "record";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
callback({
|
||||
value,
|
||||
snapshot,
|
||||
type,
|
||||
extendedType,
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export function useResolvedCoValue(
|
||||
coValueId: CoID<RawCoValue>,
|
||||
node: LocalNode,
|
||||
) {
|
||||
const [result, setResult] =
|
||||
useState<Awaited<ReturnType<typeof resolveCoValue>>>();
|
||||
|
||||
useEffect(() => {
|
||||
let isMounted = true;
|
||||
const unsubscribe = subscribeToCoValue(coValueId, node, (newResult) => {
|
||||
if (isMounted) {
|
||||
setResult(newResult);
|
||||
}
|
||||
});
|
||||
|
||||
return () => {
|
||||
isMounted = false;
|
||||
unsubscribe();
|
||||
};
|
||||
}, [coValueId, node]);
|
||||
|
||||
return (
|
||||
result || {
|
||||
value: undefined,
|
||||
snapshot: undefined,
|
||||
type: undefined,
|
||||
extendedType: undefined,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export function useResolvedCoValues(
|
||||
coValueIds: CoID<RawCoValue>[],
|
||||
node: LocalNode,
|
||||
) {
|
||||
const [results, setResults] = useState<
|
||||
Awaited<ReturnType<typeof resolveCoValue>>[]
|
||||
>([]);
|
||||
|
||||
useEffect(() => {
|
||||
let isMounted = true;
|
||||
const unsubscribes: (() => void)[] = [];
|
||||
|
||||
coValueIds.forEach((coValueId, index) => {
|
||||
const unsubscribe = subscribeToCoValue(coValueId, node, (newResult) => {
|
||||
if (isMounted) {
|
||||
setResults((prevResults) => {
|
||||
const newResults = [...prevResults];
|
||||
newResults[index] = newResult;
|
||||
return newResults;
|
||||
});
|
||||
}
|
||||
});
|
||||
unsubscribes.push(unsubscribe);
|
||||
});
|
||||
|
||||
return () => {
|
||||
isMounted = false;
|
||||
unsubscribes.forEach((unsubscribe) => unsubscribe());
|
||||
};
|
||||
}, [coValueIds, node]);
|
||||
|
||||
return results;
|
||||
}
|
||||
29
examples/multi-cursors/CHANGELOG.md
Normal file
29
examples/multi-cursors/CHANGELOG.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# multi-cursors
|
||||
|
||||
## 0.0.61
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [01523dc]
|
||||
- Updated dependencies [4ea87dc]
|
||||
- Updated dependencies [1e6da19]
|
||||
- Updated dependencies [b6c6a0a]
|
||||
- jazz-tools@0.12.0
|
||||
- jazz-react@0.12.0
|
||||
|
||||
## 0.0.60
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react@0.11.8
|
||||
- jazz-tools@0.11.8
|
||||
|
||||
## 0.0.59
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [a140f55]
|
||||
- Updated dependencies [4019918]
|
||||
- Updated dependencies [2b0d1b0]
|
||||
- jazz-tools@0.11.7
|
||||
- jazz-react@0.11.7
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "multi-cursors",
|
||||
"private": true,
|
||||
"version": "0.0.58",
|
||||
"version": "0.0.61",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
||||
@@ -7,7 +7,7 @@ import Canvas from "./Canvas";
|
||||
/** A higher order component that wraps the canvas. */
|
||||
function Container({ cursorFeedID }: { cursorFeedID: ID<CursorFeed> }) {
|
||||
const { me } = useAccount();
|
||||
const cursors = useCoState(CursorFeed, cursorFeedID, []);
|
||||
const cursors = useCoState(CursorFeed, cursorFeedID, { resolve: true });
|
||||
|
||||
return (
|
||||
<Canvas
|
||||
|
||||
@@ -3,7 +3,7 @@ import { CursorContainer, CursorFeed } from "../schema";
|
||||
|
||||
export async function loadGroup(me: Account, groupID: ID<Group>) {
|
||||
const group = await Group.load(groupID, {});
|
||||
if (group === undefined) {
|
||||
if (group === null) {
|
||||
const group = Group.create({
|
||||
owner: me,
|
||||
});
|
||||
@@ -35,15 +35,16 @@ export async function loadCursorContainer(
|
||||
group?.id as ID<Group>,
|
||||
);
|
||||
const cursorContainer = await CursorContainer.load(cursorContainerID, {
|
||||
cursorFeed: [],
|
||||
resolve: {
|
||||
cursorFeed: true,
|
||||
},
|
||||
});
|
||||
if (cursorContainer === undefined) {
|
||||
|
||||
if (cursorContainer === null) {
|
||||
console.log("Global cursors does not exist, creating...");
|
||||
const cursorContainer = CursorContainer.create(
|
||||
{
|
||||
cursorFeed: CursorFeed.create([], {
|
||||
owner: group,
|
||||
}),
|
||||
cursorFeed: CursorFeed.create([], group),
|
||||
},
|
||||
{
|
||||
owner: group,
|
||||
|
||||
@@ -1,5 +1,36 @@
|
||||
# multiauth
|
||||
|
||||
## 0.0.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [01523dc]
|
||||
- Updated dependencies [4ea87dc]
|
||||
- Updated dependencies [1e6da19]
|
||||
- Updated dependencies [b6c6a0a]
|
||||
- jazz-tools@0.12.0
|
||||
- jazz-react@0.12.0
|
||||
- jazz-react-auth-clerk@0.12.0
|
||||
|
||||
## 0.0.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react@0.11.8
|
||||
- jazz-react-auth-clerk@0.11.8
|
||||
- jazz-tools@0.11.8
|
||||
|
||||
## 0.0.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [a140f55]
|
||||
- Updated dependencies [4019918]
|
||||
- Updated dependencies [2b0d1b0]
|
||||
- jazz-tools@0.11.7
|
||||
- jazz-react@0.11.7
|
||||
- jazz-react-auth-clerk@0.11.7
|
||||
|
||||
## 0.0.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "multiauth",
|
||||
"private": true,
|
||||
"version": "0.0.5",
|
||||
"version": "0.0.8",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
||||
@@ -1,5 +1,39 @@
|
||||
# jazz-example-musicplayer
|
||||
|
||||
## 0.0.89
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [01523dc]
|
||||
- Updated dependencies [4ea87dc]
|
||||
- Updated dependencies [1e6da19]
|
||||
- Updated dependencies [b6c6a0a]
|
||||
- Updated dependencies [9a56bb3]
|
||||
- jazz-tools@0.12.0
|
||||
- jazz-inspector@0.12.0
|
||||
- jazz-react@0.12.0
|
||||
|
||||
## 0.0.88
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [71b9390]
|
||||
- jazz-inspector@0.11.8
|
||||
- jazz-react@0.11.8
|
||||
- jazz-tools@0.11.8
|
||||
|
||||
## 0.0.87
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [2c3761c]
|
||||
- Updated dependencies [a140f55]
|
||||
- Updated dependencies [4019918]
|
||||
- Updated dependencies [2b0d1b0]
|
||||
- jazz-inspector@0.11.7
|
||||
- jazz-tools@0.11.7
|
||||
- jazz-react@0.11.7
|
||||
|
||||
## 0.0.86
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "jazz-example-music-player",
|
||||
"private": true,
|
||||
"version": "0.0.86",
|
||||
"version": "0.0.89",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
@@ -22,8 +22,8 @@
|
||||
"class-variance-authority": "^0.7.0",
|
||||
"clsx": "^2.0.0",
|
||||
"jazz-inspector": "workspace:*",
|
||||
"jazz-react": "workspace:0.11.6",
|
||||
"jazz-tools": "workspace:0.11.6",
|
||||
"jazz-react": "workspace:0.12.0",
|
||||
"jazz-tools": "workspace:0.12.0",
|
||||
"lucide-react": "^0.274.0",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
|
||||
@@ -24,10 +24,7 @@ export function HomePage({ mediaPlayer }: { mediaPlayer: MediaPlayer }) {
|
||||
* access rights to CoValues. We get it from the top-level provider `<WithJazz/>`.
|
||||
*/
|
||||
const { me } = useAccount({
|
||||
root: {
|
||||
rootPlaylist: {},
|
||||
playlists: [],
|
||||
},
|
||||
resolve: { root: { rootPlaylist: true, playlists: true } },
|
||||
});
|
||||
|
||||
const navigate = useNavigate();
|
||||
@@ -51,8 +48,9 @@ export function HomePage({ mediaPlayer }: { mediaPlayer: MediaPlayer }) {
|
||||
|
||||
const params = useParams<{ playlistId: ID<Playlist> }>();
|
||||
const playlistId = params.playlistId ?? me?.root._refs.rootPlaylist.id;
|
||||
|
||||
const playlist = useCoState(Playlist, playlistId, {
|
||||
tracks: [],
|
||||
resolve: { tracks: true },
|
||||
});
|
||||
|
||||
const isRootPlaylist = !params.playlistId;
|
||||
|
||||
@@ -27,9 +27,11 @@ export async function uploadMusicTracks(
|
||||
isExampleTrack: boolean = false,
|
||||
) {
|
||||
const { root } = await MusicaAccount.getMe().ensureLoaded({
|
||||
root: {
|
||||
rootPlaylist: {
|
||||
tracks: [],
|
||||
resolve: {
|
||||
root: {
|
||||
rootPlaylist: {
|
||||
tracks: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -65,8 +67,10 @@ export async function uploadMusicTracks(
|
||||
|
||||
export async function createNewPlaylist() {
|
||||
const { root } = await MusicaAccount.getMe().ensureLoaded({
|
||||
root: {
|
||||
playlists: [],
|
||||
resolve: {
|
||||
root: {
|
||||
playlists: true,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@@ -149,9 +153,11 @@ export async function updateMusicTrackTitle(track: MusicTrack, title: string) {
|
||||
|
||||
export async function updateActivePlaylist(playlist?: Playlist) {
|
||||
const { root } = await MusicaAccount.getMe().ensureLoaded({
|
||||
root: {
|
||||
activePlaylist: {},
|
||||
rootPlaylist: {},
|
||||
resolve: {
|
||||
root: {
|
||||
activePlaylist: true,
|
||||
rootPlaylist: true,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@@ -160,7 +166,9 @@ export async function updateActivePlaylist(playlist?: Playlist) {
|
||||
|
||||
export async function updateActiveTrack(track: MusicTrack) {
|
||||
const { root } = await MusicaAccount.getMe().ensureLoaded({
|
||||
root: {},
|
||||
resolve: {
|
||||
root: {},
|
||||
},
|
||||
});
|
||||
|
||||
root.activeTrack = track;
|
||||
@@ -170,17 +178,23 @@ export async function onAnonymousAccountDiscarded(
|
||||
anonymousAccount: MusicaAccount,
|
||||
) {
|
||||
const { root: anonymousAccountRoot } = await anonymousAccount.ensureLoaded({
|
||||
root: {
|
||||
rootPlaylist: {
|
||||
tracks: [{}],
|
||||
resolve: {
|
||||
root: {
|
||||
rootPlaylist: {
|
||||
tracks: {
|
||||
$each: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const me = await MusicaAccount.getMe().ensureLoaded({
|
||||
root: {
|
||||
rootPlaylist: {
|
||||
tracks: [],
|
||||
resolve: {
|
||||
root: {
|
||||
rootPlaylist: {
|
||||
tracks: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -197,8 +211,10 @@ export async function onAnonymousAccountDiscarded(
|
||||
|
||||
export async function deletePlaylist(playlistId: string) {
|
||||
const { root } = await MusicaAccount.getMe().ensureLoaded({
|
||||
root: {
|
||||
playlists: [],
|
||||
resolve: {
|
||||
root: {
|
||||
playlists: true,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ import { getNextTrack, getPrevTrack } from "./lib/getters";
|
||||
|
||||
export function useMediaPlayer() {
|
||||
const { me } = useAccount({
|
||||
root: {},
|
||||
resolve: { root: true },
|
||||
});
|
||||
|
||||
const playState = usePlayState();
|
||||
|
||||
@@ -16,8 +16,10 @@ export function InvitePage() {
|
||||
const playlist = await Playlist.load(playlistId, {});
|
||||
|
||||
const me = await MusicaAccount.getMe().ensureLoaded({
|
||||
root: {
|
||||
playlists: [],
|
||||
resolve: {
|
||||
root: {
|
||||
playlists: true,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -22,9 +22,13 @@ export function AuthModal({ open, onOpenChange }: AuthModalProps) {
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
const { me } = useAccount({
|
||||
root: {
|
||||
rootPlaylist: {
|
||||
tracks: [{}],
|
||||
resolve: {
|
||||
root: {
|
||||
rootPlaylist: {
|
||||
tracks: {
|
||||
$each: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@@ -30,9 +30,7 @@ export function MusicTrackRow({
|
||||
const track = useCoState(MusicTrack, trackId);
|
||||
|
||||
const { me } = useAccount({
|
||||
root: {
|
||||
playlists: [{}],
|
||||
},
|
||||
resolve: { root: { playlists: { $each: true } } },
|
||||
});
|
||||
|
||||
const playlists = me?.root.playlists ?? [];
|
||||
|
||||
@@ -12,9 +12,7 @@ export function PlayerControls({ mediaPlayer }: { mediaPlayer: MediaPlayer }) {
|
||||
const isPlaying = playState.value === "play";
|
||||
|
||||
const activePlaylist = useAccount({
|
||||
root: {
|
||||
activePlaylist: {},
|
||||
},
|
||||
resolve: { root: { activePlaylist: true } },
|
||||
}).me?.root.activePlaylist;
|
||||
|
||||
useMediaEndListener(mediaPlayer.playNextTrack);
|
||||
@@ -25,7 +23,7 @@ export function PlayerControls({ mediaPlayer }: { mediaPlayer: MediaPlayer }) {
|
||||
});
|
||||
|
||||
const activeTrack = useCoState(MusicTrack, mediaPlayer.activeTrackId, {
|
||||
waveform: {},
|
||||
resolve: { waveform: true },
|
||||
});
|
||||
|
||||
if (!activeTrack) return null;
|
||||
|
||||
@@ -8,9 +8,7 @@ export function SidePanel() {
|
||||
const { playlistId } = useParams();
|
||||
const navigate = useNavigate();
|
||||
const { me } = useAccount({
|
||||
root: {
|
||||
playlists: [{}],
|
||||
},
|
||||
resolve: { root: { playlists: { $each: true } } },
|
||||
});
|
||||
|
||||
function handleAllTracksClick(evt: React.MouseEvent<HTMLAnchorElement>) {
|
||||
|
||||
@@ -8,7 +8,6 @@ export function Waveform(props: { track: MusicTrack; height: number }) {
|
||||
const waveformData = useCoState(
|
||||
MusicTrackWaveform,
|
||||
track._refs.waveform.id,
|
||||
{},
|
||||
)?.data;
|
||||
const duration = track.duration;
|
||||
|
||||
|
||||
@@ -2,9 +2,11 @@ import { MusicaAccount } from "../1_schema";
|
||||
|
||||
export async function getNextTrack() {
|
||||
const me = await MusicaAccount.getMe().ensureLoaded({
|
||||
root: {
|
||||
activePlaylist: {
|
||||
tracks: [],
|
||||
resolve: {
|
||||
root: {
|
||||
activePlaylist: {
|
||||
tracks: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -21,9 +23,11 @@ export async function getNextTrack() {
|
||||
|
||||
export async function getPrevTrack() {
|
||||
const me = await MusicaAccount.getMe().ensureLoaded({
|
||||
root: {
|
||||
activePlaylist: {
|
||||
tracks: [],
|
||||
resolve: {
|
||||
root: {
|
||||
activePlaylist: {
|
||||
tracks: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@@ -13,7 +13,7 @@ export function useUploadExampleData() {
|
||||
|
||||
async function uploadOnboardingData() {
|
||||
const me = await MusicaAccount.getMe().ensureLoaded({
|
||||
root: {},
|
||||
resolve: { root: true },
|
||||
});
|
||||
|
||||
if (me.root.exampleDataLoaded) return;
|
||||
|
||||
@@ -1,5 +1,33 @@
|
||||
# organization
|
||||
|
||||
## 0.0.61
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [01523dc]
|
||||
- Updated dependencies [4ea87dc]
|
||||
- Updated dependencies [1e6da19]
|
||||
- Updated dependencies [b6c6a0a]
|
||||
- jazz-tools@0.12.0
|
||||
- jazz-react@0.12.0
|
||||
|
||||
## 0.0.60
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react@0.11.8
|
||||
- jazz-tools@0.11.8
|
||||
|
||||
## 0.0.59
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [a140f55]
|
||||
- Updated dependencies [4019918]
|
||||
- Updated dependencies [2b0d1b0]
|
||||
- jazz-tools@0.11.7
|
||||
- jazz-react@0.11.7
|
||||
|
||||
## 0.0.58
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "organization",
|
||||
"private": true,
|
||||
"version": "0.0.58",
|
||||
"version": "0.0.61",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
||||
@@ -5,11 +5,11 @@ import { Organization } from "./schema.ts";
|
||||
|
||||
export function AcceptInvitePage() {
|
||||
const navigate = useNavigate();
|
||||
const { me } = useAccount({ root: { organizations: [] } });
|
||||
const { me } = useAccount({ resolve: { root: { organizations: true } } });
|
||||
|
||||
const onAccept = (organizationId: ID<Organization>) => {
|
||||
if (me?.root?.organizations) {
|
||||
Organization.load(organizationId, me, []).then((organization) => {
|
||||
Organization.load(organizationId).then((organization) => {
|
||||
if (organization) {
|
||||
// avoid duplicates
|
||||
const ids = me.root.organizations.map(
|
||||
|
||||
@@ -5,7 +5,7 @@ import { Heading } from "./components/Heading.tsx";
|
||||
|
||||
export function HomePage() {
|
||||
const { me } = useAccount({
|
||||
root: { organizations: [{}] },
|
||||
resolve: { root: { organizations: true } },
|
||||
});
|
||||
|
||||
if (!me?.root.organizations) return;
|
||||
|
||||
@@ -3,7 +3,7 @@ import { UserIcon } from "lucide-react";
|
||||
|
||||
export function Layout({ children }: { children: React.ReactNode }) {
|
||||
const { me, logOut } = useAccount({
|
||||
root: { draftOrganization: {} },
|
||||
resolve: { root: { draftOrganization: true } },
|
||||
});
|
||||
|
||||
return (
|
||||
|
||||
@@ -13,7 +13,7 @@ export function OrganizationPage() {
|
||||
.organizationId;
|
||||
|
||||
const organization = useCoState(Organization, paramOrganizationId, {
|
||||
projects: [],
|
||||
resolve: { projects: true },
|
||||
});
|
||||
|
||||
if (!organization) return <p>Loading organization...</p>;
|
||||
|
||||
@@ -8,7 +8,7 @@ import { OrganizationForm } from "./OrganizationForm.tsx";
|
||||
|
||||
export function CreateOrganization() {
|
||||
const { me } = useAccount({
|
||||
root: { draftOrganization: {}, organizations: [] },
|
||||
resolve: { root: { draftOrganization: true, organizations: true } },
|
||||
});
|
||||
const [errors, setErrors] = useState<string[]>([]);
|
||||
const navigate = useNavigate();
|
||||
|
||||
@@ -7,7 +7,7 @@ import { Organization } from "../schema.ts";
|
||||
|
||||
export function OrganizationSelector({ className }: { className?: string }) {
|
||||
const { me } = useAccount({
|
||||
root: { organizations: [{}] },
|
||||
resolve: { root: { organizations: { $each: true } } },
|
||||
});
|
||||
|
||||
const navigate = useNavigate();
|
||||
|
||||
@@ -1,5 +1,23 @@
|
||||
# passkey-svelte
|
||||
|
||||
## 0.0.55
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-svelte@0.12.0
|
||||
|
||||
## 0.0.54
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-svelte@0.11.8
|
||||
|
||||
## 0.0.53
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-svelte@0.11.7
|
||||
|
||||
## 0.0.52
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "passkey-svelte",
|
||||
"version": "0.0.52",
|
||||
"version": "0.0.55",
|
||||
"type": "module",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
|
||||
@@ -1,5 +1,33 @@
|
||||
# minimal-auth-passkey
|
||||
|
||||
## 0.0.66
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [01523dc]
|
||||
- Updated dependencies [4ea87dc]
|
||||
- Updated dependencies [1e6da19]
|
||||
- Updated dependencies [b6c6a0a]
|
||||
- jazz-tools@0.12.0
|
||||
- jazz-react@0.12.0
|
||||
|
||||
## 0.0.65
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react@0.11.8
|
||||
- jazz-tools@0.11.8
|
||||
|
||||
## 0.0.64
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [a140f55]
|
||||
- Updated dependencies [4019918]
|
||||
- Updated dependencies [2b0d1b0]
|
||||
- jazz-tools@0.11.7
|
||||
- jazz-react@0.11.7
|
||||
|
||||
## 0.0.63
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "passkey",
|
||||
"private": true,
|
||||
"version": "0.0.63",
|
||||
"version": "0.0.66",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
||||
@@ -1,5 +1,33 @@
|
||||
# passphrase
|
||||
|
||||
## 0.0.63
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [01523dc]
|
||||
- Updated dependencies [4ea87dc]
|
||||
- Updated dependencies [1e6da19]
|
||||
- Updated dependencies [b6c6a0a]
|
||||
- jazz-tools@0.12.0
|
||||
- jazz-react@0.12.0
|
||||
|
||||
## 0.0.62
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react@0.11.8
|
||||
- jazz-tools@0.11.8
|
||||
|
||||
## 0.0.61
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [a140f55]
|
||||
- Updated dependencies [4019918]
|
||||
- Updated dependencies [2b0d1b0]
|
||||
- jazz-tools@0.11.7
|
||||
- jazz-react@0.11.7
|
||||
|
||||
## 0.0.60
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "passphrase",
|
||||
"private": true,
|
||||
"version": "0.0.60",
|
||||
"version": "0.0.63",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
||||
@@ -1,5 +1,33 @@
|
||||
# jazz-password-manager
|
||||
|
||||
## 0.0.87
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [01523dc]
|
||||
- Updated dependencies [4ea87dc]
|
||||
- Updated dependencies [1e6da19]
|
||||
- Updated dependencies [b6c6a0a]
|
||||
- jazz-tools@0.12.0
|
||||
- jazz-react@0.12.0
|
||||
|
||||
## 0.0.86
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react@0.11.8
|
||||
- jazz-tools@0.11.8
|
||||
|
||||
## 0.0.85
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [a140f55]
|
||||
- Updated dependencies [4019918]
|
||||
- Updated dependencies [2b0d1b0]
|
||||
- jazz-tools@0.11.7
|
||||
- jazz-react@0.11.7
|
||||
|
||||
## 0.0.84
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "jazz-password-manager",
|
||||
"private": true,
|
||||
"version": "0.0.84",
|
||||
"version": "0.0.87",
|
||||
"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.11.6",
|
||||
"jazz-tools": "workspace:0.11.6",
|
||||
"jazz-react": "workspace:0.12.0",
|
||||
"jazz-tools": "workspace:0.12.0",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-hook-form": "^7.41.5",
|
||||
|
||||
@@ -43,9 +43,11 @@ const VaultPage: React.FC = () => {
|
||||
(item): item is Exclude<typeof item, null> => !!item,
|
||||
) || [],
|
||||
);
|
||||
const folders = useCoState(FolderList, me.root?._refs.folders?.id, [
|
||||
{ items: [{}] },
|
||||
]);
|
||||
const folders = useCoState(FolderList, me.root?._refs.folders?.id, {
|
||||
resolve: {
|
||||
$each: { items: { $each: true } },
|
||||
},
|
||||
});
|
||||
|
||||
const [selectedFolder, setSelectedFolder] = useState<Folder | undefined>();
|
||||
const [isNewItemModalOpen, setIsNewItemModalOpen] = useState(false);
|
||||
|
||||
@@ -60,11 +60,9 @@ export async function addSharedFolder(
|
||||
me: PasswordManagerAccount,
|
||||
) {
|
||||
const [sharedFolder, account] = await Promise.all([
|
||||
Folder.load(sharedFolderId, me, {}),
|
||||
PasswordManagerAccount.load(me.id, me, {
|
||||
root: {
|
||||
folders: [],
|
||||
},
|
||||
Folder.load(sharedFolderId),
|
||||
PasswordManagerAccount.load(me.id, {
|
||||
resolve: { root: { folders: true } },
|
||||
}),
|
||||
]);
|
||||
|
||||
|
||||
@@ -1,5 +1,33 @@
|
||||
# jazz-example-pets
|
||||
|
||||
## 0.0.185
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [01523dc]
|
||||
- Updated dependencies [4ea87dc]
|
||||
- Updated dependencies [1e6da19]
|
||||
- Updated dependencies [b6c6a0a]
|
||||
- jazz-tools@0.12.0
|
||||
- jazz-react@0.12.0
|
||||
|
||||
## 0.0.184
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react@0.11.8
|
||||
- jazz-tools@0.11.8
|
||||
|
||||
## 0.0.183
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [a140f55]
|
||||
- Updated dependencies [4019918]
|
||||
- Updated dependencies [2b0d1b0]
|
||||
- jazz-tools@0.11.7
|
||||
- jazz-react@0.11.7
|
||||
|
||||
## 0.0.182
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "jazz-example-pets",
|
||||
"private": true,
|
||||
"version": "0.0.182",
|
||||
"version": "0.0.185",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
@@ -19,8 +19,8 @@
|
||||
"@radix-ui/react-toast": "^1.1.4",
|
||||
"class-variance-authority": "^0.7.0",
|
||||
"clsx": "^2.0.0",
|
||||
"jazz-react": "workspace:0.11.6",
|
||||
"jazz-tools": "workspace:0.11.6",
|
||||
"jazz-react": "workspace:0.12.0",
|
||||
"jazz-tools": "workspace:0.12.0",
|
||||
"lucide-react": "^0.274.0",
|
||||
"qrcode": "^1.5.3",
|
||||
"react": "^18.3.1",
|
||||
@@ -40,7 +40,7 @@
|
||||
"@vitejs/plugin-react-swc": "^3.3.2",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"is-ci": "^3.0.1",
|
||||
"jazz-run": "workspace:0.11.6",
|
||||
"jazz-run": "workspace:0.12.0",
|
||||
"postcss": "^8.4.27",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"typescript": "~5.6.2",
|
||||
|
||||
@@ -1,5 +1,33 @@
|
||||
# reactions
|
||||
|
||||
## 0.0.65
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [01523dc]
|
||||
- Updated dependencies [4ea87dc]
|
||||
- Updated dependencies [1e6da19]
|
||||
- Updated dependencies [b6c6a0a]
|
||||
- jazz-tools@0.12.0
|
||||
- jazz-react@0.12.0
|
||||
|
||||
## 0.0.64
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react@0.11.8
|
||||
- jazz-tools@0.11.8
|
||||
|
||||
## 0.0.63
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [a140f55]
|
||||
- Updated dependencies [4019918]
|
||||
- Updated dependencies [2b0d1b0]
|
||||
- jazz-tools@0.11.7
|
||||
- jazz-react@0.11.7
|
||||
|
||||
## 0.0.62
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "reactions",
|
||||
"private": true,
|
||||
"version": "0.0.62",
|
||||
"version": "0.0.65",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
||||
@@ -14,7 +14,7 @@ const reactionEmojiMap: {
|
||||
};
|
||||
|
||||
export function ReactionsScreen(props: { id: ID<Reactions> }) {
|
||||
const reactions = useCoState(Reactions, props.id, []);
|
||||
const reactions = useCoState(Reactions, props.id);
|
||||
|
||||
if (!reactions) return;
|
||||
|
||||
|
||||
@@ -1,5 +1,36 @@
|
||||
# todo-vue
|
||||
|
||||
## 0.0.69
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [01523dc]
|
||||
- Updated dependencies [4ea87dc]
|
||||
- Updated dependencies [1e6da19]
|
||||
- Updated dependencies [b6c6a0a]
|
||||
- Updated dependencies [4c01459]
|
||||
- jazz-tools@0.12.0
|
||||
- jazz-vue@0.12.0
|
||||
- jazz-browser@0.12.0
|
||||
|
||||
## 0.0.68
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-browser@0.11.8
|
||||
- jazz-tools@0.11.8
|
||||
- jazz-vue@0.11.8
|
||||
|
||||
## 0.0.67
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [a140f55]
|
||||
- Updated dependencies [2b0d1b0]
|
||||
- jazz-tools@0.11.7
|
||||
- jazz-browser@0.11.7
|
||||
- jazz-vue@0.11.7
|
||||
|
||||
## 0.0.66
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "todo-vue",
|
||||
"version": "0.0.66",
|
||||
"version": "0.0.69",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
|
||||
@@ -4,15 +4,15 @@
|
||||
<div class="section-header">
|
||||
<h2>Folders</h2>
|
||||
<div class="new-folder">
|
||||
<input
|
||||
v-model="newFolderName"
|
||||
placeholder="New folder name"
|
||||
<input
|
||||
v-model="newFolderName"
|
||||
placeholder="New folder name"
|
||||
class="input"
|
||||
/>
|
||||
<button class="btn btn-primary" @click="createFolder">Create</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="folder-list">
|
||||
<div
|
||||
v-for="folder in folders"
|
||||
@@ -32,9 +32,9 @@
|
||||
<div class="section-header">
|
||||
<h2>{{ selectedFolder?.name }}</h2>
|
||||
<div class="new-todo">
|
||||
<input
|
||||
v-model="newTodoTitle"
|
||||
placeholder="Add a new task"
|
||||
<input
|
||||
v-model="newTodoTitle"
|
||||
placeholder="Add a new task"
|
||||
class="input"
|
||||
/>
|
||||
<button class="btn btn-primary" @click="createTodo">Add</button>
|
||||
@@ -72,7 +72,9 @@ import { Folder, FolderList, ToDoItem, ToDoList } from "../schema";
|
||||
const { me } = useAccount();
|
||||
|
||||
const computedFoldersId = computed(() => me.value?.root?.folders?.id);
|
||||
const folders = useCoState(FolderList, computedFoldersId, [{ items: [{}] }]);
|
||||
const folders = useCoState(FolderList, computedFoldersId, {
|
||||
resolve: { $each: { items: true } },
|
||||
});
|
||||
|
||||
const selectedFolder = ref<Folder>();
|
||||
const newFolderName = ref("");
|
||||
|
||||
@@ -1,5 +1,33 @@
|
||||
# jazz-example-todo
|
||||
|
||||
## 0.0.184
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [01523dc]
|
||||
- Updated dependencies [4ea87dc]
|
||||
- Updated dependencies [1e6da19]
|
||||
- Updated dependencies [b6c6a0a]
|
||||
- jazz-tools@0.12.0
|
||||
- jazz-react@0.12.0
|
||||
|
||||
## 0.0.183
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react@0.11.8
|
||||
- jazz-tools@0.11.8
|
||||
|
||||
## 0.0.182
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [a140f55]
|
||||
- Updated dependencies [4019918]
|
||||
- Updated dependencies [2b0d1b0]
|
||||
- jazz-tools@0.11.7
|
||||
- jazz-react@0.11.7
|
||||
|
||||
## 0.0.181
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "jazz-example-todo",
|
||||
"private": true,
|
||||
"version": "0.0.181",
|
||||
"version": "0.0.184",
|
||||
"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.11.6",
|
||||
"jazz-tools": "workspace:0.11.6",
|
||||
"jazz-react": "workspace:0.12.0",
|
||||
"jazz-tools": "workspace:0.12.0",
|
||||
"lucide-react": "^0.274.0",
|
||||
"qrcode": "^1.5.3",
|
||||
"react": "^18.3.1",
|
||||
|
||||
@@ -121,7 +121,7 @@ export default function App() {
|
||||
|
||||
function HomeScreen() {
|
||||
const { me } = useAccount({
|
||||
root: { projects: [{}] },
|
||||
resolve: { root: { projects: { $each: true } } },
|
||||
});
|
||||
const navigate = useNavigate();
|
||||
|
||||
|
||||
@@ -1,5 +1,39 @@
|
||||
# version-history
|
||||
|
||||
## 0.0.62
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [01523dc]
|
||||
- Updated dependencies [4ea87dc]
|
||||
- Updated dependencies [1e6da19]
|
||||
- Updated dependencies [b6c6a0a]
|
||||
- Updated dependencies [9a56bb3]
|
||||
- jazz-tools@0.12.0
|
||||
- jazz-inspector@0.12.0
|
||||
- jazz-react@0.12.0
|
||||
|
||||
## 0.0.61
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [71b9390]
|
||||
- jazz-inspector@0.11.8
|
||||
- jazz-react@0.11.8
|
||||
- jazz-tools@0.11.8
|
||||
|
||||
## 0.0.60
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [2c3761c]
|
||||
- Updated dependencies [a140f55]
|
||||
- Updated dependencies [4019918]
|
||||
- Updated dependencies [2b0d1b0]
|
||||
- jazz-inspector@0.11.7
|
||||
- jazz-tools@0.11.7
|
||||
- jazz-react@0.11.7
|
||||
|
||||
## 0.0.59
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "version-history",
|
||||
"private": true,
|
||||
"version": "0.0.59",
|
||||
"version": "0.0.62",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
||||
@@ -4,7 +4,9 @@ import { ID } from "jazz-tools";
|
||||
import { IssueComponent } from "./Issue.tsx";
|
||||
import { Issue, Project } from "./schema.ts";
|
||||
export function ProjectComponent({ projectID }: { projectID: ID<Project> }) {
|
||||
const project = useCoState(Project, projectID, { issues: [{}] });
|
||||
const project = useCoState(Project, projectID, {
|
||||
resolve: { issues: { $each: true } },
|
||||
});
|
||||
|
||||
if (!project) return;
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ import { clsx } from "clsx";
|
||||
import Link from "next/link";
|
||||
import { forwardRef } from "react";
|
||||
import { Icon } from "./Icon";
|
||||
import type { IconName } from "./Icon";
|
||||
import { Spinner } from "./Spinner";
|
||||
|
||||
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
||||
@@ -9,7 +10,7 @@ interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
||||
size?: "sm" | "md" | "lg";
|
||||
href?: string;
|
||||
newTab?: boolean;
|
||||
icon?: string;
|
||||
icon?: IconName;
|
||||
loading?: boolean;
|
||||
loadingText?: string;
|
||||
children?: React.ReactNode;
|
||||
|
||||
@@ -113,6 +113,8 @@ const strokeWidths = {
|
||||
"9xl": 1,
|
||||
};
|
||||
|
||||
export type IconName = keyof typeof icons;
|
||||
|
||||
export function Icon({
|
||||
name,
|
||||
icon,
|
||||
@@ -120,7 +122,7 @@ export function Icon({
|
||||
className,
|
||||
...svgProps
|
||||
}: {
|
||||
name?: string;
|
||||
name?: IconName;
|
||||
icon?: LucideIcon;
|
||||
size?: keyof typeof sizes;
|
||||
className?: string;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import clsx from "clsx";
|
||||
import { Card } from "../atoms/Card";
|
||||
import { Icon } from "../atoms/Icon";
|
||||
import { Icon, IconName } from "../atoms/Icon";
|
||||
import { Prose } from "./Prose";
|
||||
|
||||
export function FeatureCard({
|
||||
@@ -11,7 +11,7 @@ export function FeatureCard({
|
||||
className,
|
||||
}: {
|
||||
label: React.ReactNode;
|
||||
icon?: string;
|
||||
icon?: IconName;
|
||||
explanation?: React.ReactNode;
|
||||
children?: React.ReactNode;
|
||||
className?: string;
|
||||
|
||||
@@ -13,12 +13,13 @@ import { usePathname } from "next/navigation";
|
||||
import { ComponentType, ReactNode, useEffect, useState } from "react";
|
||||
import { isActive } from "../../utils/nav";
|
||||
import { Icon } from "../atoms/Icon";
|
||||
import type { IconName } from "../atoms/Icon";
|
||||
import { BreadCrumb } from "../molecules/Breadcrumb";
|
||||
import { SocialLinks, SocialLinksProps } from "./SocialLinks";
|
||||
|
||||
type NavItemProps = {
|
||||
href: string;
|
||||
icon?: string;
|
||||
icon?: IconName;
|
||||
title: string;
|
||||
firstOnRight?: boolean;
|
||||
newTab?: boolean;
|
||||
@@ -38,7 +39,7 @@ type NavProps = {
|
||||
export type NavSection = {
|
||||
name: string;
|
||||
content: ReactNode;
|
||||
icon: string;
|
||||
icon: IconName;
|
||||
};
|
||||
|
||||
function NavItem({
|
||||
@@ -134,7 +135,11 @@ export function MobileNav({
|
||||
sections,
|
||||
themeToggle: ThemeToggle,
|
||||
}: NavProps) {
|
||||
const primarySection = {
|
||||
const primarySection: {
|
||||
name: string;
|
||||
icon: IconName;
|
||||
content: ReactNode;
|
||||
} = {
|
||||
name: "Menu",
|
||||
icon: "menu",
|
||||
content: (
|
||||
@@ -254,7 +259,7 @@ export function MobileNav({
|
||||
onClick={() => toggle(section.name)}
|
||||
key={section.name}
|
||||
>
|
||||
<Icon name={section.icon} size="xs" />
|
||||
{section.icon && <Icon name={section.icon} size="xs" />}
|
||||
{section.name}
|
||||
</button>
|
||||
),
|
||||
|
||||
@@ -49,7 +49,7 @@ function highlightPlugin() {
|
||||
token.content.includes("// old"),
|
||||
);
|
||||
const isBinnedLine = line.some((token) =>
|
||||
token.content.includes("// *bin*"),
|
||||
token.content.includes("// [!code --]"),
|
||||
);
|
||||
const isHighlighted = line.some((token) =>
|
||||
token.content.includes("// *highlight*"),
|
||||
@@ -70,7 +70,7 @@ function highlightPlugin() {
|
||||
line
|
||||
.map((token) => {
|
||||
let color = isHighlighted ? "currentColor" : token.color;
|
||||
return `<span style="color: ${color};${isSubduedLine ? "opacity: 0.4;" : ""}">${escape(token.content.replace("// old", "").replace("// *bin*", "").replace("// *highlight*", ""))}</span>`;
|
||||
return `<span style="color: ${color};${isSubduedLine ? "opacity: 0.4;" : ""}">${escape(token.content.replace("// old", "").replace("// [!code --]", "").replace("// *highlight*", ""))}</span>`;
|
||||
})
|
||||
.join("") +
|
||||
"</span>"
|
||||
|
||||
@@ -331,7 +331,7 @@ This works because CoValues
|
||||
|
||||
<CodeGroup>
|
||||
```ts
|
||||
const unsub = issue.subscribe([], (updatedIssue) => console.log(updatedIssue));
|
||||
const unsub = issue.subscribe({ resolve: true }, (updatedIssue) => console.log(updatedIssue));
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
@@ -339,7 +339,7 @@ This works because CoValues
|
||||
|
||||
<CodeGroup>
|
||||
```ts
|
||||
const unsub = Issue.subscribe(issueID, me, [], (updatedIssue) => {
|
||||
const unsub = Issue.subscribe(issueID, me, { resolve: true }, (updatedIssue) => {
|
||||
console.log(updatedIssue);
|
||||
});
|
||||
```
|
||||
@@ -358,7 +358,7 @@ This works because CoValues
|
||||
function useCoState<V extends CoValue>(Schema: CoValueClass<V>, id?: ID<V>): V | undefined {
|
||||
const [value, setValue] = useState<V>();
|
||||
|
||||
useEffect(() => Schema.subscribe(id, [], setValue), [id]);
|
||||
useEffect(() => Schema.subscribe(id, { resolve: true }, setValue), [id]);
|
||||
|
||||
return value;
|
||||
}
|
||||
@@ -454,7 +454,7 @@ function App() { // old
|
||||
const issue = useCoState(Issue, issueID); // old
|
||||
// old
|
||||
const createIssue = () => { // old
|
||||
const group = Group.create({ owner: me });
|
||||
const group = Group.create();
|
||||
group.addMember("everyone", "writer");
|
||||
// old
|
||||
const newIssue = Issue.create( // old
|
||||
@@ -543,7 +543,7 @@ function App() { // old
|
||||
(window.location.search?.replace("?project=", "") || undefined) as ID<Project> | undefined
|
||||
);
|
||||
// old
|
||||
const issue = useCoState(Issue, issueID); // *bin*
|
||||
const issue = useCoState(Issue, issueID); // [!code --]
|
||||
// old
|
||||
const createProject = () => {
|
||||
const group = Group.create();
|
||||
@@ -605,6 +605,8 @@ export function ProjectComponent({ projectID }: { projectID: ID<Project> }) {
|
||||
<button onClick={createAndAddIssue}>Create Issue</button>
|
||||
</div>
|
||||
</div>
|
||||
) : project === null ? (
|
||||
<div>Project not found or access denied</div>
|
||||
) : (
|
||||
<div>Loading project...</div>
|
||||
);
|
||||
@@ -620,7 +622,7 @@ Two things to note here:
|
||||
- We only need to use `useCoState` on the Project, and the nested `ListOfIssues` and each `Issue` will be **automatically loaded and subscribed to when we access them.**
|
||||
- However, because either the `Project`, `ListOfIssues`, or each `Issue` might not be loaded yet, we have to check for them being defined.
|
||||
|
||||
### Precise loading depths
|
||||
### Precise resolve queries
|
||||
|
||||
The load-and-subscribe-on-access is a convenient way to have your rendering drive data loading (including in nested components!) and lets you quickly chuck UIs together without worrying too much about the shape of all data you'll need.
|
||||
|
||||
@@ -635,7 +637,7 @@ import { IssueComponent } from "./Issue.tsx"; // old
|
||||
import { useCoState } from "jazz-react"; // old
|
||||
// old
|
||||
export function ProjectComponent({ projectID }: { projectID: ID<Project> }) {// old
|
||||
const project = useCoState(Project, projectID, { issues: [{}] });
|
||||
const project = useCoState(Project, projectID, { resolve: { issues: { $each: true } } });
|
||||
|
||||
const createAndAddIssue = () => {// old
|
||||
project?.issues.push(Issue.create({
|
||||
@@ -663,7 +665,7 @@ export function ProjectComponent({ projectID }: { projectID: ID<Project> }) {//
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
The loading-depth spec `{ issues: [{}] }` means "in `Project`, load `issues` and load each item in `issues` shallowly". (Since an `Issue` doesn't have any further references, "shallowly" actually means all its properties will be available).
|
||||
The resolve query `{ resolve: { issues: { $each: true } } }` means "in `Project`, load `issues` and load each item in `issues` deeply". (Since an `Issue` doesn't have any further references, "deeply" actually means all its properties will be available).
|
||||
|
||||
- Now, we can get rid of a lot of conditional accesses because we know that once `project` is loaded, `project.issues` and each `Issue` in it will be loaded as well.
|
||||
- This also results in only one rerender and visual update when everything is loaded, which is faster (especially for long lists) and gives you more control over the loading UX.
|
||||
@@ -710,7 +712,7 @@ function App() { // old
|
||||
// old
|
||||
const createProject = () => { // old
|
||||
const group = Group.create(); // old
|
||||
group.addMember("everyone", "writer"); // *bin*
|
||||
group.addMember("everyone", "writer"); // [!code --]
|
||||
// old
|
||||
const newProject = Project.create( // old
|
||||
{ // old
|
||||
@@ -747,7 +749,7 @@ import { createInviteLink } from "jazz-react";
|
||||
// old
|
||||
|
||||
export function ProjectComponent({ projectID }: { projectID: ID<Project> }) {// old
|
||||
const project = useCoState(Project, projectID, { issues: [{}] }); // old
|
||||
const project = useCoState(Project, projectID, { resolve: { issues: { $each: true } } }); // old
|
||||
|
||||
const { me } = useAccount();
|
||||
|
||||
|
||||
@@ -112,7 +112,7 @@ declare module "jazz-react" {// old
|
||||
## Resolving CoValues starting at `profile` or `root`
|
||||
|
||||
<ContentByFramework framework="react">
|
||||
To use per-user data in your app, you typically use `useAccount` somewhere in a high-level component, specifying which references to resolve using a depth-spec (see [Subscribing & deep loading](/docs/using-covalues/subscription-and-loading)).
|
||||
To use per-user data in your app, you typically use `useAccount` somewhere in a high-level component, specifying which references to resolve using a resolve query (see [Subscribing & deep loading](/docs/using-covalues/subscription-and-loading)).
|
||||
|
||||
<CodeGroup>
|
||||
{/* prettier-ignore */}
|
||||
@@ -163,12 +163,12 @@ export class MyAppAccount extends Account {
|
||||
profile = co.ref(MyAppProfile);
|
||||
|
||||
async migrate(this: MyAppAccount, creationProps?: { name: string }) {
|
||||
// we specifically need to check for undefined,
|
||||
// we specifically need to check for undefined,
|
||||
// because the root might simply be not loaded (`null`) yet
|
||||
if (this.root === undefined) {
|
||||
this.root = MyAppRoot.create({
|
||||
// Using a group to set the owner is always a good idea.
|
||||
// This way if in the future we want to share
|
||||
// This way if in the future we want to share
|
||||
// this coValue we can do so easily.
|
||||
myChats: ListOfChats.create([], Group.create()),
|
||||
myContacts: ListOfAccounts.create([], Group.create())
|
||||
@@ -218,8 +218,8 @@ export class MyAppAccount extends Account {
|
||||
root: {},
|
||||
});
|
||||
|
||||
// we specifically need to check for undefined,
|
||||
// because myBookmarks might simply be not loaded (`null`) yet
|
||||
// we specifically need to check for undefined,
|
||||
// because myBookmarks might simply be not loaded (`null`) yet
|
||||
if (root.myBookmarks === undefined) {
|
||||
root.myBookmarks = ListOfBookmarks.create([], Group.create());
|
||||
}
|
||||
@@ -228,9 +228,9 @@ export class MyAppAccount extends Account {
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
{/*
|
||||
TODO: Add best practice: only ever add fields
|
||||
{/*
|
||||
TODO: Add best practice: only ever add fields
|
||||
|
||||
Note: explain and reassure that there will be more guardrails in the future
|
||||
Note: explain and reassure that there will be more guardrails in the future
|
||||
https://github.com/garden-co/jazz/issues/1160
|
||||
*/}
|
||||
|
||||
@@ -29,9 +29,9 @@ Here is what's changed in this release:
|
||||
{/* prettier-ignore */}
|
||||
```tsx
|
||||
<JazzProvider
|
||||
auth={authMethod} // removed // *bin*
|
||||
peer="wss://cloud.jazz.tools/?key=you@example.com" // moved into sync // *bin*
|
||||
sync={{ peer: "wss://cloud.jazz.tools/?key=you@example.com" }} // *add*
|
||||
auth={authMethod} // removed // [!code --]
|
||||
peer="wss://cloud.jazz.tools/?key=you@example.com" // moved into sync // [!code --]
|
||||
sync={{ peer: "wss://cloud.jazz.tools/?key=you@example.com" }} // [!code ++]
|
||||
>
|
||||
<App />
|
||||
</JazzProvider>
|
||||
|
||||
@@ -0,0 +1,299 @@
|
||||
import { CodeGroup } from '@/components/forMdx'
|
||||
|
||||
export const metadata = { title: "Jazz 0.12.0 - Deeply resolved data" };
|
||||
|
||||
# Jazz 0.12.0 - Deeply resolved data
|
||||
|
||||
Jazz 0.12.0 makes it easier and safer to load nested data. You can now specify exactly which nested data you want to load, and Jazz will check permissions and handle missing data gracefully. This helps catch errors earlier during development and makes your code more reliable.
|
||||
|
||||
## What's new?
|
||||
|
||||
- New resolve API for a more type-safe deep loading
|
||||
- A single, consistent load option for all loading methods
|
||||
- Improved permission checks on deep loading
|
||||
- Easier type safety with the `Resolved` type helper
|
||||
|
||||
## Breaking changes
|
||||
|
||||
### New Resolve API
|
||||
|
||||
We're introducing a new resolve API for deep loading, more friendly to TypeScript, IDE autocompletion and LLMs.
|
||||
|
||||
**Major changes:**
|
||||
|
||||
1. Functions and hooks for loading now take the resolve query as an explicit nested `resolve` prop
|
||||
2. Shallowly loading a collection is now done with `true` instead of `[]` or `{}`
|
||||
|
||||
<CodeGroup>
|
||||
```tsx twoslash
|
||||
// @noErrors: 2451
|
||||
import { CoMap, CoList, co, Account } from "jazz-tools";
|
||||
import { useAccount } from "jazz-react";
|
||||
class AccountRoot extends CoMap { friends = co.ref(ListOfAccounts); }
|
||||
class ListOfAccounts extends CoList.Of(co.ref(Account)) {}
|
||||
class MyAppAccount extends Account { root = co.ref(AccountRoot);}
|
||||
declare module "jazz-react" { interface Register { Account: MyAppAccount; } }
|
||||
// ---cut-before---
|
||||
// Before
|
||||
// @ts-expect-error
|
||||
const { me } = useAccount({ root: { friends: [] } }); // [!code --]
|
||||
|
||||
// After
|
||||
const { me } = useAccount({ // [!code ++]
|
||||
resolve: { root: { friends: true } } // [!code ++]
|
||||
}); // [!code ++]
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
3. For collections, resolving items deeply is now done with a special `$each` key.
|
||||
|
||||
For a `CoList`:
|
||||
|
||||
<CodeGroup>
|
||||
```tsx twoslash
|
||||
// @noErrors: 2451
|
||||
import { CoList, co, ID, CoMap } from "jazz-tools";
|
||||
import { useCoState } from "jazz-react";
|
||||
|
||||
// ---cut-before---
|
||||
class Task extends CoMap { }
|
||||
class ListOfTasks extends CoList.Of(co.ref(Task)) {}
|
||||
|
||||
const id = "co_123" as ID<Task>;
|
||||
|
||||
// Before
|
||||
// @ts-expect-error
|
||||
const tasks = useCoState(ListOfTasks, id, [{}]); // [!code --]
|
||||
|
||||
// After
|
||||
const tasks = useCoState(ListOfTasks, id, { resolve: { $each: true } }); // [!code ++]
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
For a `CoMap.Record`:
|
||||
|
||||
<CodeGroup>
|
||||
```tsx twoslash
|
||||
// @noErrors: 2451
|
||||
import { CoMap, co, Account, ID } from "jazz-tools";
|
||||
import { useCoState } from "jazz-react";
|
||||
class MyAppAccount extends Account {}
|
||||
const id = "co_123" as ID<UsersByUsername>;
|
||||
|
||||
// ---cut-before---
|
||||
class UsersByUsername extends CoMap.Record(co.ref(MyAppAccount)) {}
|
||||
|
||||
// Before
|
||||
// @ts-expect-error
|
||||
const usersByUsername = useCoState(UsersByUsername, id, [{}]); // [!code --]
|
||||
|
||||
// After
|
||||
const usersByUsername = useCoState(UsersByUsername, id, { // [!code ++]
|
||||
resolve: { $each: true } // [!code ++]
|
||||
}); // [!code ++]
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
Nested loading — note how it's now less terse, but more readable:
|
||||
|
||||
<CodeGroup>
|
||||
```tsx twoslash
|
||||
// @noErrors: 2451
|
||||
import { CoList, CoMap, co, Account, ID } from "jazz-tools";
|
||||
import { useCoState } from "jazz-react";
|
||||
|
||||
const id = "co_123" as ID<ListOfTasks>;
|
||||
|
||||
// ---cut-before---
|
||||
class Org extends CoMap {
|
||||
name = co.string;
|
||||
}
|
||||
|
||||
class Assignee extends CoMap {
|
||||
name = co.string;
|
||||
org = co.ref(Org);
|
||||
}
|
||||
class ListOfAssignees extends CoList.Of(co.ref(Assignee)) {}
|
||||
|
||||
class Task extends CoMap {
|
||||
content = co.string;
|
||||
assignees = co.ref(ListOfAssignees);
|
||||
}
|
||||
class ListOfTasks extends CoList.Of(co.ref(Task)) {}
|
||||
|
||||
// Before
|
||||
// @ts-expect-error
|
||||
const tasksWithAssigneesAndTheirOrgs = useCoState(ListOfTasks, id, [{ // [!code --]
|
||||
assignees: [{ org: {}}]} // [!code --]
|
||||
]); // [!code --]
|
||||
|
||||
// After
|
||||
const tasksWithAssigneesAndTheirOrgs = useCoState(ListOfTasks, id, { // [!code ++]
|
||||
resolve: { // [!code ++]
|
||||
$each: { // [!code ++]
|
||||
assignees: { // [!code ++]
|
||||
$each: { org: true } // [!code ++]
|
||||
} // [!code ++]
|
||||
} // [!code ++]
|
||||
} // [!code ++]
|
||||
}); // [!code ++]
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
It's also a lot more auto-complete friendly:
|
||||
|
||||
<CodeGroup>
|
||||
```tsx twoslash
|
||||
// @noErrors: 2451 2353 2581
|
||||
import { CoList, CoMap, co, ID } from "jazz-tools";
|
||||
import { useCoState } from "jazz-react";
|
||||
|
||||
class Org extends CoMap { name = co.string; }
|
||||
class Assignee extends CoMap { org = co.ref(Org); }
|
||||
class ListOfAssignees extends CoList.Of(co.ref(Assignee)) {}
|
||||
class Task extends CoMap { assignees = co.ref(ListOfAssignees); }
|
||||
class ListOfTasks extends CoList.Of(co.ref(Task)) {}
|
||||
const id = "co_123" as ID<ListOfTasks>;
|
||||
|
||||
// ---cut-before---
|
||||
const tasksWithAssigneesAndTheirOrgs = useCoState(ListOfTasks, id, {
|
||||
resolve: {
|
||||
$each: {
|
||||
assignees: {
|
||||
$
|
||||
// ^|
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
### A single, consistent load option
|
||||
|
||||
The new API works across all loading methods, and separating out the resolve query means
|
||||
other options with default values are easier to manage, for example: loading a value as a specific account instead of using the implicit current account:
|
||||
|
||||
<CodeGroup>
|
||||
```ts twoslash
|
||||
// @noErrors: 2451
|
||||
import { co, Account, CoMap, CoList, ID } from "jazz-tools";
|
||||
|
||||
class Track extends CoMap {}
|
||||
class ListOfTracks extends CoList.Of(co.ref(Track)) {}
|
||||
class Playlist extends CoMap { tracks = co.ref(ListOfTracks); }
|
||||
const id = "co_123" as ID<Playlist>;
|
||||
const otherAccount = {} as Account;
|
||||
|
||||
// ---cut-before---
|
||||
// Before
|
||||
// @ts-expect-error
|
||||
Playlist.load(id, otherAccount, { // [!code --]
|
||||
tracks: [], // [!code --]
|
||||
}); // [!code --]
|
||||
|
||||
// After
|
||||
Playlist.load(id, { // [!code ++]
|
||||
loadAs: otherAccount, // [!code ++]
|
||||
resolve: { tracks: true } // [!code ++]
|
||||
}); // [!code ++]
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
### Improved permission checks on deep loading
|
||||
|
||||
Now `useCoState` will return `null` when the current user lacks permissions to load requested data.
|
||||
|
||||
Previously, `useCoState` would return `undefined` if the current user lacked permissions, making it hard to tell if the value is loading or if it's missing.
|
||||
|
||||
Now `undefined` means that the value is definitely loading, and `null` means that the value is temporarily missing.
|
||||
|
||||
We also have implemented a more granular permission checking, where if an *optional* CoValue cannot be accessed, `useCoState` will return the data stripped of that CoValue.
|
||||
|
||||
**Note:** The state handling around loading and error states will become more detailed and easy-to-handle in future releases, so this is just a small step towards consistency.
|
||||
|
||||
<CodeGroup>
|
||||
{/* prettier-ignore */}
|
||||
```tsx twoslash
|
||||
// @noErrors: 2451
|
||||
import React from "react";
|
||||
import { CoList, CoMap, co, ID } from "jazz-tools";
|
||||
import { useCoState } from "jazz-react";
|
||||
class Track extends CoMap {}
|
||||
function TrackComponent({ track }: { track: Track }) {return ""}
|
||||
|
||||
// ---cut-before---
|
||||
class ListOfTracks extends CoList.Of(co.optional.ref(Track)) {}
|
||||
|
||||
function TrackListComponent({ id }: { id: ID<ListOfTracks> }) {
|
||||
// Before (ambiguous states)
|
||||
// @ts-expect-error
|
||||
const tracks = useCoState(ListOfTracks, id, [{}]); // [!code --]
|
||||
if (tracks === undefined) return <div>Loading or access denied</div>; // [!code --]
|
||||
if (tracks === null) return <div>Not found</div>; // [!code --]
|
||||
|
||||
// After
|
||||
const tracks = useCoState(ListOfTracks, id, { resolve: { $each: true } }); // [!code ++]
|
||||
if (tracks === undefined) return <div>Loading...</div>; // [!code ++]
|
||||
if (tracks === null) return <div>Not found or access denied</div>; // [!code ++]
|
||||
|
||||
// This will only show tracks that we have access to and that are loaded.
|
||||
return tracks.map(track => track && <TrackComponent track={track} />);
|
||||
}
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
The same change is applied to the load function, so now it returns `null` instead of `undefined` when the value is missing.
|
||||
|
||||
<CodeGroup>
|
||||
```tsx twoslash
|
||||
// @noErrors: 2451
|
||||
import { CoMap, co, ID } from "jazz-tools";
|
||||
import { useAccount } from "jazz-react";
|
||||
|
||||
class MyCoMap extends CoMap {}
|
||||
const id = "co_123" as ID<MyCoMap>;
|
||||
|
||||
// ---cut-before---
|
||||
// Before
|
||||
// @ts-expect-error
|
||||
const map = await MyCoMap.load(id);
|
||||
if (map === undefined) {
|
||||
throw new Error("Map not found");
|
||||
}
|
||||
|
||||
// After
|
||||
const map = await MyCoMap.load(id);
|
||||
if (map === null) {
|
||||
throw new Error("Map not found or access denied");
|
||||
}
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
## New Features
|
||||
|
||||
### The `Resolved` type helper
|
||||
|
||||
The new `Resolved` type can be used to define what kind of deeply loaded data you expect in your parameters, using the same resolve query syntax as the new loading APIs:
|
||||
|
||||
<CodeGroup>
|
||||
```tsx twoslash
|
||||
// @noErrors: 2451
|
||||
import React from "react";
|
||||
import { Resolved, CoMap, CoList, co } from "jazz-tools";
|
||||
class Track extends CoMap {}
|
||||
class ListOfTracks extends CoList.Of(co.ref(Track)) {}
|
||||
class Playlist extends CoMap { tracks = co.ref(ListOfTracks); }
|
||||
function TrackComponent({ track }: { track: Track }) {return ""}
|
||||
|
||||
// ---cut-before---
|
||||
type PlaylistResolved = Resolved<Playlist, {
|
||||
tracks: { $each: true }
|
||||
}>;
|
||||
|
||||
function TrackListComponent({ playlist }: { playlist: PlaylistResolved }) {
|
||||
// Safe access to resolved tracks
|
||||
return playlist.tracks.map(track => <TrackComponent track={track} />);
|
||||
}
|
||||
```
|
||||
</CodeGroup>
|
||||
@@ -25,9 +25,9 @@ So we decided to remove `createJazzRNApp` step and to provide the types through
|
||||
import { JazzProvider, useDemoAuth, DemoAuthBasicUI } from "jazz-react-native";
|
||||
import { MyAppAccount } from "./schema";
|
||||
|
||||
// Remove these lines // *bin*
|
||||
const Jazz = createJazzRNApp({ AccountSchema: MyAppAccount }); // *bin*
|
||||
export const { useAccount, useCoState } = Jazz; // *bin*
|
||||
// Remove these lines // [!code --]
|
||||
const Jazz = createJazzRNApp({ AccountSchema: MyAppAccount }); // [!code --]
|
||||
export const { useAccount, useCoState } = Jazz; // [!code --]
|
||||
|
||||
export function JazzAndAuth({ children }: { children: React.ReactNode }) { // old
|
||||
const [auth, state] = useDemoAuth(); // old
|
||||
@@ -66,8 +66,8 @@ This change improves IDE intellisense support and simplifies imports:
|
||||
{/* prettier-ignore */}
|
||||
```tsx
|
||||
// Replace local imports with "jazz-react-native" imports
|
||||
import { useAccount } from "./main"; // *bin*
|
||||
import { useAccount } from "jazz-react-native"; // *add*
|
||||
import { useAccount } from "./main"; // [!code --]
|
||||
import { useAccount } from "jazz-react-native"; // [!code ++]
|
||||
|
||||
export function Hello() {
|
||||
const { me } = useAccount();
|
||||
|
||||
@@ -24,9 +24,9 @@ So we decided to remove `createJazzReactApp` step and to provide the types throu
|
||||
import { JazzProvider, usePasskeyAuth, PasskeyAuthBasicUI } from "jazz-react";
|
||||
import { MyAppAccount } from "./schema";
|
||||
|
||||
// Remove these lines // *bin*
|
||||
const Jazz = createJazzReactApp({ AccountSchema: MyAppAccount }); // *bin*
|
||||
export const { useAccount, useCoState } = Jazz; // *bin*
|
||||
// Remove these lines // [!code --]
|
||||
const Jazz = createJazzReactApp({ AccountSchema: MyAppAccount }); // [!code --]
|
||||
export const { useAccount, useCoState } = Jazz; // [!code --]
|
||||
|
||||
export function JazzAndAuth({ children }: { children: React.ReactNode }) { // old
|
||||
const [passkeyAuth, passKeyState] = usePasskeyAuth({ appName }); // old
|
||||
@@ -37,7 +37,7 @@ So we decided to remove `createJazzReactApp` step and to provide the types throu
|
||||
<JazzProvider
|
||||
auth={passkeyAuth} // old
|
||||
peer="wss://cloud.jazz.tools/?key=you@example.com" // old
|
||||
AccountSchema={MyAppAccount} {/* The custom Account schema is passed here */} // *add*
|
||||
AccountSchema={MyAppAccount} {/* The custom Account schema is passed here */} // [!code ++]
|
||||
>
|
||||
{children} // old
|
||||
</JazzProvider>
|
||||
@@ -47,11 +47,11 @@ So we decided to remove `createJazzReactApp` step and to provide the types throu
|
||||
}
|
||||
|
||||
// Register the Account schema so `useAccount` returns our custom `MyAppAccount`
|
||||
declare module "jazz-react" { // *add*
|
||||
interface Register { // *add*
|
||||
Account: MyAppAccount; // *add*
|
||||
} // *add*
|
||||
} // *add*
|
||||
declare module "jazz-react" { // [!code ++]
|
||||
interface Register { // [!code ++]
|
||||
Account: MyAppAccount; // [!code ++]
|
||||
} // [!code ++]
|
||||
} // [!code ++]
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
@@ -65,8 +65,8 @@ This change improves IDE intellisense support and simplifies imports:
|
||||
{/* prettier-ignore */}
|
||||
```tsx
|
||||
// Replace local imports with "jazz-react" imports
|
||||
import { useAccount } from "./main"; // *bin*
|
||||
import { useAccount } from "jazz-react"; // *add*
|
||||
import { useAccount } from "./main"; // [!code --]
|
||||
import { useAccount } from "jazz-react"; // [!code ++]
|
||||
|
||||
export function Hello() {
|
||||
const { me } = useAccount();
|
||||
|
||||
@@ -32,7 +32,7 @@ So we decided to remove `createJazzApp` step and to provide the types through na
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import { Provider } from '$lib/jazz'; // *bin*
|
||||
import { Provider } from '$lib/jazz'; // [!code --]
|
||||
import { JazzProvider } from 'jazz-svelte';
|
||||
|
||||
// Example configuration for authentication and peer connection
|
||||
@@ -62,8 +62,8 @@ So we decided to remove `createJazzApp` step and to provide the types through na
|
||||
```svelte
|
||||
|
||||
<script lang="ts">
|
||||
import { useAccount } from '$lib/jazz'; // *bin*
|
||||
import { useAccount } from 'jazz-svelte'; // *add*
|
||||
import { useAccount } from '$lib/jazz'; // [!code --]
|
||||
import { useAccount } from 'jazz-svelte'; // [!code ++]
|
||||
|
||||
const { me } = useAccount();
|
||||
</script>
|
||||
|
||||
@@ -28,10 +28,10 @@ import App from "./App.vue"; // old
|
||||
import router from "./router"; // old
|
||||
import { ToDoAccount } from "./schema"; // old
|
||||
|
||||
// Remove these lines // *bin*
|
||||
const Jazz = createJazzVueApp<ToDoAccount>({ AccountSchema: ToDoAccount }); // *bin*
|
||||
export const { useAccount, useCoState } = Jazz; // *bin*
|
||||
const { JazzProvider } = Jazz; // *bin*
|
||||
// Remove these lines // [!code --]
|
||||
const Jazz = createJazzVueApp<ToDoAccount>({ AccountSchema: ToDoAccount }); // [!code --]
|
||||
export const { useAccount, useCoState } = Jazz; // [!code --]
|
||||
const { JazzProvider } = Jazz; // [!code --]
|
||||
|
||||
const RootComponent = defineComponent({ // old
|
||||
name: "RootComponent", // old
|
||||
@@ -86,8 +86,8 @@ This change improves IDE intellisense support and simplifies imports:
|
||||
|
||||
<script setup lang="ts">
|
||||
// Replace local imports with "jazz-vue" imports
|
||||
import { useAccount } from "./main"; // *bin*
|
||||
import { useAccount } from "jazz-vue"; // *add*
|
||||
import { useAccount } from "./main"; // [!code --]
|
||||
import { useAccount } from "jazz-vue"; // [!code ++]
|
||||
|
||||
const { me, logOut } = useAccount();
|
||||
</script>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user