Compare commits

...

31 Commits

Author SHA1 Message Date
Guido D'Orsi
eab128d8e8 Merge pull request #1617 from garden-co/changeset-release/main
Version Packages
2025-03-10 13:04:18 +01:00
github-actions[bot]
8793c218e7 Version Packages 2025-03-10 11:50:03 +00:00
Guido D'Orsi
57858a7cf0 Merge pull request #1624 from garden-co/better-error-logging
feat: improve error logging
2025-03-10 12:46:31 +01:00
Guido D'Orsi
68b0242793 feat: improve error logging 2025-03-10 12:40:55 +01:00
Anselm Eickhoff
9d9a067df5 Merge pull request #1621 from garden-co/fix/react-guide-optional-field
fix(react guide): update syntax for optional field
2025-03-10 10:30:11 +00:00
Trisha Lim
99779b522b fix(react guide): update syntax for optional field 2025-03-10 17:24:30 +07:00
Guido D'Orsi
80b80b5d71 Merge pull request #1610 from garden-co/changeset-release/main
Version Packages
2025-03-07 17:47:20 +01:00
Guido D'Orsi
d777b78ce4 Merge pull request #1614 from garden-co/fix/missing-apikey-ts
Move api key of react starter into apiKey.ts
2025-03-07 17:46:56 +01:00
Trisha Lim
c0a77b99bb Move api key of react starter into apiKey.ts 2025-03-07 17:47:48 +07:00
github-actions[bot]
24516116f3 Version Packages 2025-03-07 08:42:35 +00:00
Guido D'Orsi
ed0e15144c fix: reset the useCoState value when the id becomes undefined 2025-03-07 09:40:06 +01:00
Benjamin S. Leveritt
f51cf1b9ff Merge pull request #1563 from garden-co/jazz-773-add-tone-and-voice-document
jazz-773-add-tone-and-voice-document
2025-03-06 19:13:05 +00:00
Benjamin S. Leveritt
31beb0a3b4 Removes key takeaways 2025-03-06 19:11:15 +00:00
Benjamin S. Leveritt
d1b2c50801 Replaces teammate > friend 2025-03-06 19:11:15 +00:00
Benjamin S. Leveritt
0261fb5031 Adds note about docs 2025-03-06 19:10:54 +00:00
Benjamin S. Leveritt
e421af1147 Adds a tone and voice doc 2025-03-06 19:10:54 +00:00
Benjamin S. Leveritt
05df8e3b61 Merge pull request #1609 from garden-co/1606-port-applydiff-to-colist-from-corichtext
Adds `applyDiff` to `CoList`
2025-03-06 19:09:45 +00:00
Benjamin S. Leveritt
6892dc6a87 Adds changeset 2025-03-06 19:08:37 +00:00
Benjamin S. Leveritt
84badaa18b Adds applyDiff to CoList
Closes #1606
2025-03-06 17:49:50 +00:00
Trisha Lim
23059ec701 change copy icon 2025-03-06 21:06:13 +07:00
Trisha Lim
52a2533b9e cleanup 2025-03-06 21:06:13 +07:00
Trisha Lim
5df7aaf742 mobile view 2025-03-06 21:06:13 +07:00
Trisha Lim
1a818f88b2 add create-jazz-app command to hero 2025-03-06 21:06:13 +07:00
Guido D'Orsi
2e12ec55ac Merge pull request #1551 from garden-co/example-counter
feat(examples): multi-auth example
2025-03-06 14:35:28 +01:00
Guido D'Orsi
6c94c2cd3d Merge pull request #1605 from garden-co/changeset-release/main
Version Packages
2025-03-06 13:54:08 +01:00
github-actions[bot]
98c4221340 Version Packages 2025-03-06 12:46:19 +00:00
Guido D'Orsi
7b00a8155f fix: align packages versions to 0.11 2025-03-06 13:44:06 +01:00
Emil Sayahi
c563c3675f fix(multiauth): update lockfile 2025-03-03 13:09:39 -05:00
Emil Sayahi
05372df4be Merge branch 'main' into example-counter 2025-03-03 13:03:33 -05:00
Emil Sayahi
c32c405bfd feat(examples): empty multi-auth example 2025-03-03 13:00:27 -05:00
Emil Sayahi
e7ae6d95ba feat(examples): multi-auth counter example 2025-02-28 14:55:45 -05:00
134 changed files with 3924 additions and 203 deletions

View File

@@ -9,12 +9,15 @@
"cojson-storage",
"cojson-storage-indexeddb",
"cojson-storage-sqlite",
"cojson-storage-rn-sqlite",
"cojson-transport-ws",
"jazz-browser",
"jazz-auth-clerk",
"jazz-browser-media-images",
"jazz-inspector",
"jazz-nodejs",
"jazz-react",
"jazz-react-core",
"jazz-react-auth-clerk",
"jazz-react-native",
"jazz-react-native-auth-clerk",

View File

@@ -1,5 +1,31 @@
# chat-rn-clerk
## 1.0.84
### Patch Changes
- jazz-react-native@0.11.3
- jazz-react-native-auth-clerk@0.11.3
- jazz-tools@0.11.3
- jazz-react-native-media-images@0.11.3
## 1.0.83
### Patch Changes
- Updated dependencies [6892dc6]
- jazz-tools@0.11.2
- jazz-react-native@0.11.2
- jazz-react-native-auth-clerk@0.11.2
- jazz-react-native-media-images@0.11.2
## 1.0.82
### Patch Changes
- jazz-react-native@0.11.1
- jazz-react-native-auth-clerk@0.11.1
## 1.0.81
### Patch Changes

View File

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

View File

@@ -1,5 +1,26 @@
# chat-rn
## 1.0.80
### Patch Changes
- jazz-react-native@0.11.3
- jazz-tools@0.11.3
## 1.0.79
### Patch Changes
- Updated dependencies [6892dc6]
- jazz-tools@0.11.2
- jazz-react-native@0.11.2
## 1.0.78
### Patch Changes
- jazz-react-native@0.11.1
## 1.0.77
### Patch Changes

View File

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

View File

@@ -1,5 +1,22 @@
# chat-vue
## 0.0.65
### Patch Changes
- jazz-browser@0.11.3
- jazz-tools@0.11.3
- jazz-vue@0.11.3
## 0.0.64
### Patch Changes
- Updated dependencies [6892dc6]
- jazz-tools@0.11.2
- jazz-browser@0.11.2
- jazz-vue@0.11.2
## 0.0.63
### Patch Changes

View File

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

View File

@@ -1,5 +1,28 @@
# jazz-example-chat
## 0.0.162
### Patch Changes
- jazz-react@0.11.3
- jazz-tools@0.11.3
- jazz-browser-media-images@0.11.3
## 0.0.161
### Patch Changes
- Updated dependencies [6892dc6]
- jazz-tools@0.11.2
- jazz-react@0.11.2
- jazz-browser-media-images@0.11.2
## 0.0.160
### Patch Changes
- jazz-react@0.11.1
## 0.0.159
### Patch Changes

View File

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

