Compare commits

...

25 Commits

Author SHA1 Message Date
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
107 changed files with 3434 additions and 83 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,22 @@
# chat-rn-clerk
## 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.83",
"scripts": {
"build": "expo export -p ios",
"start": "expo start",

View File

@@ -1,5 +1,19 @@
# chat-rn
## 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.79",
"main": "index.js",
"scripts": {
"build": "expo export -p ios",

View File

@@ -1,5 +1,14 @@
# chat-vue
## 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.64",
"private": true,
"type": "module",
"scripts": {

View File

@@ -1,5 +1,20 @@
# jazz-example-chat
## 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.161",
"type": "module",
"scripts": {
"dev": "vite",

View File

@@ -1,5 +1,21 @@
# minimal-auth-clerk
## 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.60",
"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.2",
"jazz-tools": "workspace:*",
"react": "^18.3.1",
"react-dom": "^18.3.1"

View File

@@ -1,5 +1,13 @@
# file-share-svelte
## 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.44",
"private": true,
"type": "module",
"scripts": {

View File

@@ -1,5 +1,20 @@
# form
## 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.2",
"type": "module",
"scripts": {
"dev": "vite",

View File

@@ -1,5 +1,20 @@
# image-upload
## 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.58",
"type": "module",
"scripts": {
"dev": "vite",

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,10 @@
# multiauth
## 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.1",
"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,22 @@
# jazz-example-musicplayer
## 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.82",
"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.2",
"jazz-tools": "workspace:0.11.2",
"lucide-react": "^0.274.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",

View File

@@ -1,5 +1,19 @@
# organization
## 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.54",
"type": "module",
"scripts": {
"dev": "vite",

View File

@@ -1,5 +1,11 @@
# passkey-svelte
## 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.48",
"type": "module",
"private": true,
"scripts": {

View File

@@ -1,5 +1,19 @@
# minimal-auth-passkey
## 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.59",
"type": "module",
"scripts": {
"dev": "vite",

View File

@@ -1,5 +1,19 @@
# passphrase
## 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.56",
"type": "module",
"scripts": {
"dev": "vite",

View File

@@ -1,5 +1,19 @@
# jazz-password-manager
## 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.80",
"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.2",
"jazz-tools": "workspace:0.11.2",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-hook-form": "^7.41.5",

View File

@@ -1,5 +1,20 @@
# jazz-example-pets
## 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.178",
"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.2",
"jazz-react": "workspace:0.11.2",
"jazz-tools": "workspace:0.11.2",
"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.2",
"postcss": "^8.4.27",
"tailwindcss": "^3.4.17",
"typescript": "~5.6.2",

View File

@@ -1,5 +1,20 @@
# reactions
## 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.58",
"type": "module",
"scripts": {
"dev": "vite",

View File

@@ -1,5 +1,14 @@
# todo-vue
## 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.62",
"private": true,
"type": "module",
"scripts": {

View File

@@ -1,5 +1,19 @@
# jazz-example-todo
## 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.177",
"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.2",
"jazz-tools": "workspace:0.11.2",
"lucide-react": "^0.274.0",
"qrcode": "^1.5.3",
"react": "^18.3.1",

View File

@@ -1,5 +1,19 @@
# version-history
## 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.55",
"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

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

View File

@@ -2,6 +2,9 @@ import { H1 } from "gcmp-design-system/src/app/components/atoms/Headings";
import { Icon } from "gcmp-design-system/src/app/components/atoms/Icon";
import { Prose } from "gcmp-design-system/src/app/components/molecules/Prose";
import Link from "next/link";
import { CopyButton } from "gcmp-design-system/src/app/components/molecules/CodeGroup";
import CreateJazzApp from "@/components/home/CreateJazzApp.mdx";
import { SectionHeader } from "gcmp-design-system/src/app/components/molecules/SectionHeader";
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,23 @@ 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,11 @@
# cojson-storage-sqlite
## 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.1",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"license": "MIT",

View File

@@ -1,5 +1,13 @@
# jazz-browser-media-images
## 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.2",
"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"
"jazz-browser": "workspace:0.11.2",
"jazz-tools": "workspace:0.11.2"
},
"scripts": {
"format-and-lint": "biome check .",

View File

@@ -1,5 +1,13 @@
# jazz-browser-media-images
## 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.2",
"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.2",
"jazz-tools": "workspace:0.11.2",
"pica": "^9.0.1",
"typescript": "~5.6.2"
},

View File

@@ -1,5 +1,12 @@
# jazz-browser
## 0.11.2
### Patch Changes
- Updated dependencies [6892dc6]
- jazz-tools@0.11.2
## 0.11.0
### Minor Changes

View File

@@ -1,6 +1,6 @@
{
"name": "jazz-browser",
"version": "0.11.0",
"version": "0.11.2",
"type": "module",
"main": "dist/index.js",
"types": "dist/index.d.ts",

View File

@@ -1,5 +1,22 @@
# jazz-inspector
## 0.11.2
### Patch Changes
- Updated dependencies [ed0e151]
- Updated dependencies [6892dc6]
- jazz-react-core@0.11.2
- jazz-tools@0.11.2
## 0.11.1
### Patch Changes
- 7b00a81: Version bump
- Updated dependencies [7b00a81]
- jazz-react-core@0.11.1
## 0.10.13
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "jazz-inspector",
"version": "0.10.13",
"version": "0.11.2",
"type": "module",
"main": "./dist/app.js",
"types": "./dist/app.d.ts",

View File

@@ -1,5 +1,12 @@
# jazz-autosub
## 0.11.2
### Patch Changes
- Updated dependencies [6892dc6]
- jazz-tools@0.11.2
## 0.11.0
### Patch Changes

View File

@@ -5,7 +5,7 @@
"types": "dist/index.d.ts",
"type": "module",
"license": "MIT",
"version": "0.11.0",
"version": "0.11.2",
"dependencies": {
"cojson": "workspace:*",
"cojson-transport-ws": "workspace:*",

View File

@@ -1,5 +1,21 @@
# jazz-browser-media-images
## 0.11.2
### Patch Changes
- Updated dependencies [6892dc6]
- jazz-tools@0.11.2
- jazz-react@0.11.2
- jazz-auth-clerk@0.11.2
- jazz-browser@0.11.2
## 0.11.1
### Patch Changes
- jazz-react@0.11.1
## 0.11.0
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "jazz-react-auth-clerk",
"version": "0.11.0",
"version": "0.11.2",
"type": "module",
"main": "dist/index.js",
"types": "dist/index.d.ts",

View File

@@ -1,5 +1,19 @@
# jazz-react-core
## 0.11.2
### Patch Changes
- ed0e151: Reset the useCoState value when the id becomes undefined
- Updated dependencies [6892dc6]
- jazz-tools@0.11.2
## 0.11.1
### Patch Changes
- 7b00a81: Version bump
## 0.10.13
### Patch Changes

View File

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

View File

@@ -118,6 +118,8 @@ export function useCoState<V extends CoValue, D>(
>(
React.useCallback(
(callback) => {
observable.reset();
if (!id) return () => {};
// We subscribe to the context manager to react to the account updates

View File

@@ -174,4 +174,27 @@ describe("useCoState", () => {
current: TestMap | null | undefined;
}>();
});
it("should set the value to undefined when the id is set to undefined", () => {
class TestMap extends CoMap {
value = co.string;
}
const map = TestMap.create({
value: "123",
});
const { result, rerender } = renderHook(
(props) => useCoState(TestMap, props.id, []),
{
initialProps: { id: map.id } as { id: ID<CoValue> | undefined },
},
);
expect(result.current?.value).toBe("123");
rerender({ id: undefined });
expect(result.current?.value).toBeUndefined();
});
});

View File

@@ -1,5 +1,20 @@
# jazz-react-native-auth-clerk
## 0.11.2
### Patch Changes
- Updated dependencies [6892dc6]
- jazz-tools@0.11.2
- jazz-react-native@0.11.2
- jazz-auth-clerk@0.11.2
## 0.11.1
### Patch Changes
- jazz-react-native@0.11.1
## 0.11.0
### Patch Changes

View File

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

View File

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

View File

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

View File

@@ -1,5 +1,22 @@
# jazz-browser
## 0.11.2
### Patch Changes
- Updated dependencies [ed0e151]
- Updated dependencies [6892dc6]
- jazz-react-core@0.11.2
- jazz-tools@0.11.2
## 0.11.1
### Patch Changes
- Updated dependencies [7b00a81]
- cojson-storage-rn-sqlite@0.11.1
- jazz-react-core@0.11.1
## 0.11.0
### Patch Changes

View File

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

View File

@@ -1,5 +1,22 @@
# jazz-react
## 0.11.2
### Patch Changes
- Updated dependencies [ed0e151]
- Updated dependencies [6892dc6]
- jazz-react-core@0.11.2
- jazz-tools@0.11.2
- jazz-browser@0.11.2
## 0.11.1
### Patch Changes
- Updated dependencies [7b00a81]
- jazz-react-core@0.11.1
## 0.11.0
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "jazz-react",
"version": "0.11.0",
"version": "0.11.2",
"type": "module",
"main": "dist/index.js",
"types": "dist/index.d.ts",
@@ -18,9 +18,9 @@
"dependencies": {
"@scure/bip39": "^1.3.0",
"cojson": "workspace:0.11.0",
"jazz-browser": "workspace:0.11.0",
"jazz-browser": "workspace:0.11.2",
"jazz-react-core": "workspace:*",
"jazz-tools": "workspace:0.11.0"
"jazz-tools": "workspace:0.11.2"
},
"devDependencies": {
"@testing-library/dom": "^10.4.0",

View File

@@ -1,5 +1,12 @@
# jazz-run
## 0.11.2
### Patch Changes
- Updated dependencies [6892dc6]
- jazz-tools@0.11.2
## 0.11.0
### Patch Changes

View File

@@ -3,7 +3,7 @@
"bin": "./dist/index.js",
"type": "module",
"license": "MIT",
"version": "0.11.0",
"version": "0.11.2",
"exports": {
"./startSyncServer": {
"import": "./dist/startSyncServer.js",
@@ -31,7 +31,7 @@
"cojson-storage-sqlite": "workspace:0.11.0",
"cojson-transport-ws": "workspace:0.11.0",
"effect": "^3.6.5",
"jazz-tools": "workspace:0.11.0",
"jazz-tools": "workspace:0.11.2",
"ws": "^8.14.2"
},
"devDependencies": {

View File

@@ -1,5 +1,13 @@
# jazz-svelte
## 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-svelte",
"version": "0.11.0",
"version": "0.11.2",
"scripts": {
"dev": "vite dev",
"build": "vite build && npm run package",

View File

@@ -1,5 +1,11 @@
# jazz-tools
## 0.11.2
### Patch Changes
- 6892dc6: Adds `applyDiff` to `CoList`
## 0.11.0
### Minor Changes

View File

@@ -17,10 +17,11 @@
},
"type": "module",
"license": "MIT",
"version": "0.11.0",
"version": "0.11.2",
"dependencies": {
"@scure/bip39": "^1.3.0",
"cojson": "workspace:*"
"cojson": "workspace:*",
"fast-myers-diff": "^3.2.0"
},
"scripts": {
"format-and-lint": "biome check .",

View File

@@ -1,5 +1,6 @@
import type { JsonValue, RawCoList } from "cojson";
import { RawAccount } from "cojson";
import { calcPatch } from "fast-myers-diff";
import type {
CoValue,
CoValueClass,
@@ -287,7 +288,6 @@ export class CoList<Item = any> extends Array<Item> implements CoValue {
let appendAfter = Math.max(start - 1, 0);
for (const item of toRawItems(items as Item[], this._schema[ItemsSym])) {
console.log(this._raw.asArray(), appendAfter);
this._raw.append(item, appendAfter);
appendAfter++;
}
@@ -295,6 +295,19 @@ export class CoList<Item = any> extends Array<Item> implements CoValue {
return deleted;
}
applyDiff(other: Item[]) {
const current = this._raw.asArray() as Item[];
const cmp = isRefEncoded(this._schema[ItemsSym])
? (aIdx: number, bIdx: number) =>
(current[aIdx] as CoValue).id === (other[bIdx] as CoValue).id
: undefined;
for (const [from, to, insert] of [
...calcPatch(current, other, cmp),
].reverse()) {
this.splice(from, to - from, ...insert);
}
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
toJSON(_key?: string, seenAbove?: ID<CoValue>[]): any[] {
const itemDescriptor = this._schema[ItemsSym] as Schema;

View File

@@ -115,6 +115,26 @@ describe("Simple CoList operations", async () => {
expect(list.length).toBe(4);
expect(list._raw.asArray()).toEqual(["bread", "salt", "pepper", "onion"]);
});
test("applyDiff", () => {
const list = TestList.create(["bread", "butter", "onion"], {
owner: me,
});
// replace
list.applyDiff(["bread", "margarine", "onion"]);
expect(list._raw.asArray()).toEqual(["bread", "margarine", "onion"]);
// delete
list.applyDiff(["bread", "onion"]);
expect(list._raw.asArray()).toEqual(["bread", "onion"]);
// insert multiple
list.applyDiff(["bread", "margarine", "onion", "cheese"]);
expect(list._raw.asArray()).toEqual([
"bread",
"margarine",
"onion",
"cheese",
]);
});
});
});

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