Compare commits

...

156 Commits

Author SHA1 Message Date
Guido D'Orsi
74fa115709 Merge pull request #2455 from garden-co/changeset-release/main
Version Packages
2025-06-09 12:41:11 +02:00
github-actions[bot]
baa5278cf3 Version Packages 2025-06-09 10:33:53 +00:00
Guido D'Orsi
6852b60e72 Merge pull request #2471 from garden-co/fix/account-migration-loaded-types
Ensure the types on withMigration expect a shallowly loaded Account
2025-06-09 12:30:04 +02:00
Anselm
fc2b054fc2 Fix formatting 2025-06-09 11:13:02 +01:00
Anselm
048ac1d54f Add changeset 2025-06-09 11:10:47 +01:00
Anselm
4ed7d61ea4 Ensure the types on withMigration expect a shallowly loaded Account 2025-06-09 11:10:18 +01:00
Trisha Lim
ced325da06 Merge pull request #2470 from garden-co/docs/inspector-full-json 2025-06-09 10:23:53 +01:00
Trisha Lim
5563799a2a lint fix 2025-06-09 09:19:35 +01:00
Trisha Lim
5a783f8eac Merge pull request #2467 from joeinnes/fix-small-screen-x-overflow
Add w-full to the pagefind container div
2025-06-09 09:17:13 +01:00
Trisha Lim
0ea1530ee9 update inspector docs instruction for passing credentials 2025-06-09 09:12:56 +01:00
Trisha Lim
164579ee9c Merge pull request #2469 from timolins/paste-json-inspector
[Inspector] Allow pasting of full account JSON
2025-06-09 09:00:59 +01:00
Timo Lins
fc453e68c1 Allow pasting of full json into inspector account 2025-06-08 21:22:46 +02:00
Joe Innes
48544ca4d1 Add w-full to the pagefind container div. 2025-06-07 14:55:10 +02:00
Nikos Papadopoulos
b2e2b91dd7 Merge pull request #2461 from garden-co/nikos/ex-app-prosemirror-layout
updates richtext-prosemirror example app layout
2025-06-06 18:16:00 +02:00
Nikos Papadopoulos
36d7791326 updates richtext-prosemirror example app class names 2025-06-06 16:45:53 +01:00
Nikos Papadopoulos
707d84dea0 updates richtext-prosemirror example app layout 2025-06-06 16:22:27 +01:00
Emil Sayahi
6da8e3948c feat(docs): search (#2378)
* feat: documentation search results

Signed-off-by: Benjamin S. Leveritt <benjamin@leveritt.co.uk>
Co-authored-by: Benjamin S. Leveritt <benjamin@leveritt.co.uk>
Co-authored-by: Trisha Lim <hello@trishalim.com>
2025-06-06 15:27:55 +01:00
Sammii
225da5ca42 Merge pull request #2458 from garden-co/feat/covalues-visualisation 2025-06-06 15:14:28 +02:00
Anselm Eickhoff
3943f7fc41 Merge pull request #2460 from garden-co/fix/vercel-ingore-build-project-id
Use vercel project ID for ignore build step
2025-06-06 14:03:59 +01:00
Anselm
d982bb50db Use vercel project ID for ignore build step 2025-06-06 14:02:51 +01:00
Sammii
92de0a6683 covalues page update 2025-06-06 13:36:33 +01:00
Sammii
e10d00b444 switch refactor 2025-06-06 13:36:24 +01:00
Sammii
89b6c1cbb9 creating Switch component from radix 2025-06-06 13:34:47 +01:00
Sammii
6ec1933d65 updating schema to zod 2025-06-06 13:34:18 +01:00
Nikos Papadopoulos
854c6761a4 Merge pull request #2459 from garden-co/nikos/docs-url-updates
updates example app URLs in documentation
2025-06-06 14:19:10 +02:00
Nikos Papadopoulos
fc8acb0688 updates example app URLs in documentation 2025-06-06 13:10:50 +01:00
Trisha Lim
7a65b35ac5 Merge pull request #2437 from garden-co/chore/tailwind-v4
chore: update react starter to tailwind v4
2025-06-06 12:45:22 +01:00
Trisha Lim
2ef3938d71 update lock file 2025-06-06 12:09:16 +01:00
Trisha Lim
1e71b23779 fix(starter): wording 2025-06-06 12:08:37 +01:00
Trisha Lim
31071a4b21 chore: update react starter to tailwind v4 2025-06-06 12:08:35 +01:00
Sammii
8f53a52110 moving covalues folder into app to see components on /covalues 2025-06-06 10:04:25 +01:00
Anselm Eickhoff
08b105508f Merge pull request #2440 from garden-co/optimize-vercel-deployments
Optimize Vercel deployments
2025-06-06 09:22:00 +01:00
Benjamin S. Leveritt
f567b3d24b Restore homepage build script 2025-06-06 08:52:52 +01:00
Benjamin S. Leveritt
dd750fc6e8 Remove ignore scripts
Signed-off-by: Benjamin S. Leveritt <benjamin@leveritt.co.uk>
2025-06-06 08:52:01 +01:00
Benjamin S. Leveritt
814d99e0bc Remove app name from examples 2025-06-06 08:02:38 +01:00
Benjamin S. Leveritt
0eb70c2171 Investigating what turbo-ignore defaults to on Vercel 2025-06-06 07:52:42 +01:00
Benjamin S. Leveritt
64e787a57f Remove app name 2025-06-06 07:25:11 +01:00
Benjamin S. Leveritt
1e8c3df83e Remove app name, as we no longer use it 2025-06-06 07:24:50 +01:00
Benjamin S. Leveritt
5013b1d97d Add prosekit 2025-06-06 07:24:27 +01:00
Benjamin S. Leveritt
c4837b9b92 Add ignore to organization 2025-06-06 07:10:41 +01:00
Benjamin S. Leveritt
e527cb676b Fix clerk vercel config 2025-06-06 07:02:55 +01:00
Benjamin S. Leveritt
2c75c46029 Adds turbo-ignore to examples 2025-06-06 07:00:38 +01:00
Benjamin S. Leveritt
f92f65cc28 Trying turbo-ignore 2025-06-06 06:51:17 +01:00
Benjamin S. Leveritt
d88a94bc68 Lets see what refs we have 2025-06-05 21:26:09 +01:00
Guido D'Orsi
e9bf27467f Merge pull request #2445 from garden-co/docs/rnqc-provider
docs: RNQuickCrypto provider docs
2025-06-05 21:57:49 +02:00
Sammii
c9bd778c03 Merge pull request #2456 from garden-co/feat/create-team-profile-pages
Feat/create team profile pages
2025-06-05 21:30:39 +02:00
Sammii
c3832ad794 fix formatting qualms 2025-06-05 19:26:58 +01:00
Sammii
9b807cbba9 updating gios name 2025-06-05 19:15:21 +01:00
Sammii
32fd3cab19 creating individual team member profiles 2025-06-05 19:12:39 +01:00
Sammii
7502dba11b add Brad to team page 2025-06-05 18:43:33 +01:00
Guido D'Orsi
e9baf69126 Merge pull request #2439 from garden-co/emil/addMember-error-message
fix: clarify `Group.addMember` error message
2025-06-05 19:28:52 +02:00
Trisha Lim
f597d64423 homepage alignment fix (#2453) 2025-06-05 18:22:47 +01:00
Trisha Lim
5c8ce99ab5 Merge pull request #2449 from garden-co/feat/updated-created-dates
docs and example for _createdAt and _lastUpdatedAt
2025-06-05 18:10:38 +01:00
Joe Innes
679ca6c36b docs: ✏️ Update README files to reflect changes in local sync server setup (#2444)
* docs: ✏️ Update README files to reflect changes in local sync server setup

- Changed instructions for running a local sync server to use `sync` parameter format: `{ peer: "ws://localhost:4200" }`.
- Updated multiple example README files for consistency across projects.

* Restore the example in the music player for reference
2025-06-05 18:09:34 +01:00
Emil Sayahi
e6130219fe fix: explicitly check if other account is admin 2025-06-05 10:03:45 -07:00
Trisha Lim
046075288b docs: _createdAt and _lastUpdatedAt 2025-06-05 17:38:54 +01:00
Trisha Lim
57fa927640 use history utility functions in version history app 2025-06-05 17:28:14 +01:00
Brad Anderson
b45bf9248e docs: RNQuickCrypto provider docs 2025-06-05 11:05:03 -04:00
Emil Sayahi
6c2b8a8f8f fix(addMember): clarify admins demoting admins 2025-06-05 07:54:41 -07:00
Benjamin S. Leveritt
7be49602dd Remove ignoreCommand from clerk 2025-06-05 13:11:19 +01:00
Benjamin S. Leveritt
cb73d474a6 Check previous SHA is accessible for turbo, with fallback 2025-06-05 13:11:19 +01:00
Benjamin S. Leveritt
cd03cb77f5 Add checks to other examples
Signed-off-by: Benjamin S. Leveritt <benjamin@leveritt.co.uk>
2025-06-05 13:11:19 +01:00
Benjamin S. Leveritt
d9d5662b7a Add more inputs for turbo 2025-06-05 13:11:19 +01:00
Benjamin S. Leveritt
39cd197494 Fallback to main checks 2025-06-05 13:11:19 +01:00
Benjamin S. Leveritt
5397fb27bc Clean up imports 2025-06-05 13:11:18 +01:00
Benjamin S. Leveritt
f0bfdc3f5f Dependency checking with Turbo 2025-06-05 13:11:18 +01:00
Benjamin S. Leveritt
5f45036e2a Add ignore to form
Signed-off-by: Benjamin S. Leveritt <benjamin@leveritt.co.uk>
2025-06-05 13:11:18 +01:00
Benjamin S. Leveritt
20eab19676 Compare to last successful deployment
Hopefully this works better against derivative branches

Signed-off-by: Benjamin S. Leveritt <benjamin@leveritt.co.uk>
2025-06-05 13:11:18 +01:00
Benjamin S. Leveritt
6af2feb2e7 Check current project path 2025-06-05 13:11:18 +01:00
Benjamin S. Leveritt
60df32ba05 Try with chat first 2025-06-05 13:11:18 +01:00
Benjamin S. Leveritt
90f36e61d6 Optimize turbo.json for better caching and build performance 2025-06-05 13:11:17 +01:00
Benjamin S. Leveritt
2d27cd5356 Add enhanced Vercel build ignore script with intelligent change detection 2025-06-05 13:11:17 +01:00
Nikos Papadopoulos
0262b9d501 Merge pull request #2438 from garden-co/nikos-example_apps_updates
- Integrates prosekit example app in monorepo
- Updates URLs in all applicable apps in https://jazz.tools/examples to follow the format: app-name.demo.jazz.tools
- Updates URLs in all applicable example apps README files
- Renames richtext example app to richtext-prosemirror
- Moves Svelte example apps above Vue example apps
- Adds jazz.tools entries for richtext prosekit, richtext tiptap
2025-06-05 13:32:40 +02:00
Nikos Papadopoulos
115e22c89d updates pnpm-lock.yaml after merge from main 2025-06-05 12:24:56 +01:00
Nikos Papadopoulos
687d9bbbff Merge branch 'main' into nikos-example_apps_updates 2025-06-05 12:22:50 +01:00
Benjamin S. Leveritt
56ad6379d9 Merge pull request #2443 from garden-co/fix-design-system-build
Fix build for design system
2025-06-05 12:17:27 +01:00
Benjamin S. Leveritt
481ffa1d96 Add package manager 2025-06-05 12:12:08 +01:00
Guido D'Orsi
a383c7e984 Merge pull request #2432 from garden-co/changeset-release/main
Version Packages
2025-06-05 13:11:13 +02:00
github-actions[bot]
8ca283147d Version Packages 2025-06-05 11:04:14 +00:00
Guido D'Orsi
c3d87796ed chore: update changeset 2025-06-05 13:00:37 +02:00
Guido D'Orsi
cb88caced9 fix(comap): return a valid value on _createdAt even when setting a custom uniqueness value 2025-06-05 12:58:26 +02:00
Guido D'Orsi
6313ead62d Revert "fix: use creation time from CoValue header"
This reverts commit cc0479afe0.
2025-06-05 12:38:23 +02:00
Guido D'Orsi
f674910aa9 Merge pull request #2426 from garden-co/emil/comap-time-getters
feat: `_createdAt` and `_lastUpdatedAt`
2025-06-05 12:23:23 +02:00
Guido D'Orsi
37fc25f5a6 Merge pull request #2434 from garden-co/fix/svelte-costate
Fix id reactivity on CoState for Svelte 5.33 (second try)
2025-06-05 12:22:19 +02:00
Guido D'Orsi
5e9c338c27 Merge pull request #2436 from garden-co/feat/react-19-updates
fix(react-19): optimize re-renders when the values are already in memory
2025-06-05 12:21:55 +02:00
Guido D'Orsi
4b61f7c7a5 chore: format 2025-06-05 12:20:58 +02:00
Guido D'Orsi
1c8472ffbd Merge pull request #2441 from garden-co/fix/union-schema-conversion
Fix union schemas in anySchemaToCoSchema
2025-06-05 12:19:33 +02:00
Benjamin S. Leveritt
9dba68ac36 Remove migration script
Signed-off-by: Benjamin S. Leveritt <benjamin@leveritt.co.uk>
2025-06-05 11:18:29 +01:00
Anselm
13b57aa576 Add changeset 2025-06-05 11:10:05 +01:00
Anselm
aedf0f3ac5 Fix union schemas in anySchemaToCoSchema 2025-06-05 11:09:06 +01:00
Benjamin S. Leveritt
7fa61644b0 Revert turbo.json to original state 2025-06-05 10:19:22 +01:00
Nikos Papadopoulos
dbc6342222 renames api-key.ts to apiKey.ts 2025-06-05 10:16:53 +01:00
Benjamin S. Leveritt
12389c82f9 Add migration script to update all projects to enhanced ignore script 2025-06-05 10:05:16 +01:00
Benjamin S. Leveritt
4c03a17d3a Optimize turbo.json for better caching and build performance 2025-06-05 10:04:51 +01:00
Benjamin S. Leveritt
5d1ea45a9c Add enhanced Vercel build ignore script with change detection 2025-06-05 10:04:34 +01:00
Emil Sayahi
780961d46f fix: show role of current account 2025-06-04 16:01:45 -07:00
Emil Sayahi
cc0479afe0 fix: use creation time from CoValue header 2025-06-04 15:45:59 -07:00
Emil Sayahi
c102f18b62 Update mean-turkeys-turn.md 2025-06-04 15:15:13 -07:00
Emil Sayahi
57fb69fa6f chore: changeset 2025-06-04 15:14:41 -07:00
Emil Sayahi
8985e2d4ff fix: clarify addMember error message 2025-06-04 15:12:55 -07:00
Emil Sayahi
cfb6786468 feat(jazz-expo): API for clearing local DB (#2427)
* feat(jazz-expo): API for clearing local DB

todo:
- tests
- changeset

* Revert "feat(jazz-expo): API for clearing local DB"

This reverts commit 459e1d04ea.

* feat(jazz-expo): API for clearing local DB

* chore: changeset

* Update .changeset/plenty-ways-smash.md

Co-authored-by: Guido D'Orsi <guido@garden.co>

---------

Co-authored-by: Guido D'Orsi <guido@garden.co>
2025-06-04 12:35:04 -07:00
Emil Sayahi
5662faa9c0 chore: changeset 2025-06-04 12:10:15 -07:00
Emil Sayahi
3e7d9cb585 feat: tests 2025-06-04 12:08:56 -07:00
Nikos Papadopoulos
ec65ba74a8 reorders example apps 2025-06-04 18:52:23 +01:00
Nikos Papadopoulos
f679e6b392 updates richtext-prosemirror vercel configuration 2025-06-04 18:49:11 +01:00
Nikos Papadopoulos
3bcaa81c17 updates pnpm-lock.yaml 2025-06-04 18:34:27 +01:00
Guido D'Orsi
2116a598ae fix(react-19): optimize re-renders when the values are already in memory 2025-06-04 19:34:12 +02:00
Nikos Papadopoulos
8a00392894 adds attribution in prosekit example app README 2025-06-04 18:28:03 +01:00
Nikos Papadopoulos
f3f2e85c53 removes obsolete files 2025-06-04 18:27:17 +01:00
Nikos Papadopoulos
0ff08e9893 moves richtext example to richtext-prosemirror 2025-06-04 18:26:28 +01:00
Nikos Papadopoulos
ca517517f9 updates pnpm-lock.yaml 2025-06-04 18:07:33 +01:00
Nikos Papadopoulos
55bdbbf12e Merge branch 'main' into nikos-example_apps_updates 2025-06-04 17:55:49 +01:00
Nikos Papadopoulos
5c7a7d0f7c updates the homepage example apps URLs 2025-06-04 17:54:55 +01:00
Nikos Papadopoulos
af388c11d5 updates example apps README files, adds new apps to example page 2025-06-04 17:43:05 +01:00
Nikos Papadopoulos
df255f850f adds prosekit example app 2025-06-04 16:43:58 +01:00
Guido D'Orsi
d14a069a12 Fix id reactivity on CoState for Svelte 5.33 (second try) 2025-06-04 16:11:14 +02:00
Anselm Eickhoff
aacef80994 Merge pull request #2433 from garden-co/fix/team-page
update team page, adding me and making all socials the same order
2025-06-04 14:46:10 +01:00
Sammii
2a237e5d32 amending file .ext 2025-06-04 14:39:27 +01:00
Sammii
0fe30eca0b update team page, adding me and making all socials the same order 2025-06-04 14:23:40 +01:00
Guido D'Orsi
dea7a8dfd9 Merge pull request #2282 from Wizzel1/Add-missing-discriminator
Add missing discriminator
2025-06-04 15:21:29 +02:00
Guido D'Orsi
ab7191bed0 Merge remote-tracking branch 'origin/main' into Add-missing-discriminator 2025-06-04 15:12:14 +02:00
Guido D'Orsi
901b7c0a51 Merge pull request #2377 from garden-co/2376-groupmakepublic-as-an-alias
Add makePublic to group
2025-06-04 15:02:05 +02:00
Benjamin S. Leveritt
17bea5975c Merge pull request #2430 from garden-co/test-create-jazz-app
Test `create-jazz-app`
2025-06-04 12:54:56 +01:00
Benjamin S. Leveritt
e005ecd0a1 Add changeset 2025-06-04 12:08:27 +01:00
Benjamin S. Leveritt
e7e505e5f3 Add changeset 2025-06-04 12:03:58 +01:00
Benjamin S. Leveritt
d6ffe03d3c Add makePublic to docs 2025-06-04 12:02:18 +01:00
Benjamin S. Leveritt
1120747a24 Add makePublic alias to some example apps 2025-06-04 11:50:24 +01:00
Benjamin S. Leveritt
1e2d7d1c4e Add makePublic to group 2025-06-04 11:44:06 +01:00
Benjamin S. Leveritt
e26f110acd Merge pull request #2428 from garden-co/feature/co-map-migrations
Tweak CoMap migration copy and examples
2025-06-04 11:37:21 +01:00
Benjamin S. Leveritt
28f84a4ee6 Update lock 2025-06-04 11:31:36 +01:00
Benjamin S. Leveritt
cffe4abb84 Handle SIGINT gracefully 2025-06-04 11:21:00 +01:00
Benjamin S. Leveritt
2e0b7cee8c Refactor package manager detection into utils 2025-06-04 11:21:00 +01:00
Benjamin S. Leveritt
d3b47f59e8 Add automatic tests 2025-06-04 11:21:00 +01:00
Benjamin S. Leveritt
aea3287965 Merge pull request #2373 from lukahartwig/main
Set default package manager based on command runner
2025-06-04 11:17:25 +01:00
Benjamin S. Leveritt
6525f8a12e Merge pull request #2325 from garden-co/2324-turbo-dev-doesnt-need-to-build-the-local-package
Turbo just builds deps now
2025-06-04 09:11:16 +01:00
Benjamin S. Leveritt
fe4c934a4b Tweak copy and examples in the docs 2025-06-04 08:26:05 +01:00
Emil Sayahi
60261c8dba feat: _createdAt and _lastUpdatedAt 2025-06-03 13:34:55 -07:00
Guido D'Orsi
7411049faa Merge pull request #2423 from garden-co/changeset-release/main
Version Packages
2025-06-03 19:48:03 +02:00
github-actions[bot]
356b06559b Version Packages 2025-06-03 17:45:08 +00:00
Guido D'Orsi
193738cfe2 Merge pull request #2405 from garden-co/feature/co-map-migrations
feat: add support for coMap migrations
2025-06-03 19:40:53 +02:00
Guido D'Orsi
ddb74fa167 docs: remove unused import 2025-06-03 19:35:31 +02:00
Guido D'Orsi
a7ee0465b5 docs: small fix 2025-06-03 18:35:04 +02:00
Guido D'Orsi
e995d8a1fe chore: fix type issue in todo example 2025-06-03 17:50:17 +02:00
Guido D'Orsi
5ccb48446e docs: cover CoMap migrations 2025-06-03 17:46:12 +02:00
Guido D'Orsi
04b20c2e42 fix: fix castAs for Zod schemas and make the CoMap migrations stable 2025-06-03 17:14:59 +02:00
Guido D'Orsi
6f72419b6e feat: add support for coMap migrations 2025-06-02 20:23:52 +02:00
Luka Hartwig
fa2227716f Remove return type 2025-05-27 23:08:56 +02:00
Luka Hartwig
38dabd4602 Set default package manager based on command runner 2025-05-27 16:34:40 +02:00
Benjamin S. Leveritt
69709c2cf2 Turbo just builds deps now
What a smol change?
2025-05-22 10:29:42 +01:00
Wizzel1
e88252bee4 Fix formatting 2025-05-19 20:20:52 +02:00
Wizzel1
a6b7857f6f Fix markdown formatting 2025-05-19 20:06:28 +02:00
Wizzel1
265c30158e Fix markdown formatting 2025-05-19 19:59:56 +02:00
Wizzel1
505e132f1e Run format script 2025-05-19 19:53:12 +02:00
Wizzel1
c6d5195cb5 Update tests 2025-05-19 19:48:22 +02:00
Wizzel1
8af543e7d6 Update docs 2025-05-19 19:48:17 +02:00
Wizzel1
016b2098a7 Update example 2025-05-19 19:48:11 +02:00
337 changed files with 13400 additions and 1621 deletions

View File

@@ -1,5 +1,45 @@
# betterauth
## 0.1.25
### Patch Changes
- Updated dependencies [048ac1d]
- jazz-tools@0.14.22
- jazz-betterauth-server-plugin@0.14.22
- jazz-inspector@0.14.22
- jazz-react@0.14.22
- jazz-react-auth-betterauth@0.14.22
- jazz-betterauth-client-plugin@0.14.22
## 0.1.24
### Patch Changes
- Updated dependencies [e7e505e]
- Updated dependencies [13b57aa]
- Updated dependencies [5662faa]
- Updated dependencies [2116a59]
- jazz-tools@0.14.21
- jazz-betterauth-server-plugin@0.14.21
- jazz-inspector@0.14.21
- jazz-react@0.14.21
- jazz-react-auth-betterauth@0.14.21
- jazz-betterauth-client-plugin@0.14.21
## 0.1.23
### Patch Changes
- Updated dependencies [6f72419]
- Updated dependencies [04b20c2]
- jazz-tools@0.14.20
- jazz-betterauth-server-plugin@0.14.20
- jazz-inspector@0.14.20
- jazz-react@0.14.20
- jazz-react-auth-betterauth@0.14.20
- jazz-betterauth-client-plugin@0.14.20
## 0.1.22
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "betterauth",
"version": "0.1.22",
"version": "0.1.25",
"private": true,
"type": "module",
"scripts": {

View File

@@ -1,5 +1,37 @@
# chat-rn-expo-clerk
## 1.0.145
### Patch Changes
- Updated dependencies [048ac1d]
- jazz-tools@0.14.22
- jazz-expo@0.14.22
- jazz-react-native-media-images@0.14.22
## 1.0.144
### Patch Changes
- Updated dependencies [e7e505e]
- Updated dependencies [cfb6786]
- Updated dependencies [13b57aa]
- Updated dependencies [5662faa]
- Updated dependencies [2116a59]
- jazz-tools@0.14.21
- jazz-expo@0.14.21
- jazz-react-native-media-images@0.14.21
## 1.0.143
### Patch Changes
- Updated dependencies [6f72419]
- Updated dependencies [04b20c2]
- jazz-tools@0.14.20
- jazz-expo@0.14.20
- jazz-react-native-media-images@0.14.20
## 1.0.142
### Patch Changes

View File

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

View File

@@ -1,5 +1,34 @@
# chat-rn-expo
## 1.0.13
### Patch Changes
- Updated dependencies [048ac1d]
- jazz-tools@0.14.22
- jazz-expo@0.14.22
## 1.0.12
### Patch Changes
- Updated dependencies [e7e505e]
- Updated dependencies [cfb6786]
- Updated dependencies [13b57aa]
- Updated dependencies [5662faa]
- Updated dependencies [2116a59]
- jazz-tools@0.14.21
- jazz-expo@0.14.21
## 1.0.11
### Patch Changes
- Updated dependencies [6f72419]
- Updated dependencies [04b20c2]
- jazz-tools@0.14.20
- jazz-expo@0.14.20
## 1.0.10
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "chat-rn-expo",
"version": "1.0.10",
"version": "1.0.13",
"main": "index.ts",
"scripts": {
"build": "expo prebuild",

View File

@@ -1,5 +1,41 @@
# chat-rn
## 1.0.140
### Patch Changes
- Updated dependencies [57fb69f]
- Updated dependencies [048ac1d]
- cojson@0.14.22
- jazz-tools@0.14.22
- cojson-transport-ws@0.14.22
- jazz-react-native@0.14.22
## 1.0.139
### Patch Changes
- Updated dependencies [e7e505e]
- Updated dependencies [c3d8779]
- Updated dependencies [13b57aa]
- Updated dependencies [5662faa]
- Updated dependencies [2116a59]
- jazz-tools@0.14.21
- cojson@0.14.21
- jazz-react-native@0.14.21
- cojson-transport-ws@0.14.21
## 1.0.138
### Patch Changes
- Updated dependencies [6f72419]
- Updated dependencies [04b20c2]
- jazz-tools@0.14.20
- jazz-react-native@0.14.20
- cojson@0.14.20
- cojson-transport-ws@0.14.20
## 1.0.137
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "chat-rn",
"version": "1.0.137",
"version": "1.0.140",
"main": "index.js",
"scripts": {
"android": "react-native run-android",

View File

@@ -1,5 +1,36 @@
# chat-vue
## 0.0.120
### Patch Changes
- Updated dependencies [048ac1d]
- jazz-tools@0.14.22
- jazz-browser@0.14.22
- jazz-vue@0.14.22
## 0.0.119
### Patch Changes
- Updated dependencies [e7e505e]
- Updated dependencies [13b57aa]
- Updated dependencies [5662faa]
- Updated dependencies [2116a59]
- jazz-tools@0.14.21
- jazz-browser@0.14.21
- jazz-vue@0.14.21
## 0.0.118
### Patch Changes
- Updated dependencies [6f72419]
- Updated dependencies [04b20c2]
- jazz-tools@0.14.20
- jazz-browser@0.14.20
- jazz-vue@0.14.20
## 0.0.117
### Patch Changes

View File

@@ -58,4 +58,4 @@ If you have feedback, let us know on [Discord](https://discord.gg/utDMjHYg42) or
By default, the example app uses [Jazz Cloud](https://jazz.tools/cloud) (`wss://cloud.jazz.tools`) - so cross-device use, invites and collaboration should just work.
You can also run a local sync server by running `npx jazz-run sync` and adding the query param `?sync=ws://localhost:4200` to the URL of the example app (for example: `http://localhost:5173/?peer=ws://localhost:4200`), or by setting the `sync` parameter of `JazzProvider` in [./src/main.ts](./src/main.ts).
You can also run a local sync server by running `npx jazz-run sync`, and setting the `sync` parameter of `JazzProvider` in [./src/main.ts](./src/main.ts) to `{ peer: "ws://localhost:4200" }`.

View File

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

View File

@@ -1,5 +1,36 @@
# jazz-example-chat
## 0.0.220
### Patch Changes
- Updated dependencies [048ac1d]
- jazz-tools@0.14.22
- jazz-inspector@0.14.22
- jazz-react@0.14.22
## 0.0.219
### Patch Changes
- Updated dependencies [e7e505e]
- Updated dependencies [13b57aa]
- Updated dependencies [5662faa]
- Updated dependencies [2116a59]
- jazz-tools@0.14.21
- jazz-inspector@0.14.21
- jazz-react@0.14.21
## 0.0.218
### Patch Changes
- Updated dependencies [6f72419]
- Updated dependencies [04b20c2]
- jazz-tools@0.14.20
- jazz-inspector@0.14.20
- jazz-react@0.14.20
## 0.0.217
### Patch Changes

View File

@@ -60,4 +60,4 @@ If you have feedback, let us know on [Discord](https://discord.gg/utDMjHYg42) or
By default, the example app uses [Jazz Cloud](https://jazz.tools/cloud) (`wss://cloud.jazz.tools`) - so cross-device use, invites and collaboration should just work.
You can also run a local sync server by running `npx jazz-run sync` and adding the query param `?sync=ws://localhost:4200` to the URL of the example app (for example: `http://localhost:5173/?peer=ws://localhost:4200`), or by setting the `sync` parameter of the `<JazzProvider>` provider component in [./src/main.tsx](./src/main.tsx).
You can also run a local sync server by running `npx jazz-run sync`, and setting the `sync` parameter of `JazzProvider` in [./src/app.tsx](./src/app.tsx) to `{ peer: "ws://localhost:4200" }`.

View File

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

View File

@@ -18,7 +18,7 @@ export function App() {
const createChat = () => {
if (!me) return;
const group = Group.create();
group.addMember("everyone", "writer");
group.makePublic("writer");
const chat = Chat.create([], group);
router.navigate("/#/chat/" + chat.id);

View File

@@ -1,8 +1,3 @@
{
"build": {
"env": {
"APP_NAME": "jazz-chat"
}
},
"ignoreCommand": "node ../../ignore-vercel-build.js"
"ignoreCommand": "npx turbo-ignore"
}

View File

@@ -1,5 +1,36 @@
# minimal-auth-clerk
## 0.0.119
### Patch Changes
- Updated dependencies [048ac1d]
- jazz-tools@0.14.22
- jazz-react@0.14.22
- jazz-react-auth-clerk@0.14.22
## 0.0.118
### Patch Changes
- Updated dependencies [e7e505e]
- Updated dependencies [13b57aa]
- Updated dependencies [5662faa]
- Updated dependencies [2116a59]
- jazz-tools@0.14.21
- jazz-react@0.14.21
- jazz-react-auth-clerk@0.14.21
## 0.0.117
### Patch Changes
- Updated dependencies [6f72419]
- Updated dependencies [04b20c2]
- jazz-tools@0.14.20
- jazz-react@0.14.20
- jazz-react-auth-clerk@0.14.20
## 0.0.116
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "clerk",
"private": true,
"version": "0.0.116",
"version": "0.0.119",
"type": "module",
"scripts": {
"dev": "vite",

View File

@@ -1,8 +1,3 @@
{
"build": {
"env": {
"APP_NAME": "clerk-demo"
}
},
"ignoreCommand": "node ../../ignore-vercel-build.js"
"ignoreCommand": "npx turbo-ignore"
}

View File

@@ -1,5 +1,37 @@
# file-share-svelte
## 0.0.104
### Patch Changes
- Updated dependencies [048ac1d]
- jazz-tools@0.14.22
- jazz-svelte@0.14.22
- jazz-inspector-element@0.14.22
## 0.0.103
### Patch Changes
- Updated dependencies [e7e505e]
- Updated dependencies [d14a069]
- Updated dependencies [13b57aa]
- Updated dependencies [5662faa]
- Updated dependencies [2116a59]
- jazz-tools@0.14.21
- jazz-svelte@0.14.21
- jazz-inspector-element@0.14.21
## 0.0.102
### Patch Changes
- Updated dependencies [6f72419]
- Updated dependencies [04b20c2]
- jazz-tools@0.14.20
- jazz-inspector-element@0.14.20
- jazz-svelte@0.14.20
## 0.0.101
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "file-share-svelte",
"version": "0.0.101",
"version": "0.0.104",
"private": true,
"type": "module",
"scripts": {
@@ -30,7 +30,7 @@
"prettier": "^3.3.2",
"prettier-plugin-svelte": "^3.2.6",
"prettier-plugin-tailwindcss": "^0.6.5",
"svelte": "^5.0.0",
"svelte": "^5.33.0",
"svelte-check": "^4.0.0",
"tailwindcss": "^3.4.17",
"typescript": "5.6.2",

View File

@@ -1,5 +1,36 @@
# jazz-tailwind-demo-auth-starter
## 0.0.59
### Patch Changes
- Updated dependencies [048ac1d]
- jazz-tools@0.14.22
- jazz-inspector@0.14.22
- jazz-react@0.14.22
## 0.0.58
### Patch Changes
- Updated dependencies [e7e505e]
- Updated dependencies [13b57aa]
- Updated dependencies [5662faa]
- Updated dependencies [2116a59]
- jazz-tools@0.14.21
- jazz-inspector@0.14.21
- jazz-react@0.14.21
## 0.0.57
### Patch Changes
- Updated dependencies [6f72419]
- Updated dependencies [04b20c2]
- jazz-tools@0.14.20
- jazz-inspector@0.14.20
- jazz-react@0.14.20
## 0.0.56
### Patch Changes

View File

@@ -63,4 +63,4 @@ If you have feedback, let us know on [Discord](https://discord.gg/utDMjHYg42) or
By default, the example app uses [Jazz Cloud](https://jazz.tools/cloud) (`wss://cloud.jazz.tools`) - so cross-device use, invites and collaboration should just work.
You can also run a local sync server by running `npx jazz-run sync` and adding the query param `?sync=ws://localhost:4200` to the URL of the example app (for example: `http://localhost:5173/?peer=ws://localhost:4200`), or by setting the `sync` parameter of `JazzProvider` component in [./src/main.tsx](./src/main.tsx).
You can also run a local sync server by running `npx jazz-run sync`, and setting the `sync` parameter of `JazzProvider` in [./src/main.tsx](./src/main.tsx) to `{ peer: "ws://localhost:4200" }`.

View File

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

View File

@@ -1,8 +1,3 @@
{
"build": {
"env": {
"APP_NAME": "filestream"
}
},
"ignoreCommand": "node ../../ignore-vercel-build.js"
"ignoreCommand": "npx turbo-ignore"
}

View File

@@ -1,5 +1,33 @@
# form
## 0.1.60
### Patch Changes
- Updated dependencies [048ac1d]
- jazz-tools@0.14.22
- jazz-react@0.14.22
## 0.1.59
### Patch Changes
- Updated dependencies [e7e505e]
- Updated dependencies [13b57aa]
- Updated dependencies [5662faa]
- Updated dependencies [2116a59]
- jazz-tools@0.14.21
- jazz-react@0.14.21
## 0.1.58
### Patch Changes
- Updated dependencies [6f72419]
- Updated dependencies [04b20c2]
- jazz-tools@0.14.20
- jazz-react@0.14.20
## 0.1.57
### Patch Changes

View File

@@ -75,4 +75,4 @@ If you have feedback, let us know on [Discord](https://discord.gg/utDMjHYg42) or
By default, the example app uses [Jazz Cloud](https://jazz.tools/cloud) (`wss://cloud.jazz.tools`) - so cross-device use, invites and collaboration should just work.
You can also run a local sync server by running `npx jazz-run sync` and adding the query param `?sync=ws://localhost:4200` to the URL of the example app (for example: `http://localhost:5173/?peer=ws://localhost:4200`), or by setting the `sync` parameter of the `<JazzProvider>` provider component in [./src/main.tsx](./src/main.tsx).
You can also run a local sync server by running `npx jazz-run sync`, and setting the `sync` parameter of `JazzProvider` in [./src/main.tsx](./src/main.tsx) to `{ peer: "ws://localhost:4200" }`.

View File

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

View File

@@ -1,8 +1,3 @@
{
"build": {
"env": {
"APP_NAME": "form-demo"
}
},
"ignoreCommand": "node ../../ignore-vercel-build.js"
"ignoreCommand": "npx turbo-ignore"
}

View File

@@ -1,5 +1,33 @@
# image-upload
## 0.0.116
### Patch Changes
- Updated dependencies [048ac1d]
- jazz-tools@0.14.22
- jazz-react@0.14.22
## 0.0.115
### Patch Changes
- Updated dependencies [e7e505e]
- Updated dependencies [13b57aa]
- Updated dependencies [5662faa]
- Updated dependencies [2116a59]
- jazz-tools@0.14.21
- jazz-react@0.14.21
## 0.0.114
### Patch Changes
- Updated dependencies [6f72419]
- Updated dependencies [04b20c2]
- jazz-tools@0.14.20
- jazz-react@0.14.20
## 0.0.113
### Patch Changes

View File

@@ -63,4 +63,4 @@ If you have feedback, let us know on [Discord](https://discord.gg/utDMjHYg42) or
By default, the example app uses [Jazz Cloud](https://jazz.tools/cloud) (`wss://cloud.jazz.tools`) - so cross-device use, invites and collaboration should just work.
You can also run a local sync server by running `npx jazz-run sync` and adding the query param `?sync=ws://localhost:4200` to the URL of the example app (for example: `http://localhost:5173/?peer=ws://localhost:4200`), or by setting the `sync` parameter of `JazzProvider` component in [./src/main.tsx](./src/main.tsx).
You can also run a local sync server by running `npx jazz-run sync`, and setting the `sync` parameter of `JazzProvider` in [./src/main.tsx](./src/main.tsx) to `{ peer: "ws://localhost:4200" }`.

View File

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

View File

@@ -1,8 +1,3 @@
{
"build": {
"env": {
"APP_NAME": "image-upload-demo"
}
},
"ignoreCommand": "node ../../ignore-vercel-build.js"
"ignoreCommand": "npx turbo-ignore"
}

View File

@@ -1,5 +1,31 @@
# jazz-example-inspector
## 0.0.169
### Patch Changes
- Updated dependencies [57fb69f]
- cojson@0.14.22
- cojson-transport-ws@0.14.22
- jazz-inspector@0.14.22
## 0.0.168
### Patch Changes
- Updated dependencies [c3d8779]
- cojson@0.14.21
- jazz-inspector@0.14.21
- cojson-transport-ws@0.14.21
## 0.0.167
### Patch Changes
- jazz-inspector@0.14.20
- cojson@0.14.20
- cojson-transport-ws@0.14.20
## 0.0.166
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "jazz-inspector-app",
"private": true,
"version": "0.0.166",
"version": "0.0.169",
"type": "module",
"scripts": {
"dev": "vite",

View File

@@ -27,6 +27,13 @@ interface Account {
secret: AgentSecret;
}
interface JazzLoggedInSecret {
accountID: string;
accountSecret: string;
secretSeed?: number[];
provider?: string;
}
export default function CoJsonViewerApp() {
const [accounts, setAccounts] = useState<Account[]>(() => {
const storedAccounts = localStorage.getItem("inspectorAccounts");
@@ -269,7 +276,26 @@ function AddAccountForm({
const [id, setId] = useState("");
const [secret, setSecret] = useState("");
const handleSubmit = (e: React.FormEvent) => {
const handleIdChange = (e: React.ChangeEvent<HTMLInputElement>): void => {
const value = e.target.value;
setId(value);
// Try to parse as JSON if it looks like a JSON object
if (value.trim().startsWith("{") && value.trim().endsWith("}")) {
try {
const parsed: JazzLoggedInSecret = JSON.parse(value);
if (parsed.accountID && parsed.accountSecret) {
setId(parsed.accountID);
setSecret(parsed.accountSecret);
}
} catch (error) {
// If parsing fails, just keep the raw value in the id field
console.log("Failed to parse JSON:", error);
}
}
};
const handleSubmit = (e: React.FormEvent): void => {
e.preventDefault();
addAccount(id as RawAccountID, secret as AgentSecret);
setId("");
@@ -290,13 +316,14 @@ function AddAccountForm({
jazz-logged-in-secret
</code>{" "}
local storage key from within your Jazz app for your account
credentials.
credentials. You can paste the full JSON object or enter the ID and
secret separately.
</p>
<Input
label="Account ID"
value={id}
placeholder="co_z1234567890abcdef123456789"
onChange={(e) => setId(e.target.value)}
placeholder="co_z1234567890abcdef123456789 or paste full JSON"
onChange={handleIdChange}
/>
<Input
label="Account secret"

View File

@@ -1,8 +1,3 @@
{
"build": {
"env": {
"APP_NAME": "jazz-inspector"
}
},
"ignoreCommand": "node ../../ignore-vercel-build.js"
"ignoreCommand": "npx turbo-ignore"
}

View File

@@ -1,5 +1,33 @@
# jazz-nextjs
## 0.1.9
### Patch Changes
- Updated dependencies [048ac1d]
- jazz-tools@0.14.22
- jazz-react@0.14.22
## 0.1.8
### Patch Changes
- Updated dependencies [e7e505e]
- Updated dependencies [13b57aa]
- Updated dependencies [5662faa]
- Updated dependencies [2116a59]
- jazz-tools@0.14.21
- jazz-react@0.14.21
## 0.1.7
### Patch Changes
- Updated dependencies [6f72419]
- Updated dependencies [04b20c2]
- jazz-tools@0.14.20
- jazz-react@0.14.20
## 0.1.6
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "jazz-nextjs",
"version": "0.1.6",
"version": "0.1.9",
"private": true,
"scripts": {
"dev": "next dev --turbopack",

View File

@@ -0,0 +1,3 @@
{
"ignoreCommand": "npx turbo-ignore"
}

View File

@@ -1,5 +1,33 @@
# multi-cursors
## 0.0.112
### Patch Changes
- Updated dependencies [048ac1d]
- jazz-tools@0.14.22
- jazz-react@0.14.22
## 0.0.111
### Patch Changes
- Updated dependencies [e7e505e]
- Updated dependencies [13b57aa]
- Updated dependencies [5662faa]
- Updated dependencies [2116a59]
- jazz-tools@0.14.21
- jazz-react@0.14.21
## 0.0.110
### Patch Changes
- Updated dependencies [6f72419]
- Updated dependencies [04b20c2]
- jazz-tools@0.14.20
- jazz-react@0.14.20
## 0.0.109
### Patch Changes

View File

@@ -1,7 +1,7 @@
# Jazz Multi-Cursors Example
Track user presence on a canvas with multiple cursors and out of bounds indicators.
Live version: [https://multi-cursors-demo.jazz.tools/](https://multi-cursors-demo.jazz.tools/)
Live version: [https://multi-cursors.demo.jazz.tools/](https://multi-cursors.demo.jazz.tools/)
## Getting started
@@ -62,4 +62,4 @@ If you have feedback, let us know on [Discord](https://discord.gg/utDMjHYg42) or
By default, the example app uses [Jazz Cloud](https://jazz.tools/cloud) (`wss://cloud.jazz.tools`) - so cross-device use, invites and collaboration should just work.
You can also run a local sync server by running `npx jazz-run sync` and adding the query param `?sync=ws://localhost:4200` to the URL of the example app (for example: `http://localhost:5173/?peer=ws://localhost:4200`), or by setting the `sync` parameter of `JazzProvider` component in [./src/main.tsx](./src/main.tsx).
You can also run a local sync server by running `npx jazz-run sync`, and setting the `sync` parameter of `JazzProvider` in [./src/main.tsx](./src/main.tsx) to `{ peer: "ws://localhost:4200" }`.

View File

@@ -1,7 +1,7 @@
{
"name": "multi-cursors",
"private": true,
"version": "0.0.109",
"version": "0.0.112",
"type": "module",
"scripts": {
"dev": "vite",

View File

@@ -36,7 +36,7 @@ export const CursorAccount = co
if (account.profile === undefined) {
const group = Group.create();
group.addMember("everyone", "reader"); // The profile info is visible to everyone
group.makePublic(); // The profile info is visible to everyone
account.profile = CursorProfile.create(
{

View File

@@ -1,8 +1,3 @@
{
"build": {
"env": {
"APP_NAME": "multi-cursors"
}
},
"ignoreCommand": "node ../../ignore-vercel-build.js"
"ignoreCommand": "npx turbo-ignore"
}

View File

@@ -1,5 +1,36 @@
# multiauth
## 0.0.60
### Patch Changes
- Updated dependencies [048ac1d]
- jazz-tools@0.14.22
- jazz-react@0.14.22
- jazz-react-auth-clerk@0.14.22
## 0.0.59
### Patch Changes
- Updated dependencies [e7e505e]
- Updated dependencies [13b57aa]
- Updated dependencies [5662faa]
- Updated dependencies [2116a59]
- jazz-tools@0.14.21
- jazz-react@0.14.21
- jazz-react-auth-clerk@0.14.21
## 0.0.58
### Patch Changes
- Updated dependencies [6f72419]
- Updated dependencies [04b20c2]
- jazz-tools@0.14.20
- jazz-react@0.14.20
- jazz-react-auth-clerk@0.14.20
## 0.0.57
### Patch Changes

View File

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

View File

@@ -1,5 +1,36 @@
# jazz-example-musicplayer
## 0.0.141
### Patch Changes
- Updated dependencies [048ac1d]
- jazz-tools@0.14.22
- jazz-inspector@0.14.22
- jazz-react@0.14.22
## 0.0.140
### Patch Changes
- Updated dependencies [e7e505e]
- Updated dependencies [13b57aa]
- Updated dependencies [5662faa]
- Updated dependencies [2116a59]
- jazz-tools@0.14.21
- jazz-inspector@0.14.21
- jazz-react@0.14.21
## 0.0.139
### Patch Changes
- Updated dependencies [6f72419]
- Updated dependencies [04b20c2]
- jazz-tools@0.14.20
- jazz-inspector@0.14.20
- jazz-react@0.14.20
## 0.0.138
### Patch Changes

View File

@@ -1,6 +1,6 @@
# Music player example with Jazz and React
Live version: [https://music-demo.jazz.tools](https://music-demo.jazz.tools)
Live version: [https://music.demo.jazz.tools](https://music.demo.jazz.tools)
## Getting started
@@ -60,4 +60,4 @@ If you have feedback, let us know on [Discord](https://discord.gg/utDMjHYg42) or
By default, the example app uses [Jazz Cloud](https://jazz.tools/cloud) (`wss://cloud.jazz.tools`) - so cross-device use, invites and collaboration should just work.
You can also run a local sync server by running `npx cojson-simple-sync` and adding the query param `?sync=ws://localhost:4200` to the URL of the example app (for example: `http://localhost:5173/?peer=ws://localhost:4200`), or by setting the `sync` parameter of the `<JazzProvider>` provider component in [./src/2_main.tsx](./src/2_main.tsx).
You can also run a local sync server by running `npx jazz-run sync`, and setting the `sync` parameter of `JazzProvider` in [./src/2_main.tsx](./src/2_main.tsx) to `{ peer: "ws://localhost:4200" }`.

View File

@@ -1,7 +1,7 @@
{
"name": "jazz-example-music-player",
"private": true,
"version": "0.0.138",
"version": "0.0.141",
"type": "module",
"scripts": {
"dev": "vite",

View File

@@ -41,8 +41,8 @@ export const MusicTrack = co.map({
/**
* You can use getters for recusrive relations
*/
get sourceTrack(): z.ZodOptional<typeof MusicTrack> {
return z.optional(MusicTrack);
get sourceTrack() {
return MusicTrack.optional();
},
});
export type MusicTrack = co.loaded<typeof MusicTrack>;

View File

@@ -1,8 +1,3 @@
{
"build": {
"env": {
"APP_NAME": "music-demo"
}
},
"ignoreCommand": "node ../../ignore-vercel-build.js"
"ignoreCommand": "npx turbo-ignore"
}

View File

@@ -1,5 +1,33 @@
# organization
## 0.0.112
### Patch Changes
- Updated dependencies [048ac1d]
- jazz-tools@0.14.22
- jazz-react@0.14.22
## 0.0.111
### Patch Changes
- Updated dependencies [e7e505e]
- Updated dependencies [13b57aa]
- Updated dependencies [5662faa]
- Updated dependencies [2116a59]
- jazz-tools@0.14.21
- jazz-react@0.14.21
## 0.0.110
### Patch Changes
- Updated dependencies [6f72419]
- Updated dependencies [04b20c2]
- jazz-tools@0.14.20
- jazz-react@0.14.20
## 0.0.109
### Patch Changes

View File

@@ -2,7 +2,7 @@
This is an example of how to share a set of data between users through a CoMap called Organization.
Different apps have different names for this concept, such as "teams" or "workspaces".
Live version: [https://jazz-organization.vercel.app/](https://jazz-organization.vercel.app/)
Live version: [https://organization.demo.jazz.tools/](https://organization.demo.jazz.tools/)
Refer to the [documentation](https://jazz.tools/docs/react/design-patterns/organization) for more information.
## Getting started
@@ -63,4 +63,5 @@ If you have feedback, let us know on [Discord](https://discord.gg/utDMjHYg42) or
By default, the example app uses [Jazz Cloud](https://jazz.tools/cloud) (`wss://cloud.jazz.tools`) - so cross-device use, invites and collaboration should just work.
You can also run a local sync server by running `npx jazz-run sync` and adding the query param `?sync=ws://localhost:4200` to the URL of the example app (for example: `http://localhost:5173/?peer=ws://localhost:4200`), or by setting the `sync` parameter of the `<JazzProvider>` provider component in [./src/main.tsx](./src/main.tsx).
You can also run a local sync server by running `npx jazz-run sync`, and setting the `sync` parameter of `JazzProvider` in [./src/main.tsx](./src/main.tsx) to `{ peer: "ws://localhost:4200" }`.

View File

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

View File

@@ -0,0 +1,3 @@
{
"ignoreCommand": "npx turbo-ignore"
}

View File

@@ -1,5 +1,34 @@
# passkey-svelte
## 0.0.106
### Patch Changes
- Updated dependencies [048ac1d]
- jazz-tools@0.14.22
- jazz-svelte@0.14.22
## 0.0.105
### Patch Changes
- Updated dependencies [e7e505e]
- Updated dependencies [d14a069]
- Updated dependencies [13b57aa]
- Updated dependencies [5662faa]
- Updated dependencies [2116a59]
- jazz-tools@0.14.21
- jazz-svelte@0.14.21
## 0.0.104
### Patch Changes
- Updated dependencies [6f72419]
- Updated dependencies [04b20c2]
- jazz-tools@0.14.20
- jazz-svelte@0.14.20
## 0.0.103
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "passkey-svelte",
"version": "0.0.103",
"version": "0.0.106",
"type": "module",
"private": true,
"scripts": {
@@ -25,7 +25,7 @@
"globals": "^15.11.0",
"prettier": "^3.3.2",
"prettier-plugin-svelte": "^3.2.6",
"svelte": "^5.0.0",
"svelte": "^5.33.0",
"svelte-check": "^4.0.0",
"typescript": "5.6.2",
"typescript-eslint": "^8.0.0",

View File

@@ -1,5 +1,33 @@
# minimal-auth-passkey
## 0.0.117
### Patch Changes
- Updated dependencies [048ac1d]
- jazz-tools@0.14.22
- jazz-react@0.14.22
## 0.0.116
### Patch Changes
- Updated dependencies [e7e505e]
- Updated dependencies [13b57aa]
- Updated dependencies [5662faa]
- Updated dependencies [2116a59]
- jazz-tools@0.14.21
- jazz-react@0.14.21
## 0.0.115
### Patch Changes
- Updated dependencies [6f72419]
- Updated dependencies [04b20c2]
- jazz-tools@0.14.20
- jazz-react@0.14.20
## 0.0.114
### Patch Changes

View File

@@ -2,7 +2,7 @@
This is an example of how to use passkey authentication with Jazz.
Live version: [https://passkey-demo.jazz.tools](https://passkey-demo.jazz.tools)
Live version: [https://passkey.demo.jazz.tools](https://passkey.demo.jazz.tools)
## Getting started

View File

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

View File

@@ -1,8 +1,3 @@
{
"build": {
"env": {
"APP_NAME": "passkey-demo"
}
},
"ignoreCommand": "node ../../ignore-vercel-build.js"
"ignoreCommand": "npx turbo-ignore"
}

View File

@@ -1,5 +1,33 @@
# passphrase
## 0.0.114
### Patch Changes
- Updated dependencies [048ac1d]
- jazz-tools@0.14.22
- jazz-react@0.14.22
## 0.0.113
### Patch Changes
- Updated dependencies [e7e505e]
- Updated dependencies [13b57aa]
- Updated dependencies [5662faa]
- Updated dependencies [2116a59]
- jazz-tools@0.14.21
- jazz-react@0.14.21
## 0.0.112
### Patch Changes
- Updated dependencies [6f72419]
- Updated dependencies [04b20c2]
- jazz-tools@0.14.20
- jazz-react@0.14.20
## 0.0.111
### Patch Changes

View File

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

View File

@@ -1,8 +1,3 @@
{
"build": {
"env": {
"APP_NAME": "passphrase-demo"
}
},
"ignoreCommand": "node ../../ignore-vercel-build.js"
"ignoreCommand": "npx turbo-ignore"
}

View File

@@ -1,5 +1,33 @@
# jazz-password-manager
## 0.0.138
### Patch Changes
- Updated dependencies [048ac1d]
- jazz-tools@0.14.22
- jazz-react@0.14.22
## 0.0.137
### Patch Changes
- Updated dependencies [e7e505e]
- Updated dependencies [13b57aa]
- Updated dependencies [5662faa]
- Updated dependencies [2116a59]
- jazz-tools@0.14.21
- jazz-react@0.14.21
## 0.0.136
### Patch Changes
- Updated dependencies [6f72419]
- Updated dependencies [04b20c2]
- jazz-tools@0.14.20
- jazz-react@0.14.20
## 0.0.135
### Patch Changes

View File

@@ -1,6 +1,6 @@
# Password manager example with Jazz and React
Live version: [https://passwords-demo.jazz.tools](https://passwords-demo.jazz.tools)
Live version: [https://passwords.demo.jazz.tools](https://passwords.demo.jazz.tools)
![Password Manager Screenshot](demo.png "Screenshot")
@@ -86,4 +86,4 @@ If you have feedback, let us know on [Discord](https://discord.gg/utDMjHYg42) or
By default, the example app uses [Jazz Cloud](https://jazz.tools/cloud) (`wss://cloud.jazz.tools`) - so cross-device use, invites and collaboration should just work.
You can also run a local sync server by running `npx cojson-simple-sync` and adding the query param `?sync=ws://localhost:4200` to the URL of the example app (for example: `http://localhost:5173/?peer=ws://localhost:4200`), or by setting the `sync` parameter of the `<JazzProvider>` provider component in [./src/2_main.tsx](./src/2_main.tsx).
You can also run a local sync server by running `npx jazz-run sync`, and setting the `sync` parameter of `JazzProvider` in [./src/2_main.tsx](./src/2_main.tsx) to `{ peer: "ws://localhost:4200" }`.

View File

@@ -1,7 +1,7 @@
{
"name": "jazz-password-manager",
"private": true,
"version": "0.0.135",
"version": "0.0.138",
"type": "module",
"scripts": {
"dev": "vite",

View File

@@ -1,8 +1,3 @@
{
"build": {
"env": {
"APP_NAME": "passwords-demo"
}
},
"ignoreCommand": "node ../../ignore-vercel-build.js"
"ignoreCommand": "npx turbo-ignore"
}

View File

@@ -1,5 +1,33 @@
# jazz-example-pets
## 0.0.236
### Patch Changes
- Updated dependencies [048ac1d]
- jazz-tools@0.14.22
- jazz-react@0.14.22
## 0.0.235
### Patch Changes
- Updated dependencies [e7e505e]
- Updated dependencies [13b57aa]
- Updated dependencies [5662faa]
- Updated dependencies [2116a59]
- jazz-tools@0.14.21
- jazz-react@0.14.21
## 0.0.234
### Patch Changes
- Updated dependencies [6f72419]
- Updated dependencies [04b20c2]
- jazz-tools@0.14.20
- jazz-react@0.14.20
## 0.0.233
### Patch Changes

View File

@@ -1,6 +1,6 @@
# Rate My Pets example with Jazz and React
Live version: [https://pets-demo.jazz.tools/](https://pets-demo.jazz.tools/)
Live version: [https://pets.demo.jazz.tools/](https://pets.demo.jazz.tools/)
## Getting started
@@ -60,4 +60,4 @@ If you have feedback, let us know on [Discord](https://discord.gg/utDMjHYg42) or
By default, the example app uses [Jazz Cloud](https://jazz.tools/cloud) (`wss://cloud.jazz.tools`) - so cross-device use, invites and collaboration should just work.
You can also run a local sync server by running `npx jazz-run sync` and adding the query param `?sync=ws://localhost:4200` to the URL of the example app (for example: `http://localhost:5173/?peer=ws://localhost:4200`), or by setting the `sync` parameter of the `<JazzProvider>` provider component in [./src/2_main.tsx](./src/2_main.tsx).
You can also run a local sync server by running `npx jazz-run sync`, and setting the `sync` parameter of `JazzProvider` in [./src/2_main.tsx](./src/2_main.tsx) to `{ peer: "ws://localhost:4200" }`.

View File

@@ -1,7 +1,7 @@
{
"name": "jazz-example-pets",
"private": true,
"version": "0.0.233",
"version": "0.0.236",
"type": "module",
"scripts": {
"dev": "vite",

View File

@@ -25,11 +25,6 @@ import {
TitleAndLogo,
} from "./basicComponents/index.ts";
const peer =
(new URL(window.location.href).searchParams.get(
"peer",
) as `ws://${string}`) ?? `wss://cloud.jazz.tools/?key=${apiKey}`;
const appName = "Jazz Rate My Pet Example";
/** Walkthrough: The top-level provider `<JazzProvider/>`
@@ -45,7 +40,7 @@ ReactDOM.createRoot(document.getElementById("root")!).render(
<div className="flex flex-col h-full items-center justify-start gap-10 pt-10 pb-10 px-5">
<JazzProvider
sync={{
peer,
peer: `wss://cloud.jazz.tools/?key=${apiKey}`,
}}
AccountSchema={PetAccount}
>

View File

@@ -1,8 +1,3 @@
{
"build": {
"env": {
"APP_NAME": "jazz-pets"
}
},
"ignoreCommand": "node ../../ignore-vercel-build.js"
"ignoreCommand": "npx turbo-ignore"
}

View File

@@ -1,5 +1,33 @@
# reactions
## 0.0.116
### Patch Changes
- Updated dependencies [048ac1d]
- jazz-tools@0.14.22
- jazz-react@0.14.22
## 0.0.115
### Patch Changes
- Updated dependencies [e7e505e]
- Updated dependencies [13b57aa]
- Updated dependencies [5662faa]
- Updated dependencies [2116a59]
- jazz-tools@0.14.21
- jazz-react@0.14.21
## 0.0.114
### Patch Changes
- Updated dependencies [6f72419]
- Updated dependencies [04b20c2]
- jazz-tools@0.14.20
- jazz-react@0.14.20
## 0.0.113
### Patch Changes

View File

@@ -1,6 +1,6 @@
# Reactions example with Jazz and React
Live version: [https://reactions-demo.jazz.tools](https://reactions-demo.jazz.tools)
Live version: [https://reactions.demo.jazz.tools](https://reactions.demo.jazz.tools)
## Getting started
@@ -60,4 +60,4 @@ If you have feedback, let us know on [Discord](https://discord.gg/utDMjHYg42) or
By default, the example app uses [Jazz Cloud](https://jazz.tools/cloud) (`wss://cloud.jazz.tools`) - so cross-device use, invites and collaboration should just work.
You can also run a local sync server by running `npx jazz-run sync` and adding the query param `?sync=ws://localhost:4200` to the URL of the example app (for example: `http://localhost:5173/?peer=ws://localhost:4200`), or by setting the `sync` parameter of the `<JazzProvider>` provider component in [./src/main.tsx](./src/main.tsx).
You can also run a local sync server by running`npx jazz-run sync`, and setting the `sync` parameter of`JazzProvider` in [./src/main.tsx](./src/main.tsx) to`{ peer: "ws://localhost:4200" }`.

View File

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

View File

@@ -1,8 +1,3 @@
{
"build": {
"env": {
"APP_NAME": "reactions-demo"
}
},
"ignoreCommand": "node ../../ignore-vercel-build.js"
"ignoreCommand": "npx turbo-ignore"
}

View File

@@ -0,0 +1,5 @@
{
"semi": false,
"singleQuote": true,
"htmlWhitespaceSensitivity": "ignore"
}

View File

@@ -0,0 +1,10 @@
# example-prosekit-jazz
## 0.0.1
### Patch Changes
- Updated dependencies [048ac1d]
- jazz-tools@0.14.22
- jazz-react@0.14.22
- jazz-richtext-prosemirror@0.14.22

View File

@@ -0,0 +1,121 @@
# Jazz RichText ProseKit Example
A demonstration of collaborative rich text editing with Jazz, React, and ProseKit.
Original implementation by [prosekit](https://github.com/prosekit/prosekit-jazz)
Live version: [https://richtext-prosekit.demo.jazz.tools](https://richtext-prosekit.demo.jazz.tools)
## Overview
This example shows how to implement collaborative rich text editing using:
- **Jazz** for real-time synchronization
- **CoRichText** for collaborative rich text data structures
- **ProseKit** for the rich text editor UI
- **React** for the component framework
## Getting started
You can either
1. Clone the jazz repository, and run the app within the monorepo.
2. Or create a new Jazz project using this example as a template.
### Using the example as a template
Create a new Jazz project, and use this example as a template.
```bash
npx create-jazz-app@latest richtext-prosekit-app --example richtext-prosekit
```
Go to the new project directory.
```bash
cd richtext-prosekit-app
```
Run the dev server.
```bash
npm run dev
```
### Using the monorepo
This requires `pnpm` to be installed, see [https://pnpm.io/installation](https://pnpm.io/installation).
Clone the jazz repository.
```bash
git clone https://github.com/garden-co/jazz.git
```
Install and build dependencies.
```bash
pnpm i && npx turbo build
```
Go to the example directory.
```bash
cd jazz/examples/richtext-prosekit/
```
Start the dev server.
```bash
pnpm dev
```
Open [http://localhost:5173](http://localhost:5173) with your browser to see the result.
## How it works
This example demonstrates two key functionalities:
1. **CoRichText** - Jazz's collaborative rich text data structure
2. **Rich text integration** - Using ProseKit with Jazz
### Key components
- `src/schema.ts` - Defines the data model, including the `bio` field using CoRichText
- `src/Editor.tsx` - Implements both plaintext and rich text editor views
- `jazz-richtext-prosekit` - Provides the plugin that connects Jazz to ProseKit
### Implementation details
The example shows how to:
- Create and store CoRichText values
- Set up a plaintext editor with CoRichText
- Set up a ProseKit editor with a Jazz plugin
## Extending this example
You can extend this example by:
- Adding formatting options to the rich text toolbar
- Adding multiple collaborative documents
- Building document history or versioning
## Configuration: sync server
By default, the app uses [Jazz Cloud](https://jazz.tools/cloud) (`wss://cloud.jazz.tools`) - so cross-device use, invites and collaboration should just work.
You can also run a local sync server by running`npx jazz-run sync`, and setting the `sync` parameter of`JazzProvider` in [./src/main.tsx](./src/main.tsx) to`{ peer: "ws://localhost:4200" }`.
## Learn more
To learn more about Jazz's collaborative text capabilities:
- [Jazz documentation](https://jazz.tools/docs)
- [CoText documentation](https://jazz.tools/docs/using-covalues/cotext)
- [ProseKit documentation](https://prosekit.dev/getting-started/introduction/)
## Questions / problems / feedback
If you have feedback, let us know on [Discord](https://discord.gg/utDMjHYg42) or open an issue or PR to fix something that seems wrong.

View File

@@ -0,0 +1,16 @@
<!doctype html>
<html lang="en" class="h-full">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/png" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Rich text ProseKit example app | Jazz</title>
</head>
<body class="h-full flex flex-col">
<div id="root" class="align-self-center flex-1"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>

View File

@@ -0,0 +1,30 @@
{
"name": "example-prosekit-jazz",
"version": "0.0.1",
"private": true,
"type": "module",
"scripts": {
"build": "tsc -b && vite build",
"dev": "vite",
"preview": "vite preview"
},
"dependencies": {
"jazz-react": "workspace:*",
"jazz-richtext-prosemirror": "workspace:*",
"jazz-tools": "workspace:*",
"prosekit": "^0.13.3",
"react": "^19.1.0",
"react-dom": "^19.1.0"
},
"devDependencies": {
"@egoist/tailwindcss-icons": "^1.9.0",
"@iconify-json/lucide": "^1.2.45",
"@types/react": "^19.1.6",
"@types/react-dom": "^19.1.5",
"@vitejs/plugin-react": "^4.5.0",
"postcss": "^8.5.4",
"tailwindcss": "^3.4.17",
"typescript": "5.6.2",
"vite": "6.3.5"
}
}

3628
examples/richtext-prosekit/pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,6 @@
export default {
plugins: {
"tailwindcss/nesting": {},
tailwindcss: {},
},
};

View File

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

View File

@@ -0,0 +1,2 @@
// We use this to identify the app in the passkey auth
export const APPLICATION_NAME = "Jazz prosekit example";

View File

@@ -0,0 +1,3 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

View File

@@ -0,0 +1,56 @@
import { useAccount, useIsAuthenticated } from "jazz-react";
import { CoRichText } from "jazz-tools";
import { useMemo } from "react";
import { Logo } from "./app-logo.tsx";
import { AuthButton } from "./auth-button.tsx";
import Editor from "./editor/editor.tsx";
import { JazzAccount } from "./schema.ts";
import Textarea from "./textarea.tsx";
function App() {
const { me } = useAccount(JazzAccount, {
resolve: { profile: true, root: true },
});
const isAuthenticated = useIsAuthenticated();
const memoCoRichText: CoRichText | undefined = useMemo(() => {
console.log("memoCoRichText");
return me?.profile.bio ?? undefined;
}, [me?.id, me?.profile.bio?.id]);
// Only recreate if the account or the bio changes
// https://github.com/garden-co/jazz/blob/b4cd307ebac5860df2f83d75a915906f472a5cd4/examples/richtext/src/Editor.tsx#L46C1-L46C88
return (
<>
<header>
<nav className="container flex justify-between items-center py-3">
{isAuthenticated ? (
<span>You're logged in.</span>
) : (
<span>Authenticate to share the data with another device.</span>
)}
<AuthButton />
</nav>
</header>
<main className="container mt-16 flex flex-col gap-8">
<Logo />
<div className="text-center">
<h1>
Welcome{me?.profile.firstName ? <>, {me?.profile.firstName}</> : ""}
!
</h1>
</div>
<div className="flex flex-col gap-4">
<Editor coRichText={memoCoRichText} />
<Editor coRichText={memoCoRichText} />
<Textarea coRichText={me?.profile.bio} />
</div>
</main>
</>
);
}
export default App;

View File

@@ -0,0 +1,43 @@
import { useAccount, usePasskeyAuth } from "jazz-react";
import { APPLICATION_NAME } from "./app-name";
export function AuthButton() {
const { logOut } = useAccount();
const auth = usePasskeyAuth({
appName: APPLICATION_NAME,
});
function handleLogOut() {
logOut();
window.history.pushState({}, "", "/");
}
if (auth.state === "signedIn") {
return (
<button
className="bg-stone-100 py-1.5 px-3 text-sm rounded-md"
onClick={handleLogOut}
>
Log out
</button>
);
}
return (
<div className="flex gap-2">
<button
className="bg-stone-100 py-1.5 px-3 text-sm rounded-md"
onClick={() => auth.signUp("")}
>
Sign up
</button>
<button
onClick={() => auth.logIn()}
className="bg-stone-100 py-1.5 px-3 text-sm rounded-md"
>
Log in
</button>
</div>
);
}

View File

@@ -0,0 +1,18 @@
import {
BlockHandleAdd,
BlockHandleDraggable,
BlockHandlePopover,
} from "prosekit/react/block-handle";
export default function BlockHandle() {
return (
<BlockHandlePopover className="flex items-center flex-row box-border justify-center transition border-0 [&:not([data-state])]:hidden will-change-transform data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=open]:fade-in-0 data-[state=closed]:fade-out-0 data-[state=open]:zoom-in-95 data-[state=closed]:zoom-out-95 data-[state=open]:animate-duration-150 data-[state=closed]:animate-duration-200">
<BlockHandleAdd className="flex items-center box-border justify-center h-[1.5em] w-[1.5em] hover:bg-gray-100 dark:hover:bg-gray-800 rounded text-gray-500/50 dark:text-gray-500/50 cursor-pointer">
<div className="i-lucide-plus h-5 w-5" />
</BlockHandleAdd>
<BlockHandleDraggable className="flex items-center box-border justify-center h-[1.5em] w-[1.2em] hover:bg-gray-100 dark:hover:bg-gray-800 rounded text-gray-500/50 dark:text-gray-500/50 cursor-grab">
<div className="i-lucide-grip-vertical h-5 w-5" />
</BlockHandleDraggable>
</BlockHandlePopover>
);
}

View File

@@ -0,0 +1,42 @@
import {
TooltipContent,
TooltipRoot,
TooltipTrigger,
} from "prosekit/react/tooltip";
import type { ReactNode } from "react";
export default function Button({
pressed,
disabled,
onClick,
tooltip,
children,
}: {
pressed?: boolean;
disabled?: boolean;
onClick?: VoidFunction;
tooltip?: string;
children: ReactNode;
}) {
return (
<TooltipRoot>
<TooltipTrigger className="block">
<button
data-state={pressed ? "on" : "off"}
disabled={disabled}
onClick={() => onClick?.()}
onMouseDown={(event) => event.preventDefault()}
className="outline-unset focus-visible:outline-unset flex items-center justify-center rounded-md p-2 font-medium transition focus-visible:ring-2 text-sm focus-visible:ring-gray-900 dark:focus-visible:ring-gray-300 disabled:pointer-events-none min-w-9 min-h-9 disabled:opacity-50 hover:disabled:opacity-50 bg-transparent hover:bg-gray-100 dark:hover:bg-gray-200 data-[state=on]:bg-gray-200 dark:data-[state=on]:bg-gray-400"
>
{children}
{tooltip ? <span className="sr-only">{tooltip}</span> : null}
</button>
</TooltipTrigger>
{tooltip ? (
<TooltipContent className="z-50 overflow-hidden rounded-md border border-solid bg-gray-900 dark:bg-gray-50 px-3 py-1.5 text-xs text-gray-50 dark:text-gray-900 shadow-sm [&:not([data-state])]:hidden will-change-transform data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=open]:fade-in-0 data-[state=closed]:fade-out-0 data-[state=open]:zoom-in-95 data-[state=closed]:zoom-out-95 data-[state=open]:animate-duration-150 data-[state=closed]:animate-duration-200 data-[side=bottom]:slide-in-from-top-2 data-[side=bottom]:slide-out-to-top-2 data-[side=left]:slide-in-from-right-2 data-[side=left]:slide-out-to-right-2 data-[side=right]:slide-in-from-left-2 data-[side=right]:slide-out-to-left-2 data-[side=top]:slide-in-from-bottom-2 data-[side=top]:slide-out-to-bottom-2">
{tooltip}
</TooltipContent>
) : null}
</TooltipRoot>
);
}

View File

@@ -0,0 +1,36 @@
import type { CodeBlockAttrs } from "prosekit/extensions/code-block";
import { shikiBundledLanguagesInfo } from "prosekit/extensions/code-block";
import type { ReactNodeViewProps } from "prosekit/react";
export default function CodeBlockView(props: ReactNodeViewProps) {
const attrs = props.node.attrs as CodeBlockAttrs;
const language = attrs.language;
const setLanguage = (language: string) => {
const attrs: CodeBlockAttrs = { language };
props.setAttrs(attrs);
};
return (
<>
<div
className="relative mx-2 top-3 h-0 select-none overflow-visible text-xs"
contentEditable={false}
>
<select
className="outline-unset focus:outline-unset relative box-border w-auto cursor-pointer select-none appearance-none rounded border-none bg-transparent px-2 py-1 text-xs transition text-[var(--prosemirror-highlight)] opacity-0 hover:opacity-80 [div[data-node-view-root]:hover_&]:opacity-50 [div[data-node-view-root]:hover_&]:hover:opacity-80"
onChange={(event) => setLanguage(event.target.value)}
value={language || ""}
>
<option value="">Plain Text</option>
{shikiBundledLanguagesInfo.map((info) => (
<option key={info.id} value={info.id}>
{info.name}
</option>
))}
</select>
</div>
<pre ref={props.contentRef} data-language={language}></pre>
</>
);
}

View File

@@ -0,0 +1,49 @@
import "prosekit/basic/style.css";
import "prosekit/basic/typography.css";
import { createEditor } from "prosekit/core";
import { ProseKit } from "prosekit/react";
import { memo, useMemo } from "react";
import { CoRichText } from "jazz-tools";
import BlockHandle from "./block-handle";
import { defineExtension } from "./extension";
import InlineMenu from "./inline-menu";
import SlashMenu from "./slash-menu";
import TagMenu from "./tag-menu";
import Toolbar from "./toolbar";
import UserMenu from "./user-menu";
interface EditorProps {
coRichText?: CoRichText;
}
function EditorComponent({ coRichText }: EditorProps) {
const editor = useMemo(() => {
const extension = defineExtension({ coRichText });
return createEditor({ extension });
}, [coRichText]);
return (
<ProseKit editor={editor}>
<div className="box-border h-full w-full min-h-72 overflow-y-hidden overflow-x-hidden rounded-md border border-solid border-gray-200 dark:border-gray-700 shadow flex flex-col color-black dark:color-white bg-white">
<Toolbar />
<div className="relative bg-white w-full flex-1 box-border overflow-y-scroll">
<div
ref={editor.mount}
className="ProseMirror bg-white box-border min-h-full px-[max(4rem,_calc(50%-20rem))] py-8 outline-none outline-0 [&_span[data-mention=user]]:text-blue-500 [&_span[data-mention=tag]]:text-violet-500"
></div>
<InlineMenu />
<SlashMenu />
<UserMenu />
<TagMenu />
<BlockHandle />
</div>
</div>
</ProseKit>
);
}
const EditorMemo = memo(EditorComponent);
export default EditorMemo;

View File

@@ -0,0 +1,47 @@
import { createJazzPlugin } from "jazz-richtext-prosemirror";
import { defineBasicExtension } from "prosekit/basic";
import { definePlugin, union } from "prosekit/core";
import {
defineCodeBlock,
defineCodeBlockShiki,
} from "prosekit/extensions/code-block";
import { defineHorizontalRule } from "prosekit/extensions/horizontal-rule";
import { defineMention } from "prosekit/extensions/mention";
import { definePlaceholder } from "prosekit/extensions/placeholder";
import {
type ReactNodeViewComponent,
defineReactNodeView,
} from "prosekit/react";
import { JazzPluginConfig } from "jazz-richtext-prosemirror/src/lib/plugin";
import type { CoRichText } from "jazz-tools";
import CodeBlockView from "./code-block-view";
import ImageView from "./image-view";
import { defineImageFileHandlers } from "./upload-file";
export function defineExtension(jazz: {
coRichText?: CoRichText;
config?: JazzPluginConfig;
}) {
return union(
defineBasicExtension(),
definePlaceholder({ placeholder: "Press / for commands..." }),
defineMention(),
defineCodeBlock(),
defineCodeBlockShiki(),
defineHorizontalRule(),
defineReactNodeView({
name: "codeBlock",
contentAs: "code",
component: CodeBlockView satisfies ReactNodeViewComponent,
}),
defineReactNodeView({
name: "image",
component: ImageView satisfies ReactNodeViewComponent,
}),
defineImageFileHandlers(),
definePlugin(createJazzPlugin(jazz.coRichText, jazz.config)),
);
}
export type EditorExtension = ReturnType<typeof defineExtension>;

View File

@@ -0,0 +1,115 @@
import { useEditor } from "prosekit/react";
import {
PopoverContent,
PopoverRoot,
PopoverTrigger,
} from "prosekit/react/popover";
import { type FC, type ReactNode, useState } from "react";
import Button from "./button";
import type { EditorExtension } from "./extension";
export const ImageUploadPopover: FC<{
tooltip: string;
disabled: boolean;
children: ReactNode;
}> = ({ tooltip, disabled, children }) => {
const [open, setOpen] = useState(false);
const [webUrl, setWebUrl] = useState("");
const [objectUrl, setObjectUrl] = useState("");
const url = webUrl || objectUrl;
const editor = useEditor<EditorExtension>();
const handleFileChange: React.ChangeEventHandler<HTMLInputElement> = (
event,
) => {
const file = event.target.files?.[0];
if (file) {
setObjectUrl(URL.createObjectURL(file));
setWebUrl("");
} else {
setObjectUrl("");
}
};
const handleWebUrlChange: React.ChangeEventHandler<HTMLInputElement> = (
event,
) => {
const url = event.target.value;
if (url) {
setWebUrl(url);
setObjectUrl("");
} else {
setWebUrl("");
}
};
const deferResetState = () => {
setTimeout(() => {
setWebUrl("");
setObjectUrl("");
}, 300);
};
const handleSubmit = () => {
editor.commands.insertImage({ src: url });
deferResetState();
setOpen(false);
};
const handleOpenChange = (open: boolean) => {
if (!open) {
deferResetState();
}
setOpen(open);
};
return (
<PopoverRoot open={open} onOpenChange={handleOpenChange}>
<PopoverTrigger>
<Button pressed={open} disabled={disabled} tooltip={tooltip}>
{children}
</Button>
</PopoverTrigger>
<PopoverContent className="flex flex-col gap-y-4 p-6 text-sm w-sm z-10 box-border rounded-lg border border-gray-200 dark:border-gray-800 bg-white dark:bg-gray-950 shadow-lg [&:not([data-state])]:hidden will-change-transform data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=open]:fade-in-0 data-[state=closed]:fade-out-0 data-[state=open]:zoom-in-95 data-[state=closed]:zoom-out-95 data-[state=open]:animate-duration-150 data-[state=closed]:animate-duration-200 data-[side=bottom]:slide-in-from-top-2 data-[side=bottom]:slide-out-to-top-2 data-[side=left]:slide-in-from-right-2 data-[side=left]:slide-out-to-right-2 data-[side=right]:slide-in-from-left-2 data-[side=right]:slide-out-to-left-2 data-[side=top]:slide-in-from-bottom-2 data-[side=top]:slide-out-to-bottom-2">
{objectUrl ? null : (
<>
<label>Embed Link</label>
<input
className="flex h-9 rounded-md w-full bg-white dark:bg-gray-950 px-3 py-2 text-sm placeholder:text-gray-500 dark:placeholder:text-gray-500 transition border box-border border-gray-200 dark:border-gray-800 border-solid ring-0 ring-transparent focus-visible:ring-2 focus-visible:ring-gray-900 dark:focus-visible:ring-gray-300 focus-visible:ring-offset-0 outline-none focus-visible:outline-none file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:cursor-not-allowed disabled:opacity-50"
placeholder="Paste the image link..."
type="url"
value={webUrl}
onChange={handleWebUrlChange}
/>
</>
)}
{webUrl ? null : (
<>
<label>Upload</label>
<input
className="flex h-9 rounded-md w-full bg-white dark:bg-gray-950 px-3 py-2 text-sm placeholder:text-gray-500 dark:placeholder:text-gray-500 transition border box-border border-gray-200 dark:border-gray-800 border-solid ring-0 ring-transparent focus-visible:ring-2 focus-visible:ring-gray-900 dark:focus-visible:ring-gray-300 focus-visible:ring-offset-0 outline-none focus-visible:outline-none file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:cursor-not-allowed disabled:opacity-50"
accept="image/*"
type="file"
onChange={handleFileChange}
/>
</>
)}
{url ? (
<button
className="inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-white dark:ring-offset-gray-950 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-gray-900 dark:focus-visible:ring-gray-300 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 border-0 bg-gray-900 dark:bg-gray-50 text-gray-50 dark:text-gray-900 hover:bg-gray-900/90 dark:hover:bg-gray-50/90 h-10 px-4 py-2 w-full"
onClick={handleSubmit}
>
Insert Image
</button>
) : null}
</PopoverContent>
</PopoverRoot>
);
};

View File

@@ -0,0 +1,114 @@
import { UploadTask } from "prosekit/extensions/file";
import type { ImageAttrs } from "prosekit/extensions/image";
import type { ReactNodeViewProps } from "prosekit/react";
import { ResizableHandle, ResizableRoot } from "prosekit/react/resizable";
import { type SyntheticEvent, useEffect, useState } from "react";
export default function ImageView(props: ReactNodeViewProps) {
const { setAttrs, node } = props;
const attrs = node.attrs as ImageAttrs;
const url = attrs.src || "";
const uploading = url.startsWith("blob:");
const [aspectRatio, setAspectRatio] = useState<number | undefined>();
const [error, setError] = useState<string | undefined>();
const [progress, setProgress] = useState(0);
useEffect(() => {
if (!url.startsWith("blob:")) {
return;
}
const uploadTask = UploadTask.get<string>(url);
if (!uploadTask) {
return;
}
const abortController = new AbortController();
void uploadTask.finished
.then((resultUrl) => {
if (resultUrl && typeof resultUrl === "string") {
if (abortController.signal.aborted) {
return;
}
setAttrs({ src: resultUrl });
} else {
if (abortController.signal.aborted) {
return;
}
setError("Unexpected upload result");
}
UploadTask.delete(uploadTask.objectURL);
})
.catch((error) => {
if (abortController.signal.aborted) {
return;
}
setError(String(error));
UploadTask.delete(uploadTask.objectURL);
});
const unsubscribe = uploadTask.subscribeProgress(({ loaded, total }) => {
if (abortController.signal.aborted) {
return;
}
if (total > 0) {
setProgress(loaded / total);
}
});
return () => {
unsubscribe();
abortController.abort();
};
}, [url, setAttrs]);
const handleImageLoad = (event: SyntheticEvent) => {
const img = event.target as HTMLImageElement;
const { naturalWidth, naturalHeight } = img;
const ratio = naturalWidth / naturalHeight;
if (ratio && Number.isFinite(ratio)) {
setAspectRatio(ratio);
}
if (naturalWidth && naturalHeight && (!attrs.width || !attrs.height)) {
setAttrs({ width: naturalWidth, height: naturalHeight });
}
};
return (
<ResizableRoot
width={attrs.width ?? undefined}
height={attrs.height ?? undefined}
aspectRatio={aspectRatio}
onResizeEnd={(event) => setAttrs(event.detail)}
data-selected={props.selected ? "" : undefined}
className="relative flex items-center justify-center box-border overflow-hidden my-2 group max-h-[600px] max-w-full min-h-[64px] min-w-[64px] outline-2 outline-transparent data-[selected]:outline-blue-500 outline-solid"
>
{url && !error && (
<img
src={url}
onLoad={handleImageLoad}
className="h-full w-full max-w-full max-h-full object-contain"
/>
)}
{uploading && !error && (
<div className="absolute bottom-0 left-0 m-1 flex content-center items-center gap-2 rounded bg-gray-800/60 p-1.5 text-xs text-white/80 transition">
<div className="i-lucide-loader-circle h-4 w-4 animate-spin"></div>
<div>{Math.round(progress * 100)}%</div>
</div>
)}
{error && (
<div className="absolute bottom-0 left-0 right-0 top-0 flex flex-col items-center justify-center gap-4 bg-gray-200 p-2 text-sm dark:bg-gray-800 @container">
<div className="i-lucide-image-off h-8 w-8"></div>
<div className="hidden opacity-80 @xs:block">
Failed to upload image
</div>
</div>
)}
<ResizableHandle
className="absolute bottom-0 right-0 rounded m-1.5 p-1 transition bg-gray-900/30 active:bg-gray-800/60 hover:bg-gray-800/60 text-white/50 active:text-white/80 active:translate-x-0.5 active:translate-y-0.5 opacity-0 hover:opacity-100 group-hover:opacity-100 group-[[data-resizing]]:opacity-100"
position="bottom-right"
>
<div className="i-lucide-arrow-down-right h-4 w-4"></div>
</ResizableHandle>
</ResizableRoot>
);
}

View File

@@ -0,0 +1,146 @@
import type { LinkAttrs } from "prosekit/extensions/link";
import type { EditorState } from "prosekit/pm/state";
import { useEditor } from "prosekit/react";
import { InlinePopover } from "prosekit/react/inline-popover";
import { useState } from "react";
import Button from "./button";
import type { EditorExtension } from "./extension";
export default function InlineMenu() {
const editor = useEditor<EditorExtension>({ update: true });
const [linkMenuOpen, setLinkMenuOpen] = useState(false);
const toggleLinkMenuOpen = () => setLinkMenuOpen((open) => !open);
const getCurrentLink = (state: EditorState): string | undefined => {
const { $from } = state.selection;
const marks = $from.marksAcross($from);
if (!marks) {
return;
}
for (const mark of marks) {
if (mark.type.name === "link") {
return (mark.attrs as LinkAttrs).href;
}
}
};
const handleLinkUpdate = (href?: string) => {
if (href) {
editor.commands.addLink({ href });
} else {
editor.commands.removeLink();
}
setLinkMenuOpen(false);
editor.focus();
};
return (
<>
<InlinePopover
data-testid="inline-menu-main"
className="z-10 box-border border border-gray-200 dark:border-gray-800 bg-white dark:bg-gray-950 shadow-lg [&:not([data-state])]:hidden relative flex min-w-[8rem] space-x-1 overflow-auto whitespace-nowrap rounded-md p-1"
onOpenChange={(open) => {
if (!open) {
setLinkMenuOpen(false);
}
}}
>
<Button
pressed={editor.marks.bold.isActive()}
disabled={!editor.commands.toggleBold.canExec()}
onClick={() => editor.commands.toggleBold()}
tooltip="Bold"
>
<div className="i-lucide-bold h-5 w-5"></div>
</Button>
<Button
pressed={editor.marks.italic.isActive()}
disabled={!editor.commands.toggleItalic.canExec()}
onClick={() => editor.commands.toggleItalic()}
tooltip="Italic"
>
<div className="i-lucide-italic h-5 w-5"></div>
</Button>
<Button
pressed={editor.marks.underline.isActive()}
disabled={!editor.commands.toggleUnderline.canExec()}
onClick={() => editor.commands.toggleUnderline()}
tooltip="Underline"
>
<div className="i-lucide-underline h-5 w-5"></div>
</Button>
<Button
pressed={editor.marks.strike.isActive()}
disabled={!editor.commands.toggleStrike.canExec()}
onClick={() => editor.commands.toggleStrike()}
tooltip="Strikethrough"
>
<div className="i-lucide-strikethrough h-5 w-5"></div>
</Button>
<Button
pressed={editor.marks.code.isActive()}
disabled={!editor.commands.toggleCode.canExec()}
onClick={() => editor.commands.toggleCode()}
tooltip="Code"
>
<div className="i-lucide-code h-5 w-5"></div>
</Button>
{editor.commands.addLink.canExec({ href: "" }) && (
<Button
pressed={editor.marks.link.isActive()}
onClick={() => {
editor.commands.expandLink();
toggleLinkMenuOpen();
}}
tooltip="Link"
>
<div className="i-lucide-link h-5 w-5"></div>
</Button>
)}
</InlinePopover>
<InlinePopover
placement={"bottom"}
defaultOpen={false}
open={linkMenuOpen}
onOpenChange={setLinkMenuOpen}
data-testid="inline-menu-link"
className="z-10 box-border border border-gray-200 dark:border-gray-800 bg-white dark:bg-gray-950 shadow-lg [&:not([data-state])]:hidden relative flex flex-col w-xs rounded-lg p-4 gap-y-2 items-stretch"
>
{linkMenuOpen && (
<form
onSubmit={(event) => {
event.preventDefault();
const target = event.target as HTMLFormElement | null;
const href = target?.querySelector("input")?.value?.trim();
handleLinkUpdate(href);
}}
>
<input
placeholder="Paste the link..."
defaultValue={getCurrentLink(editor.state)}
className="flex h-9 rounded-md w-full bg-white dark:bg-gray-950 px-3 py-2 text-sm placeholder:text-gray-500 dark:placeholder:text-gray-500 transition border box-border border-gray-200 dark:border-gray-800 border-solid ring-0 ring-transparent focus-visible:ring-2 focus-visible:ring-gray-900 dark:focus-visible:ring-gray-300 focus-visible:ring-offset-0 outline-none focus-visible:outline-none file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:cursor-not-allowed disabled:opacity-50"
></input>
</form>
)}
{editor.marks.link.isActive() && (
<button
onClick={() => handleLinkUpdate()}
onMouseDown={(event) => event.preventDefault()}
className="inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-white dark:ring-offset-gray-950 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-gray-900 dark:focus-visible:ring-gray-300 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 border-0 bg-gray-900 dark:bg-gray-50 text-gray-50 dark:text-gray-900 hover:bg-gray-900/90 dark:hover:bg-gray-50/90 h-9 px-3"
>
Remove link
</button>
)}
</InlinePopover>
</>
);
}

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