View File

@@ -1,5 +1,29 @@
# minimal-auth-clerk
## 0.0.61
### Patch Changes
- jazz-react@0.11.3
- jazz-react-auth-clerk@0.11.3
- jazz-tools@0.11.3
## 0.0.60
### Patch Changes
- Updated dependencies [6892dc6]
- jazz-tools@0.11.2
- jazz-react@0.11.2
- jazz-react-auth-clerk@0.11.2
## 0.0.59
### Patch Changes
- jazz-react@0.11.1
- jazz-react-auth-clerk@0.11.1
## 0.0.58
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "clerk",
"private": true,
"version": "0.0.58",
"version": "0.0.61",
"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.0",
"jazz-react-auth-clerk": "workspace:0.11.3",
"jazz-tools": "workspace:*",
"react": "^18.3.1",
"react-dom": "^18.3.1"

View File

@@ -1,5 +1,20 @@
# file-share-svelte
## 0.0.45
### Patch Changes
- jazz-svelte@0.11.3
- jazz-tools@0.11.3
## 0.0.44
### Patch Changes
- Updated dependencies [6892dc6]
- jazz-tools@0.11.2
- jazz-svelte@0.11.2
## 0.0.43
### Patch Changes

View File

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

View File

@@ -1,5 +1,28 @@
# form
## 0.1.3
### Patch Changes
- jazz-react@0.11.3
- jazz-tools@0.11.3
- jazz-browser-media-images@0.11.3
## 0.1.2
### Patch Changes
- Updated dependencies [6892dc6]
- jazz-tools@0.11.2
- jazz-react@0.11.2
- jazz-browser-media-images@0.11.2
## 0.1.1
### Patch Changes
- jazz-react@0.11.1
## 0.1.0
### Minor Changes

View File

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

View File

@@ -1,5 +1,28 @@
# image-upload
## 0.0.59
### Patch Changes
- jazz-react@0.11.3
- jazz-tools@0.11.3
- jazz-browser-media-images@0.11.3
## 0.0.58
### Patch Changes
- Updated dependencies [6892dc6]
- jazz-tools@0.11.2
- jazz-react@0.11.2
- jazz-browser-media-images@0.11.2
## 0.0.57
### Patch Changes
- jazz-react@0.11.1
## 0.0.56
### Patch Changes

View File

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

View File

@@ -1,5 +1,13 @@
# jazz-example-inspector
## 0.0.112
### Patch Changes
- Updated dependencies [68b0242]
- cojson-transport-ws@0.11.3
- cojson@0.11.3
## 0.0.111
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "jazz-inspector-app",
"private": true,
"version": "0.0.111",
"version": "0.0.112",
"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.11.0",
"cojson-transport-ws": "workspace:0.11.0",
"cojson": "workspace:0.11.3",
"cojson-transport-ws": "workspace:0.11.3",
"hash-slash": "workspace:0.2.2",
"lucide-react": "^0.274.0",
"qrcode": "^1.5.3",

1
examples/multiauth/.env Normal file
View File

@@ -0,0 +1 @@
VITE_CLERK_PUBLISHABLE_KEY=pk_test_ZXZpZGVudC1kYW5lLTg5LmNsZXJrLmFjY291bnRzLmRldiQ

24
examples/multiauth/.gitignore vendored Normal file
View File

@@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

View File

@@ -0,0 +1,18 @@
# multiauth
## 0.0.2
### Patch Changes
- jazz-react@0.11.3
- jazz-react-auth-clerk@0.11.3
- jazz-tools@0.11.3
## 0.0.1
### Patch Changes
- Updated dependencies [6892dc6]
- jazz-tools@0.11.2
- jazz-react@0.11.2
- jazz-react-auth-clerk@0.11.2

View File

@@ -0,0 +1,43 @@
# Multi-auth example with Jazz and React
This example demonstrates using Jazz with multiple authentication methods; in this case, Clerk and passphrases are able to be used.
## Getting started
To run this example, you may either:
* Clone the Jazz monorepo and run this example from within.
* Create a new Jazz project using this example as a template, and run that new project.
### Using this example as a template
1. Create a new Jazz project, and use this example as a template.
```bash
npx create-jazz-app@latest --example counter --project-name counter
```
2. Navigate to the new project and start the development server.
```bash
cd counter
npm run dev
```
### Using the monorepo
This requires `pnpm` to be installed; see [https://pnpm.io/installation](https://pnpm.io/installation).
1. Clone the `jazz` repository.
```bash
git clone https://github.com/garden-co/jazz.git
```
2. Install dependencies.
```bash
cd jazz
pnpm install
```
3. Navigate to the example and start the development server.
```bash
cd examples/counter
pnpm dev
```
The example should be running at [http://localhost:5173](http://localhost:5173) by default.

View File

@@ -0,0 +1,28 @@
import js from "@eslint/js";
import reactHooks from "eslint-plugin-react-hooks";
import reactRefresh from "eslint-plugin-react-refresh";
import globals from "globals";
import tseslint from "typescript-eslint";
export default tseslint.config(
{ ignores: ["dist"] },
{
extends: [js.configs.recommended, ...tseslint.configs.recommended],
files: ["**/*.{ts,tsx}"],
languageOptions: {
ecmaVersion: 2020,
globals: globals.browser,
},
plugins: {
"react-hooks": reactHooks,
"react-refresh": reactRefresh,
},
rules: {
...reactHooks.configs.recommended.rules,
"react-refresh/only-export-components": [
"warn",
{ allowConstantExport: true },
],
},
},
);

View File

@@ -0,0 +1,12 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Jazz Multi-auth (React)</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>

View File

@@ -0,0 +1,30 @@
{
"name": "multiauth",
"private": true,
"version": "0.0.2",
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc -b && vite build",
"preview": "vite preview",
"format-and-lint": "biome check .",
"format-and-lint:fix": "biome check . --write"
},
"dependencies": {
"@clerk/clerk-react": "^5.4.1",
"jazz-react": "workspace:*",
"jazz-react-auth-clerk": "workspace:*",
"jazz-tools": "workspace:*",
"react": "^18.3.1",
"react-dom": "^18.3.1"
},
"devDependencies": {
"@biomejs/biome": "1.9.4",
"@types/react": "^18.3.12",
"@types/react-dom": "^18.3.1",
"@vitejs/plugin-react": "^4.3.3",
"globals": "^15.11.0",
"typescript": "~5.6.2",
"vite": "^6.0.11"
}
}

View File

@@ -0,0 +1,12 @@
#root {
max-width: 1280px;
margin: 0 auto;
padding: 2rem;
text-align: center;
}
.card {
padding: 2em;
display: flex;
flex-direction: column;
}

View File

@@ -0,0 +1,12 @@
import { Home } from "./components/Home.tsx";
import "./App.css";
export default function App() {
return (
<div className="card">
<h1>Jazz Multi-auth (React)</h1>
<Home />
</div>
);
}

View File

@@ -0,0 +1 @@
export const apiKey = "counter-example@garden.co";

View File

