Compare commits
103 Commits
jazz-react
...
jazz-react
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a383c7e984 | ||
|
|
8ca283147d | ||
|
|
c3d87796ed | ||
|
|
cb88caced9 | ||
|
|
6313ead62d | ||
|
|
f674910aa9 | ||
|
|
37fc25f5a6 | ||
|
|
5e9c338c27 | ||
|
|
4b61f7c7a5 | ||
|
|
1c8472ffbd | ||
|
|
9dba68ac36 | ||
|
|
13b57aa576 | ||
|
|
aedf0f3ac5 | ||
|
|
7fa61644b0 | ||
|
|
12389c82f9 | ||
|
|
4c03a17d3a | ||
|
|
5d1ea45a9c | ||
|
|
cc0479afe0 | ||
|
|
cfb6786468 | ||
|
|
5662faa9c0 | ||
|
|
3e7d9cb585 | ||
|
|
2116a598ae | ||
|
|
d14a069a12 | ||
|
|
aacef80994 | ||
|
|
2a237e5d32 | ||
|
|
0fe30eca0b | ||
|
|
dea7a8dfd9 | ||
|
|
ab7191bed0 | ||
|
|
901b7c0a51 | ||
|
|
17bea5975c | ||
|
|
e005ecd0a1 | ||
|
|
e7e505e5f3 | ||
|
|
d6ffe03d3c | ||
|
|
1120747a24 | ||
|
|
1e2d7d1c4e | ||
|
|
e26f110acd | ||
|
|
28f84a4ee6 | ||
|
|
cffe4abb84 | ||
|
|
2e0b7cee8c | ||
|
|
d3b47f59e8 | ||
|
|
aea3287965 | ||
|
|
6525f8a12e | ||
|
|
fe4c934a4b | ||
|
|
60261c8dba | ||
|
|
7411049faa | ||
|
|
356b06559b | ||
|
|
193738cfe2 | ||
|
|
ddb74fa167 | ||
|
|
aca5642671 | ||
|
|
a5bed20c4a | ||
|
|
09bf53a8d3 | ||
|
|
061ec996b1 | ||
|
|
a7ee0465b5 | ||
|
|
e995d8a1fe | ||
|
|
5ccb48446e | ||
|
|
04b20c2e42 | ||
|
|
7aae2441a1 | ||
|
|
650e95a528 | ||
|
|
3d80ab11d9 | ||
|
|
85e6489a3e | ||
|
|
45b6c87ade | ||
|
|
edadc4b986 | ||
|
|
455b722357 | ||
|
|
ad2e1d1e98 | ||
|
|
7c94b70c31 | ||
|
|
74bcf1752e | ||
|
|
97a54b3911 | ||
|
|
c393c8880f | ||
|
|
359157fa70 | ||
|
|
62d9680449 | ||
|
|
db6067439d | ||
|
|
5051d6a410 | ||
|
|
25efaf30f5 | ||
|
|
98aadd9842 | ||
|
|
d555b18c11 | ||
|
|
550111f8a1 | ||
|
|
3d4a00a19d | ||
|
|
d06c6677dc | ||
|
|
ce30f3c4ff | ||
|
|
1072b9c2fe | ||
|
|
5ea41c69ef | ||
|
|
2d8eed3b69 | ||
|
|
45c9c8558f | ||
|
|
dccb80edf0 | ||
|
|
6f72419b6e | ||
|
|
fa2227716f | ||
|
|
38dabd4602 | ||
|
|
156167e6d7 | ||
|
|
aef84cf2ef | ||
|
|
275a26e2c1 | ||
|
|
946ae63070 | ||
|
|
5cfe47ebbe | ||
|
|
6ee0ec755e | ||
|
|
8ffca202bd | ||
|
|
6d2bcc7490 | ||
|
|
69709c2cf2 | ||
|
|
e88252bee4 | ||
|
|
a6b7857f6f | ||
|
|
265c30158e | ||
|
|
505e132f1e | ||
|
|
c6d5195cb5 | ||
|
|
8af543e7d6 | ||
|
|
016b2098a7 |
46
.github/workflows/playwright-homepage.yml
vendored
Normal file
46
.github/workflows/playwright-homepage.yml
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
name: Playwright Tests
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: ["main"]
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
timeout-minutes: 60
|
||||
runs-on: blacksmith-4vcpu-ubuntu-2204
|
||||
strategy:
|
||||
matrix:
|
||||
project: ["homepage/homepage"]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Setup Source Code
|
||||
uses: ./.github/actions/source-code/
|
||||
|
||||
- name: Install project dependencies
|
||||
run: pnpm install
|
||||
working-directory: ./${{ matrix.project }}
|
||||
|
||||
- name: Pnpm Build
|
||||
run: pnpm turbo build
|
||||
working-directory: ./${{ matrix.project }}
|
||||
|
||||
- name: Install Playwright Browsers
|
||||
run: pnpm exec playwright install
|
||||
working-directory: ./${{ matrix.project }}
|
||||
|
||||
- name: Run Playwright tests
|
||||
run: pnpm exec playwright test
|
||||
working-directory: ./${{ matrix.project }}
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
if: failure()
|
||||
with:
|
||||
name: ${{ hashFiles(format('{0}/package.json', matrix.project)) }}-playwright-report
|
||||
path: ./${{ matrix.project }}/playwright-report/
|
||||
retention-days: 30
|
||||
@@ -64,7 +64,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"include": ["packages/**/src/tests/**"],
|
||||
"include": ["**/tests/**"],
|
||||
"linter": {
|
||||
"rules": {
|
||||
"correctness": {
|
||||
|
||||
@@ -1,5 +1,44 @@
|
||||
# betterauth
|
||||
|
||||
## 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
|
||||
|
||||
- jazz-betterauth-client-plugin@0.14.19
|
||||
- jazz-betterauth-server-plugin@0.14.19
|
||||
- jazz-react-auth-betterauth@0.14.19
|
||||
- jazz-inspector@0.14.19
|
||||
- jazz-react@0.14.19
|
||||
- jazz-tools@0.14.19
|
||||
|
||||
## 0.1.21
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "betterauth",
|
||||
"version": "0.1.21",
|
||||
"version": "0.1.24",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
|
||||
@@ -1,5 +1,37 @@
|
||||
# chat-rn-expo-clerk
|
||||
|
||||
## 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
|
||||
|
||||
- Updated dependencies [061ec99]
|
||||
- jazz-expo@0.14.19
|
||||
- jazz-react-native-media-images@0.14.19
|
||||
- jazz-tools@0.14.19
|
||||
|
||||
## 1.0.141
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "chat-rn-expo-clerk",
|
||||
"main": "index.js",
|
||||
"version": "1.0.141",
|
||||
"version": "1.0.144",
|
||||
"scripts": {
|
||||
"build": "expo export -p ios",
|
||||
"start": "expo start",
|
||||
|
||||
@@ -1,5 +1,34 @@
|
||||
# chat-rn-expo
|
||||
|
||||
## 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
|
||||
|
||||
- Updated dependencies [061ec99]
|
||||
- jazz-expo@0.14.19
|
||||
- jazz-tools@0.14.19
|
||||
|
||||
## 1.0.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "chat-rn-expo",
|
||||
"version": "1.0.9",
|
||||
"version": "1.0.12",
|
||||
"main": "index.ts",
|
||||
"scripts": {
|
||||
"build": "expo prebuild",
|
||||
|
||||
@@ -1,5 +1,40 @@
|
||||
# chat-rn
|
||||
|
||||
## 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
|
||||
|
||||
- Updated dependencies [061ec99]
|
||||
- jazz-react-native@0.14.19
|
||||
- cojson@0.14.19
|
||||
- cojson-transport-ws@0.14.19
|
||||
- jazz-tools@0.14.19
|
||||
|
||||
## 1.0.136
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "chat-rn",
|
||||
"version": "1.0.136",
|
||||
"version": "1.0.139",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"android": "react-native run-android",
|
||||
|
||||
@@ -1,5 +1,35 @@
|
||||
# chat-vue
|
||||
|
||||
## 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
|
||||
|
||||
- jazz-browser@0.14.19
|
||||
- jazz-tools@0.14.19
|
||||
- jazz-vue@0.14.19
|
||||
|
||||
## 0.0.116
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "chat-vue",
|
||||
"version": "0.0.116",
|
||||
"version": "0.0.119",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
@@ -32,7 +32,7 @@
|
||||
"postcss": "^8.4.27",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"typescript": "5.6.2",
|
||||
"vite": "6.0.11",
|
||||
"vite": "6.3.5",
|
||||
"vite-plugin-vue-devtools": "^7.4.6",
|
||||
"vue-tsc": "^2.1.6"
|
||||
}
|
||||
|
||||
@@ -1,5 +1,35 @@
|
||||
# jazz-example-chat
|
||||
|
||||
## 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
|
||||
|
||||
- jazz-inspector@0.14.19
|
||||
- jazz-react@0.14.19
|
||||
- jazz-tools@0.14.19
|
||||
|
||||
## 0.0.216
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "jazz-example-chat",
|
||||
"private": true,
|
||||
"version": "0.0.216",
|
||||
"version": "0.0.219",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
@@ -27,12 +27,12 @@
|
||||
"@playwright/test": "^1.50.1",
|
||||
"@types/react": "19.0.0",
|
||||
"@types/react-dom": "19.0.0",
|
||||
"@vitejs/plugin-react-swc": "^3.3.2",
|
||||
"@vitejs/plugin-react-swc": "^3.10.1",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"is-ci": "^3.0.1",
|
||||
"postcss": "^8.4.27",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"typescript": "5.6.2",
|
||||
"vite": "6.0.11"
|
||||
"vite": "6.3.5"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -1,5 +1,35 @@
|
||||
# minimal-auth-clerk
|
||||
|
||||
## 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
|
||||
|
||||
- jazz-react@0.14.19
|
||||
- jazz-react-auth-clerk@0.14.19
|
||||
- jazz-tools@0.14.19
|
||||
|
||||
## 0.0.115
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "clerk",
|
||||
"private": true,
|
||||
"version": "0.0.115",
|
||||
"version": "0.0.118",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
@@ -25,9 +25,9 @@
|
||||
"@biomejs/biome": "1.9.4",
|
||||
"@types/react": "19.0.0",
|
||||
"@types/react-dom": "19.0.0",
|
||||
"@vitejs/plugin-react": "^4.3.3",
|
||||
"@vitejs/plugin-react": "^4.5.1",
|
||||
"globals": "^15.11.0",
|
||||
"typescript": "5.6.2",
|
||||
"vite": "6.0.11"
|
||||
"vite": "6.3.5"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,36 @@
|
||||
# file-share-svelte
|
||||
|
||||
## 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
|
||||
|
||||
- jazz-inspector-element@0.14.19
|
||||
- jazz-svelte@0.14.19
|
||||
- jazz-tools@0.14.19
|
||||
|
||||
## 0.0.100
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "file-share-svelte",
|
||||
"version": "0.0.100",
|
||||
"version": "0.0.103",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
@@ -30,12 +30,12 @@
|
||||
"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",
|
||||
"typescript-eslint": "^8.0.0",
|
||||
"vite": "6.0.11"
|
||||
"vite": "6.3.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"@tailwindcss/typography": "^0.5.15",
|
||||
|
||||
@@ -1,5 +1,35 @@
|
||||
# jazz-tailwind-demo-auth-starter
|
||||
|
||||
## 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
|
||||
|
||||
- jazz-inspector@0.14.19
|
||||
- jazz-react@0.14.19
|
||||
- jazz-tools@0.14.19
|
||||
|
||||
## 0.0.55
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "filestream",
|
||||
"private": true,
|
||||
"version": "0.0.55",
|
||||
"version": "0.0.58",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
@@ -21,13 +21,13 @@
|
||||
"@biomejs/biome": "1.9.4",
|
||||
"@types/react": "19.0.0",
|
||||
"@types/react-dom": "19.0.0",
|
||||
"@vitejs/plugin-react": "^4.3.3",
|
||||
"@vitejs/plugin-react": "^4.5.1",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"globals": "^15.11.0",
|
||||
"is-ci": "^3.0.1",
|
||||
"postcss": "^8.5.3",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"typescript": "5.6.2",
|
||||
"vite": "6.0.11"
|
||||
"vite": "6.3.5"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,32 @@
|
||||
# form
|
||||
|
||||
## 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
|
||||
|
||||
- jazz-react@0.14.19
|
||||
- jazz-tools@0.14.19
|
||||
|
||||
## 0.1.56
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "form",
|
||||
"private": true,
|
||||
"version": "0.1.56",
|
||||
"version": "0.1.59",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
@@ -23,13 +23,13 @@
|
||||
"@tailwindcss/forms": "^0.5.9",
|
||||
"@types/react": "19.0.0",
|
||||
"@types/react-dom": "19.0.0",
|
||||
"@vitejs/plugin-react": "^4.3.3",
|
||||
"@vitejs/plugin-react": "^4.5.1",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"globals": "^15.11.0",
|
||||
"is-ci": "^3.0.1",
|
||||
"postcss": "^8.4.27",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"typescript": "5.6.2",
|
||||
"vite": "6.0.11"
|
||||
"vite": "6.3.5"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,32 @@
|
||||
# image-upload
|
||||
|
||||
## 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
|
||||
|
||||
- jazz-react@0.14.19
|
||||
- jazz-tools@0.14.19
|
||||
|
||||
## 0.0.112
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "image-upload",
|
||||
"private": true,
|
||||
"version": "0.0.112",
|
||||
"version": "0.0.115",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
@@ -20,10 +20,10 @@
|
||||
"@biomejs/biome": "1.9.4",
|
||||
"@types/react": "19.0.0",
|
||||
"@types/react-dom": "19.0.0",
|
||||
"@vitejs/plugin-react": "^4.3.3",
|
||||
"@vitejs/plugin-react": "^4.5.1",
|
||||
"globals": "^15.11.0",
|
||||
"typescript": "5.6.2",
|
||||
"vite": "6.0.11",
|
||||
"vite": "6.3.5",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"postcss": "^8.4.27",
|
||||
"tailwindcss": "^3.4.17"
|
||||
|
||||
@@ -1,5 +1,30 @@
|
||||
# jazz-example-inspector
|
||||
|
||||
## 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
|
||||
|
||||
- cojson@0.14.19
|
||||
- cojson-transport-ws@0.14.19
|
||||
- jazz-inspector@0.14.19
|
||||
|
||||
## 0.0.165
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "jazz-inspector-app",
|
||||
"private": true,
|
||||
"version": "0.0.165",
|
||||
"version": "0.0.168",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
@@ -26,11 +26,11 @@
|
||||
"devDependencies": {
|
||||
"@types/react": "19.0.0",
|
||||
"@types/react-dom": "19.0.0",
|
||||
"@vitejs/plugin-react-swc": "^3.3.2",
|
||||
"@vitejs/plugin-react-swc": "^3.10.1",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"postcss": "^8.4.27",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"typescript": "5.6.2",
|
||||
"vite": "6.0.11"
|
||||
"vite": "6.3.5"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,32 @@
|
||||
# jazz-nextjs
|
||||
|
||||
## 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
|
||||
|
||||
- jazz-react@0.14.19
|
||||
- jazz-tools@0.14.19
|
||||
|
||||
## 0.1.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "jazz-nextjs",
|
||||
"version": "0.1.5",
|
||||
"version": "0.1.8",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev --turbopack",
|
||||
|
||||
@@ -41,6 +41,6 @@
|
||||
"npm-run-all": "^4.1.5",
|
||||
"tsx": "^4.19.3",
|
||||
"typescript": "~5.6.2",
|
||||
"vite": "6.0.11"
|
||||
"vite": "6.3.5"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,32 @@
|
||||
# multi-cursors
|
||||
|
||||
## 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
|
||||
|
||||
- jazz-react@0.14.19
|
||||
- jazz-tools@0.14.19
|
||||
|
||||
## 0.0.108
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "multi-cursors",
|
||||
"private": true,
|
||||
"version": "0.0.108",
|
||||
"version": "0.0.111",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
@@ -23,14 +23,14 @@
|
||||
"@biomejs/biome": "1.9.4",
|
||||
"@types/react": "19.0.0",
|
||||
"@types/react-dom": "19.0.0",
|
||||
"@vitejs/plugin-react": "^4.3.3",
|
||||
"@vitejs/plugin-react": "^4.5.1",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"globals": "^15.11.0",
|
||||
"is-ci": "^3.0.1",
|
||||
"postcss": "^8.4.27",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"typescript": "5.6.2",
|
||||
"vite": "6.0.11",
|
||||
"vite": "6.3.5",
|
||||
"vitest": "3.1.1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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(
|
||||
{
|
||||
|
||||
@@ -1,5 +1,35 @@
|
||||
# multiauth
|
||||
|
||||
## 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
|
||||
|
||||
- jazz-react@0.14.19
|
||||
- jazz-react-auth-clerk@0.14.19
|
||||
- jazz-tools@0.14.19
|
||||
|
||||
## 0.0.56
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "multiauth",
|
||||
"private": true,
|
||||
"version": "0.0.56",
|
||||
"version": "0.0.59",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
@@ -22,9 +22,9 @@
|
||||
"@biomejs/biome": "1.9.4",
|
||||
"@types/react": "19.0.0",
|
||||
"@types/react-dom": "19.0.0",
|
||||
"@vitejs/plugin-react": "^4.3.3",
|
||||
"@vitejs/plugin-react": "^4.5.1",
|
||||
"globals": "^15.11.0",
|
||||
"typescript": "5.6.2",
|
||||
"vite": "6.0.11"
|
||||
"vite": "6.3.5"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,35 @@
|
||||
# jazz-example-musicplayer
|
||||
|
||||
## 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
|
||||
|
||||
- jazz-inspector@0.14.19
|
||||
- jazz-react@0.14.19
|
||||
- jazz-tools@0.14.19
|
||||
|
||||
## 0.0.137
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "jazz-example-music-player",
|
||||
"private": true,
|
||||
"version": "0.0.137",
|
||||
"version": "0.0.140",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
@@ -37,11 +37,11 @@
|
||||
"@playwright/test": "^1.50.1",
|
||||
"@types/react": "19.0.0",
|
||||
"@types/react-dom": "19.0.0",
|
||||
"@vitejs/plugin-react-swc": "^3.3.2",
|
||||
"@vitejs/plugin-react-swc": "^3.10.1",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"postcss": "^8.4.27",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"typescript": "5.6.2",
|
||||
"vite": "6.0.11"
|
||||
"vite": "6.3.5"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>;
|
||||
|
||||
@@ -14,6 +14,7 @@ import { apiKey } from "@/apiKey.ts";
|
||||
import { SidebarProvider } from "@/components/ui/sidebar";
|
||||
import { JazzProvider } from "jazz-react";
|
||||
import { onAnonymousAccountDiscarded } from "./4_actions";
|
||||
import { KeyboardListener } from "./components/PlayerControls";
|
||||
import { useUploadExampleData } from "./lib/useUploadExampleData";
|
||||
|
||||
/**
|
||||
@@ -50,7 +51,7 @@ function Main() {
|
||||
return (
|
||||
<>
|
||||
<RouterProvider router={router} />
|
||||
{/* <PlayerControls mediaPlayer={mediaPlayer} /> */}
|
||||
<KeyboardListener mediaPlayer={mediaPlayer} />
|
||||
<Toaster />
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -67,7 +67,7 @@ export function HomePage({ mediaPlayer }: { mediaPlayer: MediaPlayer }) {
|
||||
<SidebarInset className="flex flex-col h-screen text-gray-800 bg-blue-50">
|
||||
<div className="flex flex-1 overflow-hidden">
|
||||
<SidePanel mediaPlayer={mediaPlayer} />
|
||||
<main className="flex-1 p-6 overflow-y-auto">
|
||||
<main className="flex-1 p-6 overflow-y-auto overflow-x-hidden">
|
||||
<SidebarTrigger />
|
||||
<div className="flex items-center justify-between mb-6">
|
||||
{isRootPlaylist ? (
|
||||
@@ -90,7 +90,7 @@ export function HomePage({ mediaPlayer }: { mediaPlayer: MediaPlayer }) {
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<ul className="flex flex-col">
|
||||
<ul className="flex flex-col max-w-full">
|
||||
{playlist?.tracks?.map(
|
||||
(track) =>
|
||||
track && (
|
||||
|
||||
@@ -62,9 +62,7 @@ export function MusicTrackRow({
|
||||
|
||||
return (
|
||||
<li
|
||||
className={
|
||||
"flex gap-1 hover:bg-slate-200 group py-2 px-2 cursor-pointer"
|
||||
}
|
||||
className={"flex gap-1 hover:bg-slate-200 group py-2 px-2 cursor-pointer"}
|
||||
onClick={handleTrackClick}
|
||||
>
|
||||
<button
|
||||
|
||||
@@ -31,7 +31,7 @@ export function MusicTrackTitleInput({
|
||||
|
||||
return (
|
||||
<div
|
||||
className="relative flex-grow"
|
||||
className="relative flex-grow max-w-64"
|
||||
onClick={(evt) => evt.stopPropagation()}
|
||||
>
|
||||
<input
|
||||
|
||||
@@ -15,13 +15,6 @@ export function PlayerControls({ mediaPlayer }: { mediaPlayer: MediaPlayer }) {
|
||||
resolve: { root: { activePlaylist: true } },
|
||||
}).me?.root.activePlaylist;
|
||||
|
||||
useMediaEndListener(mediaPlayer.playNextTrack);
|
||||
useKeyboardListener("Space", () => {
|
||||
if (document.activeElement !== document.body) return;
|
||||
|
||||
playState.toggle();
|
||||
});
|
||||
|
||||
const activeTrack = useCoState(MusicTrack, mediaPlayer.activeTrackId, {
|
||||
resolve: { waveform: true },
|
||||
});
|
||||
@@ -73,3 +66,18 @@ export function PlayerControls({ mediaPlayer }: { mediaPlayer: MediaPlayer }) {
|
||||
</footer>
|
||||
);
|
||||
}
|
||||
|
||||
export function KeyboardListener({
|
||||
mediaPlayer,
|
||||
}: { mediaPlayer: MediaPlayer }) {
|
||||
const playState = usePlayState();
|
||||
|
||||
useMediaEndListener(mediaPlayer.playNextTrack);
|
||||
useKeyboardListener("Space", () => {
|
||||
if (document.activeElement !== document.body) return;
|
||||
|
||||
playState.toggle();
|
||||
});
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,32 @@
|
||||
# organization
|
||||
|
||||
## 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
|
||||
|
||||
- jazz-react@0.14.19
|
||||
- jazz-tools@0.14.19
|
||||
|
||||
## 0.0.108
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "organization",
|
||||
"private": true,
|
||||
"version": "0.0.108",
|
||||
"version": "0.0.111",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
@@ -27,12 +27,12 @@
|
||||
"@tailwindcss/forms": "^0.5.9",
|
||||
"@types/react": "19.0.0",
|
||||
"@types/react-dom": "19.0.0",
|
||||
"@vitejs/plugin-react": "^4.3.3",
|
||||
"@vitejs/plugin-react": "^4.5.1",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"globals": "^15.11.0",
|
||||
"postcss": "^8.4.27",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"typescript": "5.6.2",
|
||||
"vite": "6.0.11"
|
||||
"vite": "6.3.5"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,33 @@
|
||||
# passkey-svelte
|
||||
|
||||
## 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
|
||||
|
||||
- jazz-svelte@0.14.19
|
||||
- jazz-tools@0.14.19
|
||||
|
||||
## 0.0.102
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "passkey-svelte",
|
||||
"version": "0.0.102",
|
||||
"version": "0.0.105",
|
||||
"type": "module",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
@@ -25,11 +25,11 @@
|
||||
"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",
|
||||
"vite": "6.0.11"
|
||||
"vite": "6.3.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"jazz-svelte": "workspace:*",
|
||||
|
||||
@@ -1,5 +1,32 @@
|
||||
# minimal-auth-passkey
|
||||
|
||||
## 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
|
||||
|
||||
- jazz-react@0.14.19
|
||||
- jazz-tools@0.14.19
|
||||
|
||||
## 0.0.113
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "passkey",
|
||||
"private": true,
|
||||
"version": "0.0.113",
|
||||
"version": "0.0.116",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
@@ -20,9 +20,9 @@
|
||||
"@biomejs/biome": "1.9.4",
|
||||
"@types/react": "19.0.0",
|
||||
"@types/react-dom": "19.0.0",
|
||||
"@vitejs/plugin-react": "^4.3.3",
|
||||
"@vitejs/plugin-react": "^4.5.1",
|
||||
"globals": "^15.11.0",
|
||||
"typescript": "5.6.2",
|
||||
"vite": "6.0.11"
|
||||
"vite": "6.3.5"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,32 @@
|
||||
# passphrase
|
||||
|
||||
## 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
|
||||
|
||||
- jazz-react@0.14.19
|
||||
- jazz-tools@0.14.19
|
||||
|
||||
## 0.0.110
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "passphrase",
|
||||
"private": true,
|
||||
"version": "0.0.110",
|
||||
"version": "0.0.113",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
@@ -20,9 +20,9 @@
|
||||
"@biomejs/biome": "1.9.4",
|
||||
"@types/react": "19.0.0",
|
||||
"@types/react-dom": "19.0.0",
|
||||
"@vitejs/plugin-react": "^4.3.3",
|
||||
"@vitejs/plugin-react": "^4.5.1",
|
||||
"globals": "^15.11.0",
|
||||
"typescript": "5.6.2",
|
||||
"vite": "6.0.11"
|
||||
"vite": "6.3.5"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,32 @@
|
||||
# jazz-password-manager
|
||||
|
||||
## 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
|
||||
|
||||
- jazz-react@0.14.19
|
||||
- jazz-tools@0.14.19
|
||||
|
||||
## 0.0.134
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "jazz-password-manager",
|
||||
"private": true,
|
||||
"version": "0.0.134",
|
||||
"version": "0.0.137",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
@@ -22,12 +22,12 @@
|
||||
"devDependencies": {
|
||||
"@types/react": "19.0.0",
|
||||
"@types/react-dom": "19.0.0",
|
||||
"@vitejs/plugin-react": "^4.3.3",
|
||||
"@vitejs/plugin-react-swc": "^3.3.2",
|
||||
"@vitejs/plugin-react": "^4.5.1",
|
||||
"@vitejs/plugin-react-swc": "^3.10.1",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"postcss": "^8.4.27",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"typescript": "5.6.2",
|
||||
"vite": "6.0.11"
|
||||
"vite": "6.3.5"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,32 @@
|
||||
# jazz-example-pets
|
||||
|
||||
## 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
|
||||
|
||||
- jazz-react@0.14.19
|
||||
- jazz-tools@0.14.19
|
||||
|
||||
## 0.0.232
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "jazz-example-pets",
|
||||
"private": true,
|
||||
"version": "0.0.232",
|
||||
"version": "0.0.235",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
@@ -37,14 +37,14 @@
|
||||
"@types/qrcode": "^1.5.1",
|
||||
"@types/react": "19.0.0",
|
||||
"@types/react-dom": "19.0.0",
|
||||
"@vitejs/plugin-react-swc": "^3.3.2",
|
||||
"@vitejs/plugin-react-swc": "^3.10.1",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"is-ci": "^3.0.1",
|
||||
"jazz-run": "workspace:*",
|
||||
"postcss": "^8.4.27",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"typescript": "5.6.2",
|
||||
"vite": "6.0.11",
|
||||
"vite": "6.3.5",
|
||||
"vite-plugin-top-level-await": "^1.4.4"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,32 @@
|
||||
# reactions
|
||||
|
||||
## 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
|
||||
|
||||
- jazz-react@0.14.19
|
||||
- jazz-tools@0.14.19
|
||||
|
||||
## 0.0.112
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "reactions",
|
||||
"private": true,
|
||||
"version": "0.0.112",
|
||||
"version": "0.0.115",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
@@ -21,9 +21,9 @@
|
||||
"@biomejs/biome": "1.9.4",
|
||||
"@types/react": "19.0.0",
|
||||
"@types/react-dom": "19.0.0",
|
||||
"@vitejs/plugin-react": "^4.3.3",
|
||||
"@vitejs/plugin-react": "^4.5.1",
|
||||
"globals": "^15.11.0",
|
||||
"typescript": "5.6.2",
|
||||
"vite": "6.0.11"
|
||||
"vite": "6.3.5"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,35 @@
|
||||
# richtext-tiptap
|
||||
|
||||
## 0.1.28
|
||||
|
||||
### 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-richtext-tiptap@0.14.21
|
||||
|
||||
## 0.1.27
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [6f72419]
|
||||
- Updated dependencies [04b20c2]
|
||||
- jazz-tools@0.14.20
|
||||
- jazz-react@0.14.20
|
||||
- jazz-richtext-tiptap@0.14.20
|
||||
|
||||
## 0.1.26
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react@0.14.19
|
||||
- jazz-richtext-tiptap@0.14.19
|
||||
- jazz-tools@0.14.19
|
||||
|
||||
## 0.1.25
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "richtext-tiptap",
|
||||
"private": true,
|
||||
"version": "0.1.25",
|
||||
"version": "0.1.28",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
@@ -33,13 +33,13 @@
|
||||
"@playwright/test": "^1.50.1",
|
||||
"@types/react": "19.0.0",
|
||||
"@types/react-dom": "19.0.0",
|
||||
"@vitejs/plugin-react": "^4.3.3",
|
||||
"@vitejs/plugin-react": "^4.5.1",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"globals": "^15.11.0",
|
||||
"is-ci": "^3.0.1",
|
||||
"postcss": "^8.4.27",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"typescript": "5.6.2",
|
||||
"vite": "6.0.11"
|
||||
"vite": "6.3.5"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ export const JazzAccount = 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 = JazzProfile.create(
|
||||
{
|
||||
|
||||
@@ -1,5 +1,35 @@
|
||||
# richtext
|
||||
|
||||
## 0.0.105
|
||||
|
||||
### 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-richtext-prosemirror@0.14.21
|
||||
|
||||
## 0.0.104
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [6f72419]
|
||||
- Updated dependencies [04b20c2]
|
||||
- jazz-tools@0.14.20
|
||||
- jazz-react@0.14.20
|
||||
- jazz-richtext-prosemirror@0.14.20
|
||||
|
||||
## 0.0.103
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react@0.14.19
|
||||
- jazz-richtext-prosemirror@0.14.19
|
||||
- jazz-tools@0.14.19
|
||||
|
||||
## 0.0.102
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "richtext",
|
||||
"private": true,
|
||||
"version": "0.0.102",
|
||||
"version": "0.0.105",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
@@ -30,13 +30,13 @@
|
||||
"@playwright/test": "^1.50.1",
|
||||
"@types/react": "19.0.0",
|
||||
"@types/react-dom": "19.0.0",
|
||||
"@vitejs/plugin-react": "^4.3.3",
|
||||
"@vitejs/plugin-react": "^4.5.1",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"globals": "^15.11.0",
|
||||
"is-ci": "^3.0.1",
|
||||
"postcss": "^8.4.27",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"typescript": "5.6.2",
|
||||
"vite": "6.0.11"
|
||||
"vite": "6.3.5"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ export const JazzAccount = 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 = JazzProfile.create(
|
||||
{
|
||||
|
||||
@@ -1,5 +1,35 @@
|
||||
# todo-vue
|
||||
|
||||
## 0.0.117
|
||||
|
||||
### 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.116
|
||||
|
||||
### 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.115
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-browser@0.14.19
|
||||
- jazz-tools@0.14.19
|
||||
- jazz-vue@0.14.19
|
||||
|
||||
## 0.0.114
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "todo-vue",
|
||||
"version": "0.0.114",
|
||||
"version": "0.0.117",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
@@ -32,7 +32,7 @@
|
||||
"postcss": "^8.4.27",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"typescript": "5.6.2",
|
||||
"vite": "6.0.11",
|
||||
"vite": "6.3.5",
|
||||
"vite-plugin-vue-devtools": "^7.4.6",
|
||||
"vue-tsc": "^2.1.6"
|
||||
}
|
||||
|
||||
@@ -1,5 +1,32 @@
|
||||
# jazz-example-todo
|
||||
|
||||
## 0.0.234
|
||||
|
||||
### 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.233
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [6f72419]
|
||||
- Updated dependencies [04b20c2]
|
||||
- jazz-tools@0.14.20
|
||||
- jazz-react@0.14.20
|
||||
|
||||
## 0.0.232
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react@0.14.19
|
||||
- jazz-tools@0.14.19
|
||||
|
||||
## 0.0.231
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "jazz-example-todo",
|
||||
"private": true,
|
||||
"version": "0.0.231",
|
||||
"version": "0.0.234",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
@@ -33,11 +33,11 @@
|
||||
"@types/qrcode": "^1.5.1",
|
||||
"@types/react": "19.0.0",
|
||||
"@types/react-dom": "19.0.0",
|
||||
"@vitejs/plugin-react-swc": "^3.3.2",
|
||||
"@vitejs/plugin-react-swc": "^3.10.1",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"postcss": "^8.4.27",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"typescript": "5.6.2",
|
||||
"vite": "6.0.11"
|
||||
"vite": "6.3.5"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { co, z } from "jazz-tools";
|
||||
import { CoPlainText, co, z } from "jazz-tools";
|
||||
|
||||
/** Walkthrough: Defining the data model with CoJSON
|
||||
*
|
||||
@@ -11,9 +11,30 @@ import { co, z } from "jazz-tools";
|
||||
**/
|
||||
|
||||
/** An individual task which collaborators can tick or rename */
|
||||
export const Task = co.map({
|
||||
export const Task = co
|
||||
.map({
|
||||
done: z.boolean(),
|
||||
text: co.plainText(),
|
||||
version: z.literal(1),
|
||||
})
|
||||
.withMigration((task) => {
|
||||
if (!task.version) {
|
||||
// Cast to the v1 version
|
||||
const task_v1 = task.castAs(Task_V1);
|
||||
|
||||
// Check if the task text field is a string or an id
|
||||
// if it's a string migrate to plaintext
|
||||
// We need to do this check because some tasks with plainText have been created before we added the version field
|
||||
if (!task_v1.text.startsWith("co_z")) {
|
||||
task.text = CoPlainText.create(task_v1.text, task._owner);
|
||||
}
|
||||
task.version = 1;
|
||||
}
|
||||
});
|
||||
|
||||
const Task_V1 = co.map({
|
||||
done: z.boolean(),
|
||||
text: co.plainText(),
|
||||
text: z.string(),
|
||||
});
|
||||
|
||||
/** Our top level object: a project with a title, referencing a list of tasks */
|
||||
|
||||
@@ -51,6 +51,7 @@ export function ProjectTodoTable() {
|
||||
{
|
||||
done: false,
|
||||
text: CoPlainText.create(text, project._owner),
|
||||
version: 1,
|
||||
},
|
||||
project._owner,
|
||||
);
|
||||
|
||||
@@ -19,6 +19,7 @@ export function generateRandomProject(
|
||||
faker.lorem.sentence({ min: 3, max: 8 }),
|
||||
tasks._owner,
|
||||
),
|
||||
version: 1,
|
||||
});
|
||||
tasks.push(task);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,35 @@
|
||||
# version-history
|
||||
|
||||
## 0.0.113
|
||||
|
||||
### 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.112
|
||||
|
||||
### 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.111
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-inspector@0.14.19
|
||||
- jazz-react@0.14.19
|
||||
- jazz-tools@0.14.19
|
||||
|
||||
## 0.0.110
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "version-history",
|
||||
"private": true,
|
||||
"version": "0.0.110",
|
||||
"version": "0.0.113",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
@@ -23,9 +23,9 @@
|
||||
"@biomejs/biome": "1.9.4",
|
||||
"@types/react": "19.0.0",
|
||||
"@types/react-dom": "19.0.0",
|
||||
"@vitejs/plugin-react": "^4.3.3",
|
||||
"@vitejs/plugin-react": "^4.5.1",
|
||||
"globals": "^15.11.0",
|
||||
"typescript": "5.6.2",
|
||||
"vite": "6.0.11"
|
||||
"vite": "6.3.5"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ function App() {
|
||||
),
|
||||
estimate: 5,
|
||||
status: "backlog",
|
||||
createdAt: new Date(),
|
||||
},
|
||||
group,
|
||||
);
|
||||
|
||||
@@ -74,6 +74,8 @@ export function IssueVersionHistory({ id }: { id: string }) {
|
||||
].sort((a, b) => (a.madeAt < b.madeAt ? -1 : a.madeAt > b.madeAt ? 1 : 0));
|
||||
}, [issue?._edits]);
|
||||
|
||||
if (!issue) return;
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="flex flex-col text-sm gap-2">
|
||||
@@ -98,6 +100,12 @@ export function IssueVersionHistory({ id }: { id: string }) {
|
||||
<hr />
|
||||
|
||||
<DescriptionVersionHistory id={id} />
|
||||
|
||||
<hr />
|
||||
|
||||
<div>
|
||||
<p>This issue was created at {issue.createdAt.toLocaleString()}</p>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ export function ProjectComponent({ projectID }: { projectID: string }) {
|
||||
description: CoPlainText.create("", project._owner),
|
||||
estimate: 0,
|
||||
status: "backlog",
|
||||
createdAt: new Date(),
|
||||
},
|
||||
project._owner,
|
||||
),
|
||||
|
||||
@@ -10,6 +10,7 @@ export const Issue = co.map({
|
||||
description: co.plainText(),
|
||||
estimate: z.number(),
|
||||
status: z.literal(["backlog", "in progress", "done"]),
|
||||
createdAt: z.date(),
|
||||
});
|
||||
|
||||
export const Project = co.map({
|
||||
|
||||
1
homepage/gcmp/.gitignore
vendored
1
homepage/gcmp/.gitignore
vendored
@@ -34,5 +34,4 @@ yarn-error.log*
|
||||
*.tsbuildinfo
|
||||
next-env.d.ts
|
||||
|
||||
typedoc
|
||||
codeSamples
|
||||
@@ -20,6 +20,7 @@ export const team: Array<TeamMember> = [
|
||||
github: "aeplay",
|
||||
website: "http://anselm.io",
|
||||
bluesky: "anselm.io",
|
||||
linkedin: "anselm-eickhoff",
|
||||
},
|
||||
{
|
||||
name: "Guido D'Orsi",
|
||||
@@ -29,12 +30,13 @@ export const team: Array<TeamMember> = [
|
||||
github: "gdorsi",
|
||||
},
|
||||
{
|
||||
name: "Andrei Popa",
|
||||
titles: ["Full-Stack Dev", "Infra"],
|
||||
image: "andrei.jpeg",
|
||||
location: "Bucharest, Romania ",
|
||||
x: "elitepax",
|
||||
github: "pax-k",
|
||||
name: "Giordano Ricci",
|
||||
titles: ["Full-Stack Dev", "Observability Expert"],
|
||||
location: "Lisbon, Portugal ",
|
||||
github: "Elfo404",
|
||||
website: "https://giordanoricci.com",
|
||||
linkedin: "giordanoricci",
|
||||
image: "gio.jpg",
|
||||
},
|
||||
{
|
||||
name: "Trisha Lim",
|
||||
@@ -51,22 +53,13 @@ export const team: Array<TeamMember> = [
|
||||
location: "Portsmouth, UK ",
|
||||
github: "bensleveritt",
|
||||
},
|
||||
{
|
||||
name: "Giordano Ricci",
|
||||
titles: ["Full-Stack Dev", "DevOps"],
|
||||
location: "Lisbon, Portugal ",
|
||||
linkedin: "giordanoricci",
|
||||
github: "Elfo404",
|
||||
website: "https://giordanoricci.com",
|
||||
image: "gio.jpg",
|
||||
},
|
||||
{
|
||||
name: "Nikos Papadopoulos",
|
||||
titles: ["Full-Stack Dev"],
|
||||
location: "Farnham, UK",
|
||||
github: "4rknova",
|
||||
website: "https://www.4rknova.com",
|
||||
linkedin: "nikpapas",
|
||||
github: "4rknova",
|
||||
image: "nikos.png",
|
||||
},
|
||||
{
|
||||
@@ -74,8 +67,8 @@ export const team: Array<TeamMember> = [
|
||||
titles: ["Full-Stack Dev", "Support Dev"],
|
||||
location: "San Francisco, California, US",
|
||||
github: "emmyoh",
|
||||
linkedin: "emil-sayahi",
|
||||
bluesky: "sayahi.bsky.social",
|
||||
linkedin: "emil-sayahi",
|
||||
image: "emil.jpg",
|
||||
},
|
||||
{
|
||||
@@ -85,30 +78,23 @@ export const team: Array<TeamMember> = [
|
||||
github: "mculotta120",
|
||||
image: "meg.jpg",
|
||||
},
|
||||
{
|
||||
name: "James Vickery",
|
||||
location: "Birmingham, UK",
|
||||
titles: ["Full-Stack Dev", "Support Dev"],
|
||||
github: "jmsv",
|
||||
bluesky: "jmsv.bsky.social",
|
||||
image: "james.jpg",
|
||||
},
|
||||
{
|
||||
name: "Stephanie Lemmeyer",
|
||||
location: "Boston, Massachusetts, US",
|
||||
titles: ["Lead DevOps"],
|
||||
github: "slemmeyer",
|
||||
linkedin: "stephanielemmeyer",
|
||||
website: "https://stephanielemmeyer.me",
|
||||
image: "stephanie.jpg",
|
||||
},
|
||||
{
|
||||
name: "Nikita Voloboev",
|
||||
location: "Barcelona, Spain",
|
||||
titles: ["Full-Stack Dev"],
|
||||
github: "nikitavoloboev",
|
||||
x: "nikitavoloboev",
|
||||
github: "nikitavoloboev",
|
||||
website: "https://nikiv.dev",
|
||||
image: "nikita.jpg",
|
||||
},
|
||||
{
|
||||
name: "Sammii Kellow",
|
||||
location: "London, UK",
|
||||
titles: ["Design Engineer", "Marketing"],
|
||||
x: "SammiiHaylock",
|
||||
github: "sammii-hk",
|
||||
website: "https://sammii.dev",
|
||||
linkedin: "sammii",
|
||||
image: "sammii.jpg",
|
||||
},
|
||||
];
|
||||
|
||||
@@ -44,7 +44,6 @@
|
||||
"autoprefixer": "^10",
|
||||
"postcss": "^8",
|
||||
"tailwindcss": "^3",
|
||||
"typedoc": "^0.25.13",
|
||||
"typescript": "^5.3.3"
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 18 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 100 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 35 KiB |
BIN
homepage/gcmp/public/team/sammii.jpg
Normal file
BIN
homepage/gcmp/public/team/sammii.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 631 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 252 KiB |
1
homepage/homepage/.gitignore
vendored
1
homepage/homepage/.gitignore
vendored
@@ -34,7 +34,6 @@ yarn-error.log*
|
||||
*.tsbuildinfo
|
||||
next-env.d.ts
|
||||
|
||||
typedoc
|
||||
codeSamples
|
||||
# Turborepo
|
||||
.turbo
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
import { PackageDocs } from "@/components/docs/packageDocs";
|
||||
import { packages } from "@/content/packages";
|
||||
import { notFound } from "next/navigation";
|
||||
|
||||
interface Props {
|
||||
params: Promise<{ package: string }>;
|
||||
}
|
||||
|
||||
export default async function Page({ params }: Props) {
|
||||
const packageName = (await params).package;
|
||||
if (!packages.map((p) => p.name).includes(packageName)) {
|
||||
return notFound();
|
||||
}
|
||||
|
||||
return <PackageDocs package={packageName} />;
|
||||
}
|
||||
|
||||
export async function generateMetadata({ params }: Props) {
|
||||
const packageName = (await params).package;
|
||||
return {
|
||||
title: `${packageName} - jazz`,
|
||||
description: `API reference for ${packageName}.`,
|
||||
};
|
||||
}
|
||||
|
||||
export async function generateStaticParams() {
|
||||
// TODO: ideally we check which files exist in ../../typedoc
|
||||
return packages.map((pkg) => ({ package: pkg.name }));
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
import { SideNavLayout } from "@/components/SideNavLayout";
|
||||
import { ApiNav } from "@/components/docs/ApiNav";
|
||||
import { JazzMobileNav } from "@/components/nav";
|
||||
import { Prose } from "@garden-co/design-system/src/components/molecules/Prose";
|
||||
|
||||
export default function RootLayout({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<SideNavLayout
|
||||
sideNav={<ApiNav />}
|
||||
floatingNavSections={[
|
||||
{
|
||||
name: "API Ref",
|
||||
content: <ApiNav />,
|
||||
icon: "package",
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Prose className="overflow-x-hidden lg:flex-1 pb-10 pt-[calc(61px+2.5rem)] md:pt-10">
|
||||
{children}
|
||||
</Prose>
|
||||
|
||||
<JazzMobileNav
|
||||
sections={[
|
||||
{
|
||||
name: "API Ref",
|
||||
content: <ApiNav />,
|
||||
icon: "package",
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</SideNavLayout>
|
||||
);
|
||||
}
|
||||
@@ -1,107 +0,0 @@
|
||||
import { packages } from "@/content/packages";
|
||||
import { Icon } from "@garden-co/design-system/src/components/atoms/Icon";
|
||||
import { clsx } from "clsx";
|
||||
import type { Metadata } from "next";
|
||||
import Link from "next/link";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "API reference",
|
||||
openGraph: {
|
||||
title: "API reference",
|
||||
},
|
||||
};
|
||||
|
||||
const CardHeading = ({
|
||||
children,
|
||||
className,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
className?: string;
|
||||
}) => {
|
||||
return (
|
||||
<h2
|
||||
className={clsx(
|
||||
className,
|
||||
"font-medium text-stone-950 dark:text-white text-lg transition-colors",
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
</h2>
|
||||
);
|
||||
};
|
||||
|
||||
const CardBody = ({
|
||||
children,
|
||||
className,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
className?: string;
|
||||
}) => {
|
||||
return <p className={clsx(className, "text-sm")}>{children}</p>;
|
||||
};
|
||||
|
||||
const Card = ({
|
||||
children,
|
||||
className,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
className?: string;
|
||||
}) => {
|
||||
return (
|
||||
<div
|
||||
className={clsx(
|
||||
className,
|
||||
"not-prose p-4 h-full rounded-xl flex flex-col gap-1.5 group lg:p-5",
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default function Page() {
|
||||
return (
|
||||
<>
|
||||
<h1>API Reference</h1>
|
||||
|
||||
<div className="grid sm:grid-cols-2 lg:grid-cols-3 gap-4">
|
||||
{packages.map(({ name, description }) => (
|
||||
<Link
|
||||
className="not-prose block"
|
||||
href={`/api-reference/${name}`}
|
||||
key={name}
|
||||
>
|
||||
<Card className="border shadow-sm">
|
||||
<Icon name="package" className="text-stone-500" />
|
||||
<CardHeading className="group-hover:text-primary dark:group-hover:text-blue-600">
|
||||
{name}
|
||||
</CardHeading>
|
||||
<CardBody>{description}</CardBody>
|
||||
</Card>
|
||||
</Link>
|
||||
))}
|
||||
|
||||
<Card className="bg-stone-50 dark:bg-stone-925">
|
||||
<Icon name="help" size="md" className="text-stone-500 " />
|
||||
<CardHeading>
|
||||
Can't find what you're looking for?
|
||||
</CardHeading>
|
||||
<CardBody>
|
||||
Get help from our{" "}
|
||||
<Link href="https://discord.gg/utDMjHYg42" className="underline">
|
||||
Discord
|
||||
</Link>
|
||||
, or open an issue on{" "}
|
||||
<Link
|
||||
href="https://github.com/garden-co/jazz"
|
||||
className="underline"
|
||||
>
|
||||
GitHub
|
||||
</Link>
|
||||
.
|
||||
</CardBody>
|
||||
</Card>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
import { SideNav, SideNavBody, SideNavHeader } from "@/components/SideNav";
|
||||
import { SideNavItem } from "@/components/SideNavItem";
|
||||
import { packages } from "@/content/packages";
|
||||
import { Icon } from "@garden-co/design-system/src/components/atoms/Icon";
|
||||
import Link from "next/link";
|
||||
import { requestProject } from "./requestProject";
|
||||
|
||||
export function ApiNav({ className }: { className?: string }) {
|
||||
return (
|
||||
<SideNav className={className}>
|
||||
<SideNavBody>
|
||||
<SideNavHeader className="mb-5" href="/api-reference">
|
||||
API Reference
|
||||
</SideNavHeader>
|
||||
<ul className="space-y-5">
|
||||
{packages.map(({ name }) => (
|
||||
<li key={name}>
|
||||
<PackageNavItem package={name} />
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</SideNavBody>
|
||||
</SideNav>
|
||||
);
|
||||
}
|
||||
|
||||
export async function PackageNavItem({
|
||||
package: packageName,
|
||||
}: {
|
||||
package: string;
|
||||
}) {
|
||||
let project = await requestProject(packageName as any);
|
||||
|
||||
return (
|
||||
<>
|
||||
<SideNavItem
|
||||
className="mb-1 flex gap-2 items-center"
|
||||
href={`/api-reference/${packageName}`}
|
||||
>
|
||||
<Icon name="package" size="xs" />
|
||||
{packageName}
|
||||
</SideNavItem>
|
||||
{project.categories?.map((category) => {
|
||||
return (
|
||||
<details
|
||||
key={category.title}
|
||||
open={category.title !== "Other"}
|
||||
className="group ml-1.5 border-l"
|
||||
>
|
||||
<summary className="pl-[13px] py-1 cursor-pointer flex gap-2 items-center justify-between hover:text-stone-800 dark:hover:text-stone-200 [&::-webkit-details-marker]:hidden">
|
||||
{category.title}
|
||||
|
||||
<Icon
|
||||
name="chevronRight"
|
||||
size="sm"
|
||||
className="text-stone-300 group-open:rotate-90 transition-transform dark:text-stone-800"
|
||||
/>
|
||||
</summary>
|
||||
<div className="pl-6">
|
||||
{category.children.map(
|
||||
(child, i, children) =>
|
||||
(i == 0 || child.name !== children[i - 1]!.name) && (
|
||||
<Link
|
||||
key={child.id}
|
||||
className="block py-0.5 text-ellipsis overflow-hidden font-mono hover:text-stone-800 dark:hover:text-stone-200"
|
||||
href={`/api-reference/${packageName}#${child.name}`}
|
||||
>
|
||||
{child.name}
|
||||
</Link>
|
||||
),
|
||||
)}
|
||||
</div>
|
||||
</details>
|
||||
);
|
||||
})}
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -1,425 +0,0 @@
|
||||
import { Icon } from "@garden-co/design-system/src/components/atoms/Icon";
|
||||
import { Fragment } from "react";
|
||||
import {
|
||||
CommentDisplayPart,
|
||||
DeclarationReflection,
|
||||
ReflectionKind,
|
||||
SignatureReflection,
|
||||
SomeType,
|
||||
TypeContext,
|
||||
TypeParameterReflection,
|
||||
} from "typedoc";
|
||||
import { requestProject } from "./requestProject";
|
||||
import {
|
||||
ClassOrInterface,
|
||||
DocComment,
|
||||
FnDecl,
|
||||
Highlight,
|
||||
PropCategory,
|
||||
PropDecl,
|
||||
} from "./tags";
|
||||
|
||||
export async function PackageDocs({
|
||||
package: packageName,
|
||||
}: {
|
||||
package: string;
|
||||
}) {
|
||||
let project = await requestProject(packageName as any);
|
||||
|
||||
// console.dir(project, {depth: 10});
|
||||
|
||||
return (
|
||||
<>
|
||||
<h2 className="flex items-center gap-2">
|
||||
<code>{packageName}</code> <Icon name="package" size="md" />
|
||||
</h2>
|
||||
{project.categories?.map((category) => {
|
||||
return (
|
||||
<section key={category.title}>
|
||||
<h2>{category.title}</h2>
|
||||
{category.children.map(
|
||||
(child) =>
|
||||
// Ability to link external documents has been added. Turning it off for now
|
||||
// https://typedoc.org/documents/External_Documents.html
|
||||
child.variant !== "document" && (
|
||||
<RenderPackageChild
|
||||
child={child}
|
||||
key={child.id}
|
||||
inPackage={packageName}
|
||||
/>
|
||||
),
|
||||
)}
|
||||
</section>
|
||||
);
|
||||
})}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
function RenderPackageChild({
|
||||
child,
|
||||
inPackage,
|
||||
}: {
|
||||
child: DeclarationReflection;
|
||||
inPackage: string;
|
||||
}) {
|
||||
if (
|
||||
child.kind === ReflectionKind.Class ||
|
||||
child.kind === ReflectionKind.Interface
|
||||
) {
|
||||
return (
|
||||
<RenderClassOrInterface classOrInterface={child} inPackage={inPackage} />
|
||||
);
|
||||
} else if (child.kind === ReflectionKind.TypeAlias) {
|
||||
return <RenderTypeAlias inPackage={inPackage} child={child} />;
|
||||
} else if (child.kind === ReflectionKind.Function) {
|
||||
return child.getAllSignatures().map((signature, i) => {
|
||||
const paramTypes = printParamsWithTypes(signature);
|
||||
return (
|
||||
<div
|
||||
key={i}
|
||||
id={child.name}
|
||||
className="not-prose mt-4 p-3 rounded bg-stone-50 dark:bg-stone-925"
|
||||
>
|
||||
{
|
||||
<Highlight hide={[0, 2]}>
|
||||
{`function \n${printSimpleSignature(child, signature) + ":"}\n {}`}
|
||||
</Highlight>
|
||||
}{" "}
|
||||
<span className="opacity-75 text-xs pl-1">
|
||||
<Highlight>{printType(signature.type)}</Highlight>
|
||||
</span>
|
||||
<div className="ml-4 mt-0 text-xs opacity-75 flex">
|
||||
{paramTypes.length > 0 && (
|
||||
<div>
|
||||
<Highlight
|
||||
hide={[0, 1 + paramTypes.length]}
|
||||
>{`function fn(...args: [\n${paramTypes.join(
|
||||
",\n",
|
||||
)}\n]) {}`}</Highlight>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
} else {
|
||||
return (
|
||||
<h3 id={child.name}>
|
||||
{child.name} {child.type?.type}
|
||||
</h3>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function RenderTypeAlias({
|
||||
inPackage,
|
||||
child,
|
||||
}: {
|
||||
inPackage: string;
|
||||
child: DeclarationReflection;
|
||||
}) {
|
||||
const typeParameters = child.typeParameters?.map(
|
||||
(tParam) =>
|
||||
tParam.name + (tParam.type ? ` extends ${printType(tParam.type)}` : ""),
|
||||
);
|
||||
return (
|
||||
<div className="mt-4">
|
||||
<h3 className="not-prose" id={child.name}>
|
||||
<Highlight>{`type ${child.name}`}</Highlight>
|
||||
</h3>
|
||||
<p className="not-prose text-sm ml-4">
|
||||
<Highlight>{`type ${child.name}${typeParameters?.length && `<${typeParameters?.join(", ")}>`} = ${printType(
|
||||
child.type,
|
||||
)}`}</Highlight>
|
||||
</p>
|
||||
<div className="ml-4 mt-2 flex-[3]">
|
||||
<DocComment>
|
||||
{child.comment
|
||||
? renderSummary(child.comment.summary)
|
||||
: "⚠️ undocumented"}
|
||||
</DocComment>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function RenderClassOrInterface({
|
||||
inPackage,
|
||||
classOrInterface: classOrInterface,
|
||||
}: {
|
||||
inPackage: string;
|
||||
classOrInterface: DeclarationReflection;
|
||||
}) {
|
||||
const commentSummary = classOrInterface.comment?.summary;
|
||||
const typeParamsWithConstraints = printTypeParamsWithConstraints(
|
||||
classOrInterface.typeParameters,
|
||||
);
|
||||
return (
|
||||
<ClassOrInterface
|
||||
inPackage={inPackage}
|
||||
name={classOrInterface.name}
|
||||
doc={renderSummary(commentSummary)}
|
||||
isInterface={classOrInterface.kind === ReflectionKind.Interface}
|
||||
typeParameters={
|
||||
classOrInterface.typeParameters?.length
|
||||
? "<" +
|
||||
classOrInterface.typeParameters
|
||||
.map((tParam) => tParam.name)
|
||||
.join(", ") +
|
||||
">"
|
||||
: ""
|
||||
}
|
||||
>
|
||||
{typeParamsWithConstraints.length > 0 && (
|
||||
<div className="text-sm -mt-4">
|
||||
<Highlight
|
||||
hide={[0, 1 + typeParamsWithConstraints.length]}
|
||||
>{`class Thing<\n${typeParamsWithConstraints.join(
|
||||
",\n",
|
||||
)}\n]> {}`}</Highlight>
|
||||
</div>
|
||||
)}
|
||||
{classOrInterface.categories?.map((category) => (
|
||||
<div className="flex flex-col mt-6 first:mt-0" key={category.title}>
|
||||
<PropCategory
|
||||
name={category.title}
|
||||
description={renderSummary(
|
||||
category.description?.filter(
|
||||
(p) => p.kind !== "code" || !p.text.startsWith("```"),
|
||||
),
|
||||
)}
|
||||
example={renderSummary(
|
||||
category.description?.filter(
|
||||
(p) => p.kind === "code" && p.text.startsWith("```"),
|
||||
),
|
||||
)}
|
||||
/>
|
||||
{category.children.map(
|
||||
(prop) =>
|
||||
prop.variant !== "document" && (
|
||||
<RenderProp
|
||||
prop={prop}
|
||||
klass={classOrInterface}
|
||||
key={prop.id}
|
||||
/>
|
||||
),
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</ClassOrInterface>
|
||||
);
|
||||
}
|
||||
|
||||
function renderSummary(commentSummary: CommentDisplayPart[] | undefined) {
|
||||
return commentSummary?.map((part, idx) =>
|
||||
part.kind === "text" ? (
|
||||
<span key={idx}>
|
||||
{part.text.split("\n").map((line, i, lines) => (
|
||||
<Fragment key={i}>
|
||||
{line}
|
||||
{i !== lines.length - 1 && <br />}
|
||||
</Fragment>
|
||||
))}
|
||||
</span>
|
||||
) : part.kind === "inline-tag" ? (
|
||||
<code key={idx}>
|
||||
{part.tag} {part.text}
|
||||
</code>
|
||||
) : part.text.startsWith("```") ? (
|
||||
<pre key={idx} className="text-xs sm:text-sm">
|
||||
<Highlight>{part.text.split("\n").slice(1, -1).join("\n")}</Highlight>
|
||||
</pre>
|
||||
) : (
|
||||
<Highlight className="whitespace-nowrap" key={idx}>
|
||||
{part.text.slice(1, -1)}
|
||||
</Highlight>
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
function RenderProp({
|
||||
prop,
|
||||
klass,
|
||||
}: {
|
||||
prop: DeclarationReflection;
|
||||
klass: DeclarationReflection;
|
||||
}) {
|
||||
const propOrGetSig = prop.getSignature ? prop.getSignature : prop;
|
||||
return prop.kind & ReflectionKind.FunctionOrMethod ? (
|
||||
prop
|
||||
.getAllSignatures()
|
||||
.map((signature) => (
|
||||
<FnDecl
|
||||
key={signature.id}
|
||||
signature={printSimplePropSignature(prop, klass, signature)}
|
||||
typeParams={printTypeParamsWithConstraints(signature.typeParameters)}
|
||||
paramTypes={printParamsWithTypes(signature)}
|
||||
returnType={printType(signature.type)}
|
||||
doc={renderSummary(signature.comment?.summary)}
|
||||
example={renderSummary(
|
||||
signature.comment?.getTag("@example")?.content,
|
||||
)}
|
||||
/>
|
||||
))
|
||||
) : (
|
||||
<PropDecl
|
||||
name={
|
||||
(prop.flags.isStatic ? klass.name : "") +
|
||||
(prop.name.startsWith("[") ? "" : ".") +
|
||||
prop.name
|
||||
}
|
||||
type={printType(propOrGetSig.type)}
|
||||
doc={propOrGetSig.comment && renderSummary(propOrGetSig.comment.summary)}
|
||||
example={renderSummary(propOrGetSig.comment?.getTag("@example")?.content)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function printSimplePropSignature(
|
||||
prop: DeclarationReflection,
|
||||
klass: DeclarationReflection,
|
||||
signature: SignatureReflection,
|
||||
): string {
|
||||
return (
|
||||
`${prop.flags.isStatic ? klass.name : ""}.` +
|
||||
printSimpleSignature(prop, signature)
|
||||
);
|
||||
}
|
||||
|
||||
function printSimpleSignature(
|
||||
item: DeclarationReflection,
|
||||
signature: SignatureReflection,
|
||||
) {
|
||||
return `${item.name}${
|
||||
signature.typeParameters?.length
|
||||
? "<" +
|
||||
signature.typeParameters.map((tParam) => tParam.name).join(", ") +
|
||||
">"
|
||||
: ""
|
||||
}(${printParams(signature)?.join(", ")})`;
|
||||
}
|
||||
|
||||
function printParams(signature: SignatureReflection) {
|
||||
return (
|
||||
signature.parameters?.flatMap((param) =>
|
||||
param.name === "this"
|
||||
? []
|
||||
: [
|
||||
param.name === "__namedParameters" &&
|
||||
param.type?.type === "reflection"
|
||||
? "{ " +
|
||||
param.type.declaration.children
|
||||
?.map(
|
||||
(child) => child.name + (child.flags.isOptional ? "?" : ""),
|
||||
)
|
||||
.join(", ") +
|
||||
" }"
|
||||
: param.name + (param.defaultValue ? "?" : ""),
|
||||
],
|
||||
) || []
|
||||
);
|
||||
}
|
||||
|
||||
function printParamsWithTypes(signature: SignatureReflection) {
|
||||
return (
|
||||
signature.parameters?.map(
|
||||
(param) =>
|
||||
(param.name === "__namedParameters"
|
||||
? ""
|
||||
: param.name + (param.defaultValue ? "?" : "") + ": ") +
|
||||
printType(param.type),
|
||||
) || []
|
||||
);
|
||||
}
|
||||
|
||||
function printTypeParamsWithConstraints(
|
||||
typeParams: TypeParameterReflection[] | undefined,
|
||||
): string[] {
|
||||
return (
|
||||
typeParams?.flatMap((tParam) =>
|
||||
tParam.type ? [`${tParam.name} extends ${printType(tParam.type)}`] : [],
|
||||
) || []
|
||||
);
|
||||
}
|
||||
|
||||
function printType(type: SomeType | undefined): string {
|
||||
if (!type) return "NO TYPE";
|
||||
if (type.type === "reflection") {
|
||||
if (type.declaration.kind === ReflectionKind.TypeLiteral) {
|
||||
if (type.declaration.signatures?.length) {
|
||||
return (
|
||||
type.declaration.signatures
|
||||
?.map(
|
||||
(sig) =>
|
||||
`(${printParamsWithTypes(sig).join(
|
||||
", ",
|
||||
)}) => ${printType(sig.type)}`,
|
||||
)
|
||||
.join(" | ") || ""
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
"{ " +
|
||||
type.declaration.children
|
||||
?.map((child) => `${child.name}: ${printType(child.type)}`)
|
||||
.join(", ") +
|
||||
" }"
|
||||
);
|
||||
}
|
||||
}
|
||||
return "TODO reflection type " + type.declaration.kind;
|
||||
} else if (type.type === "reference") {
|
||||
return (
|
||||
type.name +
|
||||
(type.typeArguments?.length
|
||||
? "<" + type.typeArguments.map(printType).join(", ") + ">"
|
||||
: "")
|
||||
);
|
||||
} else if (type.type === "intersection") {
|
||||
return (
|
||||
type.types
|
||||
?.map((part) =>
|
||||
part.needsParenthesis(TypeContext["intersectionElement"])
|
||||
? `(${printType(part)})`
|
||||
: printType(part),
|
||||
)
|
||||
.join(" & ") || "NO TYPES"
|
||||
);
|
||||
} else if (type.type === "union") {
|
||||
return (
|
||||
type.types
|
||||
.sort((a, b) => (a.type === "intrinsic" ? 1 : -1))
|
||||
?.map((part) =>
|
||||
part.needsParenthesis(TypeContext["unionElement"])
|
||||
? `(${printType(part)})`
|
||||
: printType(part),
|
||||
)
|
||||
.join(" | ") || "NO TYPES"
|
||||
);
|
||||
} else if (type.type === "tuple") {
|
||||
return `[${type.elements.map(printType).join(", ")}]`;
|
||||
} else if (type.type === "array") {
|
||||
if (type.needsParenthesis()) {
|
||||
return `(${printType(type.elementType)})[]`;
|
||||
} else {
|
||||
return printType(type.elementType) + "[]";
|
||||
}
|
||||
} else if (type.type === "mapped") {
|
||||
return `{[${type.parameter} in ${printType(
|
||||
type.parameterType,
|
||||
)}]: ${printType(type.templateType)}}`;
|
||||
} else if (type.type === "indexedAccess") {
|
||||
return `${printType(type.objectType)}[${printType(type.indexType)}]`;
|
||||
} else if (type.type === "intrinsic") {
|
||||
return type.name;
|
||||
} else if (type.type === "predicate") {
|
||||
return `${type.name} is ${printType(type.targetType)}`;
|
||||
} else if (type.type === "query") {
|
||||
return printType(type.queryType);
|
||||
} else if (type.type === "literal") {
|
||||
return JSON.stringify(type.value);
|
||||
} else {
|
||||
return "TODO type " + type.type;
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
import {
|
||||
Deserializer,
|
||||
FileRegistry,
|
||||
JSONOutput,
|
||||
ProjectReflection,
|
||||
} from "typedoc";
|
||||
|
||||
import JazzBrowserMediaImagesDocs from "../../typedoc/jazz-browser-media-images.json";
|
||||
import JazzBrowserDocs from "../../typedoc/jazz-browser.json";
|
||||
import JazzNodejsDocs from "../../typedoc/jazz-nodejs.json";
|
||||
import JazzReactDocs from "../../typedoc/jazz-react.json";
|
||||
import JazzToolsDocs from "../../typedoc/jazz-tools.json";
|
||||
|
||||
const docs = {
|
||||
"jazz-tools": JazzToolsDocs as unknown as JSONOutput.ProjectReflection,
|
||||
"jazz-react": JazzReactDocs as unknown as JSONOutput.ProjectReflection,
|
||||
"jazz-browser": JazzBrowserDocs as unknown as JSONOutput.ProjectReflection,
|
||||
"jazz-browser-media-images":
|
||||
JazzBrowserMediaImagesDocs as unknown as JSONOutput.ProjectReflection,
|
||||
"jazz-nodejs": JazzNodejsDocs as unknown as JSONOutput.ProjectReflection,
|
||||
};
|
||||
|
||||
export async function requestProject(
|
||||
packageName: keyof typeof docs,
|
||||
): Promise<ProjectReflection> {
|
||||
const deserializer = new Deserializer({} as any);
|
||||
return deserializer.reviveProject(packageName, docs[packageName], {
|
||||
projectRoot: "/",
|
||||
registry: new FileRegistry(),
|
||||
});
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
```tsx
|
||||
const group = Group.create();
|
||||
group.addMember(Alice, "writer");
|
||||
group.addMember("everyone", "reader");
|
||||
group.makePublic();
|
||||
|
||||
Message.create({ text: "..." }, group);
|
||||
```
|
||||
|
||||
@@ -13,7 +13,7 @@ export function ExpoLogo(props: SVGProps<SVGSVGElement>) {
|
||||
>
|
||||
<path
|
||||
d="M11.39 8.269c.19-.277.397-.312.565-.312.168 0 .447.035.637.312 1.49 2.03 3.95 6.075 5.765 9.06 1.184 1.945 2.093 3.44 2.28 3.63.7.714 1.66.269 2.218-.541.549-.797.701-1.357.701-1.954 0-.407-7.958-15.087-8.759-16.309C14.027.98 13.775.683 12.457.683h-.988c-1.315 0-1.505.297-2.276 1.472C8.392 3.377.433 18.057.433 18.463c0 .598.153 1.158.703 1.955.558.81 1.518 1.255 2.218.54.186-.19 1.095-1.684 2.279-3.63 1.815-2.984 4.267-7.029 5.758-9.06z"
|
||||
fill="#000"
|
||||
className="fill-black dark:fill-white"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
|
||||
@@ -0,0 +1,246 @@
|
||||
import { CodeGroup } from "@/components/forMdx";
|
||||
export const metadata = { title: "History Patterns" };
|
||||
|
||||
# History Patterns
|
||||
|
||||
Jazz's automatic history tracking enables powerful patterns for building collaborative features. Here's how to implement common history-based functionality.
|
||||
|
||||
## Audit Logs
|
||||
|
||||
Build a complete audit trail showing all changes to your data:
|
||||
|
||||
<CodeGroup>
|
||||
```ts twoslash
|
||||
import { co, z } from 'jazz-tools'
|
||||
import { createJazzTestAccount } from 'jazz-tools/testing'
|
||||
const me = await createJazzTestAccount();
|
||||
|
||||
const Task = co.map({
|
||||
title: z.string(),
|
||||
status: z.literal(["todo", "in-progress", "completed"]),
|
||||
});
|
||||
type Task = co.loaded<typeof Task>;
|
||||
const task = Task.create({ title: "New task", status: "todo" }, { owner: me });
|
||||
|
||||
// ---cut---
|
||||
function getAuditLog(task: Task) {
|
||||
const changes = [];
|
||||
|
||||
// Collect edits for all fields
|
||||
const fields = Object.keys(task);
|
||||
for (const field of fields) {
|
||||
const editField = field as keyof typeof task._edits;
|
||||
if (!task._edits[editField]) continue;
|
||||
|
||||
for (const edit of task._edits[editField].all) {
|
||||
changes.push({
|
||||
field,
|
||||
value: edit.value,
|
||||
by: edit.by,
|
||||
at: edit.madeAt,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Sort by timestamp (newest first)
|
||||
return changes.sort((a, b) => b.at.getTime() - a.at.getTime());
|
||||
}
|
||||
|
||||
// Use it to show change history
|
||||
const auditLog = getAuditLog(task);
|
||||
auditLog.forEach((entry) => {
|
||||
const when = entry.at.toLocaleString();
|
||||
const who = entry.by?.profile?.name;
|
||||
const what = entry.field;
|
||||
const value = entry.value;
|
||||
|
||||
console.log(`${when} - ${who} changed ${what} to "${value}"`);
|
||||
// 22/05/2025, 12:00:00 - Alice changed title to "New task"
|
||||
});
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
## Activity Feeds
|
||||
|
||||
Show recent activity across your application:
|
||||
|
||||
<CodeGroup>
|
||||
```ts twoslash
|
||||
import { co, z } from 'jazz-tools'
|
||||
import { createJazzTestAccount } from 'jazz-tools/testing'
|
||||
const me = await createJazzTestAccount();
|
||||
|
||||
const Project = co.map({
|
||||
name: z.string(),
|
||||
status: z.literal(["todo", "in-progress", "completed"]),
|
||||
});
|
||||
type Project = co.loaded<typeof Project>;
|
||||
|
||||
const project = Project.create({ name: "New project", status: "todo" }, { owner: me });
|
||||
const myProjects = [project];
|
||||
|
||||
// ---cut---
|
||||
function getRecentActivity(projects: Project[], since: Date) {
|
||||
const activity = [];
|
||||
|
||||
for (const project of projects) {
|
||||
// Get all fields that might have edits
|
||||
const fields = Object.keys(project);
|
||||
|
||||
// Check each field for edit history
|
||||
for (const field of fields) {
|
||||
const editField = field as keyof typeof project._edits;
|
||||
// Skip if no edits exist for this field
|
||||
if (!project._edits[editField]) continue;
|
||||
|
||||
for (const edit of project._edits[editField].all) {
|
||||
// Only include edits made after the 'since' date
|
||||
if (edit.madeAt > since) {
|
||||
activity.push({
|
||||
project: project.name,
|
||||
field,
|
||||
value: edit.value,
|
||||
by: edit.by,
|
||||
at: edit.madeAt
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return activity.sort((a, b) => b.at.getTime() - a.at.getTime());
|
||||
}
|
||||
|
||||
// Show activity from the last hour
|
||||
const hourAgo = new Date(Date.now() - 60 * 60 * 1000);
|
||||
const recentActivity = getRecentActivity(myProjects, hourAgo);
|
||||
// [{
|
||||
// project: "New project",
|
||||
// field: "name",
|
||||
// value: "New project",
|
||||
// by: Account,
|
||||
// at: Date
|
||||
// }]
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
## Change Indicators
|
||||
|
||||
Show when something was last updated:
|
||||
|
||||
<CodeGroup>
|
||||
```ts twoslash
|
||||
import { co, z } from 'jazz-tools'
|
||||
import { createJazzTestAccount } from 'jazz-tools/testing'
|
||||
|
||||
const me = await createJazzTestAccount();
|
||||
|
||||
const Task = co.map({
|
||||
title: z.string(),
|
||||
status: z.literal(["todo", "in-progress", "completed"]),
|
||||
});
|
||||
type Task = co.loaded<typeof Task>;
|
||||
const task = Task.create({ title: "New task", status: "todo" }, { owner: me });
|
||||
|
||||
// ---cut---
|
||||
function getLastUpdated(task: Task) {
|
||||
// Find the most recent edit across all fields
|
||||
let lastEdit: any = null;
|
||||
|
||||
for (const field of Object.keys(task)) {
|
||||
const editField = field as keyof typeof task._edits;
|
||||
// Skip if no edits exist for this field
|
||||
if (!task._edits[editField]) continue;
|
||||
|
||||
const fieldEdit = task._edits[editField];
|
||||
if (fieldEdit && (!lastEdit || fieldEdit.madeAt > lastEdit.madeAt)) {
|
||||
lastEdit = fieldEdit;
|
||||
}
|
||||
}
|
||||
|
||||
if (!lastEdit) return null;
|
||||
|
||||
return {
|
||||
updatedBy: lastEdit.by?.profile?.name,
|
||||
updatedAt: lastEdit.madeAt,
|
||||
message: `Last updated by ${lastEdit.by?.profile?.name} at ${lastEdit.madeAt.toLocaleString()}`
|
||||
};
|
||||
}
|
||||
|
||||
const lastUpdated = getLastUpdated(task);
|
||||
console.log(lastUpdated?.message);
|
||||
// "Last updated by Alice at 22/05/2025, 12:00:00"
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
## Finding Specific Changes
|
||||
|
||||
Query history for specific events:
|
||||
|
||||
<CodeGroup>
|
||||
```ts twoslash
|
||||
import { co, z } from 'jazz-tools'
|
||||
import { createJazzTestAccount } from 'jazz-tools/testing'
|
||||
|
||||
const me = await createJazzTestAccount();
|
||||
|
||||
const Task = co.map({
|
||||
title: z.string(),
|
||||
status: z.literal(["todo", "in-progress", "completed"]),
|
||||
});
|
||||
type Task = co.loaded<typeof Task>;
|
||||
const task = Task.create({ title: "New task", status: "todo" }, { owner: me });
|
||||
|
||||
task.status = "completed";
|
||||
task.status = "in-progress";
|
||||
task.status = "completed";
|
||||
|
||||
// ---cut---
|
||||
// Find when a task was completed
|
||||
function findCompletionTime(task: Task): Date | null {
|
||||
if (!task._edits.status) return null;
|
||||
|
||||
// find() returns the FIRST completion time
|
||||
// If status toggles (completed → in-progress → completed),
|
||||
// this gives you the earliest completion, not the latest
|
||||
const completionEdit = task._edits.status.all.find(
|
||||
edit => edit.value === "completed"
|
||||
);
|
||||
|
||||
return completionEdit?.madeAt || null;
|
||||
}
|
||||
|
||||
// To get the LATEST completion time instead reverse the array, then find:
|
||||
function findLatestCompletionTime(task: Task): Date | null {
|
||||
if (!task._edits.status) return null;
|
||||
|
||||
// Reverse and find (stops at first match)
|
||||
const latestCompletionEdit = task._edits.status.all
|
||||
.slice() // Create copy to avoid mutating original
|
||||
.reverse()
|
||||
.find(edit => edit.value === "completed");
|
||||
|
||||
return latestCompletionEdit?.madeAt || null;
|
||||
}
|
||||
|
||||
console.log(findCompletionTime(task)); // First completion
|
||||
console.log(findLatestCompletionTime(task)); // Most recent completion
|
||||
|
||||
// Find who made a specific change
|
||||
function findWhoChanged(task: Task, field: string, value: any) {
|
||||
const edits = task._edits[field as keyof typeof task._edits];
|
||||
if (!edits) return null;
|
||||
|
||||
const matchingEdit = edits.all.find(edit => edit.value === value);
|
||||
return matchingEdit?.by || null;
|
||||
}
|
||||
const account = findWhoChanged(task, "status", "completed");
|
||||
console.log(account?.profile?.name);
|
||||
// Alice
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
## Further Reading
|
||||
|
||||
- [History](/docs/using-covalues/history) - Complete reference for the history API
|
||||
- [Subscription & Loading](/docs/using-covalues/subscription-and-loading) - Ensure CoValues are loaded before accessing history
|
||||
@@ -213,9 +213,9 @@ export const docNavigationItems = [
|
||||
done: 80,
|
||||
},
|
||||
{
|
||||
name: "History & time travel",
|
||||
name: "History",
|
||||
href: "/docs/using-covalues/history",
|
||||
done: 0,
|
||||
done: 100,
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -296,6 +296,11 @@ export const docNavigationItems = [
|
||||
href: "/docs/design-patterns/organization",
|
||||
done: 80,
|
||||
},
|
||||
{
|
||||
name: "History Patterns",
|
||||
href: "/docs/design-patterns/history-patterns",
|
||||
done: 100,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
||||
@@ -8,8 +8,7 @@ import { ContentByFramework, CodeGroup } from '@/components/forMdx'
|
||||
|
||||
## Public sharing
|
||||
|
||||
You can share CoValues publicly by setting the `owner` to a `Group`, and granting
|
||||
access to "everyone".
|
||||
You can share CoValues publicly by setting the `owner` to a `Group`, and granting access to "everyone".
|
||||
|
||||
<CodeGroup>
|
||||
```ts twoslash
|
||||
@@ -20,6 +19,19 @@ group.addMember("everyone", "writer");
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
You can also use `makePublic(role)` alias to grant access to everyone with a specific role (defaults to `reader`).
|
||||
|
||||
<CodeGroup>
|
||||
```ts twoslash
|
||||
import { Group } from "jazz-tools";
|
||||
// ---cut---
|
||||
const group = Group.create();
|
||||
group.addMember("everyone", "writer"); // [!code --]
|
||||
group.makePublic("writer"); // [!code ++]
|
||||
// group.makePublic(); // Defaults to "reader" access
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
This is done in the [chat example](https://github.com/garden-co/jazz/tree/main/examples/chat) where anyone can join the chat, and send messages.
|
||||
|
||||
You can also [add members by Account ID](/docs/groups/intro#adding-group-members-by-id).
|
||||
|
||||
@@ -209,7 +209,7 @@ export const MyAppAccount = co.account({
|
||||
if (account.profile === undefined) {
|
||||
const profileGroup = Group.create();
|
||||
// Unlike the root, we want the profile to be publicly readable.
|
||||
profileGroup.addMember("everyone", "reader");
|
||||
profileGroup.makePublic();
|
||||
|
||||
account.profile = MyAppProfile.create({
|
||||
name: creationProps?.name ?? "New user",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
export const metadata = {
|
||||
description: "CoValues are the core abstraction of Jazz. They're your bread-and-butter datastructures that you use to represent everything in your app."
|
||||
description: "CoValues are the core abstraction of Jazz. They're your bread-and-butter datastructures that you use to represent everything in your app.",
|
||||
};
|
||||
|
||||
import { CodeGroup, ComingSoon } from "@/components/forMdx";
|
||||
@@ -23,6 +23,7 @@ CoValues model JSON with CoMaps and CoLists, but also offer CoFeeds for simple p
|
||||
Fundamentally, CoValues are as dynamic and flexible as JSON, but in Jazz you use them by defining fixed schemas to describe the shape of data in your app.
|
||||
|
||||
This helps correctness and development speed, but is particularly important...
|
||||
|
||||
- when you evolve your app and need migrations
|
||||
- when different clients and server workers collaborate on CoValues and need to make compatible changes
|
||||
|
||||
@@ -76,6 +77,7 @@ const project = TodoProject.create(
|
||||
Group.create()
|
||||
);
|
||||
```
|
||||
|
||||
</CodeGroup>
|
||||
|
||||
## Types of CoValues
|
||||
@@ -96,6 +98,7 @@ const Task = co.map({
|
||||
completed: z.boolean(),
|
||||
});
|
||||
```
|
||||
|
||||
</CodeGroup>
|
||||
|
||||
Or record-like CoMaps (key-value pairs, where keys are always `string`):
|
||||
@@ -112,6 +115,7 @@ const ColorToHex = co.record(z.string(), z.string());
|
||||
|
||||
const ColorToFruit = co.record(z.string(), Fruit);
|
||||
```
|
||||
|
||||
</CodeGroup>
|
||||
|
||||
|
||||
@@ -137,6 +141,7 @@ const Task = co.map({
|
||||
const ListOfColors = co.list(z.string());
|
||||
const ListOfTasks = co.list(Task);
|
||||
```
|
||||
|
||||
</CodeGroup>
|
||||
|
||||
See the corresponding sections for [creating](/docs/using-covalues/colists#creating-colists),
|
||||
@@ -207,7 +212,7 @@ import { co, z } from "jazz-tools";
|
||||
const ButtonWidget = co.map({
|
||||
type: z.literal("button"),
|
||||
label: z.string(),
|
||||
});
|
||||
});
|
||||
|
||||
const SliderWidget = co.map({
|
||||
type: z.literal("slider"),
|
||||
@@ -215,8 +220,9 @@ const SliderWidget = co.map({
|
||||
max: z.number(),
|
||||
});
|
||||
|
||||
const WidgetUnion = z.discriminatedUnion([ButtonWidget, SliderWidget]);
|
||||
const WidgetUnion = z.discriminatedUnion("type", [ButtonWidget, SliderWidget]);
|
||||
```
|
||||
|
||||
</CodeGroup>
|
||||
|
||||
See the corresponding sections for [creating](/docs/using-covalues/schemaunions#creating-schemaunions),
|
||||
@@ -246,15 +252,15 @@ export const ListOfColors = co.list(z.string());
|
||||
Here's a quick overview of the primitive types you can use:
|
||||
|
||||
<CodeGroup>
|
||||
```ts twoslash
|
||||
import { z } from "jazz-tools";
|
||||
// ---cut---
|
||||
z.string(); // For simple strings
|
||||
z.number(); // For numbers
|
||||
```ts twoslash
|
||||
import {z} from "jazz-tools";
|
||||
// ---cut---
|
||||
z.string(); // For simple strings
|
||||
z.number(); // For numbers
|
||||
z.boolean(); // For booleans
|
||||
z.null(); // For null
|
||||
z.date(); // For dates
|
||||
z.literal(["waiting", "ready"]); // For enums
|
||||
z.null(); // For null
|
||||
z.date(); // For dates
|
||||
z.literal(["waiting", "ready"]); // For enums
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
@@ -311,6 +317,7 @@ const Company = co.map({
|
||||
members: ListOfPeople,
|
||||
});
|
||||
```
|
||||
|
||||
</CodeGroup>
|
||||
|
||||
#### Optional References
|
||||
@@ -363,6 +370,7 @@ const Person = co.map({
|
||||
|
||||
const ListOfPeople = co.list(Person);
|
||||
```
|
||||
|
||||
</CodeGroup>
|
||||
|
||||
Note: similarly, if you use modifiers like `z.optional()` you'll need to help TypeScript along:
|
||||
@@ -378,6 +386,7 @@ const Person = co.map({
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
</CodeGroup>
|
||||
|
||||
### Helper methods
|
||||
@@ -417,3 +426,4 @@ const fullName = getPersonFullName(person);
|
||||
const age = getPersonAgeAsOf(person, new Date());
|
||||
```
|
||||
</CodeGroup>
|
||||
```
|
||||
|
||||
@@ -306,6 +306,88 @@ project.coordinator = undefined; // Remove the reference
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
## Running migrations on CoMaps
|
||||
|
||||
Migrations are functions that run when a CoMap is loaded, allowing you to update existing data to match new schema versions. Use them when you need to modify the structure of CoMaps that already exist in your app. Unlike [Account migrations](/docs/schemas/accounts-and-migrations#when-migrations-run), CoMap migrations are not run when a CoMap is created.
|
||||
|
||||
**Note:** Migrations are run synchronously and cannot be run asynchronously.
|
||||
|
||||
Here's an example of a migration that adds the `priority` field to the `Task` CoMap:
|
||||
|
||||
<CodeGroup>
|
||||
```ts twoslash
|
||||
import { co, z } from "jazz-tools";
|
||||
|
||||
// ---cut---
|
||||
const Task = co
|
||||
.map({
|
||||
done: z.boolean(),
|
||||
text: co.plainText(),
|
||||
version: z.literal([1, 2]),
|
||||
priority: z.enum(["low", "medium", "high"]), // new field
|
||||
})
|
||||
.withMigration((task) => {
|
||||
if (task.version === 1) {
|
||||
task.priority = "medium";
|
||||
// Upgrade the version so the migration won't run again
|
||||
task.version = 2;
|
||||
}
|
||||
});
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
### Migration best practices
|
||||
|
||||
Design your schema changes to be compatible with existing data:
|
||||
- **Add, don't change:** Only add new fields; avoid renaming or changing types of existing fields
|
||||
- **Make new fields optional:** This prevents errors when loading older data
|
||||
- **Use version fields:** Track schema versions to run migrations only when needed
|
||||
|
||||
### Migration & reader permissions
|
||||
|
||||
Migrations need write access to modify CoMaps. If some users only have read permissions, they can't run migrations on those CoMaps.
|
||||
|
||||
**Forward-compatible schemas** (where new fields are optional) handle this gracefully - users can still use the app even if migrations haven't run.
|
||||
|
||||
**Non-compatible changes** require handling both schema versions in your app code using discriminated unions.
|
||||
|
||||
When you can't guarantee all users can run migrations, handle multiple schema versions explicitly:
|
||||
|
||||
<CodeGroup>
|
||||
```ts twoslash
|
||||
import { co, z } from "jazz-tools";
|
||||
|
||||
// ---cut---
|
||||
const TaskV1 = co.map({
|
||||
version: z.literal(1),
|
||||
done: z.boolean(),
|
||||
text: z.string(),
|
||||
});
|
||||
|
||||
const TaskV2 = co.map({
|
||||
// We need to be more strict about the version to make the
|
||||
// discriminated union work
|
||||
version: z.literal(2),
|
||||
done: z.boolean(),
|
||||
text: z.string(),
|
||||
priority: z.enum(["low", "medium", "high"]),
|
||||
}).withMigration((task) => {
|
||||
// @ts-expect-error - check if we need to run the migration
|
||||
if (task.version === 1) {
|
||||
task.version = 2;
|
||||
task.priority = "medium";
|
||||
}
|
||||
});
|
||||
|
||||
// Export the discriminated union; because some users might
|
||||
// not be able to run the migration
|
||||
export const Task = z.discriminatedUnion("version", [
|
||||
TaskV1,
|
||||
TaskV2,
|
||||
]);
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
## Best Practices
|
||||
|
||||
### Structuring Data
|
||||
|
||||
@@ -1,267 +0,0 @@
|
||||
import { CodeGroup } from "@/components/forMdx";
|
||||
|
||||
# History & time-travel
|
||||
|
||||
One of Jazz's most powerful features is that every CoValue automatically tracks its complete edit history. This means you can see who changed what and when, examine the state of your data at any point in time, and build features like audit logs, activity feeds, and undo/redo functionality. This page explores how to access and work with the rich metadata that comes with every CoValue.
|
||||
|
||||
## Understanding Edit History
|
||||
|
||||
Every CoValue in Jazz maintains a full history of all changes made to it. This edit history is accessible through two main APIs:
|
||||
|
||||
`CoValue._edits` provides a structured, field-by-field view of a CoValue's edit history. It organizes edits by property name and makes them easily accessible. For each field:
|
||||
- `_edits.fieldName` gives you the most recent edit
|
||||
- `_edits.fieldName.all` provides all historical edits as an array
|
||||
- `_edits.fieldName.madeAt` gives you the timestamp of the last edit
|
||||
- Each edit contains the value, who made the change, and when it happened
|
||||
|
||||
`CoValue._raw` gives you access to the internal state and lower-level operations on a CoValue. As this is an internal API, it should be used with caution. If you find yourself using `_raw`, consider letting us know so we can consider adding a public API for your use case.
|
||||
|
||||
## Working with Edit History Metadata
|
||||
|
||||
CoValues track who made each change and when. Every edit has metadata attached to it, including the author, timestamp, value, and transaction ID. This metadata enables you to build powerful audit and history features without having to implement your own tracking system.
|
||||
|
||||
<CodeGroup>
|
||||
```ts
|
||||
class Task extends CoMap {
|
||||
title = coField.string;
|
||||
description = coField.string;
|
||||
status = coField.literal("todo", "in-progress", "completed");
|
||||
priority = coField.literal("low", "medium", "high");
|
||||
subtasks = coField.optional.ref(ListOfTasks);
|
||||
}
|
||||
|
||||
class ListOfTasks extends CoList.Of(coField.ref(Task)) {}
|
||||
|
||||
const task = Task.create({
|
||||
title: "Plant spring vegetables",
|
||||
description: "Plant peas, carrots, and lettuce in the south garden bed",
|
||||
status: "todo",
|
||||
priority: "medium",
|
||||
});
|
||||
|
||||
// Change the status
|
||||
task.status = "in-progress";
|
||||
|
||||
// Get the latest edit for a field
|
||||
console.log("Latest edit:", task._edits.status);
|
||||
// { value: "in-progress", by: Account, madeAt: Date, ... }
|
||||
|
||||
// Get when a field was last edited (timestamp)
|
||||
const lastEditTime = task._edits.status.madeAt;
|
||||
console.log(`Status was last changed at: ${lastEditTime?.toLocaleString()}`);
|
||||
|
||||
// Get the full edit history for a field
|
||||
for (const edit of task._edits.status.all) {
|
||||
console.log({
|
||||
author: edit.by, // Account that made the change
|
||||
timestamp: edit.madeAt, // When the change happened
|
||||
value: edit.value, // Value of the change
|
||||
});
|
||||
}
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
### Common Patterns
|
||||
|
||||
With knowledge of the edit history, you can build all sorts of useful features that enhance your application's user experience and administrative capabilities. Here are some common patterns that leverage CoValue metadata.
|
||||
|
||||
#### Audit Log
|
||||
|
||||
Getting all the changes to a CoValue in order allows you to build an audit log. This is especially useful for tracking important changes in collaborative environments or for compliance purposes:
|
||||
|
||||
<CodeGroup>
|
||||
```ts
|
||||
|
||||
function getAuditLog(task: Task) {
|
||||
const changes = [];
|
||||
|
||||
for (const field of Object.keys(task)) {
|
||||
// Check if the field has edits to avoid accessing non-existent properties
|
||||
if (task._edits[field as keyof typeof task._edits]) {
|
||||
for (const edit of task._edits[field as keyof typeof task._edits].all) {
|
||||
changes.push({
|
||||
field,
|
||||
...edit,
|
||||
timestamp: edit.madeAt,
|
||||
at: edit.madeAt,
|
||||
by: edit.by,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sort by timestamp
|
||||
return changes.sort((a, b) => b.at.getTime() - a.at.getTime());
|
||||
}
|
||||
|
||||
// Example usage
|
||||
const auditLog = getAuditLog(task);
|
||||
auditLog.forEach((entry) => {
|
||||
console.log(
|
||||
`${entry.timestamp} - ${entry.field} changed to "${entry.value}" by ${entry.by?.id}`,
|
||||
);
|
||||
});
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
#### Activity Feeds
|
||||
|
||||
Activity feeds are a great way to see recent changes to a CoValue, helping users understand what's happening in a collaborative workspace. They can show who did what and when, creating transparency in team environments:
|
||||
|
||||
<CodeGroup>
|
||||
```ts
|
||||
function getRecentActivity(project: Project) {
|
||||
const activity = [];
|
||||
const hourAgo = new Date(Date.now() - 3600000);
|
||||
|
||||
for (const field of Object.keys(project)) {
|
||||
// Skip if the field doesn't have edits
|
||||
if (!project._edits[field as keyof typeof project._edits]) continue;
|
||||
|
||||
for (const edit of project._edits[field as keyof typeof project._edits].all) {
|
||||
if (edit.madeAt > hourAgo) {
|
||||
activity.push({
|
||||
field,
|
||||
value: edit.value,
|
||||
by: edit.by,
|
||||
at: edit.madeAt
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return activity.sort((a, b) => b.at.getTime() - a.at.getTime());
|
||||
}
|
||||
|
||||
// Example usage
|
||||
const recentActivity = getRecentActivity(gardenProject);
|
||||
console.log("Recent Garden Activity:");
|
||||
recentActivity.forEach(activity => {
|
||||
console.log(`${activity.at.toLocaleString()} - ${activity.field} updated by ${activity.by?.id}`);
|
||||
});
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
## Edit History & Time Travel
|
||||
|
||||
CoValues track their entire history of changes, creating a timeline you can explore. You can see who changed what and when, or even view past states of the data. This capability enables powerful debugging tools and user-facing features like history browsing and restoration of previous versions:
|
||||
|
||||
<CodeGroup>
|
||||
```ts
|
||||
class Task extends CoMap {
|
||||
title = coField.string;
|
||||
description = coField.string;
|
||||
status = coField.literal("todo", "in-progress", "completed");
|
||||
priority = coField.literal("low", "medium", "high");
|
||||
}
|
||||
|
||||
// Create a new task
|
||||
const task = Task.create({
|
||||
title: "Plant spring vegetables",
|
||||
description: "Plant peas, carrots, and lettuce in the south garden bed",
|
||||
status: "todo",
|
||||
priority: "medium",
|
||||
});
|
||||
|
||||
// Make some changes
|
||||
task.status = "in-progress";
|
||||
task.priority = "high";
|
||||
|
||||
// See all edits for a field
|
||||
for (const edit of task._edits.status.all) {
|
||||
console.log(
|
||||
`${edit.madeAt.toISOString()}: Status changed to "${edit.value}" by ${edit.by?.id}`,
|
||||
);
|
||||
}
|
||||
|
||||
// Get the initial value
|
||||
const initialStatus = task._edits.status.all[0]?.value;
|
||||
console.log(`Original status: ${initialStatus}`);
|
||||
|
||||
// Get a specific edit by index
|
||||
const previousEdit = task._edits.status.all[1]; // Second edit
|
||||
console.log(`Previous status: ${previousEdit?.value}`);
|
||||
|
||||
// Check who made the most recent change
|
||||
const latestEdit = task._edits.status;
|
||||
console.log(`Latest change made by: ${latestEdit?.by?.id}`);
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
## Time Travel
|
||||
|
||||
The ability to view a CoValue as it existed at any point in time is one of Jazz's most powerful features. Looking into the past can help you understand how things changed - perfect for audit logs, debugging, or showing user activity. You can reconstruct the exact state of any CoValue at any moment in its history:
|
||||
|
||||
<CodeGroup>
|
||||
```ts
|
||||
class Project extends CoMap {
|
||||
name = coField.string;
|
||||
status = coField.literal("planning", "active", "completed");
|
||||
lastUpdate = coField.Date;
|
||||
}
|
||||
|
||||
// See when a project was started
|
||||
function findStatusChange(project: Project, targetStatus: string) {
|
||||
// Get all the edits for the status field
|
||||
const statusEdits = project._edits.status.all;
|
||||
|
||||
for (const edit of statusEdits) {
|
||||
if (edit.value === targetStatus) {
|
||||
console.log({
|
||||
changeTime: edit.madeAt,
|
||||
lastUpdate: project.lastUpdate,
|
||||
changedBy: edit.by,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Example usage
|
||||
findStatusChange(gardenProject, "active");
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
### Common Use Cases
|
||||
|
||||
The time travel capabilities of CoValues enable several practical use cases that would otherwise require complex custom implementations. Here are some examples of how you can use time travel in your applications:
|
||||
|
||||
<CodeGroup>
|
||||
```ts
|
||||
// Track task progress over time
|
||||
function getTaskStatusHistory(task: Task, days: number = 7) {
|
||||
const statusHistory = [];
|
||||
const dayInMs = 86400000;
|
||||
|
||||
// Check every day for the past week
|
||||
for (let day = 0; day < days; day++) {
|
||||
const timePoint = new Date(Date.now() - day * dayInMs);
|
||||
// Using the internal _raw API to get state at a specific point in time
|
||||
const state = task._raw.atTime(timePoint);
|
||||
statusHistory.push({
|
||||
date: timePoint.toLocaleDateString(),
|
||||
status: state.status,
|
||||
priority: state.priority
|
||||
});
|
||||
}
|
||||
|
||||
return statusHistory;
|
||||
}
|
||||
|
||||
// Example usage
|
||||
const history = getTaskStatusHistory(plantingTask);
|
||||
history.forEach(entry => {
|
||||
console.log(`${entry.date}: Status was "${entry.status}" with ${entry.priority} priority`);
|
||||
});
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
### Best Practices
|
||||
|
||||
- Check field existence before accessing edits (`if (task._edits.fieldName)`)
|
||||
- Access the most recent edit directly with `_edits.fieldName` instead of using any `.latest` property
|
||||
- Cache historical queries if you're displaying them in UI
|
||||
- Be specific about time ranges you care about
|
||||
- Remember that accessing history requires loading the CoValue
|
||||
- Consider using timestamps from your data rather than scanning all edits
|
||||
|
||||
Time travel is great for understanding how you got here, but keep queries focused on the range of time that matters to your use case.
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user