Compare commits

...

57 Commits

Author SHA1 Message Date
Guido D'Orsi
617ea91a13 Merge pull request #1384 from garden-co/changeset-release/main
Version Packages
2025-02-15 01:23:35 +01:00
github-actions[bot]
b0ef1259ae Version Packages 2025-02-15 00:23:03 +00:00
Guido D'Orsi
a0ba4f235f Merge pull request #1383 from garden-co/revert-queue-changes
Revert queue changes
2025-02-15 01:21:37 +01:00
Guido D'Orsi
e197900fc5 test: remove isNotEmpty reference 2025-02-15 01:19:00 +01:00
Guido D'Orsi
1af6072299 chore: changeset 2025-02-15 01:12:35 +01:00
Guido D'Orsi
510e8874e1 Revert "perf: optimize queue processing under heavy load"
This reverts commit b90393b43e.
2025-02-15 01:11:02 +01:00
Anselm Eickhoff
ed7ee85304 Merge pull request #1381 from jmsv/extremely-important-fix
upgrade @unicorn-poo/pizzazz to fix scroll offset
2025-02-14 16:45:48 +00:00
James Vickery
ac726421d2 extremely important fix 2025-02-14 16:33:26 +00:00
Anselm
585b22941e pizzazz 2025-02-14 10:54:19 +00:00
Guido D'Orsi
5d557a830a Merge pull request #1368 from garden-co/changeset-release/main
Version Packages
2025-02-13 12:06:41 +01:00
github-actions[bot]
f0188df13b Version Packages 2025-02-13 11:06:09 +00:00
Guido D'Orsi
4c8ce0a24f Merge pull request #1376 from garden-co/create-jazz-app-cleanup
Remove redundant passkey auth starter in create-jazz-app
2025-02-13 12:04:47 +01:00
Trisha Lim
8645f8ce86 Update help text 2025-02-13 17:54:04 +07:00
Trisha Lim
d01d467136 Change name of react native clerk starter 2025-02-13 17:39:50 +07:00
Trisha Lim
ad4fcbafa4 Add changeset 2025-02-13 17:38:14 +07:00
Trisha Lim
05c51d5a85 Rephrase starter prompt 2025-02-13 17:34:56 +07:00
Trisha Lim
ab20a81751 Rename react starter app to react-passkey-auth 2025-02-13 17:32:39 +07:00
Trisha Lim
adad802ceb Rename starters 2025-02-13 16:16:24 +07:00
Trisha Lim
32b1cc9dab Remove gradient text 2025-02-13 16:15:09 +07:00
Guido D'Orsi
5c236e5c3c Merge pull request #1371 from garden-co/jazz-706-fix-organization-example-build
Jazz 706 fix organization example build
2025-02-13 09:52:29 +01:00
Guido D'Orsi
7616d5789b chore(ci): trigger the React Native e2e tests when packages are changed 2025-02-13 09:17:29 +01:00
Guido D'Orsi
631486e235 Merge pull request #1364 from boorad/feat/move-e2e-to-android
feat: move E2E tests to Android
2025-02-13 09:15:15 +01:00
Guido D'Orsi
5e0d63a4d6 docs: fix broken links in the upgrade page 2025-02-13 08:37:54 +01:00
Benjamin S. Leveritt
ba988cbb90 Removes tsc builds of config files 2025-02-12 22:59:42 +00:00
Benjamin S. Leveritt
6f6800bcd8 Adds aliases for vite to build 2025-02-12 22:59:03 +00:00
Benjamin S. Leveritt
90290902e8 Merge pull request #1365 from garden-co/jazz-675-explicitly-assigning-undefined-to-a-cooptionaldate-on-create
Jazz 675 explicitly assigning undefined to a cooptionaldate on create
2025-02-12 21:50:09 +00:00
Benjamin S. Leveritt
d8582fc9ed Adds changeset 2025-02-12 21:49:01 +00:00
Brad Anderson
58905ae8f4 feat: move E2E tests to Android 2025-02-12 15:16:44 -05:00
Guido D'Orsi
65f630fb44 Merge pull request #1367 from garden-co/changeset-release/main
Version Packages
2025-02-12 20:26:56 +01:00
github-actions[bot]
b68f85542b Version Packages 2025-02-12 18:32:59 +00:00
Guido D'Orsi
f122a9f938 Merge pull request #1366 from garden-co/fix-metro-config
fix: correctly setup the metro config on React Native templates
2025-02-12 19:31:50 +01:00
Benjamin S. Leveritt
e15d994df6 Adds OptionalDate encoding 2025-02-12 18:23:20 +00:00
Guido D'Orsi
48ac92bc67 fix: correctly setup the metro config on React Native templates 2025-02-12 19:22:23 +01:00
Benjamin S. Leveritt
226b1171e6 Adds check for undefined to co.optional.Date 2025-02-12 18:09:15 +00:00
Benjamin S. Leveritt
29228e21fe Adds optional date test 2025-02-12 18:08:56 +00:00
Trisha Lim
d3603625fd Fix copy password button 2025-02-12 19:43:20 +07:00
Trisha Lim
fa94d8c171 Show button on mobile 2025-02-12 19:43:20 +07:00
Trisha Lim
aeb094baa1 Add "use as template" button to examples 2025-02-12 19:43:20 +07:00
Guido D'Orsi
18f3497397 Merge pull request #1361 from garden-co/changeset-release/main
Version Packages
2025-02-12 12:55:19 +01:00
github-actions[bot]
8be7158d1f Version Packages 2025-02-12 11:52:07 +00:00
Guido D'Orsi
cae3a9ee32 feat: add debug info to load failure end missing header errors 2025-02-12 12:50:29 +01:00
Guido D'Orsi
6260045140 docs: small improvement on the upgrade guide 2025-02-12 11:57:00 +01:00
Guido D'Orsi
466d79d9a6 docs: fix missing enclosing div 2025-02-12 11:47:46 +01:00
Guido D'Orsi
67776c77a0 Merge pull request #1360 from garden-co/changeset-release/main
Version Packages
2025-02-12 11:42:59 +01:00
github-actions[bot]
e6868d3030 Version Packages 2025-02-12 10:41:24 +00:00
Guido D'Orsi
c8ae3a36ca Merge pull request #1350 from garden-co/jazz-701-docs-in-main-nav-doesnt-get-highlighted-when-active
Fix: docs in main nav doesn't get highlighted when active
2025-02-12 11:39:47 +01:00
Guido D'Orsi
bf9c158455 Merge pull request #1359 from garden-co/fix/unstable_enablePackageExports
feat: remove the unstable_enablePackageExports requirement from RN
2025-02-12 11:38:53 +01:00
Guido D'Orsi
1301112a6b docs: add the breaking change to the 0-10-0 upgrade guide 2025-02-12 11:38:25 +01:00
Guido D'Orsi
c447f08029 chore: improve pre-release comment output 2025-02-12 11:31:20 +01:00
Guido D'Orsi
5a63cbae9b feat: remove the unstable_enablePackageExports requirement from RN 2025-02-12 10:48:08 +01:00
Guido D'Orsi
7d06f1dbf4 fix: fix the username input style in dark mode 2025-02-11 16:53:51 +01:00
Guido D'Orsi
e48a3e4c27 chore: fix test type error 2025-02-11 16:09:26 +01:00
Guido D'Orsi
a326ed971c Merge pull request #1353 from garden-co/jazz-696-mark-vue-and-svelte-as-experimental
Mark vue and svelte as experimental
2025-02-11 16:03:34 +01:00
Trisha Lim
6139803679 Use dropdown for framework selector 2025-02-11 19:18:48 +07:00
Trisha Lim
bb2052e1f2 Add dropdown 2025-02-11 17:42:30 +07:00
Trisha Lim
40af02acb3 Mark vue and svelte as experimental 2025-02-11 17:39:57 +07:00
Trisha Lim
3bdb753b78 Fix: docs in main nav doesn't get highlighted when active 2025-02-11 17:37:14 +07:00
203 changed files with 2443 additions and 543 deletions

View File