@@ -0,0 +1,26 @@
import { useAccount, useIsAuthenticated } from "jazz-react";
export function Home() {
const { me, logOut } = useAccount({ root: {} });
const isAuthenticated = useIsAuthenticated();
if (!me) return;
if (!isAuthenticated) return;
return (
<div
style={{
display: "flex",
flexDirection: "column",
alignItems: "center",
gap: "1rem",
}}
>
<div className="container">
<h1>You're logged in</h1>
<p>Welcome back, {me?.profile?.name}</p>
<button onClick={() => logOut()}>Logout</button>
</div>
</div>
);
}

View File

@@ -0,0 +1,184 @@
import { SignInButton } from "@clerk/clerk-react";
import { usePassphraseAuth } from "jazz-react";
import { JazzProviderProps, useIsAuthenticated } from "jazz-react";
import { useState } from "react";
import "../index.css";
import { useClerk } from "@clerk/clerk-react";
import { JazzProviderWithClerk } from "jazz-react-auth-clerk";
import { wordlist } from "../wordlist.ts";
export function OmniAuthContainer(props: {
appName: string;
wordlist: string[];
children?: React.ReactNode;
}) {
const isAuthenticated = useIsAuthenticated();
const passphraseAuth = usePassphraseAuth({
wordlist: props.wordlist,
});
const [step, setStep] = useState<
"initial" | "create" | "loginWithPassphrase" | "loginWithClerk"
>("initial");
const [loginPassphrase, setLoginPassphrase] = useState("");
const [isCopied, setIsCopied] = useState(false);
const [currentPassphrase, setCurrentPassphrase] = useState(() =>
passphraseAuth.generateRandomPassphrase(),
);
if (passphraseAuth.state === "signedIn" || isAuthenticated) {
return props.children ?? null;
}
const handleCreateAccount = async () => {
setStep("create");
};
const handleLoginWithPassphrase = () => {
setStep("loginWithPassphrase");
};
const handleLoginWithClerk = () => {
setStep("loginWithClerk");
};
const handleReroll = () => {
const newPassphrase = passphraseAuth.generateRandomPassphrase();
setCurrentPassphrase(newPassphrase);
setIsCopied(false);
};
const handleBack = () => {
setStep("initial");
setLoginPassphrase("");
};
const handleCopy = async () => {
await navigator.clipboard.writeText(passphraseAuth.passphrase);
setIsCopied(true);
};
const handleLoginSubmit = async () => {
await passphraseAuth.logIn(loginPassphrase);
setStep("initial");
setLoginPassphrase("");
};
const handleNext = async () => {
await passphraseAuth.registerNewAccount(currentPassphrase, "My Account");
setStep("initial");
setLoginPassphrase("");
};
return (
<div className="auth-container">
<div className="auth-card">
{step === "initial" && (
<div>
<h1 className="auth-heading">{props.appName}</h1>
<button
onClick={handleCreateAccount}
className="auth-button-primary"
>
Signup with passphrase
</button>
<button
onClick={handleLoginWithPassphrase}
className="auth-button-secondary"
>
Login with passphrase
</button>
<button
onClick={handleLoginWithClerk}
className="auth-button-secondary"
>
Login with Clerk
</button>
</div>
)}
{step === "create" && (
<>
<h1 className="auth-heading">Your Passphrase</h1>
<p className="auth-description">
Please copy and store this passphrase somewhere safe. You'll need
it to log in.
</p>
<textarea
readOnly
value={currentPassphrase}
className="auth-textarea"
rows={5}
/>
<button onClick={handleCopy} className="auth-button-primary">
{isCopied ? "Copied!" : "Copy"}
</button>
<div className="auth-button-group">
<button onClick={handleBack} className="auth-button-secondary">
Back
</button>
<button onClick={handleReroll} className="auth-button-secondary">
Generate New Passphrase
</button>
<button onClick={handleNext} className="auth-button-primary">
Register
</button>
</div>
</>
)}
{step === "loginWithPassphrase" && (
<div>
<h1 className="auth-heading">Log In</h1>
<textarea
value={loginPassphrase}
onChange={(e) => setLoginPassphrase(e.target.value)}
placeholder="Enter your passphrase"
className="auth-textarea"
rows={5}
/>
<div className="auth-button-group">
<button onClick={handleBack} className="auth-button-secondary">
Back
</button>
<button
onClick={handleLoginSubmit}
className="auth-button-primary"
>
Log In
</button>
</div>
</div>
)}
{step === "loginWithClerk" && <SignInButton />}
</div>
</div>
);
}
export function OmniAuth({
children,
AccountSchema,
sync,
}: {
children: React.ReactNode;
} & JazzProviderProps) {
const clerk = useClerk();
return (
<JazzProviderWithClerk
clerk={clerk}
sync={sync}
AccountSchema={AccountSchema}
>
<OmniAuthContainer
appName="Jazz Multi-Authentication Example"
wordlist={wordlist}
>
{children}
</OmniAuthContainer>
</JazzProviderWithClerk>
);
}

View File

@@ -0,0 +1,151 @@
:root {
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
line-height: 1.5;
font-weight: 400;
color-scheme: light dark;
color: rgba(255, 255, 255, 0.87);
background-color: #242424;
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
a {
font-weight: 500;
color: #646cff;
text-decoration: inherit;
}
a:hover {
color: #535bf2;
}
body {
margin: auto 0;
display: flex;
place-items: center;
min-width: 320px;
min-height: 100vh;
}
h1 {
font-size: 2.2em;
line-height: 1.1;
font-weight: 500;
letter-spacing: 0.6px;
}
button {
border-radius: 6px;
border: 1px solid white;
color: inherit;
padding: 0.5rem 1rem;
font-size: 1em;
font-weight: 500;
font-family: inherit;
background-color: transparent;
cursor: pointer;
transition: all 0.05s ease, border-color 0.1s ease;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
}
button:hover {
background-color: #313131;
}
button:active {
border-color: #3313f7;
transform: translateY(2px);
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
}
@media (prefers-color-scheme: light) {
:root {
color: rgb(21, 20, 20);
background-color: #ffffff;
}
a:hover {
color: #747bff;
}
button {
border-color: #e5e4e2;
}
button:hover {
border-color: rgb(47, 46, 46);
background-color: white;
}
button:active {
border-color: #3313f7;
}
}
.auth-container {
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
background-color: #f3f4f6;
}
.auth-card {
background-color: white;
padding: 2rem;
border-radius: 0.5rem;
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px
rgba(0, 0, 0, 0.06);
width: 28rem;
}
.auth-button-primary,
.auth-button-secondary {
width: 100%;
padding: 0.5rem 1rem;
border-radius: 0.25rem;
font-weight: bold;
cursor: pointer;
margin-bottom: 1rem;
}
.auth-button-primary {
background-color: black;
color: white;
border: none;
}
.auth-button-secondary {
background-color: white;
color: black;
border: 1px solid black;
}
.auth-heading {
color: black;
font-size: 1.5rem;
font-weight: bold;
text-align: center;
margin-bottom: 1rem;
}
.auth-textarea {
width: 100%;
padding: 0.5rem;
border: 1px solid #d1d5db;
border-radius: 0.25rem;
margin-bottom: 1rem;
box-sizing: border-box;
}
.auth-description {
font-size: 0.875rem;
color: #4b5563;
text-align: center;
margin-bottom: 1rem;
}
.auth-button-group {
display: flex;
justify-content: space-between;
gap: 1rem;
}

View File

@@ -0,0 +1,29 @@
import { ClerkProvider } from "@clerk/clerk-react";
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import App from "./App";
import "./index.css";
import { apiKey } from "./apiKey.ts";
import { OmniAuth } from "./components/OmniAuth.tsx";
// Import your publishable key
const PUBLISHABLE_KEY = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY;
if (!PUBLISHABLE_KEY) {
throw new Error("Add your Clerk publishable key to the .env.local file");
}
createRoot(document.getElementById("root")!).render(
<StrictMode>
<ClerkProvider publishableKey={PUBLISHABLE_KEY} afterSignOutUrl="/">
<OmniAuth
sync={{
peer: `wss://cloud.jazz.tools/?key=${apiKey}`,
when: "signedUp", // This makes the app work in local mode when the user is not authenticated
}}
>
<App />
</OmniAuth>
</ClerkProvider>
</StrictMode>,
);

1
examples/multiauth/src/vite-env.d.ts vendored Normal file
View File

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

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,24 @@
{
"compilerOptions": {
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2023", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,
"moduleResolution": "Bundler",
"allowImportingTsExtensions": true,
"isolatedModules": true,
"moduleDetection": "force",
"noEmit": true,
"jsx": "react-jsx",
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedSideEffectImports": true
},
"include": ["src"]
}

View File

@@ -0,0 +1,7 @@
{
"files": [],
"references": [
{ "path": "./tsconfig.app.json" },
{ "path": "./tsconfig.node.json" }
]
}

View File

@@ -0,0 +1,22 @@
{
"compilerOptions": {
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
"target": "ES2022",
"lib": ["ES2023"],
"module": "ESNext",
"skipLibCheck": true,
"moduleResolution": "Bundler",
"allowImportingTsExtensions": true,
"isolatedModules": true,
"moduleDetection": "force",
"noEmit": true,
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedSideEffectImports": true
},
"include": ["vite.config.ts"]
}

View File

@@ -0,0 +1,7 @@
import react from "@vitejs/plugin-react";
import { defineConfig } from "vite";
// https://vite.dev/config/
export default defineConfig({
plugins: [react()],
});

View File

@@ -1,5 +1,30 @@
# jazz-example-musicplayer
## 0.0.83
### Patch Changes
- jazz-inspector@0.11.3
- jazz-react@0.11.3
- jazz-tools@0.11.3
## 0.0.82
### Patch Changes
- Updated dependencies [6892dc6]
- jazz-tools@0.11.2
- jazz-inspector@0.11.2
- jazz-react@0.11.2
## 0.0.81
### Patch Changes
- Updated dependencies [7b00a81]
- jazz-inspector@0.11.1
- jazz-react@0.11.1
## 0.0.80
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "jazz-example-music-player",
"private": true,
"version": "0.0.80",
"version": "0.0.83",
"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.0",
"jazz-tools": "workspace:0.11.0",
"jazz-react": "workspace:0.11.3",
"jazz-tools": "workspace:0.11.3",
"lucide-react": "^0.274.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",

View File

@@ -1,5 +1,26 @@
# organization
## 0.0.55
### Patch Changes
- jazz-react@0.11.3
- jazz-tools@0.11.3
## 0.0.54
### Patch Changes
- Updated dependencies [6892dc6]
- jazz-tools@0.11.2
- jazz-react@0.11.2
## 0.0.53
### Patch Changes
- jazz-react@0.11.1
## 0.0.52
### Patch Changes

View File

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

View File

@@ -1,5 +1,17 @@
# passkey-svelte
## 0.0.49
### Patch Changes
- jazz-svelte@0.11.3
## 0.0.48
### Patch Changes
- jazz-svelte@0.11.2
## 0.0.47
### Patch Changes

View File

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

View File

@@ -1,5 +1,26 @@
# minimal-auth-passkey
## 0.0.60
### Patch Changes
- jazz-react@0.11.3
- jazz-tools@0.11.3
## 0.0.59
### Patch Changes
- Updated dependencies [6892dc6]
- jazz-tools@0.11.2
- jazz-react@0.11.2
## 0.0.58
### Patch Changes
- jazz-react@0.11.1
## 0.0.57
### Patch Changes

View File

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

View File

@@ -1,5 +1,26 @@
# passphrase
## 0.0.57
### Patch Changes
- jazz-react@0.11.3
- jazz-tools@0.11.3
## 0.0.56
### Patch Changes
- Updated dependencies [6892dc6]
- jazz-tools@0.11.2
- jazz-react@0.11.2
## 0.0.55
### Patch Changes
- jazz-react@0.11.1
## 0.0.54
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "passphrase",
"private": true,
"version": "0.0.54",
"version": "0.0.57",
"type": "module",
"scripts": {
"dev": "vite",

View File

@@ -1,5 +1,26 @@
# jazz-password-manager
## 0.0.81
### Patch Changes
- jazz-react@0.11.3
- jazz-tools@0.11.3
## 0.0.80
### Patch Changes
- Updated dependencies [6892dc6]
- jazz-tools@0.11.2
- jazz-react@0.11.2
## 0.0.79
### Patch Changes
- jazz-react@0.11.1
## 0.0.78
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "jazz-password-manager",
"private": true,
"version": "0.0.78",
"version": "0.0.81",
"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.0",
"jazz-tools": "workspace:0.11.0",
"jazz-react": "workspace:0.11.3",
"jazz-tools": "workspace:0.11.3",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-hook-form": "^7.41.5",

View File

@@ -1,5 +1,28 @@
# jazz-example-pets
## 0.0.179
### Patch Changes
- jazz-react@0.11.3
- jazz-tools@0.11.3
- jazz-browser-media-images@0.11.3
## 0.0.178
### Patch Changes
- Updated dependencies [6892dc6]
- jazz-tools@0.11.2
- jazz-react@0.11.2
- jazz-browser-media-images@0.11.2
## 0.0.177
### Patch Changes
- jazz-react@0.11.1
## 0.0.176
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "jazz-example-pets",
"private": true,
"version": "0.0.176",
"version": "0.0.179",
"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.11.0",
"jazz-react": "workspace:0.11.0",
"jazz-tools": "workspace:0.11.0",
"jazz-browser-media-images": "workspace:0.11.3",
"jazz-react": "workspace:0.11.3",
"jazz-tools": "workspace:0.11.3",
"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.11.0",
"jazz-run": "workspace:0.11.3",
"postcss": "^8.4.27",
"tailwindcss": "^3.4.17",
"typescript": "~5.6.2",

View File

@@ -1,5 +1,28 @@
# reactions
## 0.0.59
### Patch Changes
- jazz-react@0.11.3
- jazz-tools@0.11.3
- jazz-browser-media-images@0.11.3
## 0.0.58
### Patch Changes
- Updated dependencies [6892dc6]
- jazz-tools@0.11.2
- jazz-react@0.11.2
- jazz-browser-media-images@0.11.2
## 0.0.57
### Patch Changes
- jazz-react@0.11.1
## 0.0.56
### Patch Changes

View File

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

View File

@@ -1,5 +1,22 @@
# todo-vue
## 0.0.63
### Patch Changes
- jazz-browser@0.11.3
- jazz-tools@0.11.3
- jazz-vue@0.11.3
## 0.0.62
### Patch Changes
- Updated dependencies [6892dc6]
- jazz-tools@0.11.2
- jazz-browser@0.11.2
- jazz-vue@0.11.2
## 0.0.61
### Patch Changes

View File

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

View File

@@ -1,5 +1,26 @@
# jazz-example-todo
## 0.0.178
### Patch Changes
- jazz-react@0.11.3
- jazz-tools@0.11.3
## 0.0.177
### Patch Changes
- Updated dependencies [6892dc6]
- jazz-tools@0.11.2
- jazz-react@0.11.2
## 0.0.176
### Patch Changes
- jazz-react@0.11.1
## 0.0.175
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "jazz-example-todo",
"private": true,
"version": "0.0.175",
"version": "0.0.178",
"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.0",
"jazz-tools": "workspace:0.11.0",
"jazz-react": "workspace:0.11.3",
"jazz-tools": "workspace:0.11.3",
"lucide-react": "^0.274.0",
"qrcode": "^1.5.3",
"react": "^18.3.1",

View File

@@ -1,5 +1,26 @@
# version-history
## 0.0.56
### Patch Changes
- jazz-react@0.11.3
- jazz-tools@0.11.3
## 0.0.55
### Patch Changes
- Updated dependencies [6892dc6]
- jazz-tools@0.11.2
- jazz-react@0.11.2
## 0.0.54
### Patch Changes
- jazz-react@0.11.1
## 0.0.53
### Patch Changes

View File

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

View File

@@ -8,8 +8,8 @@ import {
CheckIcon,
ChevronDown,
ChevronRight,
ClipboardIcon,
CodeIcon,
CopyIcon,
FileLock2Icon,
FileTextIcon,
FingerprintIcon,
@@ -49,7 +49,7 @@ const icons = {
chevronDown: ChevronDown,
close: XIcon,
code: CodeIcon,
copy: CopyIcon,
copy: ClipboardIcon,
darkTheme: MoonIcon,
delete: TrashIcon,
devices: MonitorSmartphoneIcon,

View File

@@ -6,7 +6,11 @@ import { Icon } from "../atoms/Icon";
// TODO: add tabs feature, and remove CodeExampleTabs
function CopyButton({ code, size }: { code: string; size: "md" | "lg" }) {
export function CopyButton({
code,
size,
className,
}: { code: string; size: "md" | "lg"; className?: string }) {
const [copyCount, setCopyCount] = useState(0);
const copied = copyCount > 0;
@@ -23,6 +27,7 @@ function CopyButton({ code, size }: { code: string; size: "md" | "lg" }) {
<button
type="button"
className={clsx(
className,
"group/button absolute overflow-hidden rounded text-2xs font-medium md:opacity-0 backdrop-blur transition md:focus:opacity-100 group-hover:opacity-100",
copied
? "bg-emerald-400/10 ring-1 ring-inset ring-emerald-400/20"

View File

@@ -2,6 +2,10 @@
The homepage of the [Jazz](https://github.com/garden-co/jazz) project, including information about the project, features, and resources.
## Documentation
Documentation about the documentation can be found in the `./docs` folder.
## Build
The homepage is built using [Next.js](https://nextjs.org/) and [Tailwind CSS](https://tailwindcss.com/).

View File

@@ -98,7 +98,7 @@ export class Issue extends CoMap {
title = co.string;
description = co.string;
estimate = co.number;
status? = co.literal("backlog", "in progress", "done");
status = co.optional.literal("backlog", "in progress", "done");
}
```
</CodeGroup>
@@ -514,7 +514,7 @@ export class Issue extends CoMap { // old
title = co.string; // old
description = co.string; // old
estimate = co.number; // old
status? = co.literal("backlog", "in progress", "done"); // old
status? = co.optional.literal("backlog", "in progress", "done"); // old
} // old
// old
export class ListOfIssues extends CoList.Of(co.ref(Issue)) {}

View File

@@ -0,0 +1,7 @@
```sh
npx create-jazz-app@latest
> Framework: react
> Auth: passkey
> Project name: _
```

View File

@@ -1,6 +1,9 @@
import CreateJazzApp from "@/components/home/CreateJazzApp.mdx";
import { H1 } from "gcmp-design-system/src/app/components/atoms/Headings";
import { Icon } from "gcmp-design-system/src/app/components/atoms/Icon";
import { CopyButton } from "gcmp-design-system/src/app/components/molecules/CodeGroup";
import { Prose } from "gcmp-design-system/src/app/components/molecules/Prose";
import { SectionHeader } from "gcmp-design-system/src/app/components/molecules/SectionHeader";
import Link from "next/link";
const features = [
@@ -40,8 +43,8 @@ const features = [
export function HeroSection() {
return (
<div className="container grid gap-x-8 gap-y-10 py-12 md:py-16 lg:py-24 lg:gap-0 lg:grid-cols-3">
<div className="flex flex-col justify-center gap-4 lg:col-span-3 lg:gap-8">
<div className="container grid items-center gap-x-8 gap-y-10 py-12 md:py-16 lg:py-24 lg:gap-x-10 lg:grid-cols-3">
<div className="flex flex-col justify-center gap-5 lg:col-span-2 lg:gap-8">
<p className="uppercase text-blue tracking-widest text-sm font-medium dark:text-stone-400">
Local-first development toolkit
</p>
@@ -79,6 +82,30 @@ export function HeroSection() {
))}
</div>
</div>
<div className="h-full pt-12 group grid md:grid-cols-2 items-center lg:grid-cols-1">
<SectionHeader
className="md:col-span-2 lg:sr-only"
title="Get a Jazz app running in minutes."
/>
<div className=" overflow-hidden sm:rounded-xl sm:border h-full sm:px-8 sm:pt-6 bg-stone-50 dark:bg-stone-950">
<div className="rounded-lg bg-white dark:bg-stone-925 sm:ring-4 ring-stone-400/20 sm:shadow-xl shadow-blue/20 border relative sm:top-2 h-full w-full">
<div className="py-4 flex items-center gap-2.5 px-6 border-b">
<span className="rounded-full size-3 bg-stone-200 dark:bg-stone-900" />
<span className="rounded-full size-3 bg-stone-200 dark:bg-stone-900" />
<span className="rounded-full size-3 bg-stone-200 dark:bg-stone-900" />
<CopyButton
code="npx create-jazz-app@latest"
size="md"
className="mt-0.5 mr-0.5"
/>
</div>
<div className="p-3">
<CreateJazzApp />
</div>
</div>
</div>
</div>
</div>
);
}

View File

@@ -0,0 +1,12 @@
# Homepage documentation
This folder contains the documentation for the homepage documentation. Yup.
## Tone and Voice
We have a tone and voice document. `./tone-and-voice.md`
## Writing docs
We use MDX to write docs. You can find our docs in the `../app/(docs)/docs` folder.

View File

@@ -0,0 +1,74 @@
# Jazz Documentation Tone and Voice Guide
## Core Principles
Write like you're helping a friend understand a new tool. Be clear, direct, and practical. Assume your reader is smart but busy.
## Voice
- **Direct**: Say what you mean simply
- **Practical**: Focus on getting things done
- **Friendly**: Write like you're talking to a friend
- **Knowledgeable**: Show depth through examples, not jargon
- **Progressive**: Build concepts step by step
## Do
- Start with working examples
- Add context naturally as needed
- Use active voice
- Break complex ideas into smaller chunks
- Let code do the heavy lifting
- Show common gotchas through examples
## Don't
- Explain what's obvious
- Use fancy technical terms when simple ones work
- Add artificial formality
- Repeat yourself
- State the obvious
- Hide key details in long paragraphs
## Examples
---
Instead of:
The CoValue instantiation process requires extending the CoMap class and defining appropriate schema fields utilizing the co namespace for type specification.
Write:
Create a CoValue by extending CoMap and defining your fields:
```ts
class Agent extends CoMap {
name = co.string;
status = co.string;
}
```
---
Instead of:
It is imperative to ensure proper cleanup of subscriptions to prevent memory leaks and unnecessary network connections in your application.
Write:
Remember to clean up subscriptions when you're done:
```ts
const unsubscribe = Company.subscribe(id, me, {...});
// Later:
unsubscribe();
```
## Code Examples
- Should be complete and runnable
- Start simple, add complexity gradually
- Include TypeScript types naturally
- Show real-world patterns
- Handle errors without being verbose

View File

@@ -1,5 +1,13 @@
# cojson-storage-indexeddb
## 0.11.3
### Patch Changes
- Updated dependencies [68b0242]
- cojson-storage@0.11.3
- cojson@0.11.3
## 0.11.0
### Patch Changes

View File

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

View File

@@ -1,5 +1,19 @@
# cojson-storage-sqlite
## 0.11.3
### Patch Changes
- Updated dependencies [68b0242]
- cojson-storage@0.11.3
- cojson@0.11.3
## 0.11.1
### Patch Changes
- 7b00a81: Version bump
## 0.8.68
### Patch Changes

View File

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

View File

@@ -1,5 +1,14 @@
# cojson-storage-sqlite
## 0.11.3
### Patch Changes
- 68b0242: Improve the error logging to have more information on errors leveraging the pino err serializer
- Updated dependencies [68b0242]
- cojson-storage@0.11.3
- cojson@0.11.3
## 0.11.0
### Patch Changes

View File

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

View File

@@ -61,6 +61,7 @@ export class SQLiteClient implements DBClientInterface {
const headerValue = coValueRow?.header ?? "";
logger.warn(`Invalid JSON in header: ${headerValue}`, {
id: coValueId,
err: e,
});
return;
}
@@ -99,7 +100,7 @@ export class SQLiteClient implements DBClientInterface {
tx: JSON.parse(transactionRow.tx) as Transaction,
}));
} catch (e) {
logger.warn("Invalid JSON in transaction");
logger.warn("Invalid JSON in transaction", { err: e });
return [];
}
}

View File

@@ -41,21 +41,16 @@ export class SQLiteNode {
await new Promise((resolve) => setTimeout(resolve, 0));
}
} catch (e) {
logger.error(
`Error reading from localNode, handling msg\n\n${JSON.stringify(
msg,
(k, v) =>
k === "changes" || k === "encryptedChanges"
? `${v.slice(0, 20)}...`
: v,
)}`,
);
logger.error("Error reading from localNode, handling msg", {
msg,
err: e,
});
}
}
};
processMessages().catch((e) =>
logger.error("Error in processMessages in sqlite", e),
logger.error("Error in processMessages in sqlite", { err: e }),
);
}

View File

@@ -1,5 +1,13 @@
# cojson-storage
## 0.11.3
### Patch Changes
- 68b0242: Improve the error logging to have more information on errors leveraging the pino err serializer
- Updated dependencies [68b0242]
- cojson@0.11.3
## 0.11.0
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "cojson-storage",
"version": "0.11.0",
"version": "0.11.3",
"main": "dist/index.js",
"type": "module",
"types": "dist/index.d.ts",

View File

@@ -320,10 +320,10 @@ export class SyncManager {
| CojsonInternalTypes.KnownStateMessage
| CojsonInternalTypes.NewContentMessage,
): Promise<unknown> {
return this.toLocalNode
.push(msg)
.catch((e) =>
logger.error(`Error sending ${msg.action} state, id ${msg.id}`, e),
);
return this.toLocalNode.push(msg).catch((e) =>
logger.error(`Error sending ${msg.action} state, id ${msg.id}`, {
err: e,
}),
);
}
}

View File

@@ -1,5 +1,13 @@
# cojson-transport-nodejs-ws
## 0.11.3
### Patch Changes
- 68b0242: Improve the error logging to have more information on errors leveraging the pino err serializer
- Updated dependencies [68b0242]
- cojson@0.11.3
## 0.11.0
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "cojson-transport-ws",
"type": "module",
"version": "0.11.0",
"version": "0.11.3",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"license": "MIT",

View File

@@ -139,7 +139,9 @@ export function createWebSocketPeer({
function handleClose() {
incoming
.push("Disconnected")
.catch((e) => logger.error("Error while pushing disconnect msg", e));
.catch((e) =>
logger.error("Error while pushing disconnect msg", { err: e }),
);
emitClosedEvent();
}
@@ -148,7 +150,7 @@ export function createWebSocketPeer({
// biome-ignore lint/suspicious/noExplicitAny: WebSocket error event type
websocket.addEventListener("error" as any, (err) => {
if (err.message) {
logger.warn(err.message);
logger.warn("WebSocket error", { err });
}
handleClose();
@@ -157,7 +159,9 @@ export function createWebSocketPeer({
const pingTimeout = createPingTimeoutListener(expectPings, () => {
incoming
.push("PingTimeout")
.catch((e) => logger.error("Error while pushing ping timeout", e));
.catch((e) =>
logger.error("Error while pushing ping timeout", { err: e }),
);
emitClosedEvent();
});
@@ -175,9 +179,7 @@ export function createWebSocketPeer({
const result = deserializeMessages(event.data);
if (!result.ok) {
logger.warn(
`Error while deserializing messages: ${getErrorMessage(result.error)}`,
);
logger.warn("Error while deserializing messages", { err: result.error });
return;
}
@@ -201,7 +203,9 @@ export function createWebSocketPeer({
if (msg && "action" in msg) {
incoming
.push(msg)
.catch((e) => logger.error("Error while pushing incoming msg", e));
.catch((e) =>
logger.error("Error while pushing incoming msg", { err: e }),
);
}
}
}

View File

@@ -28,7 +28,7 @@ export function deserializeMessages(messages: unknown) {
| PingMsg[],
} as const;
} catch (e) {
logger.error(`Error while deserializing messages: ${getErrorMessage(e)}`);
logger.error("Error while deserializing messages", { err: e });
return {
ok: false,
error: e,

View File

@@ -1,5 +1,11 @@
# cojson
## 0.11.3
### Patch Changes
- 68b0242: Improve the error logging to have more information on errors leveraging the pino err serializer
## 0.11.0
### Minor Changes

View File

@@ -25,7 +25,7 @@
},
"type": "module",
"license": "MIT",
"version": "0.11.0",
"version": "0.11.3",
"devDependencies": {
"@opentelemetry/sdk-metrics": "^1.29.0",
"typescript": "~5.6.2",

View File

@@ -328,10 +328,7 @@ export class CoValueCore {
try {
listener(content);
} catch (e) {
logger.error(
"Error in listener for coValue " + this.id,
parseError(e),
);
logger.error("Error in listener for coValue " + this.id, { err: e });
}
}
} else {
@@ -345,10 +342,9 @@ export class CoValueCore {
try {
listener(content);
} catch (e) {
logger.error(
"Error in listener for coValue " + this.id,
parseError(e),
);
logger.error("Error in listener for coValue " + this.id, {
err: e,
});
}
}
resolve();
@@ -545,7 +541,9 @@ export class CoValueCore {
}
if (!decryptedChanges) {
logger.error("Failed to decrypt transaction despite having key");
logger.error("Failed to decrypt transaction despite having key", {
err: new Error("Failed to decrypt transaction despite having key"),
});
continue;
}

View File

@@ -285,7 +285,9 @@ async function loadCoValueFromPeers(
...coValueEntry.state.coValue.knownState(),
})
.catch((err) => {
logger.warn(`Failed to push load message to peer ${peer.id}`, err);
logger.warn(`Failed to push load message to peer ${peer.id}`, {
err,
});
});
} else {
/**
@@ -299,7 +301,9 @@ async function loadCoValueFromPeers(
sessions: {},
})
.catch((err) => {
logger.warn(`Failed to push load message to peer ${peer.id}`, err);
logger.warn(`Failed to push load message to peer ${peer.id}`, {
err,
});
});
}

View File

@@ -195,9 +195,7 @@ export class PureJSCrypto extends CryptoProvider<Blake3State> {
try {
return JSON.parse(textDecoder.decode(plaintext));
} catch (e) {
logger.error(
"Failed to decrypt/parse sealed message: " + (e as Error)?.message,
);
logger.error("Failed to decrypt/parse sealed message", { err: e });
return undefined;
}
}

View File

@@ -179,9 +179,7 @@ export class WasmCrypto extends CryptoProvider<Blake3State> {
try {
return JSON.parse(plaintext) as T;
} catch (e) {
logger.error(
"Failed to decrypt/parse sealed message: " + (e as Error)?.message,
);
logger.error("Failed to decrypt/parse sealed message", { err: e });
return undefined;
}
}

View File

@@ -163,7 +163,7 @@ export abstract class CryptoProvider<Blake3State = any> {
try {
return parseJSON(this.decryptRaw(encrypted, keySecret, nOnceMaterial));
} catch (e) {
logger.error("Decryption error: " + (e as Error)?.message);
logger.error("Decryption error", { err: e });
return undefined;
}
}

View File

@@ -231,7 +231,7 @@ export class LocalNode {
return node;
} catch (e) {
logger.error("Error withLoadedAccount: " + (e as Error)?.message);
logger.error("Error withLoadedAccount", { err: e });
throw e;
}
}
@@ -270,8 +270,9 @@ export class LocalNode {
this.syncManager.getServerAndStoragePeers(skipLoadingFromPeer);
await entry.loadFromPeers(peers).catch((e) => {
logger.error("Error loading from peers: " + (e as Error)?.message, {
logger.error("Error loading from peers", {
id,
err: e,
});
});
}
@@ -326,9 +327,10 @@ export class LocalNode {
unsubscribe = coValue.subscribe(callback);
})
.catch((e) => {
logger.error(
"Error subscribing to " + id + ": " + (e as Error)?.message,
);
logger.error("Subscription error", {
id,
err: e,
});
});
return () => {

View File

@@ -8,11 +8,19 @@ export enum LogLevel {
NONE = 4,
}
type ErrorAttributes = { err: unknown };
export interface LogSystem {
debug(message: string, attributes?: Record<string, JsonValue>): void;
info(message: string, attributes?: Record<string, JsonValue>): void;
warn(message: string, attributes?: Record<string, JsonValue>): void;
error(message: string, attributes?: Record<string, JsonValue>): void;
warn(
message: string,
attributes?: Record<string, JsonValue> | ErrorAttributes,
): void;
error(
message: string,
attributes?: Record<string, JsonValue> | ErrorAttributes,
): void;
}
// Default console-based logging system
@@ -23,10 +31,16 @@ export class ConsoleLogSystem implements LogSystem {
info(message: string, attributes?: Record<string, JsonValue>) {
console.info(message, attributes);
}
warn(message: string, attributes?: Record<string, JsonValue>) {
warn(
message: string,
attributes?: Record<string, JsonValue> | ErrorAttributes,
) {
console.warn(message, attributes);
}
error(message: string, attributes?: Record<string, JsonValue>) {
error(
message: string,
attributes?: Record<string, JsonValue> | ErrorAttributes,
) {
console.error(message, attributes);
}
}
@@ -63,13 +77,19 @@ export class Logger {
}
}
warn(message: string, attributes?: Record<string, JsonValue>) {
warn(
message: string,
attributes?: Record<string, JsonValue> | ErrorAttributes,
) {
if (this.level <= LogLevel.WARN) {
this.logSystem.warn(message, attributes);
}
}
error(message: string, attributes?: Record<string, JsonValue>) {
error(
message: string,
attributes?: Record<string, JsonValue> | ErrorAttributes,
) {
if (this.level <= LogLevel.ERROR) {
this.logSystem.error(message, attributes);
}

View File

@@ -83,30 +83,23 @@ export class LSMStorage<WH, RH, FS extends FileSystem<WH, RH>> {
await this.sendNewContent(msg.id, msg, undefined);
}
} catch (e) {
logger.error(
`Error reading from localNode, handling msg\n\n${JSON.stringify(
msg,
(k, v) =>
k === "changes" || k === "encryptedChanges"
? v.slice(0, 20) + "..."
: v,
)}
Error: ${e instanceof Error ? e.message : "Unknown error"},
`,
);
logger.error(`Error reading from localNode, handling msg`, {
msg,
err: e,
});
}
nMsg++;
}
};
processMessages().catch((e) =>
logger.error("Error in processMessages in storage", e),
logger.error("Error in processMessages in storage", { err: e }),
);
setTimeout(
() =>
this.compact().catch((e) => {
logger.error("Error while compacting", e);
logger.error("Error while compacting", { err: e });
}),
20000,
);
@@ -132,7 +125,7 @@ export class LSMStorage<WH, RH, FS extends FileSystem<WH, RH>> {
sessions: {},
asDependencyOf,
})
.catch((e) => logger.error("Error while pushing known", e));
.catch((e) => logger.error("Error while pushing known", { err: e }));
return;
}
@@ -188,13 +181,15 @@ export class LSMStorage<WH, RH, FS extends FileSystem<WH, RH>> {
...ourKnown,
asDependencyOf,
})
.catch((e) => logger.error("Error while pushing known", e));
.catch((e) => logger.error("Error while pushing known", { err: e }));
for (const message of newContentMessages) {
if (Object.keys(message.new).length === 0) continue;
this.toLocalNode
.push(message)
.catch((e) => logger.error("Error while pushing new content", e));
.catch((e) =>
logger.error("Error while pushing new content", { err: e }),
);
}
this.coValues[id] = coValue;
@@ -502,7 +497,7 @@ export class LSMStorage<WH, RH, FS extends FileSystem<WH, RH>> {
setTimeout(
() =>
this.compact().catch((e) => {
logger.error("Error while compacting", e);
logger.error("Error while compacting", { err: e });
}),
5000,
);

View File

@@ -187,7 +187,7 @@ export class SyncManager {
if (entry.state.type !== "available") {
entry.loadFromPeers([peer]).catch((e: unknown) => {
logger.error("Error sending load: " + getErrorMessage(e));
logger.error("Error sending load", { err: e });
});
return;
}
@@ -204,7 +204,7 @@ export class SyncManager {
action: "load",
...coValue.knownState(),
}).catch((e: unknown) => {
logger.error("Error sending load: " + getErrorMessage(e));
logger.error("Error sending load", { err: e });
});
}
}
@@ -234,7 +234,7 @@ export class SyncManager {
asDependencyOf,
...coValue.knownState(),
}).catch((e: unknown) => {
logger.error("Error sending known state: " + getErrorMessage(e));
logger.error("Error sending known state", { err: e });
});
peer.toldKnownState.add(id);
@@ -262,7 +262,7 @@ export class SyncManager {
let lastYield = performance.now();
for (const [_i, piece] of newContentPieces.entries()) {
this.trySendToPeer(peer, piece).catch((e: unknown) => {
logger.error("Error sending content piece: " + getErrorMessage(e));
logger.error("Error sending content piece", { err: e });
});
if (performance.now() - lastYield > 10) {
@@ -275,7 +275,7 @@ export class SyncManager {
};
sendPieces().catch((e) => {
logger.error("Error sending new content piece, retrying", e);
logger.error("Error sending new content piece, retrying", { err: e });
peer.optimisticKnownStates.dispatch({
type: "SET",
id,
@@ -358,13 +358,11 @@ export class SyncManager {
}
})
.catch((e) => {
logger.error(
"Error processing messages from peer: " + getErrorMessage(e),
{
peerId: peer.id,
peerRole: peer.role,
},
);
logger.error("Error processing messages from peer", {
err: e,
peerId: peer.id,
peerRole: peer.role,
});
if (peer.crashOnClose) {
this.local.crashed = e;
throw new Error(e);
@@ -404,13 +402,13 @@ export class SyncManager {
// where we can get informations about the coValue
if (msg.header || Object.keys(msg.sessions).length > 0) {
entry.loadFromPeers([peer]).catch((e) => {
logger.error("Error loading coValue in handleLoad", e);
logger.error("Error loading coValue in handleLoad", { err: e });
});
}
return;
} else {
this.local.loadCoValueCore(msg.id, peer.id).catch((e) => {
logger.error("Error loading coValue in handleLoad", e);
logger.error("Error loading coValue in handleLoad", { err: e });
});
}
}
@@ -437,7 +435,7 @@ export class SyncManager {
header: false,
sessions: {},
}).catch((e) => {
logger.error("Error sending known state back", e);
logger.error("Error sending known state back", { err: e });
});
return;
@@ -447,7 +445,9 @@ export class SyncManager {
await this.sendNewContentIncludingDependencies(msg.id, peer);
})
.catch((e) => {
logger.error("Error loading coValue in handleLoad loading state", e);
logger.error("Error loading coValue in handleLoad loading state", {
err: e,
});
});
}
@@ -484,7 +484,7 @@ export class SyncManager {
.catch((e) => {
logger.error(
`Error loading coValue ${msg.id} to create loading state, as dependency of ${msg.asDependencyOf}`,
e,
{ err: e },
);
});
}
@@ -604,10 +604,11 @@ export class SyncManager {
// );
if (result.isErr()) {
logger.error("Failed to add transactions: " + result.error.type, {
logger.error("Failed to add transactions", {
peerId: peer.id,
peerRole: peer.role,
id: msg.id,
err: result.error,
});
peer.erroredCoValues.set(msg.id, result.error);
continue;
@@ -629,13 +630,11 @@ export class SyncManager {
isCorrection: true,
...coValue.knownState(),
}).catch((e) => {
logger.error(
"Error sending known state correction: " + getErrorMessage(e),
{
peerId: peer.id,
peerRole: peer.role,
},
);
logger.error("Error sending known state correction", {
peerId: peer.id,
peerRole: peer.role,
err: e,
});
});
} else {
/**
@@ -649,9 +648,10 @@ export class SyncManager {
action: "known",
...coValue.knownState(),
}).catch((e: unknown) => {
logger.error("Error sending known state: " + getErrorMessage(e), {
logger.error("Error sending known state", {
peerId: peer.id,
peerRole: peer.role,
err: e,
});
});
}

View File

@@ -1,5 +1,22 @@
# jazz-browser-media-images
## 0.11.3
### Patch Changes
- Updated dependencies [68b0242]
- cojson@0.11.3
- jazz-browser@0.11.3
- jazz-tools@0.11.3
## 0.11.2
### Patch Changes
- Updated dependencies [6892dc6]
- jazz-tools@0.11.2
- jazz-browser@0.11.2
## 0.11.0
### Patch Changes

View File

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

View File

@@ -1,5 +1,20 @@
# jazz-browser-media-images
## 0.11.3
### Patch Changes
- jazz-browser@0.11.3
- jazz-tools@0.11.3
## 0.11.2
### Patch Changes
- Updated dependencies [6892dc6]
- jazz-tools@0.11.2
- jazz-browser@0.11.2
## 0.11.0
### Patch Changes

View File

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

View File

@@ -1,5 +1,22 @@
# jazz-browser
## 0.11.3
### Patch Changes
- Updated dependencies [68b0242]
- cojson-transport-ws@0.11.3
- cojson@0.11.3
- cojson-storage-indexeddb@0.11.3
- jazz-tools@0.11.3
## 0.11.2
### Patch Changes
- Updated dependencies [6892dc6]
- jazz-tools@0.11.2
## 0.11.0
### Minor Changes

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