@@ -0,0 +1,39 @@
name: Setup Android Emulator
inputs:
api-level:
description: 'API level to use for the emulator'
required: true
default: '29'
runs:
using: "composite"
steps:
- name: Enable KVM
shell: bash
run: |
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
sudo udevadm control --reload-rules
sudo udevadm trigger --name-match=kvm
- name: Gradle cache
uses: gradle/actions/setup-gradle@v4
- name: AVD cache
uses: useblacksmith/cache@v5
id: avd-cache
with:
path: |
~/.android/avd/*
~/.android/adb*
key: avd-${{ inputs.api-level }}
- name: Create AVD and Generate Snapshot for Caching
if: steps.avd-cache.outputs.cache-hit != 'true'
uses: reactivecircus/android-emulator-runner@v2
with:
api-level: ${{ inputs.api-level }}
force-avd-creation: false
emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none -no-metrics
disable-animations: false
script: echo "Generated AVD snapshot for caching."

View File

@@ -9,7 +9,7 @@ jobs:
runs-on: blacksmith-4vcpu-ubuntu-2204
strategy:
matrix:
starter: ["react-demo-auth-tailwind"]
starter: ["react-passkey-auth"]
steps:
- uses: actions/checkout@v4

View File

@@ -4,14 +4,16 @@ on:
pull_request:
types: [opened, synchronize, reopened]
paths:
- ".github/actions/android-emulator/**"
- ".github/actions/source-code/**"
- ".github/workflows/e2e-rn-test.yml"
- "examples/chat-rn/**"
- "examples/chat-rn-clerk/**"
- "packages/jazz-react-native*/**"
- "packages/**"
jobs:
e2e-tests:
runs-on: macos-latest
runs-on: blacksmith-4vcpu-ubuntu-2204
steps:
- name: Checkout
@@ -24,55 +26,47 @@ jobs:
run: |
mkdir -p ~/output
- name: Setup JDK
uses: actions/setup-java@v4
with:
distribution: corretto
java-version: 22
cache: gradle
- name: Pnpm Build
run: pnpm turbo build --filter="./packages/*"
- name: iOS Simulator
id: ios-simulator
uses: futureware-tech/simulator-action@v4
with:
os: iOS
wait_for_boot: true
- name: chat-rn App Pre Build
working-directory: ./examples/chat-rn
run: |
pnpm build
pnpm expo prebuild --clean
- name: chat-rn App Build
working-directory: ./examples/chat-rn/ios
run: |
xcodebuild -scheme "jazzchatrn" \
-workspace jazzchatrn.xcworkspace \
-archivePath $RUNNER_TEMP/jazzchatrn.xcarchive \
-derivedDataPath $RUNNER_TEMP/build \
-destination "id=${{ steps.ios-simulator.outputs.udid }}" \
-configuration Release \
-sdk iphonesimulator \
build
xcrun simctl install booted $RUNNER_TEMP/build/Build/Products/Release-iphonesimulator/jazzchatrn.app
xcrun simctl spawn booted log stream --level debug | tee ~/output/sim.log &
- name: Install Maestro
run: |
curl -fsSL "https://get.maestro.mobile.dev" | bash
- name: chat-rn App Test
id: e2e_test
working-directory: ./examples/chat-rn
continue-on-error: true
run: |
export PATH="$PATH":"$HOME/.maestro/bin"
export MAESTRO_DRIVER_STARTUP_TIMEOUT=300000 # setting to 5 mins 👀
export MAESTRO_CLI_NO_ANALYTICS=1
maestro test test/e2e/flow.yml
- name: Setup Android Emulator
id: android-emulator
uses: ./.github/actions/android-emulator/
with:
api-level: 29
- name: Copy Maestro and Diagnostic Files
- name: Test App
uses: reactivecircus/android-emulator-runner@v2
id: e2e_test
continue-on-error: true
with:
api-level: 29
force-avd-creation: false
emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none -no-metrics
disable-animations: true
working-directory: ./examples/chat-rn/
script: ./test/e2e/run.sh
- name: Copy Maestro Output
if: steps.e2e_test.outcome != 'success'
run: |
cp -r ~/Library/Logs/DiagnosticReports/* ~/output
cp -r ~/.maestro/tests/* ~/output
- name: Upload Output Files

View File

@@ -13,7 +13,7 @@ jobs:
continue-on-error: true
strategy:
matrix:
project: ["tests/e2e", "examples/chat", "examples/file-share-svelte", "examples/form", "examples/music-player", "examples/pets", "examples/onboarding", "starters/react-demo-auth-tailwind"]
project: ["tests/e2e", "examples/chat", "examples/file-share-svelte", "examples/form", "examples/music-player", "examples/pets", "examples/onboarding", "starters/react-passkey-auth"]
steps:
- uses: actions/checkout@v4

View File

@@ -19,4 +19,84 @@ jobs:
run: pnpm turbo build --filter="./packages/*"
- name: Pre publish
run: pnpm exec pkg-pr-new publish "./packages/*"
run: pnpm exec pkg-pr-new publish --json output.json --comment=off "./packages/*"
- name: Post or update comment
uses: actions/github-script@v6
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const fs = require('fs');
const output = JSON.parse(fs.readFileSync('output.json', 'utf8'));
const packages = output.packages
.map((p) => `- ${p.name}: ${p.url}`)
.join('\n');
const sha =
context.event_name === 'pull_request'
? context.payload.pull_request.head.sha
: context.payload.after;
const resolutions = Object.fromEntries(
output.packages.map((p) => [p.name, p.url])
);
const commitUrl = `https://github.com/${context.repo.owner}/${context.repo.repo}/commit/${sha}`;
const body = `## Jazz pre-release
### Packages:
\`\`\`json
${JSON.stringify(resolutions, null, 4)}
\`\`\`
[View Commit](${commitUrl})`;
async function logPublishInfo() {
console.log('\n' + '='.repeat(50));
console.log('Publish Information');
console.log('='.repeat(50));
console.log('\nPublished Packages:');
console.log(output.packages);
console.log('\nTemplates:');
console.log(templates);
console.log(`\nCommit URL: ${commitUrl}`);
console.log('\n' + '='.repeat(50));
}
if (context.eventName === 'pull_request') {
if (context.issue.number) {
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body,
});
}
} else if (context.eventName === 'push') {
const pullRequests = await github.rest.pulls.list({
owner: context.repo.owner,
repo: context.repo.repo,
state: 'open',
head: `${context.repo.owner}:${context.ref.replace(
'refs/heads/',
''
)}`,
});
if (pullRequests.data.length > 0) {
await github.rest.issues.createComment({
issue_number: pullRequests.data[0].number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body,
});
} else {
console.log(
'No open pull request found for this push. Logging publish information to console:'
);
await logPublishInfo();
}
}

View File

@@ -1,5 +1,43 @@
# chat-rn-clerk
## 1.0.69
### Patch Changes
- jazz-react-native@0.10.4
- jazz-react-native-auth-clerk@0.10.4
- jazz-tools@0.10.4
- jazz-react-native-media-images@0.10.4
## 1.0.68
### Patch Changes
- Updated dependencies [d8582fc]
- jazz-tools@0.10.3
- jazz-react-native@0.10.3
- jazz-react-native-auth-clerk@0.10.3
- jazz-react-native-media-images@0.10.3
## 1.0.67
### Patch Changes
- jazz-react-native@0.10.2
- jazz-react-native-auth-clerk@0.10.2
- jazz-tools@0.10.2
- jazz-react-native-media-images@0.10.2
## 1.0.66
### Patch Changes
- Updated dependencies [5a63cba]
- jazz-tools@0.10.1
- jazz-react-native@0.10.1
- jazz-react-native-auth-clerk@0.10.1
- jazz-react-native-media-images@0.10.1
## 1.0.65
### Patch Changes

View File

@@ -19,7 +19,6 @@ config.resolver.nodeModulesPaths = [
path.resolve(workspaceRoot, "node_modules"),
];
config.resolver.sourceExts = ["mjs", "js", "json", "ts", "tsx"];
config.resolver.unstable_enablePackageExports = true;
config.resolver.requireCycleIgnorePatterns = [
/(^|\/|\\)node_modules($|\/|\\)/,
/(^|\/|\\)packages($|\/|\\)/,

View File

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

View File

@@ -1,5 +1,35 @@
# chat-rn
## 1.0.66
### Patch Changes
- jazz-react-native@0.10.4
- jazz-tools@0.10.4
## 1.0.65
### Patch Changes
- Updated dependencies [d8582fc]
- jazz-tools@0.10.3
- jazz-react-native@0.10.3
## 1.0.64
### Patch Changes
- jazz-react-native@0.10.2
- jazz-tools@0.10.2
## 1.0.63
### Patch Changes
- Updated dependencies [5a63cba]
- jazz-tools@0.10.1
- jazz-react-native@0.10.1
## 1.0.62
### Patch Changes

View File

@@ -19,7 +19,6 @@ config.resolver.nodeModulesPaths = [
path.resolve(workspaceRoot, "node_modules"),
];
config.resolver.sourceExts = ["mjs", "js", "json", "ts", "tsx"];
config.resolver.unstable_enablePackageExports = true;
config.resolver.requireCycleIgnorePatterns = [
/(^|\/|\\)node_modules($|\/|\\)/,
/(^|\/|\\)packages($|\/|\\)/,

View File

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

View File

@@ -0,0 +1,18 @@
#!/bin/bash
# This script is necessary, because unlike ios, the android emulator action
# accepts a script, runs it as your tests, then terminates.
set -e
# build and install the app
cd ./android/
./gradlew installRelease
cd ..
# run the e2e tests
export PATH="$PATH":"$HOME/.maestro/bin"
export MAESTRO_DRIVER_STARTUP_TIMEOUT=300000 # setting to 5 mins 👀
export MAESTRO_CLI_NO_ANALYTICS=1
export MAESTRO_CLI_ANALYSIS_NOTIFICATION_DISABLED=true
maestro test test/e2e/flow.yml

View File

@@ -1,5 +1,39 @@
# chat-vue
## 0.0.53
### Patch Changes
- jazz-browser@0.10.4
- jazz-tools@0.10.4
- jazz-vue@0.10.4
## 0.0.52
### Patch Changes
- Updated dependencies [d8582fc]
- jazz-tools@0.10.3
- jazz-browser@0.10.3
- jazz-vue@0.10.3
## 0.0.51
### Patch Changes
- jazz-browser@0.10.2
- jazz-tools@0.10.2
- jazz-vue@0.10.2
## 0.0.50
### Patch Changes
- Updated dependencies [5a63cba]
- jazz-tools@0.10.1
- jazz-browser@0.10.1
- jazz-vue@0.10.1
## 0.0.49
### Patch Changes

View File

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

View File

@@ -1,5 +1,39 @@
# jazz-example-chat
## 0.0.149
### Patch Changes
- jazz-react@0.10.4
- jazz-tools@0.10.4
- jazz-browser-media-images@0.10.4
## 0.0.148
### Patch Changes
- Updated dependencies [d8582fc]
- jazz-tools@0.10.3
- jazz-browser-media-images@0.10.3
- jazz-react@0.10.3
## 0.0.147
### Patch Changes
- jazz-react@0.10.2
- jazz-tools@0.10.2
- jazz-browser-media-images@0.10.2
## 0.0.146
### Patch Changes
- Updated dependencies [5a63cba]
- jazz-tools@0.10.1
- jazz-browser-media-images@0.10.1
- jazz-react@0.10.1
## 0.0.145
### Patch Changes

View File

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

View File

@@ -31,6 +31,7 @@ export function App() {
<input
type="text"
value={me?.profile?.name ?? ""}
className="bg-transparent"
onChange={(e) => {
if (!me?.profile) return;
me.profile.name = e.target.value;

View File

@@ -1,5 +1,39 @@
# minimal-auth-clerk
## 0.0.48
### Patch Changes
- jazz-react@0.10.4
- jazz-react-auth-clerk@0.10.4
- jazz-tools@0.10.4
## 0.0.47
### Patch Changes
- Updated dependencies [d8582fc]
- jazz-tools@0.10.3
- jazz-react@0.10.3
- jazz-react-auth-clerk@0.10.3
## 0.0.46
### Patch Changes
- jazz-react@0.10.2
- jazz-react-auth-clerk@0.10.2
- jazz-tools@0.10.2
## 0.0.45
### Patch Changes
- Updated dependencies [5a63cba]
- jazz-tools@0.10.1
- jazz-react@0.10.1
- jazz-react-auth-clerk@0.10.1
## 0.0.44
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "clerk",
"private": true,
"version": "0.0.44",
"version": "0.0.48",
"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.10.0",
"jazz-react-auth-clerk": "workspace:0.10.4",
"jazz-tools": "workspace:*",
"react": "^18.3.1",
"react-dom": "^18.3.1"

View File

@@ -1,5 +1,35 @@
# file-share-svelte
## 0.0.33
### Patch Changes
- jazz-svelte@0.10.4
- jazz-tools@0.10.4
## 0.0.32
### Patch Changes
- Updated dependencies [d8582fc]
- jazz-tools@0.10.3
- jazz-svelte@0.10.3
## 0.0.31
### Patch Changes
- jazz-svelte@0.10.2
- jazz-tools@0.10.2
## 0.0.30
### Patch Changes
- Updated dependencies [5a63cba]
- jazz-tools@0.10.1
- jazz-svelte@0.10.1
## 0.0.29
### Patch Changes

View File

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

View File

@@ -1,5 +1,39 @@
# form
## 0.0.44
### Patch Changes
- jazz-react@0.10.4
- jazz-tools@0.10.4
- jazz-browser-media-images@0.10.4
## 0.0.43
### Patch Changes
- Updated dependencies [d8582fc]
- jazz-tools@0.10.3
- jazz-browser-media-images@0.10.3
- jazz-react@0.10.3
## 0.0.42
### Patch Changes
- jazz-react@0.10.2
- jazz-tools@0.10.2
- jazz-browser-media-images@0.10.2
## 0.0.41
### Patch Changes
- Updated dependencies [5a63cba]
- jazz-tools@0.10.1
- jazz-browser-media-images@0.10.1
- jazz-react@0.10.1
## 0.0.40
### Patch Changes

View File

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

View File

@@ -1,5 +1,39 @@
# image-upload
## 0.0.46
### Patch Changes
- jazz-react@0.10.4
- jazz-tools@0.10.4
- jazz-browser-media-images@0.10.4
## 0.0.45
### Patch Changes
- Updated dependencies [d8582fc]
- jazz-tools@0.10.3
- jazz-browser-media-images@0.10.3
- jazz-react@0.10.3
## 0.0.44
### Patch Changes
- jazz-react@0.10.2
- jazz-tools@0.10.2
- jazz-browser-media-images@0.10.2
## 0.0.43
### Patch Changes
- Updated dependencies [5a63cba]
- jazz-tools@0.10.1
- jazz-browser-media-images@0.10.1
- jazz-react@0.10.1
## 0.0.42
### Patch Changes

View File

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

View File

@@ -1,5 +1,29 @@
# jazz-example-inspector
## 0.0.106
### Patch Changes
- Updated dependencies [1af6072]
- cojson@0.10.4
- cojson-transport-ws@0.10.4
## 0.0.105
### Patch Changes
- Updated dependencies [cae3a9e]
- cojson@0.10.2
- cojson-transport-ws@0.10.2
## 0.0.104
### Patch Changes
- Updated dependencies [5a63cba]
- cojson@0.10.1
- cojson-transport-ws@0.10.1
## 0.0.103
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "jazz-inspector-app",
"private": true,
"version": "0.0.103",
"version": "0.0.106",
"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.10.0",
"cojson-transport-ws": "workspace:0.10.0",
"cojson": "workspace:0.10.4",
"cojson-transport-ws": "workspace:0.10.4",
"hash-slash": "workspace:0.2.1",
"lucide-react": "^0.274.0",
"qrcode": "^1.5.3",

View File

@@ -5,13 +5,9 @@ import {
RawCoStream,
RawCoValue,
} from "cojson";
import { base64URLtoBytes } from "cojson/src/base64url.ts";
import {
BinaryStreamItem,
BinaryStreamStart,
CoStreamItem,
} from "cojson/src/coValues/coStream.ts";
import { JsonObject, JsonValue } from "cojson/src/jsonValue.ts";
import { base64URLtoBytes } from "cojson";
import { BinaryStreamItem, BinaryStreamStart, CoStreamItem } from "cojson";
import { JsonObject, JsonValue } from "cojson";
import { ArrowDownToLine } from "lucide-react";
import { useEffect, useState } from "react";
import { PageInfo } from "./types";

View File

@@ -1,6 +1,6 @@
import clsx from "clsx";
import { CoID, LocalNode, RawCoValue } from "cojson";
import { JsonObject } from "cojson/src/jsonValue.ts";
import { JsonObject } from "cojson";
import { ResolveIcon } from "./type-icon";
import { PageInfo, isCoId } from "./types";
import { CoMapPreview, ValueRenderer } from "./value-renderer";

View File

@@ -6,9 +6,9 @@ import {
RawAccount,
RawAccountID,
RawCoValue,
WasmCrypto,
} from "cojson";
import { createWebSocketPeer } from "cojson-transport-ws";
import { WasmCrypto } from "cojson/crypto/WasmCrypto";
import { Trash2 } from "lucide-react";
import React, { useState, useEffect } from "react";
import { Breadcrumbs } from "./breadcrumbs";

View File

@@ -1,5 +1,5 @@
import { CoID, LocalNode, RawCoValue } from "cojson";
import { JsonObject } from "cojson/src/jsonValue.ts";
import { JsonObject } from "cojson";
import { useMemo, useState } from "react";
import { LinkIcon } from "../link-icon";
import { PageInfo } from "./types";

View File

@@ -1,5 +1,39 @@
# jazz-example-musicplayer
## 0.0.70
### Patch Changes
- jazz-inspector@0.10.4
- jazz-react@0.10.4
- jazz-tools@0.10.4
## 0.0.69
### Patch Changes
- Updated dependencies [d8582fc]
- jazz-tools@0.10.3
- jazz-inspector@0.10.3
- jazz-react@0.10.3
## 0.0.68
### Patch Changes
- jazz-inspector@0.10.2
- jazz-react@0.10.2
- jazz-tools@0.10.2
## 0.0.67
### Patch Changes
- Updated dependencies [5a63cba]
- jazz-tools@0.10.1
- jazz-inspector@0.10.1
- jazz-react@0.10.1
## 0.0.66
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "jazz-example-music-player",
"private": true,
"version": "0.0.66",
"version": "0.0.70",
"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.10.0",
"jazz-tools": "workspace:0.10.0",
"jazz-react": "workspace:0.10.4",
"jazz-tools": "workspace:0.10.4",
"lucide-react": "^0.274.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",

View File

@@ -1,5 +1,39 @@
# jazz-example-onboarding
## 0.0.50
### Patch Changes
- jazz-react@0.10.4
- jazz-tools@0.10.4
- jazz-browser-media-images@0.10.4
## 0.0.49
### Patch Changes
- Updated dependencies [d8582fc]
- jazz-tools@0.10.3
- jazz-browser-media-images@0.10.3
- jazz-react@0.10.3
## 0.0.48
### Patch Changes
- jazz-react@0.10.2
- jazz-tools@0.10.2
- jazz-browser-media-images@0.10.2
## 0.0.47
### Patch Changes
- Updated dependencies [5a63cba]
- jazz-tools@0.10.1
- jazz-browser-media-images@0.10.1
- jazz-react@0.10.1
## 0.0.46
### Patch Changes

View File

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

View File

@@ -1,5 +1,35 @@
# organization
## 0.0.42
### Patch Changes
- jazz-react@0.10.4
- jazz-tools@0.10.4
## 0.0.41
### Patch Changes
- Updated dependencies [d8582fc]
- jazz-tools@0.10.3
- jazz-react@0.10.3
## 0.0.40
### Patch Changes
- jazz-react@0.10.2
- jazz-tools@0.10.2
## 0.0.39
### Patch Changes
- Updated dependencies [5a63cba]
- jazz-tools@0.10.1
- jazz-react@0.10.1
## 0.0.38
### Patch Changes

View File

@@ -1,11 +1,11 @@
{
"name": "organization",
"private": true,
"version": "0.0.38",
"version": "0.0.42",
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc -b && vite build",
"build": "vite build",
"preview": "vite preview",
"format-and-lint": "biome check .",
"format-and-lint:fix": "biome check . --write"

View File

@@ -1,2 +0,0 @@
declare const _default: import("vite").UserConfig;
export default _default;

View File

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

View File

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

View File

@@ -1,5 +1,29 @@
# passkey-svelte
## 0.0.37
### Patch Changes
- jazz-svelte@0.10.4
## 0.0.36
### Patch Changes
- jazz-svelte@0.10.3
## 0.0.35
### Patch Changes
- jazz-svelte@0.10.2
## 0.0.34
### Patch Changes
- jazz-svelte@0.10.1
## 0.0.33
### Patch Changes

View File

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

View File

@@ -1,5 +1,35 @@
# minimal-auth-passkey
## 0.0.47
### Patch Changes
- jazz-react@0.10.4
- jazz-tools@0.10.4
## 0.0.46
### Patch Changes
- Updated dependencies [d8582fc]
- jazz-tools@0.10.3
- jazz-react@0.10.3
## 0.0.45
### Patch Changes
- jazz-react@0.10.2
- jazz-tools@0.10.2
## 0.0.44
### Patch Changes
- Updated dependencies [5a63cba]
- jazz-tools@0.10.1
- jazz-react@0.10.1
## 0.0.43
### Patch Changes

View File

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

View File

@@ -1,5 +1,35 @@
# passphrase
## 0.0.44
### Patch Changes
- jazz-react@0.10.4
- jazz-tools@0.10.4
## 0.0.43
### Patch Changes
- Updated dependencies [d8582fc]
- jazz-tools@0.10.3
- jazz-react@0.10.3
## 0.0.42
### Patch Changes
- jazz-react@0.10.2
- jazz-tools@0.10.2
## 0.0.41
### Patch Changes
- Updated dependencies [5a63cba]
- jazz-tools@0.10.1
- jazz-react@0.10.1
## 0.0.40
### Patch Changes

View File

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

View File

@@ -1,5 +1,35 @@
# jazz-password-manager
## 0.0.68
### Patch Changes
- jazz-react@0.10.4
- jazz-tools@0.10.4
## 0.0.67
### Patch Changes
- Updated dependencies [d8582fc]
- jazz-tools@0.10.3
- jazz-react@0.10.3
## 0.0.66
### Patch Changes
- jazz-react@0.10.2
- jazz-tools@0.10.2
## 0.0.65
### Patch Changes
- Updated dependencies [5a63cba]
- jazz-tools@0.10.1
- jazz-react@0.10.1
## 0.0.64
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "jazz-password-manager",
"private": true,
"version": "0.0.64",
"version": "0.0.68",
"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.10.0",
"jazz-tools": "workspace:0.10.0",
"jazz-react": "workspace:0.10.4",
"jazz-tools": "workspace:0.10.4",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-hook-form": "^7.41.5",

View File

@@ -1,5 +1,39 @@
# jazz-example-pets
## 0.0.166
### Patch Changes
- jazz-react@0.10.4
- jazz-tools@0.10.4
- jazz-browser-media-images@0.10.4
## 0.0.165
### Patch Changes
- Updated dependencies [d8582fc]
- jazz-tools@0.10.3
- jazz-browser-media-images@0.10.3
- jazz-react@0.10.3
## 0.0.164
### Patch Changes
- jazz-react@0.10.2
- jazz-tools@0.10.2
- jazz-browser-media-images@0.10.2
## 0.0.163
### Patch Changes
- Updated dependencies [5a63cba]
- jazz-tools@0.10.1
- jazz-browser-media-images@0.10.1
- jazz-react@0.10.1
## 0.0.162
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "jazz-example-pets",
"private": true,
"version": "0.0.162",
"version": "0.0.166",
"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.10.0",
"jazz-react": "workspace:0.10.0",
"jazz-tools": "workspace:0.10.0",
"jazz-browser-media-images": "workspace:0.10.4",
"jazz-react": "workspace:0.10.4",
"jazz-tools": "workspace:0.10.4",
"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.10.0",
"jazz-run": "workspace:0.10.4",
"postcss": "^8.4.27",
"tailwindcss": "^3.4.17",
"typescript": "~5.6.2",

View File

@@ -1,5 +1,39 @@
# reactions
## 0.0.46
### Patch Changes
- jazz-react@0.10.4
- jazz-tools@0.10.4
- jazz-browser-media-images@0.10.4
## 0.0.45
### Patch Changes
- Updated dependencies [d8582fc]
- jazz-tools@0.10.3
- jazz-browser-media-images@0.10.3
- jazz-react@0.10.3
## 0.0.44
### Patch Changes
- jazz-react@0.10.2
- jazz-tools@0.10.2
- jazz-browser-media-images@0.10.2
## 0.0.43
### Patch Changes
- Updated dependencies [5a63cba]
- jazz-tools@0.10.1
- jazz-browser-media-images@0.10.1
- jazz-react@0.10.1
## 0.0.42
### Patch Changes

View File

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

View File

@@ -1,5 +1,39 @@
# todo-vue
## 0.0.51
### Patch Changes
- jazz-browser@0.10.4
- jazz-tools@0.10.4
- jazz-vue@0.10.4
## 0.0.50
### Patch Changes
- Updated dependencies [d8582fc]
- jazz-tools@0.10.3
- jazz-browser@0.10.3
- jazz-vue@0.10.3
## 0.0.49
### Patch Changes
- jazz-browser@0.10.2
- jazz-tools@0.10.2
- jazz-vue@0.10.2
## 0.0.48
### Patch Changes
- Updated dependencies [5a63cba]
- jazz-tools@0.10.1
- jazz-browser@0.10.1
- jazz-vue@0.10.1
## 0.0.47
### Patch Changes

View File

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

View File

@@ -1,5 +1,35 @@
# jazz-example-todo
## 0.0.165
### Patch Changes
- jazz-react@0.10.4
- jazz-tools@0.10.4
## 0.0.164
### Patch Changes
- Updated dependencies [d8582fc]
- jazz-tools@0.10.3
- jazz-react@0.10.3
## 0.0.163
### Patch Changes
- jazz-react@0.10.2
- jazz-tools@0.10.2
## 0.0.162
### Patch Changes
- Updated dependencies [5a63cba]
- jazz-tools@0.10.1
- jazz-react@0.10.1
## 0.0.161
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "jazz-example-todo",
"private": true,
"version": "0.0.161",
"version": "0.0.165",
"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.10.0",
"jazz-tools": "workspace:0.10.0",
"jazz-react": "workspace:0.10.4",
"jazz-tools": "workspace:0.10.4",
"lucide-react": "^0.274.0",
"qrcode": "^1.5.3",
"react": "^18.3.1",

View File

@@ -1,5 +1,35 @@
# version-history
## 0.0.43
### Patch Changes
- jazz-react@0.10.4
- jazz-tools@0.10.4
## 0.0.42
### Patch Changes
- Updated dependencies [d8582fc]
- jazz-tools@0.10.3
- jazz-react@0.10.3
## 0.0.41
### Patch Changes
- jazz-react@0.10.2
- jazz-tools@0.10.2
## 0.0.40
### Patch Changes
- Updated dependencies [5a63cba]
- jazz-tools@0.10.1
- jazz-react@0.10.1
## 0.0.39
### Patch Changes

View File

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

View File

@@ -77,6 +77,7 @@ const icons = {
// copied from tailwind line height https://tailwindcss.com/docs/font-size
const sizes = {
"2xs": 14,
xs: 16,
sm: 20,
md: 24,
@@ -93,6 +94,7 @@ const sizes = {
};
const strokeWidths = {
"2xs": 2.5,
xs: 2,
sm: 2,
md: 1.5,

View File

@@ -1,18 +1,18 @@
"use client";
import { clsx } from "clsx";
import { useEffect, useRef, useState } from "react";
import { useEffect, useId, useRef, useState } from "react";
import { Icon } from "../atoms/Icon";
// TODO: add tabs feature, and remove CodeExampleTabs
function CopyButton({ code, size }: { code: string; size: "md" | "lg" }) {
let [copyCount, setCopyCount] = useState(0);
let copied = copyCount > 0;
const [copyCount, setCopyCount] = useState(0);
const copied = copyCount > 0;
useEffect(() => {
if (copyCount > 0) {
let timeout = setTimeout(() => setCopyCount(0), 1000);
const timeout = setTimeout(() => setCopyCount(0), 1000);
return () => {
clearTimeout(timeout);
};
@@ -23,7 +23,8 @@ function CopyButton({ code, size }: { code: string; size: "md" | "lg" }) {
<button
type="button"
className={clsx(
"group/button absolute overflow-hidden rounded text-2xs font-medium opacity-0 backdrop-blur transition focus:opacity-100 group-hover:opacity-100",
"group/button absolute overflow-hidden rounded text-2xs font-medium md:opacity-0 backdrop-blur transition md:focus:opacity-100 group-hover:opacity-100",
"right-[9px] top-[9px]",
copied
? "bg-emerald-400/10 ring-1 ring-inset ring-emerald-400/20"
: "bg-white/5 hover:bg-white/7.5 dark:bg-white/2.5 dark:hover:bg-white/5",
@@ -72,13 +73,13 @@ export function CodeGroup({
size = "md",
className,
}: {
children: React.ReactNode;
children?: React.ReactNode;
text?: string;
size?: "md" | "lg";
className?: string;
}) {
const textRef = useRef<HTMLPreElement | null>(null);
const [code, setCode] = useState<string>();
useEffect(() => {
if (textRef.current) {
setCode(textRef.current.innerText);

View File

@@ -0,0 +1,108 @@
import * as Headless from "@headlessui/react";
import clsx from "clsx";
import type React from "react";
const sizes = {
xs: "sm:max-w-xs",
sm: "sm:max-w-sm",
md: "sm:max-w-md",
lg: "sm:max-w-lg",
xl: "sm:max-w-xl",
"2xl": "sm:max-w-2xl",
"3xl": "sm:max-w-3xl",
"4xl": "sm:max-w-4xl",
"5xl": "sm:max-w-5xl",
};
export type DialogProps = {
size?: keyof typeof sizes;
className?: string;
children: React.ReactNode;
} & Omit<Headless.DialogProps, "as" | "className">;
export function Dialog({
size = "lg",
className,
children,
...props
}: DialogProps) {
return (
<Headless.Dialog {...props}>
<Headless.DialogBackdrop
transition
className="z-50 fixed inset-0 flex w-screen justify-center overflow-y-auto bg-stone-950/25 px-2 py-2 transition duration-100 focus:outline-0 data-[closed]:opacity-0 data-[enter]:ease-out data-[leave]:ease-in sm:px-6 sm:py-8 lg:px-8 lg:py-16 dark:bg-stone-950/70"
/>
<div className="z-50 fixed inset-0 w-screen overflow-y-auto pt-6 sm:pt-0">
<div className="grid min-h-full grid-rows-[1fr_auto] justify-items-center sm:grid-rows-[1fr_auto_3fr] sm:p-4">
<Headless.DialogPanel
transition
className={clsx(
className,
sizes[size],
"row-start-2 w-full min-w-0 rounded-t-3xl bg-white p-[--gutter] shadow-lg ring-1 ring-stone-950/10 [--gutter:theme(spacing.8)] sm:mb-auto sm:rounded-2xl dark:bg-stone-950 dark:ring-white/10 forced-colors:outline",
"transition duration-100 will-change-transform data-[closed]:translate-y-12 data-[closed]:opacity-0 data-[enter]:ease-out data-[leave]:ease-in sm:data-[closed]:translate-y-0 sm:data-[closed]:data-[enter]:scale-95",
)}
>
{children}
</Headless.DialogPanel>
</div>
</div>
</Headless.Dialog>
);
}
export function DialogTitle({
className,
...props
}: { className?: string } & Omit<
Headless.DialogTitleProps,
"as" | "className"
>) {
return (
<Headless.DialogTitle
{...props}
className={clsx(
className,
"text-balance text-lg/6 font-semibold text-stone-900 dark:text-white",
)}
/>
);
}
export function DialogDescription({
className,
...props
}: { className?: string } & Omit<
Headless.DescriptionProps,
"as" | "className"
>) {
return (
<Headless.Description
{...props}
className={clsx(className, "mt-2 text-pretty")}
/>
);
}
export function DialogBody({
className,
...props
}: React.ComponentPropsWithoutRef<"div">) {
return <div {...props} className={clsx(className, "mt-6")} />;
}
export function DialogActions({
className,
...props
}: React.ComponentPropsWithoutRef<"div">) {
return (
<div
{...props}
className={clsx(
className,
"mt-8 flex flex-col-reverse items-center justify-end gap-3 *:w-full sm:flex-row sm:*:w-auto",
)}
/>
);
}

View File

@@ -0,0 +1,227 @@
"use client";
import * as Headless from "@headlessui/react";
import clsx from "clsx";
import Link from "next/link";
import type React from "react";
import { Button } from "../atoms/Button";
export function Dropdown(props: Headless.MenuProps) {
return <Headless.Menu {...props} />;
}
export function DropdownButton<T extends React.ElementType = typeof Button>({
as = Button,
...props
}: { className?: string } & Omit<Headless.MenuButtonProps<T>, "className">) {
return <Headless.MenuButton as={as} {...props} />;
}
export function DropdownMenu({
anchor = "bottom",
className,
...props
}: { className?: string } & Omit<Headless.MenuItemsProps, "as" | "className">) {
return (
<Headless.MenuItems
{...props}
transition
anchor={anchor}
className={clsx(
className,
// Anchor positioning
"[--anchor-gap:theme(spacing.2)] [--anchor-padding:theme(spacing.1)] data-[anchor~=start]:[--anchor-offset:-6px] data-[anchor~=end]:[--anchor-offset:6px] sm:data-[anchor~=start]:[--anchor-offset:-4px] sm:data-[anchor~=end]:[--anchor-offset:4px]",
// Base styles
"isolate w-max rounded-xl p-1",
// Invisible border that is only visible in `forced-colors` mode for accessibility purposes
"outline outline-1 outline-transparent focus:outline-none",
// Handle scrolling when menu won't fit in viewport
"overflow-y-auto",
// Popover background
"bg-white/75 backdrop-blur-xl dark:bg-stone-925",
// Shadows
"shadow-lg ring-1 ring-stone-950/10 dark:ring-inset dark:ring-white/10",
// Define grid at the menu level if subgrid is supported
"supports-[grid-template-columns:subgrid]:grid supports-[grid-template-columns:subgrid]:grid-cols-[auto_1fr_1.5rem_0.5rem_auto]",
// Transitions
"transition data-[closed]:data-[leave]:opacity-0 data-[leave]:duration-100 data-[leave]:ease-in",
)}
/>
);
}
export function DropdownItem({
className,
...props
}: { className?: string } & (
| Omit<Headless.MenuItemProps<"button">, "as" | "className">
| Omit<Headless.MenuItemProps<typeof Link>, "as" | "className">
)) {
let classes = clsx(
className,
// Base styles
"group rounded-lg space-x-2 px-3.5 py-2.5 focus:outline-none sm:px-3 sm:py-1.5",
// Text styles
"text-left text-stone-600 text-sm/6 dark:text-white forced-colors:text-[CanvasText]",
// Focus
"data-[focus]:bg-stone-100 dark:data-[focus]:bg-stone-900 ",
// Disabled state
"data-[disabled]:opacity-50",
// Forced colors mode
"forced-color-adjust-none forced-colors:data-[focus]:bg-[Highlight] forced-colors:data-[focus]:text-[HighlightText] forced-colors:[&>[data-slot=icon]]:data-[focus]:text-[HighlightText]",
// Use subgrid when available but fallback to an explicit grid layout if not
"col-span-full grid grid-cols-[auto_1fr_1.5rem_0.5rem_auto] items-center",
// Icons
"[&>[data-slot=icon]]:col-start-1 [&>[data-slot=icon]]:row-start-1 [&>[data-slot=icon]]:-ml-0.5 [&>[data-slot=icon]]:mr-2.5 [&>[data-slot=icon]]:size-5 sm:[&>[data-slot=icon]]:mr-2 [&>[data-slot=icon]]:sm:size-4",
"[&>[data-slot=icon]]:text-stone-500 [&>[data-slot=icon]]:data-[focus]:text-white [&>[data-slot=icon]]:dark:text-stone-400 [&>[data-slot=icon]]:data-[focus]:dark:text-white",
// Avatar
"[&>[data-slot=avatar]]:mr-2.5 [&>[data-slot=avatar]]:size-6 sm:[&>[data-slot=avatar]]:mr-2 sm:[&>[data-slot=avatar]]:size-5",
);
return "href" in props ? (
<Headless.MenuItem as={Link} {...props} className={classes} />
) : (
<Headless.MenuItem
as="button"
type="button"
{...props}
className={classes}
/>
);
}
export function DropdownHeader({
className,
...props
}: React.ComponentPropsWithoutRef<"div">) {
return (
<div
{...props}
className={clsx(className, "col-span-5 px-3.5 pb-1 pt-2.5 sm:px-3")}
/>
);
}
export function DropdownSection({
className,
...props
}: { className?: string } & Omit<
Headless.MenuSectionProps,
"as" | "className"
>) {
return (
<Headless.MenuSection
{...props}
className={clsx(
className,
// Define grid at the section level instead of the item level if subgrid is supported
"col-span-full supports-[grid-template-columns:subgrid]:grid supports-[grid-template-columns:subgrid]:grid-cols-[auto_1fr_1.5rem_0.5rem_auto]",
)}
/>
);
}
export function DropdownHeading({
className,
...props
}: { className?: string } & Omit<
Headless.MenuHeadingProps,
"as" | "className"
>) {
return (
<Headless.MenuHeading
{...props}
className={clsx(
className,
"col-span-full grid grid-cols-[1fr,auto] gap-x-12 px-3.5 pb-1 pt-2 text-sm/5 font-medium text-stone-500 sm:px-3 sm:text-xs/5 dark:text-stone-400",
)}
/>
);
}
export function DropdownDivider({
className,
...props
}: { className?: string } & Omit<
Headless.MenuSeparatorProps,
"as" | "className"
>) {
return (
<Headless.MenuSeparator
{...props}
className={clsx(
className,
"col-span-full mx-3.5 my-1 h-px border-0 bg-stone-950/5 sm:mx-3 dark:bg-white/10 forced-colors:bg-[CanvasText]",
)}
/>
);
}
export function DropdownLabel({
className,
...props
}: { className?: string } & Omit<Headless.LabelProps, "as" | "className">) {
return (
<Headless.Label
{...props}
data-slot="label"
className={clsx(
className,
"text-stone-900 dark:text-white col-start-2 row-start-1",
)}
{...props}
/>
);
}
export function DropdownDescription({
className,
...props
}: { className?: string } & Omit<
Headless.DescriptionProps,
"as" | "className"
>) {
return (
<Headless.Description
data-slot="description"
{...props}
className={clsx(
className,
"col-span-2 col-start-2 row-start-2 text-sm/5 text-stone-500 group-data-[focus]:text-white sm:text-xs/5 dark:text-stone-400 forced-colors:group-data-[focus]:text-[HighlightText]",
)}
/>
);
}
export function DropdownShortcut({
keys,
className,
...props
}: { keys: string | string[]; className?: string } & Omit<
Headless.DescriptionProps<"kbd">,
"as" | "className"
>) {
return (
<Headless.Description
as="kbd"
{...props}
className={clsx(
className,
"col-start-5 row-start-1 flex justify-self-end",
)}
>
{(Array.isArray(keys) ? keys : keys.split("")).map((char, index) => (
<kbd
key={index}
className={clsx([
"min-w-[2ch] text-center font-sans capitalize text-stone-400 group-data-[focus]:text-white forced-colors:group-data-[focus]:text-[HighlightText]",
// Make sure key names that are longer than one character (like "Tab") have extra space
index > 0 && char.length > 1 && "pl-1",
])}
>
{char}
</kbd>
))}
</Headless.Description>
);
}

View File

@@ -4,6 +4,7 @@ import clsx from "clsx";
import Link from "next/link";
import { usePathname } from "next/navigation";
import { ComponentType, ReactNode } from "react";
import { isActive } from "../../utils/nav";
import { Copyright } from "../atoms/Copyright";
import { NewsletterForm } from "./NewsletterForm";
import { SocialLinks, SocialLinksProps } from "./SocialLinks";
@@ -100,7 +101,7 @@ function FooterLink({
className={clsx(
"py-0.5 px-0 text-sm",
className,
path === href
isActive(href)
? "font-medium text-black dark:text-white cursor-default"
: "text-stone-600 dark:text-stone-400 hover:text-black dark:hover:text-white transition-colors hover:transition-none",
)}

View File

@@ -11,6 +11,7 @@ import clsx from "clsx";
import Link from "next/link";
import { usePathname } from "next/navigation";
import { ComponentType, ReactNode, useEffect, useState } from "react";
import { isActive } from "../../utils/nav";
import { Icon } from "../atoms/Icon";
import { BreadCrumb } from "../molecules/Breadcrumb";
import { SocialLinks, SocialLinksProps } from "./SocialLinks";
@@ -48,6 +49,7 @@ function NavItem({
className?: string;
}) {
const { href, icon, title, items, firstOnRight } = item;
const active = isActive(href);
const path = usePathname();
@@ -67,7 +69,7 @@ function NavItem({
className,
"text-sm px-2 lg:px-4 py-3 ",
firstOnRight && "ml-auto",
path === href ? "text-stone-900 dark:text-white" : "",
active ? "text-stone-900 dark:text-white" : "",
)}
{...item}
>
@@ -81,7 +83,7 @@ function NavItem({
<PopoverButton
className={clsx(
"flex items-center gap-1.5 text-sm px-2 lg:px-4 py-3 max-sm:w-full hover:text-stone-900 dark:hover:text-white transition-colors hover:transition-none focus-visible:outline-none",
path === href ? "text-stone-900 dark:text-white" : "",
active ? "text-stone-900 dark:text-white" : "",
)}
>
<span>{title}</span>

View File

@@ -0,0 +1,11 @@
import { usePathname } from "next/navigation";
export function isActive(href: string) {
const path = usePathname();
if (href === "/") {
return path === "/";
}
return path.startsWith(href);
}

View File

@@ -69,21 +69,12 @@ If you are not working within a monorepo, create a new file metro.config.js in t
```ts
const { getDefaultConfig } = require("expo/metro-config");
const config = getDefaultConfig(projectRoot);
config.resolver.unstable_enablePackageExports = true; // important setting
config.resolver.sourceExts = ["mjs", "js", "json", "ts", "tsx"];
config.resolver.requireCycleIgnorePatterns = [/(^|\/|\\)node_modules($|\/|\\)/];
module.exports = config;
```
</CodeGroup>
If you created the project using the command `npx create-expo-app -e with-router-tailwind my-jazz-app`, then `metro.config.js` is already present. In that case, simply add this setting to the existing file:
<CodeGroup>
```ts
config.resolver.unstable_enablePackageExports = true
```
</CodeGroup>
#### Monorepos
For monorepos, use the following metro.config.js:
@@ -106,7 +97,6 @@ For monorepos, use the following metro.config.js:
path.resolve(workspaceRoot, "node_modules"),
];
config.resolver.sourceExts = ["mjs", "js", "json", "ts", "tsx"];
config.resolver.unstable_enablePackageExports = true;
config.resolver.requireCycleIgnorePatterns = [/(^|\/|\\)node_modules($|\/|\\)/];
config.cacheStores = [
new FileStore({

View File

@@ -17,13 +17,14 @@ export const metadata = { title: "Jazz 0.10.0 is out!" };
<h3>What's new?</h3>
Here is what's changed in this release:
- [New authentication flow](/docs/upgrade/0-10-0#new-authentication-flow): Now with anonymous auth, redesigned to make Jazz easier to start with and be more flexible.
- [Local-only mode](/docs/upgrade/0-10-0#local-only-mode): Users can now explore your app in local-only mode before signing up.
- [Improvements on the loading APIs](/docs/upgrade/0-10-0#improved-loading-api); `ensureLoaded` now always returns a value and `useCoState` now returns `null` if the value is not found.
- [Jazz Workers on native WebSockets](/docs/upgrade/0-10-0#native-websocket-for-jazz-workers): Improves compatibility with a wider set of Javascript runtimes.
- [Group inheritance with role mapping](/docs/upgrade/0-10-0#group-inheritance): Groups can now inherit members from other groups with a fixed role.
- [New authentication flow](#new-authentication-flow): Now with anonymous auth, redesigned to make Jazz easier to start with and be more flexible.
- [Local-only mode](#local-only-mode): Users can now explore your app in local-only mode before signing up.
- [Improvements on the loading APIs](#improved-loading-api); `ensureLoaded` now always returns a value and `useCoState` now returns `null` if the value is not found.
- [Jazz Workers on native WebSockets](#native-websocket-for-jazz-workers): Improves compatibility with a wider set of Javascript runtimes.
- [Group inheritance with role mapping](#group-inheritance): Groups can now inherit members from other groups with a fixed role.
- Support for Node 14 dropped on cojson.
- Bugfix: `Group.removeMember` now returns a promise.
- Now `cojson` and `jazz-tools` don't export directly the crypto providers anymore. Replace the import with `cojson/crypto/WasmCrypto` or `cojson/crypto/PureJSCrypto` depending on your use case.
</div>
<h3 id="new-authentication-flow">New authentication flow</h3>

View File

@@ -283,27 +283,31 @@ const PasswordManagerIllustration = () => (
</tr>
</thead>
<tbody>
<tr className="border-b">
<td className="p-2">user@gmail.com</td>
<td className="p-2">gmail.com</td>
<td className="p-2">
<MockButton>Copy password</MockButton>
</td>
</tr>
<tr className="border-b">
<td className="p-2">user@gmail.com</td>
<td className="p-2">fb.com</td>
<td className="p-2">
<MockButton>Copy password</MockButton>
</td>
</tr>
<tr className="border-b">
<td className="p-2">user@gmail.com</td>
<td className="p-2">x.com</td>
<td className="p-2">
<MockButton>Copy password</MockButton>
</td>
</tr>
{[
{
email: "user@gmail.com",
domain: "gmail.com",
},
{
email: "user@gmail.com",
domain: "fb.com",
},
{
email: "user@gmail.com",
domain: "x.com",
},
].map(({ email, domain }) => (
<tr className="border-b max-sm:last:hidden" key={domain}>
<td className="p-2">{email}</td>
<td className="p-2">{domain}</td>
<td className="p-2">
<MockButton>
<Icon name="copy" size="2xs" className="mr-1" />
Password
</MockButton>
</td>
</tr>
))}
</tbody>
</table>
</div>

View File

@@ -1,3 +1,4 @@
import { Pizzazz } from "@/components/Pizzazz";
import { JazzNav } from "@/components/nav";
export default function RootLayout({
@@ -9,6 +10,7 @@ export default function RootLayout({
<div className="flex-1 w-full">
<JazzNav />
<main>{children}</main>
<Pizzazz />
</div>
);
}

View File

@@ -0,0 +1,12 @@
"use client";
import { addPizzazz } from "@unicorn-poo/pizzazz";
import { useEffect } from "react";
export function Pizzazz() {
useEffect(() => {
addPizzazz(document?.body, { effectType: "valentines" });
}, []);
return null;
}

View File

@@ -1,40 +1,81 @@
"use client";
import { Framework, frameworkNames, frameworks } from "@/lib/framework";
import { Framework } from "@/lib/framework";
import { useFramework } from "@/lib/use-framework";
import { clsx } from "clsx";
import { Select } from "gcmp-design-system/src/app/components/molecules/Select";
import { Button } from "gcmp-design-system/src/app/components/atoms/Button";
import {
Dropdown,
DropdownButton,
DropdownItem,
DropdownMenu,
} from "gcmp-design-system/src/app/components/organisms/Dropdown";
import { usePathname, useRouter } from "next/navigation";
import { useState } from "react";
const frameworks: Record<
Framework,
{
label: string;
experimental: boolean;
}
> = {
[Framework.React]: {
label: "React",
experimental: false,
},
[Framework.ReactNative]: {
label: "React Native",
experimental: false,
},
[Framework.Svelte]: {
label: "Svelte",
experimental: true,
},
[Framework.Vue]: {
label: "Vue",
experimental: true,
},
};
export function FrameworkSelect({ className }: { className?: string }) {
const router = useRouter();
const defaultFramework = useFramework();
const [framework, setFramework] = useState(defaultFramework);
const [selectedFramework, setSelectedFramework] =
useState<Framework>(defaultFramework);
const path = usePathname();
const onChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
e.preventDefault();
const newFramework = e.target.value as Framework;
setFramework(newFramework);
const selectFramework = (newFramework: Framework) => {
setSelectedFramework(newFramework);
router.push(path.replace(defaultFramework, newFramework));
};
return (
<Select
label="Framework"
value={framework}
onChange={onChange}
className={clsx("label:sr-only", className)}
>
{frameworks.map((framework) => (
<option key={framework} value={framework}>
{frameworkNames[framework]}
</option>
))}
</Select>
<Dropdown>
<DropdownButton
icon="chevronDown"
className="flex-row-reverse w-full justify-between"
as={Button}
variant="secondary"
>
{frameworks[selectedFramework].label}
</DropdownButton>
<DropdownMenu anchor="bottom start" className="z-50">
{Object.entries(frameworks).map(([key, framework]) => (
<DropdownItem
className="items-baseline"
key={key}
onClick={() => selectFramework(key as Framework)}
>
{framework.label}
{framework.experimental && (
<span className="ml-1 text-xs text-stone-500">
(experimental)
</span>
)}
</DropdownItem>
))}
</DropdownMenu>
</Dropdown>
);
}

View File

@@ -0,0 +1,3 @@
```sh
npx create-jazz-app@latest --example $EXAMPLE
```

View File

@@ -1,21 +1,66 @@
"use client";
import { Example } from "@/lib/example";
import { InterpolateInCode } from "@/mdx-components";
import { DialogDescription } from "@headlessui/react";
import { Button } from "gcmp-design-system/src/app/components/atoms/Button";
import { CodeGroup } from "gcmp-design-system/src/app/components/molecules/CodeGroup";
import {
Dialog,
DialogActions,
DialogBody,
DialogTitle,
} from "gcmp-design-system/src/app/components/organisms/Dialog";
import { useState } from "react";
import CreateJazzApp from "./CreateJazzApp.mdx";
export function ExampleLinks({ example }: { example: Example }) {
const { slug, demoUrl } = example;
const githubUrl = `https://github.com/gardencmp/jazz/tree/main/examples/${slug}`;
const [isOpen, setIsOpen] = useState(false);
return (
<div className="flex gap-2">
<Button href={githubUrl} newTab variant="secondary" size="sm">
View code
</Button>
{demoUrl && (
<Button href={demoUrl} newTab variant="secondary" size="sm">
View demo
<>
<div className="flex gap-2">
<Button variant="secondary" size="sm" onClick={() => setIsOpen(true)}>
Use as template
</Button>
)}
</div>
<Button href={githubUrl} newTab variant="secondary" size="sm">
<span className="md:hidden">Code</span>
<span className="hidden md:inline">View code</span>
</Button>
{demoUrl && (
<Button href={demoUrl} newTab variant="secondary" size="sm">
<span className="md:hidden">Demo</span>
<span className="hidden md:inline">View demo</span>
</Button>
)}
</div>
<Dialog onClose={() => setIsOpen(false)} open={isOpen}>
<DialogTitle>Use {example.name} example as a template</DialogTitle>
<DialogBody>
<div className="mb-6 aspect-[16/9] overflow-hidden w-full rounded-md bg-white border dark:bg-stone-925 sm:aspect-[2/1] md:aspect-[3/2]">
{example.illustration}
</div>
<p className="mb-3">
Generate a new Jazz app by running the command below.
</p>
<CodeGroup>
<CreateJazzApp
components={InterpolateInCode({
$EXAMPLE: example.slug,
})}
/>
</CodeGroup>
</DialogBody>
<DialogActions>
<Button onClick={() => setIsOpen(false)} variant="secondary">
Cancel
</Button>
</DialogActions>
</Dialog>
</>
);
}

View File

@@ -7,13 +7,6 @@ export enum Framework {
export const frameworks = Object.values(Framework);
export const frameworkNames: Record<Framework, string> = {
[Framework.React]: "React",
[Framework.ReactNative]: "React Native",
[Framework.Vue]: "Vue",
[Framework.Svelte]: "Svelte",
};
export const DEFAULT_FRAMEWORK = Framework.React;
export function isValidFramework(value: string): value is Framework {

View File

@@ -1,9 +1,31 @@
import { DocsLink } from "@/components/docs/DocsLink";
import type { MDXComponents } from "mdx/types";
export function useMDXComponents(components: MDXComponents): MDXComponents {
return {
a: (props) => <DocsLink {...props} />,
...components,
CodeWithInterpolation: ({
highlightedCode,
}: { highlightedCode: string }) => {
return <div dangerouslySetInnerHTML={{ __html: highlightedCode }} />;
},
};
}
export function InterpolateInCode(replace: { [key: string]: string }) {
return {
CodeWithInterpolation: ({
highlightedCode,
}: { highlightedCode: string }) => {
const newHighlightedCode = Object.entries(replace).reduce(
(acc, [key, value]) => {
return acc.replaceAll(
key.replaceAll("$", "&#36;").replaceAll("_", "&#95;"),
value,
);
},
highlightedCode,
);
return <div dangerouslySetInnerHTML={{ __html: newHighlightedCode }} />;
},
};
}

View File

@@ -38,7 +38,7 @@ function highlightPlugin() {
return async function transformer(tree) {
const highlighter = await getHighlighter({
langs: ["typescript", "bash", "tsx", "json", "svelte"],
theme: "css-variables", // use the theme
theme: "css-variables", // use css variables in shiki.css
});
visit(tree, "code", visitor);
@@ -116,7 +116,7 @@ function remarkHtmlToJsx() {
const [ast] = args;
visit(ast, "html", (node) => {
const escapedHtml = JSON.stringify(node.value);
const jsx = `<div dangerouslySetInnerHTML={{__html: ${escapedHtml} }}/>`;
const jsx = `<CodeWithInterpolation highlightedCode={${escapedHtml}}/>`;
const rawHtmlNode = fromMarkdown(jsx, {
extensions: [mdxjs()],
mdastExtensions: [mdxFromMarkdown()],

View File

@@ -27,6 +27,7 @@
"@turf/turf": "^7.1.0",
"@types/mdx": "^2.0.8",
"@types/topojson-client": "^3.1.5",
"@unicorn-poo/pizzazz": "^1.0.13",
"@vercel/analytics": "^1.3.1",
"@vercel/speed-insights": "^1.0.12",
"clsx": "^2.1.1",

View File

@@ -205,6 +205,9 @@ importers:
'@types/topojson-client':
specifier: ^3.1.5
version: 3.1.5
'@unicorn-poo/pizzazz':
specifier: ^1.0.13
version: 1.0.13
'@vercel/analytics':
specifier: ^1.3.1
version: 1.3.1(next@14.2.15(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
@@ -1323,6 +1326,10 @@ packages:
'@typescript/vfs@1.3.5':
resolution: {integrity: sha512-pI8Saqjupf9MfLw7w2+og+fmb0fZS0J6vsKXXrp4/PDXEFvntgzXmChCXC/KefZZS0YGS6AT8e0hGAJcTsdJlg==}
'@unicorn-poo/pizzazz@1.0.13':
resolution: {integrity: sha512-vw4sHhGBD5R6gJlaW3QEcXBsKOQ4w7WMCmw/0ef5x4ie3u1tqK/3j/pMhxinu2ahatdgoEK7lSO/2qAfYicwhA==}
engines: {node: '>=14.0.0', npm: '>=6.0.0'}
'@vercel/analytics@1.3.1':
resolution: {integrity: sha512-xhSlYgAuJ6Q4WQGkzYTLmXwhYl39sWjoMA3nHxfkvG+WdBT25c563a7QhwwKivEOZtPJXifYHR1m2ihoisbWyA==}
peerDependencies:
@@ -4684,6 +4691,8 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@unicorn-poo/pizzazz@1.0.13': {}
'@vercel/analytics@1.3.1(next@14.2.15(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)':
dependencies:
server-only: 0.0.1

View File

@@ -1,5 +1,29 @@
# cojson-storage-indexeddb
## 0.10.4
### Patch Changes
- Updated dependencies [1af6072]
- cojson@0.10.4
- cojson-storage@0.10.4
## 0.10.2
### Patch Changes
- Updated dependencies [cae3a9e]
- cojson@0.10.2
- cojson-storage@0.10.2
## 0.10.1
### Patch Changes
- Updated dependencies [5a63cba]
- cojson@0.10.1
- cojson-storage@0.10.1
## 0.10.0
### Patch Changes

View File

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

View File

@@ -1,4 +1,5 @@
import { ControlledAgent, LocalNode, WasmCrypto } from "cojson";
import { ControlledAgent, LocalNode } from "cojson";
import { WasmCrypto } from "cojson/crypto/WasmCrypto";
import { expect, test } from "vitest";
import { IDBStorage } from "../index.js";

View File

@@ -1,5 +1,29 @@
# cojson-storage-sqlite
## 0.8.63
### Patch Changes
- Updated dependencies [1af6072]
- cojson@0.10.4
- cojson-storage@0.10.4
## 0.8.62
### Patch Changes
- Updated dependencies [cae3a9e]
- cojson@0.10.2
- cojson-storage@0.10.2
## 0.8.61
### Patch Changes
- Updated dependencies [5a63cba]
- cojson@0.10.1
- cojson-storage@0.10.1
## 0.8.60
### Patch Changes

View File

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

View File

@@ -8,8 +8,6 @@ import type {
StoredSessionRow,
TransactionRow,
} from "cojson-storage";
import { Transaction } from "cojson/src/coValueCore.js";
import { Signature } from "cojson/src/crypto/crypto.js";
export class SQLiteClient implements DBClientInterface {
private readonly db: DatabaseT;
@@ -64,7 +62,7 @@ export class SQLiteClient implements DBClientInterface {
try {
return rows.map((row: any) => ({
...row,
tx: JSON.parse(row.tx) as Transaction,
tx: JSON.parse(row.tx) as CojsonInternalTypes.Transaction,
}));
} catch (e) {
console.warn("Invalid JSON in transaction", e);
@@ -121,7 +119,7 @@ export class SQLiteClient implements DBClientInterface {
async addTransaction(
sessionRowID: number,
nextIdx: number,
newTransaction: Transaction,
newTransaction: CojsonInternalTypes.Transaction,
): Promise<void> {
await this.db.execute(
"INSERT INTO transactions (ses, idx, tx) VALUES (?, ?, ?)",
@@ -136,7 +134,7 @@ export class SQLiteClient implements DBClientInterface {
}: {
sessionRowID: number;
idx: number;
signature: Signature;
signature: CojsonInternalTypes.Signature;
}): Promise<void> {
await this.db.execute(
"INSERT INTO signatureAfter (ses, idx, signature) VALUES (?, ?, ?)",

View File

@@ -1,5 +1,29 @@
# cojson-storage-sqlite
## 0.10.4
### Patch Changes
- Updated dependencies [1af6072]
- cojson@0.10.4
- cojson-storage@0.10.4
## 0.10.2
### Patch Changes
- Updated dependencies [cae3a9e]
- cojson@0.10.2
- cojson-storage@0.10.2
## 0.10.1
### Patch Changes
- Updated dependencies [5a63cba]
- cojson@0.10.1
- cojson-storage@0.10.1
## 0.10.0
### Patch Changes

View File

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

View File

@@ -1,5 +1,26 @@
# cojson-storage
## 0.10.4
### Patch Changes
- Updated dependencies [1af6072]
- cojson@0.10.4
## 0.10.2
### Patch Changes
- Updated dependencies [cae3a9e]
- cojson@0.10.2
## 0.10.1
### Patch Changes
- Updated dependencies [5a63cba]
- cojson@0.10.1
## 0.10.0
### Patch Changes

View File

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

View File

@@ -1,5 +1,26 @@
# cojson-transport-nodejs-ws
## 0.10.4
### Patch Changes
- Updated dependencies [1af6072]
- cojson@0.10.4
## 0.10.2
### Patch Changes
- Updated dependencies [cae3a9e]
- cojson@0.10.2
## 0.10.1
### Patch Changes
- Updated dependencies [5a63cba]
- cojson@0.10.1
## 0.10.0
### Minor Changes

View File

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

View File

@@ -1,5 +1,5 @@
import { SyncMessage } from "cojson";
import { CoValueKnownState } from "cojson/src/sync.js";
import { CojsonInternalTypes } from "cojson";
import { afterEach, beforeEach, describe, expect, test, vi } from "vitest";
import {
BatchedOutgoingMessages,
@@ -58,7 +58,7 @@ describe("BatchedOutgoingMessages", () => {
sessions: {
// Add a large payload to exceed MAX_OUTGOING_MESSAGES_CHUNK_BYTES
payload: "x".repeat(MAX_OUTGOING_MESSAGES_CHUNK_BYTES),
} as CoValueKnownState["sessions"],
} as CojsonInternalTypes.CoValueKnownState["sessions"],
};
batchedMessages.push(largeMessage);
@@ -82,7 +82,7 @@ describe("BatchedOutgoingMessages", () => {
sessions: {
// Add a large payload to exceed MAX_OUTGOING_MESSAGES_CHUNK_BYTES
payload: "x".repeat(MAX_OUTGOING_MESSAGES_CHUNK_BYTES),
} as CoValueKnownState["sessions"],
} as CojsonInternalTypes.CoValueKnownState["sessions"],
};
batchedMessages.push(smallMessage);

View File

@@ -1,4 +1,5 @@
import { ControlledAgent, LocalNode, WasmCrypto } from "cojson";
import { ControlledAgent, LocalNode } from "cojson";
import { WasmCrypto } from "cojson/crypto/WasmCrypto";
import { afterEach, beforeEach, describe, expect, test } from "vitest";
import { WebSocket } from "ws";
import { createWebSocketPeer } from "../createWebSocketPeer";

View File

@@ -1,5 +1,6 @@
import { createServer } from "http";
import { ControlledAgent, LocalNode, WasmCrypto } from "cojson";
import { ControlledAgent, LocalNode } from "cojson";
import { WasmCrypto } from "cojson/crypto/WasmCrypto";
import { WebSocket, WebSocketServer } from "ws";
import { createWebSocketPeer } from "../createWebSocketPeer";

View File

@@ -1,5 +1,24 @@
# cojson
## 0.10.4
### Patch Changes
- 1af6072: Revert PriorityBasedMessageQueue to use an array-based queue
## 0.10.2
### Patch Changes
- cae3a9e: Add debug info to load failure end missing header errors
## 0.10.1
### Patch Changes
- 5a63cba: Crypto packages must now be imported from cojson/crypto/WasmCrypto or cojson/crypto/PureJSCrypto
Removed the separated dists for React Native.
## 0.10.0
### Minor Changes

View File

@@ -1,30 +1,31 @@
{
"name": "cojson",
"module": "dist/web/index.web.js",
"main": "dist/web/index.web.js",
"types": "src/index.web.ts",
"react-native": "dist/native/index.native.js",
"module": "dist/index.js",
"main": "dist/index.js",
"types": "src/index.ts",
"exports": {
".": {
"react-native": "./dist/native/index.native.js",
"types": "./src/index.web.ts",
"default": "./dist/web/index.web.js"
"types": "./src/index.ts",
"default": "./dist/index.js"
},
"./crypto": {
"react-native": "./dist/native/crypto/export.js",
"types": "./src/crypto/export.ts",
"default": "./dist/web/crypto/export.js"
"./dist/crypto/PureJSCrypto": {
"types": "./src/crypto/PureJSCrypto.ts",
"default": "./dist/crypto/PureJSCrypto.js"
},
"./native": {
"react-native": "./dist/native/index.native.js",
"types": "./src/index.native.ts",
"default": "./dist/native/index.native.js"
"./crypto/PureJSCrypto": {
"types": "./src/crypto/PureJSCrypto.ts",
"default": "./dist/crypto/PureJSCrypto.js"
},
"./crypto/WasmCrypto": {
"types": "./src/crypto/WasmCrypto.ts",
"default": "./dist/crypto/WasmCrypto.js"
},
"./dist/*": "./dist/*",
"./src/*": "./src/*"
},
"type": "module",
"license": "MIT",
"version": "0.10.0",
"version": "0.10.4",
"devDependencies": {
"@opentelemetry/sdk-metrics": "^1.29.0",
"typescript": "~5.6.2",
@@ -42,15 +43,12 @@
"queueueue": "^4.1.2"
},
"scripts": {
"dev": "tsc --watch --sourceMap --outDir dist/web -p tsconfig.web.json",
"dev:native": "tsc --watch --sourceMap --outDir dist/native -p tsconfig.native.json",
"dev": "tsc --watch --sourceMap --outDir dist",
"test": "vitest --run --root ../../ --project cojson",
"test:watch": "vitest --watch --root ../../ --project cojson",
"format-and-lint": "biome check .",
"format-and-lint:fix": "biome check . --write",
"build:web": "tsc --sourceMap --outDir dist/web -p tsconfig.web.json",
"build:native": "tsc --sourceMap --outDir dist/native -p tsconfig.native.json",
"build": "rm -rf ./dist && pnpm run build:native && pnpm run build:web",
"build": "rm -rf ./dist && tsc --sourceMap --outDir dist",
"prepublishOnly": "npm run build"
},
"gitHead": "33c27053293b4801b968c61d5c4c989f93a67d13"

View File

@@ -93,7 +93,7 @@ export class PeerState {
this.processing = true;
let entry: QueueEntry<SyncMessage> | undefined;
let entry: QueueEntry | undefined;
while ((entry = this.queue.pull())) {
// Awaiting the push to send one message at a time
// This way when the peer is "under pressure" we can enqueue all
@@ -130,7 +130,7 @@ export class PeerState {
}
private closeQueue() {
let entry: QueueEntry<SyncMessage> | undefined;
let entry: QueueEntry | undefined;
while ((entry = this.queue.pull())) {
// Using resolve here to avoid unnecessary noise in the logs
entry.resolve();

View File

@@ -18,12 +18,11 @@ function promiseWithResolvers<R>() {
};
}
export type QueueEntry<V> = {
msg: V;
export type QueueEntry = {
msg: SyncMessage;
promise: Promise<void>;
resolve: () => void;
reject: (_: unknown) => void;
next: QueueEntry<V> | undefined;
};
/**
@@ -34,68 +33,10 @@ type Tuple<T, N extends number, A extends unknown[] = []> = A extends {
}
? A
: Tuple<T, N, [...A, T]>;
type QueueTuple = Tuple<Queue<SyncMessage>, 8>;
class Queue<V> {
head: QueueEntry<V> | undefined = undefined;
tail: QueueEntry<V> | undefined = undefined;
push(msg: V) {
const { promise, resolve, reject } = promiseWithResolvers<void>();
const entry: QueueEntry<V> = {
msg,
promise,
resolve,
reject,
next: undefined,
};
if (this.head === undefined) {
this.head = entry;
} else {
if (this.tail === undefined) {
throw new Error("Tail is null but head is not");
}
this.tail.next = entry;
}
this.tail = entry;
return entry;
}
pull() {
const entry = this.head;
if (entry) {
this.head = entry.next;
}
if (this.head === undefined) {
this.tail = undefined;
}
return entry;
}
isNonEmpty() {
return this.head !== undefined;
}
}
type QueueTuple = Tuple<QueueEntry[], 8>;
export class PriorityBasedMessageQueue {
private queues: QueueTuple = [
new Queue(),
new Queue(),
new Queue(),
new Queue(),
new Queue(),
new Queue(),
new Queue(),
new Queue(),
];
private queues: QueueTuple = [[], [], [], [], [], [], [], []];
queueSizeCounter = metrics
.getMeter("cojson")
.createUpDownCounter("jazz.messagequeue.size", {
@@ -111,19 +52,22 @@ export class PriorityBasedMessageQueue {
constructor(private defaultPriority: CoValuePriority) {}
public push(msg: SyncMessage) {
const { promise, resolve, reject } = promiseWithResolvers<void>();
const entry: QueueEntry = { msg, promise, resolve, reject };
const priority = "priority" in msg ? msg.priority : this.defaultPriority;
const entry = this.getQueue(priority).push(msg);
this.getQueue(priority).push(entry);
this.queueSizeCounter.add(1, {
priority,
});
return entry.promise;
return promise;
}
public pull() {
const priority = this.queues.findIndex((queue) => queue.isNonEmpty());
const priority = this.queues.findIndex((queue) => queue.length > 0);
if (priority === -1) {
return;
@@ -133,6 +77,6 @@ export class PriorityBasedMessageQueue {
priority,
});
return this.queues[priority]?.pull();
return this.queues[priority]?.shift();
}
}

View File

@@ -307,6 +307,7 @@ async function loadCoValueFromPeers(
const timeout = setTimeout(() => {
if (coValueEntry.state.type === "loading") {
logger.warn("Failed to load coValue from peer", {
coValueId: coValueEntry.id,
peerId: peer.id,
peerRole: peer.role,
});

View File

@@ -1,2 +0,0 @@
export * from "./PureJSCrypto.js";
export * from "./WasmCrypto.js";

View File

@@ -173,6 +173,7 @@ export type {
// eslint-disable-next-line @typescript-eslint/no-namespace
export namespace CojsonInternalTypes {
export type CoValueKnownState = import("./sync.js").CoValueKnownState;
export type CoJsonValue<T> = import("./jsonValue.js").CoJsonValue<T>;
export type DoneMessage = import("./sync.js").DoneMessage;
export type KnownStateMessage = import("./sync.js").KnownStateMessage;
export type LoadMessage = import("./sync.js").LoadMessage;

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