Compare commits
25 Commits
refactor/p
...
perf/coMap
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
22f6db8141 | ||
|
|
3d9f12e9ea | ||
|
|
68620a3df9 | ||
|
|
1767f024d9 | ||
|
|
c55924a04a | ||
|
|
31e00a96ae | ||
|
|
7bb834f399 | ||
|
|
667f36e1cf | ||
|
|
07669923ad | ||
|
|
9082a099ee | ||
|
|
aba059db28 | ||
|
|
ae6b9c8dd2 | ||
|
|
7b9f96bf1a | ||
|
|
8df49546fe | ||
|
|
bb4460f422 | ||
|
|
2099099afc | ||
|
|
06b0758d7c | ||
|
|
6135250e57 | ||
|
|
aacd03bbdd | ||
|
|
ca7f250d47 | ||
|
|
83ad506b94 | ||
|
|
e9751f5b69 | ||
|
|
c84764acd5 | ||
|
|
c2a805bffa | ||
|
|
8728dde42b |
@@ -1,6 +0,0 @@
|
||||
---
|
||||
"cojson": patch
|
||||
"jazz-tools": patch
|
||||
---
|
||||
|
||||
Optimise large record-like CoMaps for access of latest value
|
||||
5
.changeset/late-suits-hug.md
Normal file
5
.changeset/late-suits-hug.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"cojson": patch
|
||||
---
|
||||
|
||||
Optimize the atTime processing on CoMap
|
||||
@@ -1,7 +0,0 @@
|
||||
---
|
||||
"cojson-storage-indexeddb": patch
|
||||
"cojson-storage-sqlite": patch
|
||||
"cojson-storage": patch
|
||||
---
|
||||
|
||||
Refactor the SQLite and IndexedDB storage packages to extract common synchronization functionality into newly created cojson-storage package.
|
||||
@@ -1,5 +1,14 @@
|
||||
# jazz-example-book-shelf
|
||||
|
||||
## 0.1.28
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [441fe27]
|
||||
- jazz-tools@0.8.36
|
||||
- jazz-react@0.8.36
|
||||
- jazz-browser-media-images@0.8.36
|
||||
|
||||
## 0.1.27
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "jazz-example-book-shelf",
|
||||
"version": "0.1.27",
|
||||
"version": "0.1.28",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
@@ -11,9 +11,9 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"clsx": "^2.0.0",
|
||||
"jazz-browser-media-images": "workspace:0.8.35",
|
||||
"jazz-react": "workspace:0.8.35",
|
||||
"jazz-tools": "workspace:0.8.35",
|
||||
"jazz-browser-media-images": "workspace:0.8.36",
|
||||
"jazz-react": "workspace:0.8.36",
|
||||
"jazz-tools": "workspace:0.8.36",
|
||||
"next": "14.2.5",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0"
|
||||
|
||||
@@ -1 +1 @@
|
||||
EXPO_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_ZXZpZGVudC1kYW5lLTg5LmNsZXJrLmFjY291bnRzLmRldiQ
|
||||
EXPO_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_ZXZpZGVudC1kYW5lLTg5LmNsZXJrLmFjY291bnRzLmRldiQ
|
||||
|
||||
@@ -1,5 +1,17 @@
|
||||
# chat-rn-clerk
|
||||
|
||||
## 1.0.28
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- c84764a: feat: added jazz-react-native-auth-clerk package
|
||||
- Updated dependencies [c84764a]
|
||||
- Updated dependencies [441fe27]
|
||||
- jazz-react-native-auth-clerk@0.8.36
|
||||
- jazz-react-native@0.8.36
|
||||
- jazz-tools@0.8.36
|
||||
- jazz-react-native-media-images@0.8.27
|
||||
|
||||
## 1.0.27
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -35,7 +35,9 @@
|
||||
}
|
||||
}
|
||||
],
|
||||
"expo-secure-store"
|
||||
"expo-secure-store",
|
||||
"expo-font",
|
||||
"expo-router"
|
||||
],
|
||||
"extra": {
|
||||
"eas": {
|
||||
|
||||
@@ -4,7 +4,7 @@ import { Platform } from "react-native";
|
||||
export interface TokenCache {
|
||||
getToken: (key: string) => Promise<string | undefined | null>;
|
||||
saveToken: (key: string, token: string) => Promise<void>;
|
||||
clearToken?: (key: string) => void;
|
||||
clearToken: (key: string) => void;
|
||||
}
|
||||
|
||||
const createTokenCache = (): TokenCache => {
|
||||
@@ -27,6 +27,9 @@ const createTokenCache = (): TokenCache => {
|
||||
saveToken: (key: string, token: string) => {
|
||||
return SecureStore.setItemAsync(key, token);
|
||||
},
|
||||
clearToken: (key: string) => {
|
||||
return SecureStore.deleteItemAsync(key);
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -19,7 +19,10 @@ config.resolver.nodeModulesPaths = [
|
||||
];
|
||||
config.resolver.sourceExts = ["mjs", "js", "json", "ts", "tsx"];
|
||||
config.resolver.unstable_enablePackageExports = true;
|
||||
config.resolver.requireCycleIgnorePatterns = [/(^|\/|\\)node_modules($|\/|\\)/];
|
||||
config.resolver.requireCycleIgnorePatterns = [
|
||||
/(^|\/|\\)node_modules($|\/|\\)/,
|
||||
/(^|\/|\\)packages($|\/|\\)/,
|
||||
];
|
||||
|
||||
// Use turborepo to restore the cache when possible
|
||||
config.cacheStores = [
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "chat-rn-clerk",
|
||||
"main": "index.js",
|
||||
"version": "1.0.27",
|
||||
"version": "1.0.28",
|
||||
"scripts": {
|
||||
"build": "expo export -p ios",
|
||||
"start": "expo start",
|
||||
@@ -17,59 +17,58 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@azure/core-asynciterator-polyfill": "^1.0.2",
|
||||
"@bam.tech/react-native-image-resizer": "^3.0.10",
|
||||
"@bam.tech/react-native-image-resizer": "^3.0.11",
|
||||
"@clerk/clerk-expo": "^2.2.21",
|
||||
"@expo/vector-icons": "^14.0.2",
|
||||
"@react-native-community/netinfo": "^11.3.1",
|
||||
"@react-navigation/native": "^6.1.18",
|
||||
"@react-navigation/native-stack": "^6.11.0",
|
||||
"@react-native-community/netinfo": "^11.4.1",
|
||||
"@react-navigation/native": "^7.0.13",
|
||||
"@react-navigation/native-stack": "^7.1.14",
|
||||
"base-64": "^1.0.0",
|
||||
"buffer": "^6.0.3",
|
||||
"clsx": "^2.0.0",
|
||||
"expo": "~51.0.37",
|
||||
"expo-build-properties": "~0.12.5",
|
||||
"expo-clipboard": "~6.0.3",
|
||||
"expo-constants": "~16.0.2",
|
||||
"expo-crypto": "~13.0.2",
|
||||
"expo-dev-client": "~4.0.28",
|
||||
"expo-file-system": "^17.0.1",
|
||||
"expo-font": "~12.0.4",
|
||||
"expo-linking": "~6.3.1",
|
||||
"expo-router": "~3.5.23",
|
||||
"expo-secure-store": "~13.0.2",
|
||||
"expo-splash-screen": "~0.27.5",
|
||||
"expo-status-bar": "~1.12.1",
|
||||
"expo-system-ui": "~3.0.7",
|
||||
"expo-web-browser": "~13.0.3",
|
||||
"jazz-react-auth-clerk": "workspace:*",
|
||||
"expo": "^52.0.0",
|
||||
"expo-build-properties": "~0.13.1",
|
||||
"expo-clipboard": "~7.0.0",
|
||||
"expo-constants": "~17.0.3",
|
||||
"expo-crypto": "~14.0.1",
|
||||
"expo-dev-client": "~5.0.5",
|
||||
"expo-file-system": "^18.0.4",
|
||||
"expo-font": "~13.0.1",
|
||||
"expo-linking": "~7.0.3",
|
||||
"expo-router": "~4.0.11",
|
||||
"expo-secure-store": "~14.0.0",
|
||||
"expo-splash-screen": "~0.29.16",
|
||||
"expo-status-bar": "~2.0.0",
|
||||
"expo-system-ui": "~4.0.5",
|
||||
"expo-web-browser": "~14.0.1",
|
||||
"jazz-react-native": "workspace:*",
|
||||
"jazz-react-native-auth-clerk": "workspace:*",
|
||||
"jazz-react-native-media-images": "workspace:*",
|
||||
"jazz-tools": "workspace:*",
|
||||
"nativewind": "^2.0.11",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-native": "~0.74.5",
|
||||
"react-native": "~0.76.3",
|
||||
"react-native-fetch-api": "^3.0.0",
|
||||
"react-native-gesture-handler": "~2.16.1",
|
||||
"react-native-gesture-handler": "~2.20.2",
|
||||
"react-native-get-random-values": "^1.11.0",
|
||||
"react-native-mmkv": "3.0.1",
|
||||
"react-native-polyfill-globals": "^3.1.0",
|
||||
"react-native-quick-base64": "^2.1.2",
|
||||
"react-native-reanimated": "~3.10.1",
|
||||
"react-native-safe-area-context": "4.10.5",
|
||||
"react-native-screens": "3.31.1",
|
||||
"react-native-reanimated": "~3.16.3",
|
||||
"react-native-safe-area-context": "4.12.0",
|
||||
"react-native-screens": "4.1.0",
|
||||
"react-native-url-polyfill": "^2.0.0",
|
||||
"react-native-web": "~0.19.10",
|
||||
"react-native-web": "~0.19.13",
|
||||
"text-encoding": "^0.7.0",
|
||||
"web-streams-polyfill": "^3.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.20.0",
|
||||
"@types/jest": "^29.5.3",
|
||||
"@types/react": "^18.2.19",
|
||||
"@types/react": "^18.3.12",
|
||||
"@types/react-test-renderer": "^18.0.7",
|
||||
"jest": "^29.2.1",
|
||||
"jest-expo": "~51.0.3",
|
||||
"jest-expo": "~52.0.2",
|
||||
"react-test-renderer": "18.2.0",
|
||||
"tailwindcss": "3.3.2",
|
||||
"typescript": "^5.3.3"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useClerk, useUser } from "@clerk/clerk-expo";
|
||||
import { useJazzClerkAuth } from "jazz-react-auth-clerk";
|
||||
import { useJazzClerkAuth } from "jazz-react-native-auth-clerk";
|
||||
import React, {
|
||||
createContext,
|
||||
PropsWithChildren,
|
||||
@@ -8,7 +8,7 @@ import React, {
|
||||
useState,
|
||||
} from "react";
|
||||
import { Text, View } from "react-native";
|
||||
import { Jazz } from "./jazz";
|
||||
import { Jazz, kvStore } from "./jazz";
|
||||
|
||||
const AuthContext = createContext<{
|
||||
isAuthenticated: boolean;
|
||||
@@ -25,7 +25,7 @@ export function useAuth() {
|
||||
export function JazzAndAuth({ children }: PropsWithChildren) {
|
||||
const { isSignedIn, isLoaded: isClerkLoaded } = useUser();
|
||||
const clerk = useClerk();
|
||||
const [auth, state] = useJazzClerkAuth(clerk);
|
||||
const [auth, state] = useJazzClerkAuth(clerk, kvStore);
|
||||
const [isAuthenticated, setIsAuthenticated] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -46,7 +46,7 @@ export function JazzAndAuth({ children }: PropsWithChildren) {
|
||||
<Text style={{ color: "red" }}>{error}</Text>
|
||||
</View>
|
||||
))}
|
||||
{auth ? (
|
||||
{auth && clerk.user ? (
|
||||
<Jazz.Provider
|
||||
auth={auth}
|
||||
peer="wss://cloud.jazz.tools/?key=chat-rn-clerk-example-jazz@garden.co"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { createJazzRNApp } from "jazz-react-native";
|
||||
|
||||
export const Jazz = createJazzRNApp();
|
||||
export const { useAccount, useCoState, useAcceptInvite } = Jazz;
|
||||
export const { useAccount, useCoState, useAcceptInvite, kvStore } = Jazz;
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
# chat-rn
|
||||
|
||||
## 1.0.26
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [c84764a]
|
||||
- Updated dependencies [441fe27]
|
||||
- jazz-react-native@0.8.36
|
||||
- jazz-tools@0.8.36
|
||||
|
||||
## 1.0.25
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "chat-rn",
|
||||
"version": "1.0.25",
|
||||
"version": "1.0.26",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"build": "expo export -p ios",
|
||||
@@ -13,39 +13,38 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@azure/core-asynciterator-polyfill": "^1.0.2",
|
||||
"@react-native-community/netinfo": "^11.3.1",
|
||||
"@react-native-community/netinfo": "^11.4.1",
|
||||
"@react-navigation/native": "^6.1.18",
|
||||
"@react-navigation/native-stack": "^6.11.0",
|
||||
"base-64": "^1.0.0",
|
||||
"clsx": "^2.0.0",
|
||||
"expo": "~51.0.37",
|
||||
"expo-build-properties": "~0.12.5",
|
||||
"expo-clipboard": "~6.0.3",
|
||||
"expo-constants": "~16.0.2",
|
||||
"expo-crypto": "~13.0.2",
|
||||
"expo-dev-client": "~4.0.28",
|
||||
"expo-linking": "~6.3.1",
|
||||
"expo-secure-store": "~13.0.2",
|
||||
"expo-status-bar": "~1.12.1",
|
||||
"expo-web-browser": "~13.0.3",
|
||||
"expo": "^52.0.0",
|
||||
"expo-build-properties": "~0.13.1",
|
||||
"expo-clipboard": "~7.0.0",
|
||||
"expo-constants": "~17.0.3",
|
||||
"expo-crypto": "~14.0.1",
|
||||
"expo-dev-client": "~5.0.5",
|
||||
"expo-linking": "~7.0.3",
|
||||
"expo-secure-store": "~14.0.0",
|
||||
"expo-status-bar": "~2.0.0",
|
||||
"expo-web-browser": "~14.0.1",
|
||||
"jazz-react-native": "workspace:*",
|
||||
"jazz-tools": "workspace:*",
|
||||
"nativewind": "^2.0.11",
|
||||
"react": "^18.2.0",
|
||||
"react-native": "~0.74.5",
|
||||
"react": "18.2.0",
|
||||
"react-native": "~0.76.3",
|
||||
"react-native-fetch-api": "^3.0.0",
|
||||
"react-native-get-random-values": "^1.11.0",
|
||||
"react-native-mmkv": "3.0.1",
|
||||
"react-native-polyfill-globals": "^3.1.0",
|
||||
"react-native-safe-area-context": "4.10.5",
|
||||
"react-native-screens": "3.31.1",
|
||||
"react-native-safe-area-context": "4.12.0",
|
||||
"react-native-screens": "4.1.0",
|
||||
"react-native-url-polyfill": "^2.0.0",
|
||||
"text-encoding": "^0.7.0",
|
||||
"web-streams-polyfill": "^3.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.20.0",
|
||||
"@types/react": "^18.2.19",
|
||||
"@types/react": "^18.3.12",
|
||||
"tailwindcss": "3.3.2",
|
||||
"typescript": "^5.3.3"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
# chat-vue
|
||||
|
||||
## 0.0.19
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [441fe27]
|
||||
- jazz-tools@0.8.36
|
||||
- jazz-browser@0.8.36
|
||||
- jazz-vue@0.8.24
|
||||
|
||||
## 0.0.18
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "chat-vue",
|
||||
"version": "0.0.18",
|
||||
"version": "0.0.19",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
# jazz-example-chat
|
||||
|
||||
## 0.0.114
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [441fe27]
|
||||
- cojson@0.8.36
|
||||
- jazz-tools@0.8.36
|
||||
- jazz-react@0.8.36
|
||||
|
||||
## 0.0.113
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "jazz-example-chat",
|
||||
"private": true,
|
||||
"version": "0.0.113",
|
||||
"version": "0.0.114",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
@@ -18,10 +18,10 @@
|
||||
"@radix-ui/react-toast": "^1.1.4",
|
||||
"class-variance-authority": "^0.7.0",
|
||||
"clsx": "^2.0.0",
|
||||
"cojson": "workspace:0.8.35",
|
||||
"cojson": "workspace:0.8.36",
|
||||
"hash-slash": "workspace:0.2.1",
|
||||
"jazz-react": "workspace:0.8.35",
|
||||
"jazz-tools": "workspace:0.8.35",
|
||||
"jazz-react": "workspace:0.8.36",
|
||||
"jazz-tools": "workspace:0.8.36",
|
||||
"lucide-react": "^0.274.0",
|
||||
"qrcode": "^1.5.3",
|
||||
"react": "^18.2.0",
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
# minimal-auth-clerk
|
||||
|
||||
## 0.0.13
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [441fe27]
|
||||
- jazz-tools@0.8.36
|
||||
- jazz-react@0.8.36
|
||||
- jazz-react-auth-clerk@0.8.36
|
||||
|
||||
## 0.0.12
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "clerk",
|
||||
"private": true,
|
||||
"version": "0.0.12",
|
||||
"version": "0.0.13",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
@@ -14,7 +14,7 @@
|
||||
"@clerk/clerk-react": "^5.4.1",
|
||||
"jazz-tools": "workspace:*",
|
||||
"jazz-react": "workspace:*",
|
||||
"jazz-react-auth-clerk": "workspace:0.8.35",
|
||||
"jazz-react-auth-clerk": "workspace:0.8.36",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
# image-upload
|
||||
|
||||
## 0.0.11
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [441fe27]
|
||||
- jazz-tools@0.8.36
|
||||
- jazz-react@0.8.36
|
||||
- jazz-browser-media-images@0.8.36
|
||||
|
||||
## 0.0.10
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "image-upload",
|
||||
"private": true,
|
||||
"version": "0.0.10",
|
||||
"version": "0.0.11",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
# jazz-example-inspector
|
||||
|
||||
## 0.0.83
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [441fe27]
|
||||
- cojson@0.8.36
|
||||
- cojson-transport-ws@0.8.36
|
||||
|
||||
## 0.0.82
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "jazz-inspector",
|
||||
"private": true,
|
||||
"version": "0.0.82",
|
||||
"version": "0.0.83",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
@@ -16,8 +16,8 @@
|
||||
"@radix-ui/react-toast": "^1.1.4",
|
||||
"class-variance-authority": "^0.7.0",
|
||||
"clsx": "^2.0.0",
|
||||
"cojson": "workspace:0.8.35",
|
||||
"cojson-transport-ws": "workspace:0.8.35",
|
||||
"cojson": "workspace:0.8.36",
|
||||
"cojson-transport-ws": "workspace:0.8.36",
|
||||
"hash-slash": "workspace:0.2.1",
|
||||
"lucide-react": "^0.274.0",
|
||||
"qrcode": "^1.5.3",
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
# jazz-example-musicplayer
|
||||
|
||||
## 0.0.34
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [441fe27]
|
||||
- jazz-tools@0.8.36
|
||||
- jazz-react@0.8.36
|
||||
|
||||
## 0.0.33
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "jazz-example-music-player",
|
||||
"private": true,
|
||||
"version": "0.0.33",
|
||||
"version": "0.0.34",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
@@ -18,8 +18,8 @@
|
||||
"@radix-ui/react-toast": "^1.1.4",
|
||||
"class-variance-authority": "^0.7.0",
|
||||
"clsx": "^2.0.0",
|
||||
"jazz-react": "workspace:0.8.35",
|
||||
"jazz-tools": "workspace:0.8.35",
|
||||
"jazz-react": "workspace:0.8.36",
|
||||
"jazz-tools": "workspace:0.8.36",
|
||||
"lucide-react": "^0.274.0",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
# jazz-example-onboarding
|
||||
|
||||
## 0.0.15
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [441fe27]
|
||||
- jazz-tools@0.8.36
|
||||
- jazz-react@0.8.36
|
||||
- jazz-browser-media-images@0.8.36
|
||||
|
||||
## 0.0.14
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "jazz-example-onboarding",
|
||||
"private": true,
|
||||
"version": "0.0.14",
|
||||
"version": "0.0.15",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# passkey-svelte
|
||||
|
||||
## 0.0.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-svelte@0.0.3
|
||||
|
||||
## 0.0.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "passkey-svelte",
|
||||
"version": "0.0.2",
|
||||
"version": "0.0.3",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite dev",
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
# minimal-auth-passkey
|
||||
|
||||
## 0.0.12
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [441fe27]
|
||||
- jazz-tools@0.8.36
|
||||
- jazz-react@0.8.36
|
||||
|
||||
## 0.0.11
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "passkey",
|
||||
"private": true,
|
||||
"version": "0.0.11",
|
||||
"version": "0.0.12",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
# jazz-password-manager
|
||||
|
||||
## 0.0.33
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [441fe27]
|
||||
- jazz-tools@0.8.36
|
||||
- jazz-react@0.8.36
|
||||
|
||||
## 0.0.32
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "jazz-password-manager",
|
||||
"private": true,
|
||||
"version": "0.0.32",
|
||||
"version": "0.0.33",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
@@ -12,8 +12,8 @@
|
||||
"clean-install": "rm -rf node_modules pnpm-lock.yaml && pnpm install"
|
||||
},
|
||||
"dependencies": {
|
||||
"jazz-react": "workspace:0.8.35",
|
||||
"jazz-tools": "workspace:0.8.35",
|
||||
"jazz-react": "workspace:0.8.36",
|
||||
"jazz-tools": "workspace:0.8.36",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-hook-form": "^7.41.5",
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
# jazz-example-pets
|
||||
|
||||
## 0.0.131
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [441fe27]
|
||||
- jazz-tools@0.8.36
|
||||
- jazz-react@0.8.36
|
||||
- jazz-browser-media-images@0.8.36
|
||||
|
||||
## 0.0.130
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "jazz-example-pets",
|
||||
"private": true,
|
||||
"version": "0.0.130",
|
||||
"version": "0.0.131",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
@@ -19,9 +19,9 @@
|
||||
"@radix-ui/react-toast": "^1.1.4",
|
||||
"class-variance-authority": "^0.7.0",
|
||||
"clsx": "^2.0.0",
|
||||
"jazz-browser-media-images": "workspace:0.8.35",
|
||||
"jazz-react": "workspace:0.8.35",
|
||||
"jazz-tools": "workspace:0.8.35",
|
||||
"jazz-browser-media-images": "workspace:0.8.36",
|
||||
"jazz-react": "workspace:0.8.36",
|
||||
"jazz-tools": "workspace:0.8.36",
|
||||
"lucide-react": "^0.274.0",
|
||||
"qrcode": "^1.5.3",
|
||||
"react": "^18.2.0",
|
||||
@@ -41,7 +41,7 @@
|
||||
"@vitejs/plugin-react-swc": "^3.3.2",
|
||||
"autoprefixer": "^10.4.14",
|
||||
"is-ci": "^3.0.1",
|
||||
"jazz-run": "workspace:0.8.35",
|
||||
"jazz-run": "workspace:0.8.36",
|
||||
"postcss": "^8.4.27",
|
||||
"tailwindcss": "3.3.2",
|
||||
"typescript": "^5.3.3",
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
# reactions
|
||||
|
||||
## 0.0.11
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [441fe27]
|
||||
- jazz-tools@0.8.36
|
||||
- jazz-react@0.8.36
|
||||
- jazz-browser-media-images@0.8.36
|
||||
|
||||
## 0.0.10
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "reactions",
|
||||
"private": true,
|
||||
"version": "0.0.10",
|
||||
"version": "0.0.11",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
# todo-vue
|
||||
|
||||
## 0.0.17
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [441fe27]
|
||||
- jazz-tools@0.8.36
|
||||
- jazz-browser@0.8.36
|
||||
- jazz-vue@0.8.24
|
||||
|
||||
## 0.0.16
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "todo-vue",
|
||||
"version": "0.0.16",
|
||||
"version": "0.0.17",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
# jazz-example-todo
|
||||
|
||||
## 0.0.130
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [441fe27]
|
||||
- jazz-tools@0.8.36
|
||||
- jazz-react@0.8.36
|
||||
|
||||
## 0.0.129
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "jazz-example-todo",
|
||||
"private": true,
|
||||
"version": "0.0.129",
|
||||
"version": "0.0.130",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
@@ -16,8 +16,8 @@
|
||||
"@radix-ui/react-toast": "^1.1.4",
|
||||
"class-variance-authority": "^0.7.0",
|
||||
"clsx": "^2.0.0",
|
||||
"jazz-react": "workspace:0.8.35",
|
||||
"jazz-tools": "workspace:0.8.35",
|
||||
"jazz-react": "workspace:0.8.36",
|
||||
"jazz-tools": "workspace:0.8.36",
|
||||
"lucide-react": "^0.274.0",
|
||||
"qrcode": "^1.5.3",
|
||||
"react": "^18.2.0",
|
||||
|
||||
235
homepage/homepage/app/api/latencyMap/route.ts
Normal file
235
homepage/homepage/app/api/latencyMap/route.ts
Normal file
@@ -0,0 +1,235 @@
|
||||
import * as turf from "@turf/turf";
|
||||
import type { FeatureCollection, Point, Position } from "geojson";
|
||||
import { type NextRequest } from "next/server";
|
||||
import land from "../../../components/cloud/ne_110m_land.json";
|
||||
|
||||
import { pingColorThresholds } from "../../../components/cloud/pingColorThresholds";
|
||||
// generated with: globalping ping cloud.jazz.tools from world --limit 500 --packets 16 --json | jq "del(.results[].result.rawOutput)" > pings.json
|
||||
import pings from "../../../components/cloud/pings.json";
|
||||
|
||||
export const revalidate = 2 * 60 * 60; // 2 hours
|
||||
|
||||
export async function GET(req: NextRequest) {
|
||||
const spacing = parseFloat(req.nextUrl.searchParams.get("spacing") || "1.5");
|
||||
const dark = req.nextUrl.searchParams.get("dark") === "true";
|
||||
const addMouseScript = req.nextUrl.searchParams.get("mouse") === "true";
|
||||
|
||||
const serverLocations = [
|
||||
{
|
||||
city: "Los Angeles",
|
||||
lat: 34.0522,
|
||||
lng: -118.2437,
|
||||
ip: "134.195.91.235",
|
||||
color: "hsl(0, 50%, 50%)",
|
||||
},
|
||||
{
|
||||
city: "New York",
|
||||
lat: 40.7128,
|
||||
lng: -74.006,
|
||||
ip: "45.45.219.149",
|
||||
color: "hsl(25, 50%, 50%)",
|
||||
},
|
||||
{
|
||||
city: "London",
|
||||
lat: 51.5074,
|
||||
lng: -0.1278,
|
||||
ip: "150.107.201.83",
|
||||
color: "hsl(50, 50%, 50%)",
|
||||
},
|
||||
{
|
||||
city: "Singapore",
|
||||
lat: 1.3521,
|
||||
lng: 103.8198,
|
||||
ip: "103.214.23.227",
|
||||
color: "hsl(250, 50%, 50%)",
|
||||
},
|
||||
{
|
||||
city: "Sydney",
|
||||
lat: -33.8688,
|
||||
lng: 151.2153,
|
||||
ip: "103.73.65.179",
|
||||
color: "hsl(100, 50%, 50%)",
|
||||
},
|
||||
{
|
||||
city: "Tokyo",
|
||||
lat: 35.6895,
|
||||
lng: 139.7014,
|
||||
ip: "103.173.179.181",
|
||||
color: "hsl(150, 50%, 50%)",
|
||||
},
|
||||
{
|
||||
city: "Tel Aviv",
|
||||
lat: 32.0853,
|
||||
lng: 34.7818,
|
||||
ip: "64.176.162.228",
|
||||
color: "hsl(200, 50%, 50%)",
|
||||
},
|
||||
{
|
||||
city: "Johannesburg",
|
||||
lat: -26.2041,
|
||||
lng: 28.0473,
|
||||
ip: "139.84.228.42",
|
||||
color: "hsl(225, 50%, 50%)",
|
||||
},
|
||||
{
|
||||
city: "Vienna",
|
||||
lat: 48.2085,
|
||||
lng: 16.3721,
|
||||
ip: "185.175.59.44",
|
||||
color: "hsl(75, 50%, 50%)",
|
||||
},
|
||||
{
|
||||
city: "Sao Paulo",
|
||||
lat: -23.5505,
|
||||
lng: -46.6333,
|
||||
ip: "216.238.99.7",
|
||||
color: "hsl(275, 50%, 50%)",
|
||||
},
|
||||
{
|
||||
city: "Dallas",
|
||||
lat: 32.7767,
|
||||
lng: -96.797,
|
||||
ip: "45.32.192.94",
|
||||
color: "hsl(300, 50%, 50%)",
|
||||
},
|
||||
];
|
||||
|
||||
// create a grid of dots that are green if on land (contained in landOutlines) and blue if not
|
||||
const extentX = 720;
|
||||
const extentY = 160;
|
||||
const grid = new Array(Math.round(extentX / spacing))
|
||||
.fill(0)
|
||||
.map((_, i) =>
|
||||
new Array(Math.round(extentY / spacing))
|
||||
.fill(0)
|
||||
.map((_, j) => ({ x: i, y: j })),
|
||||
);
|
||||
// manually add Hawaii by lat/lng
|
||||
grid.push([{ x: -155.844437, y: 19.8987 }]);
|
||||
const dots = grid.flatMap((row) =>
|
||||
row.map(({ x, y }) => ({
|
||||
x: -450 + x * spacing + ((y % 2) * spacing) / 2,
|
||||
y: -60 + y * spacing,
|
||||
})),
|
||||
);
|
||||
const landPolygon = turf.multiPolygon(
|
||||
land.geometries.map((g) => g.coordinates),
|
||||
);
|
||||
const dotsOnLand = turf.pointsWithinPolygon(
|
||||
turf.points(dots.map((d) => [d.x, d.y])),
|
||||
landPolygon,
|
||||
) as FeatureCollection<Point>;
|
||||
|
||||
const scaleX = 3;
|
||||
const scaleY = 3;
|
||||
const offsetX = 600;
|
||||
const offsetY = 260;
|
||||
|
||||
const svg = `<svg
|
||||
viewBox="0 0 1200 440"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<style>
|
||||
circle {
|
||||
transition: fill 0.2s ease-in-out;
|
||||
}
|
||||
</style>
|
||||
${dotsOnLand.features
|
||||
.map((dot, index) => {
|
||||
const nearestMeasurement = pings.results.reduce(
|
||||
(minDistance, ping) => {
|
||||
if (
|
||||
!ping.result.stats ||
|
||||
ping.result.stats.rcv === 0 ||
|
||||
ping.result.stats.avg === null
|
||||
)
|
||||
return minDistance;
|
||||
const distance = turf.distance(
|
||||
dot.geometry.coordinates,
|
||||
[ping.probe.longitude, ping.probe.latitude],
|
||||
{ units: "kilometers" },
|
||||
);
|
||||
const totalPing =
|
||||
(2 * 1000 * distance) / (0.66 * 299_792) +
|
||||
ping.result.stats.min;
|
||||
|
||||
if (distance < minDistance.dist) {
|
||||
return {
|
||||
city: ping.probe.city,
|
||||
dist: distance,
|
||||
ping: ping.result.stats.min,
|
||||
totalPing,
|
||||
resolvedAddress: ping.result.resolvedAddress,
|
||||
};
|
||||
}
|
||||
return minDistance;
|
||||
},
|
||||
{
|
||||
city: "",
|
||||
dist: Infinity,
|
||||
ping: Infinity,
|
||||
totalPing: Infinity,
|
||||
resolvedAddress: "",
|
||||
},
|
||||
);
|
||||
|
||||
return `<circle cx="${
|
||||
dot.geometry.coordinates[0] * scaleX + offsetX
|
||||
}" cy="${
|
||||
-dot.geometry.coordinates[1] * scaleY + offsetY
|
||||
}" r="${1.9 * spacing}" fill="${
|
||||
pingColorThresholds.find(
|
||||
(t) => nearestMeasurement.totalPing < t.ping,
|
||||
)?.[dark ? "darkFill" : "fill"]
|
||||
// serverLocations.find(
|
||||
// (srv) => srv.ip == nearestMeasurement.resolvedAddress,
|
||||
// )?.color
|
||||
}" data-ping="${nearestMeasurement.totalPing.toFixed(
|
||||
1,
|
||||
)}ms" data-via="${nearestMeasurement.city + ""}" data-to="${
|
||||
serverLocations.find(
|
||||
(srv) => srv.ip == nearestMeasurement.resolvedAddress,
|
||||
)?.city
|
||||
}"/>`;
|
||||
})
|
||||
.join("\n")}
|
||||
${
|
||||
addMouseScript
|
||||
? `<script>
|
||||
document.addEventListener("mousemove", (e) => {
|
||||
const target = e.target;
|
||||
|
||||
if (target?.nodeName === "circle") {
|
||||
const x = target.cx.baseVal.value;
|
||||
const y = target.cy.baseVal.value;
|
||||
const ping = parseInt(target.dataset.ping || "0");
|
||||
const via = target.dataset.via;
|
||||
const to = target.dataset.to;
|
||||
const text = \`\${ping}ms via \${via} to \${to}\`;
|
||||
|
||||
window.parent.postMessage({
|
||||
type: "svgmouseover",
|
||||
x,
|
||||
y,
|
||||
ping,
|
||||
via,
|
||||
to,
|
||||
}, "*");
|
||||
} else {
|
||||
window.parent.postMessage({
|
||||
type: "svgmouseout",
|
||||
}, "*");
|
||||
}
|
||||
});
|
||||
</script>`
|
||||
: ""
|
||||
}
|
||||
</svg>`;
|
||||
|
||||
return new Response(svg, {
|
||||
headers: {
|
||||
"Content-Type": "image/svg+xml",
|
||||
"Cache-Control": "public, s-maxage=7200, stale-while-revalidate=3600",
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -36,7 +36,7 @@ Passkey authentication allows users to create a new account or log in with an ex
|
||||
|
||||
Passkey authentication is supported out of the box.
|
||||
|
||||
We have a [minimal example of a passkey authentication setup](https://github.com/garden-co/jazz/tree/main/examples/minimal-auth-passkey).
|
||||
We have a [minimal example of a passkey authentication setup](https://github.com/garden-co/jazz/tree/main/examples/passkey).
|
||||
|
||||
### How to use
|
||||
|
||||
@@ -58,7 +58,7 @@ const [passkeyAuth, passkeyState] = usePasskeyAuth({ appName });
|
||||
|
||||
We have a React package `jazz-react-auth-clerk` to add Clerk authentication to your app.
|
||||
|
||||
We have a [minimal example of a Clerk authentication setup](https://github.com/garden-co/jazz/tree/main/examples/minimal-auth-clerk).
|
||||
We have a [minimal example of a Clerk authentication setup](https://github.com/garden-co/jazz/tree/main/examples/clerk).
|
||||
|
||||
### How to use
|
||||
|
||||
@@ -108,4 +108,4 @@ createRoot(document.getElementById("root")!).render(
|
||||
</StrictMode>,
|
||||
);
|
||||
```
|
||||
</CodeGroup>
|
||||
</CodeGroup>
|
||||
|
||||
@@ -32,7 +32,7 @@ Tested with:
|
||||
|
||||
<CodeGroup>
|
||||
```bash
|
||||
npx expo install expo-linking expo-secure-store expo-file-system @react-native-community/netinfo @bam.tech/react-native-image-resizer
|
||||
npx expo install expo-linking expo-secure-store expo-file-system @react-native-community/netinfo @bam.tech/react-native-image-resizer @azure/core-asynciterator-polyfill
|
||||
|
||||
npm i -S react-native-polyfill-globals react-native-url-polyfill web-streams-polyfill@3.2.1 base-64 text-encoding react-native-fetch-api react-native-get-random-values buffer
|
||||
|
||||
|
||||
@@ -1,25 +1,14 @@
|
||||
"use client";
|
||||
|
||||
import React, { memo } from "react";
|
||||
|
||||
import { usePingColorThresholds } from "@/components/cloud/usePingColorThresholds";
|
||||
import * as turf from "@turf/turf";
|
||||
import type { FeatureCollection, Point, Position } from "geojson";
|
||||
import MapTooltip from "./mapTooltip";
|
||||
import land from "./ne_110m_land.json";
|
||||
|
||||
import { clsx } from "clsx";
|
||||
// generated with: globalping ping cloud.jazz.tools from world --limit 500 --packets 16 --json | jq "del(.results[].result.rawOutput)" > pings.json
|
||||
import pings from "./pings.json";
|
||||
import MapTooltip from "./mapTooltip";
|
||||
import { pingColorThresholds } from "./pingColorThresholds";
|
||||
|
||||
export const LatencyMap = () => {
|
||||
const pingColorThresholds = usePingColorThresholds();
|
||||
|
||||
return (
|
||||
<div className="relative mb-10 sm:-mt-5 -left-4 lg:-left-8 rounded-lg">
|
||||
<MapSVG />
|
||||
<MapTooltip />
|
||||
<div className="absolute bottom-0 left-4 lg:bottom-8 lg:left-8 flex flex-col md:gap-1">
|
||||
<div className="mb-4 rounded-lg relative">
|
||||
<div className="relative xl:-mx-[10%] xl:w-[120%] aspect-[12/4]">
|
||||
<MapTooltip />
|
||||
</div>
|
||||
<div className="absolute bottom-0 left-0 lg:bottom-8 flex flex-col md:gap-1">
|
||||
{pingColorThresholds.map((t, i) => (
|
||||
<div
|
||||
key={t.ping}
|
||||
@@ -27,10 +16,7 @@ export const LatencyMap = () => {
|
||||
"hidden sm:flex": i % 2 !== 0,
|
||||
})}
|
||||
>
|
||||
<div
|
||||
className="size-2 md:size-3 rounded-full"
|
||||
style={{ background: t.color }}
|
||||
></div>
|
||||
<div className={"size-2 md:size-3 rounded-full " + t.bgClass}></div>
|
||||
<div className="text-[9px] md:text-xs font-mono">
|
||||
<{t.ping}ms
|
||||
</div>
|
||||
@@ -40,187 +26,3 @@ export const LatencyMap = () => {
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const MapSVG = memo(({ spacing = 1.5 }: { spacing?: number }) => {
|
||||
const pingColorThresholds = usePingColorThresholds();
|
||||
|
||||
// Define the data points with their latitudes, longitudes, and ping times
|
||||
const serverLocations = [
|
||||
{
|
||||
city: "Los Angeles",
|
||||
lat: 34.0522,
|
||||
lng: -118.2437,
|
||||
ip: "134.195.91.235",
|
||||
color: "hsl(0, 50%, 50%)",
|
||||
},
|
||||
{
|
||||
city: "New York",
|
||||
lat: 40.7128,
|
||||
lng: -74.006,
|
||||
ip: "45.45.219.149",
|
||||
color: "hsl(25, 50%, 50%)",
|
||||
},
|
||||
{
|
||||
city: "London",
|
||||
lat: 51.5074,
|
||||
lng: -0.1278,
|
||||
ip: "150.107.201.83",
|
||||
color: "hsl(50, 50%, 50%)",
|
||||
},
|
||||
{
|
||||
city: "Singapore",
|
||||
lat: 1.3521,
|
||||
lng: 103.8198,
|
||||
ip: "103.214.23.227",
|
||||
color: "hsl(250, 50%, 50%)",
|
||||
},
|
||||
{
|
||||
city: "Sydney",
|
||||
lat: -33.8688,
|
||||
lng: 151.2153,
|
||||
ip: "103.73.65.179",
|
||||
color: "hsl(100, 50%, 50%)",
|
||||
},
|
||||
{
|
||||
city: "Tokyo",
|
||||
lat: 35.6895,
|
||||
lng: 139.7014,
|
||||
ip: "103.173.179.181",
|
||||
color: "hsl(150, 50%, 50%)",
|
||||
},
|
||||
{
|
||||
city: "Tel Aviv",
|
||||
lat: 32.0853,
|
||||
lng: 34.7818,
|
||||
ip: "64.176.162.228",
|
||||
color: "hsl(200, 50%, 50%)",
|
||||
},
|
||||
{
|
||||
city: "Johannesburg",
|
||||
lat: -26.2041,
|
||||
lng: 28.0473,
|
||||
ip: "139.84.228.42",
|
||||
color: "hsl(225, 50%, 50%)",
|
||||
},
|
||||
{
|
||||
city: "Vienna",
|
||||
lat: 48.2085,
|
||||
lng: 16.3721,
|
||||
ip: "185.175.59.44",
|
||||
color: "hsl(75, 50%, 50%)",
|
||||
},
|
||||
{
|
||||
city: "Sao Paulo",
|
||||
lat: -23.5505,
|
||||
lng: -46.6333,
|
||||
ip: "216.238.99.7",
|
||||
color: "hsl(275, 50%, 50%)",
|
||||
},
|
||||
{
|
||||
city: "Dallas",
|
||||
lat: 32.7767,
|
||||
lng: -96.797,
|
||||
ip: "45.32.192.94",
|
||||
color: "hsl(300, 50%, 50%)",
|
||||
},
|
||||
];
|
||||
|
||||
// create a grid of dots that are green if on land (contained in landOutlines) and blue if not
|
||||
const extentX = 720;
|
||||
const extentY = 160;
|
||||
const grid = new Array(Math.round(extentX / spacing))
|
||||
.fill(0)
|
||||
.map((_, i) =>
|
||||
new Array(Math.round(extentY / spacing))
|
||||
.fill(0)
|
||||
.map((_, j) => ({ x: i, y: j })),
|
||||
);
|
||||
// manually add Hawaii by lat/lng
|
||||
grid.push([{ x: -155.844437, y: 19.8987 }]);
|
||||
const dots = grid.flatMap((row) =>
|
||||
row.map(({ x, y }) => ({
|
||||
x: -450 + x * spacing + ((y % 2) * spacing) / 2,
|
||||
y: -60 + y * spacing,
|
||||
})),
|
||||
);
|
||||
const landPolygon = turf.multiPolygon(
|
||||
land.geometries.map((g) => g.coordinates),
|
||||
);
|
||||
const dotsOnLand = turf.pointsWithinPolygon(
|
||||
turf.points(dots.map((d) => [d.x, d.y])),
|
||||
landPolygon,
|
||||
) as FeatureCollection<Point>;
|
||||
|
||||
const scaleX = 3;
|
||||
const scaleY = 3;
|
||||
const offsetX = 600;
|
||||
const offsetY = 260;
|
||||
|
||||
return (
|
||||
<svg
|
||||
viewBox="0 0 1200 440"
|
||||
className="mx-auto"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: dotsOnLand.features
|
||||
.map((dot, index) => {
|
||||
const nearestMeasurement = pings.results.reduce(
|
||||
(minDistance, ping) => {
|
||||
if (
|
||||
!ping.result.stats ||
|
||||
ping.result.stats.rcv === 0 ||
|
||||
ping.result.stats.avg === null
|
||||
)
|
||||
return minDistance;
|
||||
const distance = turf.distance(
|
||||
dot.geometry.coordinates,
|
||||
[ping.probe.longitude, ping.probe.latitude],
|
||||
{ units: "kilometers" },
|
||||
);
|
||||
const totalPing =
|
||||
(2 * 1000 * distance) / (0.66 * 299_792) +
|
||||
ping.result.stats.min;
|
||||
|
||||
if (distance < minDistance.dist) {
|
||||
return {
|
||||
city: ping.probe.city,
|
||||
dist: distance,
|
||||
ping: ping.result.stats.min,
|
||||
totalPing,
|
||||
resolvedAddress: ping.result.resolvedAddress,
|
||||
};
|
||||
}
|
||||
return minDistance;
|
||||
},
|
||||
{
|
||||
city: "",
|
||||
dist: Infinity,
|
||||
ping: Infinity,
|
||||
totalPing: Infinity,
|
||||
resolvedAddress: "",
|
||||
},
|
||||
);
|
||||
|
||||
return `<circle cx="${
|
||||
dot.geometry.coordinates[0] * scaleX + offsetX
|
||||
}" cy="${
|
||||
-dot.geometry.coordinates[1] * scaleY + offsetY
|
||||
}" r="${1.9 * spacing}" fill="${
|
||||
pingColorThresholds.find(
|
||||
(t) => nearestMeasurement.totalPing < t.ping,
|
||||
)?.color
|
||||
// serverLocations.find(
|
||||
// (srv) => srv.ip == nearestMeasurement.resolvedAddress,
|
||||
// )?.color
|
||||
}" data-ping="${nearestMeasurement.totalPing.toFixed(
|
||||
1,
|
||||
)}ms" data-via="${nearestMeasurement.city + ""}" data-to="${
|
||||
serverLocations.find(
|
||||
(srv) => srv.ip == nearestMeasurement.resolvedAddress,
|
||||
)?.city
|
||||
}"/>`;
|
||||
})
|
||||
.join("\n"),
|
||||
}}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
@@ -1,52 +1,66 @@
|
||||
"use client";
|
||||
|
||||
import { usePingColorThresholds } from "@/components/cloud/usePingColorThresholds";
|
||||
import { useEffect } from "react";
|
||||
import { clsx } from "clsx";
|
||||
import { useLayoutEffect, useState } from "react";
|
||||
import { pingColorThresholds } from "./pingColorThresholds";
|
||||
|
||||
export default function MapTooltip() {
|
||||
const pingColorThresholds = usePingColorThresholds();
|
||||
const [style, setStyle] = useState<React.CSSProperties>({});
|
||||
const [circleClass, setCircleClass] = useState("");
|
||||
const [text, setText] = useState("");
|
||||
|
||||
useEffect(() => {
|
||||
// register callback for hovering, if we're over any circle, show the tooltip based on the data attributes
|
||||
const onMouseMove = (e: MouseEvent) => {
|
||||
const circ = e.target;
|
||||
|
||||
const el = document.querySelector(
|
||||
".map-tooltip",
|
||||
) as HTMLDivElement | null;
|
||||
if (!el) return;
|
||||
|
||||
if (circ instanceof SVGCircleElement) {
|
||||
const x = circ.cx.baseVal.value;
|
||||
const y = circ.cy.baseVal.value;
|
||||
const ping = parseInt(circ.dataset.ping || "0");
|
||||
const via = circ.dataset.via;
|
||||
const to = circ.dataset.to;
|
||||
const text = `${ping}ms via ${via} to ${to}`;
|
||||
|
||||
el.style.display = "flex";
|
||||
|
||||
el.style.left = `calc(100% * ${x / 1400} + 30px)`;
|
||||
el.style.top = `calc(100% * ${(y || 0) / 440} + 15px)`;
|
||||
(el.children[0] as HTMLDivElement).style.backgroundColor =
|
||||
pingColorThresholds.find((t) => t.ping >= ping)?.color || "";
|
||||
(el.children[1] as HTMLDivElement).textContent = text;
|
||||
} else {
|
||||
el.style.display = "none";
|
||||
useLayoutEffect(() => {
|
||||
const onSvgMouseMove = (e: MessageEvent) => {
|
||||
if (e.data.type === "svgmouseout") {
|
||||
setStyle({ display: "none" });
|
||||
return;
|
||||
}
|
||||
if (e.data.type !== "svgmouseover") return;
|
||||
|
||||
const x = e.data.x;
|
||||
const y = e.data.y;
|
||||
const ping = e.data.ping;
|
||||
const via = e.data.via;
|
||||
const to = e.data.to;
|
||||
const text = `${ping}ms via ${via} to ${to}`;
|
||||
|
||||
setStyle({
|
||||
display: "flex",
|
||||
left: `calc(100% * ${x / 1400} + 30px)`,
|
||||
top: `calc(100% * ${(y || 0) / 440} + 15px)`,
|
||||
});
|
||||
setCircleClass(
|
||||
"w-3 h-3 rounded-full " +
|
||||
(pingColorThresholds.find((t) => t.ping >= ping)?.bgClass || ""),
|
||||
);
|
||||
setText(text);
|
||||
};
|
||||
|
||||
document.addEventListener("mousemove", onMouseMove);
|
||||
window.addEventListener("message", onSvgMouseMove);
|
||||
|
||||
return () => {
|
||||
document.removeEventListener("mousemove", onMouseMove);
|
||||
window.removeEventListener("message", onSvgMouseMove);
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="map-tooltip absolute pointer-events-none text-xs bg-stone-925 text-stone-50 p-2 rounded-lg gap-1 items-center">
|
||||
<div className="w-3 h-3 rounded-full"></div>
|
||||
<div className="text-xs"></div>
|
||||
</div>
|
||||
<>
|
||||
<iframe
|
||||
className="w-full aspect-[12/4] dark:hidden"
|
||||
src="/api/latencyMap?spacing=1.5&dark=false&mouse=true"
|
||||
/>
|
||||
<iframe
|
||||
className="w-full aspect-[12/4] hidden dark:block"
|
||||
src="/api/latencyMap?spacing=1.5&dark=true&mouse=true"
|
||||
style={{ colorScheme: "light" }}
|
||||
/>
|
||||
<div
|
||||
className="hidden map-tooltip absolute pointer-events-none text-xs bg-stone-925 text-stone-50 p-2 rounded-lg gap-1 items-center"
|
||||
style={style}
|
||||
>
|
||||
<div className={clsx("w-3 h-3 rounded-full", circleClass)}></div>
|
||||
<div className="text-xs">{text}</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
80
homepage/homepage/components/cloud/pingColorThresholds.ts
Normal file
80
homepage/homepage/components/cloud/pingColorThresholds.ts
Normal file
@@ -0,0 +1,80 @@
|
||||
export const pingColorThresholds = [
|
||||
{
|
||||
ping: 5,
|
||||
bgClass: "dark:bg-[hsl(248,50%,100%)] bg-[hsl(260,100%,53%)]",
|
||||
fill: "hsl(260,100%,53%)",
|
||||
darkFill: "hsl(248,50%,100%)",
|
||||
},
|
||||
{
|
||||
ping: 10,
|
||||
bgClass: "dark:bg-[hsl(248,50%,80%)] bg-[hsl(258,95%,56%)]",
|
||||
fill: "hsl(258,95%,56%)",
|
||||
darkFill: "hsl(248,50%,80%)",
|
||||
},
|
||||
{
|
||||
ping: 15,
|
||||
bgClass: "dark:bg-[hsl(248,50%,72%)] bg-[hsl(256,93%,59%)]",
|
||||
fill: "hsl(256,93%,59%)",
|
||||
darkFill: "hsl(248,50%,72%)",
|
||||
},
|
||||
{
|
||||
ping: 25,
|
||||
bgClass: "dark:bg-[hsl(248,50%,62%)] bg-[hsl(252,90%,62%)]",
|
||||
fill: "hsl(252,90%,62%)",
|
||||
darkFill: "hsl(248,50%,62%)",
|
||||
},
|
||||
{
|
||||
ping: 35,
|
||||
bgClass: "dark:bg-[hsl(248,50%,54%)] bg-[hsl(250,88%,65%)]",
|
||||
fill: "hsl(250,88%,65%)",
|
||||
darkFill: "hsl(248,50%,54%)",
|
||||
},
|
||||
{
|
||||
ping: 45,
|
||||
bgClass: "dark:bg-[hsl(248,50%,49%)] bg-[hsl(245,87%,68%)]",
|
||||
fill: "hsl(245,87%,68%)",
|
||||
darkFill: "hsl(248,50%,49%)",
|
||||
},
|
||||
{
|
||||
ping: 55,
|
||||
bgClass: "dark:bg-[hsl(248,50%,43%)] bg-[hsl(240,86%,71%)]",
|
||||
fill: "hsl(240,86%,71%)",
|
||||
darkFill: "hsl(248,50%,43%)",
|
||||
},
|
||||
{
|
||||
ping: 65,
|
||||
bgClass: "dark:bg-[hsl(248,50%,39%)] bg-[hsl(238,84%,74%)]",
|
||||
fill: "hsl(238,84%,74%)",
|
||||
darkFill: "hsl(248,50%,39%)",
|
||||
},
|
||||
{
|
||||
ping: 100,
|
||||
bgClass: "dark:bg-[hsl(248,50%,35%)] bg-[hsl(235,80%,77%)]",
|
||||
fill: "hsl(235,80%,77%)",
|
||||
darkFill: "hsl(248,50%,35%)",
|
||||
},
|
||||
{
|
||||
ping: 150,
|
||||
bgClass: "dark:bg-[hsl(248,50%,28%)] bg-[hsl(232,73%,80%)]",
|
||||
fill: "hsl(232,73%,80%)",
|
||||
darkFill: "hsl(248,50%,28%)",
|
||||
},
|
||||
{
|
||||
ping: 200,
|
||||
bgClass: "dark:bg-[hsl(248,50%,23%)] bg-[hsl(230,69%,83%)]",
|
||||
fill: "hsl(230,69%,83%)",
|
||||
darkFill: "hsl(248,50%,23%)",
|
||||
},
|
||||
{
|
||||
ping: 300,
|
||||
bgClass: "dark:bg-[hsl(248,50%,20%)] bg-[hsl(230,65%,88%)]",
|
||||
fill: "hsl(230,65%,88%)",
|
||||
darkFill: "hsl(248,50%,20%)",
|
||||
},
|
||||
{
|
||||
ping: 1000,
|
||||
bgClass: "dark:bg-[hsl(248,50%,16%)] bg-[hsl(220,60%,92%)]",
|
||||
fill: "hsl(220,60%,92%)",
|
||||
darkFill: "hsl(248,50%,16%)",
|
||||
},
|
||||
];
|
||||
@@ -1,41 +0,0 @@
|
||||
import { useTheme } from "next-themes";
|
||||
|
||||
export const pingColorThresholdsDark = [
|
||||
{ ping: 5, color: "hsl(248, 50%, 100%)" },
|
||||
{ ping: 10, color: "hsl(248, 50%, 80%)" },
|
||||
{ ping: 15, color: "hsl(248, 50%, 72%)" },
|
||||
{ ping: 25, color: "hsl(248, 50%, 62%)" },
|
||||
{ ping: 35, color: "hsl(248, 50%, 54%)" },
|
||||
{ ping: 45, color: "hsl(248, 50%, 49%)" },
|
||||
{ ping: 55, color: "hsl(248, 50%, 43%)" },
|
||||
{ ping: 65, color: "hsl(248, 50%, 39%)" },
|
||||
{ ping: 100, color: "hsl(248, 50%, 35%)" },
|
||||
{ ping: 150, color: "hsl(248, 50%, 28%)" },
|
||||
{ ping: 200, color: "hsl(248, 50%, 23%)" },
|
||||
{ ping: 300, color: "hsl(248, 50%, 20%)" },
|
||||
{ ping: 1000, color: "hsl(248, 50%, 16%)" },
|
||||
];
|
||||
|
||||
export const pingColorThresholdsLight = [
|
||||
{ ping: 5, color: "hsl(260,100%,53%)" },
|
||||
{ ping: 10, color: "hsl(258,95%,56%)" },
|
||||
{ ping: 15, color: "hsl(256,93%,59%)" },
|
||||
{ ping: 25, color: "hsl(252,90%,62%)" },
|
||||
{ ping: 35, color: "hsl(250,88%,65%)" },
|
||||
{ ping: 45, color: "hsl(245,87%,68%)" },
|
||||
{ ping: 55, color: "hsl(240,86%,71%)" },
|
||||
{ ping: 65, color: "hsl(238,84%,74%)" },
|
||||
{ ping: 100, color: "hsl(235,80%,77%)" },
|
||||
{ ping: 150, color: "hsl(232,73%,80%)" },
|
||||
{ ping: 200, color: "hsl(230,69%,83%)" },
|
||||
{ ping: 300, color: "hsl(230,65%,88%)" },
|
||||
{ ping: 1000, color: "hsl(220,60%,92%)" },
|
||||
];
|
||||
|
||||
export const usePingColorThresholds = () => {
|
||||
const { resolvedTheme } = useTheme();
|
||||
|
||||
return resolvedTheme === "dark"
|
||||
? pingColorThresholdsDark
|
||||
: pingColorThresholdsLight;
|
||||
};
|
||||
@@ -16,7 +16,6 @@ import {
|
||||
UserIcon,
|
||||
} from "lucide-react";
|
||||
import Link from "next/link";
|
||||
import { MapSVG } from "../cloud/latencyMap";
|
||||
|
||||
const features = [
|
||||
{
|
||||
@@ -141,7 +140,14 @@ export function FeaturesSection() {
|
||||
|
||||
<div className="relative border p-4 sm:p-8 shadow-sm rounded-xl col-span-2 sm:col-span-4 flex flex-col justify-end">
|
||||
<div className="mb-3 sm:-right-3 sm:bottom-30 sm:absolute sm:left-[40%] sm:top-2 md:top-4 md:left-[23%]">
|
||||
<MapSVG spacing={3} />
|
||||
<img
|
||||
src="/api/latencyMap?spacing=2&dark=false"
|
||||
className="w-full dark:hidden"
|
||||
/>
|
||||
<img
|
||||
src="/api/latencyMap?spacing=2&dark=true"
|
||||
className="w-full hidden dark:block"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<H3>Jazz Cloud</H3>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"format-and-lint": "biome check .",
|
||||
"format-and-lint:fix": "biome check . --write"
|
||||
},
|
||||
"packageManager": "pnpm@9.1.4",
|
||||
"packageManager": "pnpm@9.14.0",
|
||||
"dependencies": {
|
||||
"@headlessui/react": "^2.2.0",
|
||||
"@icons-pack/react-simple-icons": "^9.1.0",
|
||||
|
||||
2
homepage/homepage/pnpm-lock.yaml
generated
2
homepage/homepage/pnpm-lock.yaml
generated
@@ -1,4 +1,4 @@
|
||||
lockfileVersion: '6.0'
|
||||
lockfileVersion: '9.0'
|
||||
|
||||
settings:
|
||||
autoInstallPeers: true
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"workspaces": ["packages/*", "examples/*"],
|
||||
"packageManager": "pnpm@9.1.4",
|
||||
"packageManager": "pnpm@9.14.0",
|
||||
"devDependencies": {
|
||||
"@biomejs/biome": "1.9.4",
|
||||
"@changesets/cli": "^2.27.3",
|
||||
|
||||
@@ -1,5 +1,15 @@
|
||||
# cojson-storage-indexeddb
|
||||
|
||||
## 0.8.36
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 1afbd2c: Refactor the SQLite and IndexedDB storage packages to extract common synchronization functionality into newly created cojson-storage package.
|
||||
- Updated dependencies [441fe27]
|
||||
- Updated dependencies [1afbd2c]
|
||||
- cojson@0.8.36
|
||||
- cojson-storage@0.8.36
|
||||
|
||||
## 0.8.35
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "cojson-storage-indexeddb",
|
||||
"version": "0.8.35",
|
||||
"version": "0.8.36",
|
||||
"main": "dist/index.js",
|
||||
"type": "module",
|
||||
"types": "src/index.ts",
|
||||
|
||||
@@ -1,5 +1,15 @@
|
||||
# cojson-storage-sqlite
|
||||
|
||||
## 0.8.36
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 1afbd2c: Refactor the SQLite and IndexedDB storage packages to extract common synchronization functionality into newly created cojson-storage package.
|
||||
- Updated dependencies [441fe27]
|
||||
- Updated dependencies [1afbd2c]
|
||||
- cojson@0.8.36
|
||||
- cojson-storage@0.8.36
|
||||
|
||||
## 0.8.35
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
{
|
||||
"name": "cojson-storage-sqlite",
|
||||
"type": "module",
|
||||
"version": "0.8.35",
|
||||
"version": "0.8.36",
|
||||
"main": "dist/index.js",
|
||||
"types": "src/index.ts",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"better-sqlite3": "^8.5.2",
|
||||
"cojson": "workspace:0.8.35",
|
||||
"cojson": "workspace:0.8.36",
|
||||
"cojson-storage": "workspace:*"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
9
packages/cojson-storage/CHANGELOG.md
Normal file
9
packages/cojson-storage/CHANGELOG.md
Normal file
@@ -0,0 +1,9 @@
|
||||
# cojson-storage
|
||||
|
||||
## 0.8.36
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 1afbd2c: Refactor the SQLite and IndexedDB storage packages to extract common synchronization functionality into newly created cojson-storage package.
|
||||
- Updated dependencies [441fe27]
|
||||
- cojson@0.8.36
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "cojson-storage",
|
||||
"version": "0.8.35",
|
||||
"version": "0.8.36",
|
||||
"main": "dist/index.js",
|
||||
"type": "module",
|
||||
"types": "src/index.ts",
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
# cojson-transport-nodejs-ws
|
||||
|
||||
## 0.8.36
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [441fe27]
|
||||
- cojson@0.8.36
|
||||
|
||||
## 0.8.35
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "cojson-transport-ws",
|
||||
"type": "module",
|
||||
"version": "0.8.35",
|
||||
"version": "0.8.36",
|
||||
"main": "dist/index.js",
|
||||
"types": "src/index.ts",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"cojson": "workspace:0.8.35",
|
||||
"cojson": "workspace:0.8.36",
|
||||
"typescript": "^5.3.3"
|
||||
},
|
||||
"scripts": {
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# cojson
|
||||
|
||||
## 0.8.36
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 441fe27: Optimise large record-like CoMaps for access of latest value
|
||||
|
||||
## 0.8.35
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
},
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
"version": "0.8.35",
|
||||
"version": "0.8.36",
|
||||
"devDependencies": {
|
||||
"@types/jest": "^29.5.3",
|
||||
"typescript": "^5.3.3",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { CoID, RawCoValue } from "../coValue.js";
|
||||
import { CoValueCore } from "../coValueCore.js";
|
||||
import { CoValueCore, DecryptedTransaction } from "../coValueCore.js";
|
||||
import { AgentID, TransactionID } from "../ids.js";
|
||||
import { JsonObject, JsonValue } from "../jsonValue.js";
|
||||
import { accountOrAgentIDfromSessionID } from "../typeUtils/accountOrAgentIDfromSessionID.js";
|
||||
@@ -49,6 +49,9 @@ export class RawCoMapView<
|
||||
cachedOps?: {
|
||||
[Key in keyof Shape & string]?: MapOp<Key, Shape[Key]>[];
|
||||
};
|
||||
/** @internal */
|
||||
validSortedTransactions?: DecryptedTransaction[];
|
||||
|
||||
/** @internal */
|
||||
options?: { ignorePrivateTransactions: boolean; atTime?: number };
|
||||
/** @internal */
|
||||
@@ -59,27 +62,58 @@ export class RawCoMapView<
|
||||
/** @internal */
|
||||
constructor(
|
||||
core: CoValueCore,
|
||||
options?: { ignorePrivateTransactions: boolean; atTime?: number },
|
||||
options?: {
|
||||
ignorePrivateTransactions: boolean;
|
||||
atTime?: number;
|
||||
validSortedTransactions?: DecryptedTransaction[];
|
||||
cachedOps?: {
|
||||
[Key in keyof Shape & string]?: MapOp<Key, Shape[Key]>[];
|
||||
};
|
||||
},
|
||||
) {
|
||||
this.id = core.id as CoID<this>;
|
||||
this.core = core;
|
||||
this.latest = {};
|
||||
this.latestTxMadeAt = 0;
|
||||
this.options = options;
|
||||
this.cachedOps = options?.cachedOps;
|
||||
this.validSortedTransactions = options?.validSortedTransactions;
|
||||
|
||||
this.processLatestTransactions();
|
||||
}
|
||||
|
||||
processLatestTransactions() {
|
||||
/** @internal */
|
||||
private getValidSortedTransactions() {
|
||||
if (this.validSortedTransactions) {
|
||||
return this.validSortedTransactions;
|
||||
}
|
||||
|
||||
const validSortedTransactions = this.core.getValidSortedTransactions({
|
||||
ignorePrivateTransactions:
|
||||
this.options?.ignorePrivateTransactions ?? false,
|
||||
});
|
||||
|
||||
this.validSortedTransactions = validSortedTransactions;
|
||||
|
||||
return validSortedTransactions;
|
||||
}
|
||||
|
||||
private resetCachedValues() {
|
||||
this.validSortedTransactions = undefined;
|
||||
this.cachedOps = undefined;
|
||||
}
|
||||
|
||||
private processLatestTransactions() {
|
||||
// Reset all internal state and cached values
|
||||
this.latest = {};
|
||||
this.latestTxMadeAt = 0;
|
||||
|
||||
const { core, options, latest } = this;
|
||||
const { latest } = this;
|
||||
|
||||
for (const { txID, changes, madeAt } of core.getValidSortedTransactions({
|
||||
ignorePrivateTransactions: options?.ignorePrivateTransactions ?? false,
|
||||
})) {
|
||||
if (options?.atTime && madeAt > options.atTime) {
|
||||
const atTimeFilter = this.options?.atTime;
|
||||
|
||||
for (const { txID, changes, madeAt } of this.getValidSortedTransactions()) {
|
||||
if (atTimeFilter && madeAt > atTimeFilter) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -111,6 +145,11 @@ export class RawCoMapView<
|
||||
}
|
||||
}
|
||||
|
||||
revalidateTransactions() {
|
||||
this.resetCachedValues();
|
||||
this.processLatestTransactions();
|
||||
}
|
||||
|
||||
private getOps() {
|
||||
if (this.cachedOps) {
|
||||
return this.cachedOps;
|
||||
@@ -120,11 +159,7 @@ export class RawCoMapView<
|
||||
[Key in keyof Shape & string]?: MapOp<Key, Shape[Key]>[];
|
||||
} = {};
|
||||
|
||||
for (const {
|
||||
txID,
|
||||
changes,
|
||||
madeAt,
|
||||
} of this.core.getValidSortedTransactions(this.options)) {
|
||||
for (const { txID, changes, madeAt } of this.getValidSortedTransactions()) {
|
||||
for (let changeIdx = 0; changeIdx < changes.length; changeIdx++) {
|
||||
const change = changes[changeIdx] as MapOpPayload<
|
||||
keyof Shape & string,
|
||||
@@ -168,6 +203,8 @@ export class RawCoMapView<
|
||||
ignorePrivateTransactions:
|
||||
this.options?.ignorePrivateTransactions ?? false,
|
||||
atTime: time,
|
||||
cachedOps: this.cachedOps,
|
||||
validSortedTransactions: this.validSortedTransactions,
|
||||
});
|
||||
Object.setPrototypeOf(clone, this);
|
||||
return clone as this;
|
||||
@@ -182,10 +219,10 @@ export class RawCoMapView<
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (this.atTimeFilter) {
|
||||
return this.getOps()[key]?.filter(
|
||||
(op) => op.madeAt <= this.atTimeFilter!,
|
||||
);
|
||||
const atTimeFilter = this.options?.atTime;
|
||||
|
||||
if (atTimeFilter) {
|
||||
return this.getOps()[key]?.filter((op) => op.madeAt <= atTimeFilter);
|
||||
} else {
|
||||
return this.getOps()[key];
|
||||
}
|
||||
@@ -197,17 +234,13 @@ export class RawCoMapView<
|
||||
* @category 1. Reading */
|
||||
keys<K extends keyof Shape & string = keyof Shape & string>(): K[] {
|
||||
return (Object.keys(this.latest) as K[]).filter((key) => {
|
||||
const latest = this.latest[key];
|
||||
if (!latest) {
|
||||
return undefined;
|
||||
const latestChange = this.latest[key];
|
||||
|
||||
if (!latestChange) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const includeUntil = this.atTimeFilter;
|
||||
const lastEntry = includeUntil
|
||||
? this.getOps()[key]?.findLast((entry) => entry.madeAt <= includeUntil)
|
||||
: latest!;
|
||||
|
||||
if (lastEntry?.change.op === "del") {
|
||||
if (latestChange.change.op === "del") {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
@@ -221,22 +254,15 @@ export class RawCoMapView<
|
||||
* @category 1. Reading
|
||||
**/
|
||||
get<K extends keyof Shape & string>(key: K): Shape[K] | undefined {
|
||||
const latest = this.latest[key];
|
||||
if (!latest) {
|
||||
const latestChange = this.latest[key];
|
||||
if (!latestChange) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const includeUntil = this.atTimeFilter;
|
||||
const lastEntry = includeUntil
|
||||
? this.timeFilteredOps(key)?.findLast(
|
||||
(entry) => entry.madeAt <= includeUntil,
|
||||
)
|
||||
: latest;
|
||||
|
||||
if (lastEntry?.change.op === "del") {
|
||||
if (latestChange.change.op === "del") {
|
||||
return undefined;
|
||||
} else {
|
||||
return lastEntry?.change.value;
|
||||
return latestChange.change.value as Shape[K];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -248,7 +274,7 @@ export class RawCoMapView<
|
||||
[K in keyof Shape & string]: Shape[K];
|
||||
}> = {};
|
||||
|
||||
for (const key of this.keys()) {
|
||||
for (const key of Object.keys(this.latest) as (keyof Shape & string)[]) {
|
||||
const value = this.get(key);
|
||||
if (value !== undefined) {
|
||||
object[key] = value;
|
||||
@@ -268,34 +294,21 @@ export class RawCoMapView<
|
||||
}
|
||||
|
||||
/** @category 5. Edit history */
|
||||
nthEditAt<K extends keyof Shape & string>(
|
||||
key: K,
|
||||
n: number,
|
||||
):
|
||||
| {
|
||||
by: RawAccountID | AgentID;
|
||||
tx: TransactionID;
|
||||
at: Date;
|
||||
value?: Shape[K];
|
||||
}
|
||||
| undefined {
|
||||
const ops = this.timeFilteredOps(key);
|
||||
if (!ops || ops.length <= n) {
|
||||
nthEditAt<K extends keyof Shape & string>(key: K, n: number) {
|
||||
const ops = this.getOps()[key];
|
||||
|
||||
const atTimeFilter = this.options?.atTime;
|
||||
const entry = ops?.[n];
|
||||
|
||||
if (!entry) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const entry = ops[n]!;
|
||||
|
||||
if (this.atTimeFilter && entry.madeAt > this.atTimeFilter) {
|
||||
if (atTimeFilter && entry.madeAt > atTimeFilter) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return {
|
||||
by: accountOrAgentIDfromSessionID(entry.txID.sessionID),
|
||||
tx: entry.txID,
|
||||
at: new Date(entry.madeAt),
|
||||
value: entry.change.op === "del" ? undefined : entry.change.value,
|
||||
};
|
||||
return operationToEditEntry(entry);
|
||||
}
|
||||
|
||||
/** @category 5. Edit history */
|
||||
@@ -310,10 +323,13 @@ export class RawCoMapView<
|
||||
}
|
||||
| undefined {
|
||||
const ops = this.timeFilteredOps(key);
|
||||
if (!ops || ops.length === 0) {
|
||||
const lastEntry = ops?.[ops.length - 1];
|
||||
|
||||
if (!lastEntry) {
|
||||
return undefined;
|
||||
}
|
||||
return this.nthEditAt(key, ops.length - 1);
|
||||
|
||||
return operationToEditEntry(lastEntry);
|
||||
}
|
||||
|
||||
/** @category 5. Edit history */
|
||||
@@ -323,8 +339,8 @@ export class RawCoMapView<
|
||||
return;
|
||||
}
|
||||
|
||||
for (let i = 0; i < ops.length; i++) {
|
||||
yield this.nthEditAt(key, i)!;
|
||||
for (const entry of ops) {
|
||||
yield operationToEditEntry(entry);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -370,8 +386,7 @@ export class RawCoMap<
|
||||
privacy,
|
||||
);
|
||||
|
||||
this.processLatestTransactions();
|
||||
this.cachedOps = undefined;
|
||||
this.revalidateTransactions();
|
||||
}
|
||||
|
||||
/** Delete the given key (setting it to undefined).
|
||||
@@ -396,7 +411,18 @@ export class RawCoMap<
|
||||
privacy,
|
||||
);
|
||||
|
||||
this.processLatestTransactions();
|
||||
this.cachedOps = undefined;
|
||||
this.revalidateTransactions();
|
||||
}
|
||||
}
|
||||
|
||||
export function operationToEditEntry<
|
||||
K extends string,
|
||||
V extends JsonValue | undefined,
|
||||
>(op: MapOp<K, V>) {
|
||||
return {
|
||||
by: accountOrAgentIDfromSessionID(op.txID.sessionID),
|
||||
tx: op.txID,
|
||||
at: new Date(op.madeAt),
|
||||
value: op.change.op === "del" ? undefined : op.change.value,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { expect, test } from "vitest";
|
||||
import { expectMap } from "../coValue.js";
|
||||
import { operationToEditEntry } from "../coValues/coMap.js";
|
||||
import { WasmCrypto } from "../crypto/WasmCrypto.js";
|
||||
import { LocalNode } from "../localNode.js";
|
||||
import { accountOrAgentIDfromSessionID } from "../typeUtils/accountOrAgentIDfromSessionID.js";
|
||||
@@ -82,6 +83,29 @@ test("Can get CoMap entry values at different points in time", () => {
|
||||
expect(content.atTime(beforeA).get("hello")).toEqual(undefined);
|
||||
expect(content.atTime(beforeB).get("hello")).toEqual("A");
|
||||
expect(content.atTime(beforeC).get("hello")).toEqual("B");
|
||||
|
||||
const ops = content.timeFilteredOps("hello");
|
||||
|
||||
expect(content.atTime(beforeC).lastEditAt("hello")).toEqual(
|
||||
operationToEditEntry(ops![1]!),
|
||||
);
|
||||
expect(content.atTime(beforeC).nthEditAt("hello", 0)).toEqual(
|
||||
operationToEditEntry(ops![0]!),
|
||||
);
|
||||
expect(content.atTime(beforeC).nthEditAt("hello", 2)).toEqual(undefined);
|
||||
|
||||
expect([...content.atTime(beforeC).editsAt("hello")]).toEqual([
|
||||
operationToEditEntry(ops![0]!),
|
||||
operationToEditEntry(ops![1]!),
|
||||
]);
|
||||
|
||||
expect(content.atTime(beforeB).asObject()).toEqual({
|
||||
hello: "A",
|
||||
});
|
||||
|
||||
expect(content.atTime(beforeC).asObject()).toEqual({
|
||||
hello: "B",
|
||||
});
|
||||
});
|
||||
|
||||
test("Can get all historic values of key in CoMap", () => {
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
# jazz-browser-media-images
|
||||
|
||||
## 0.8.36
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [441fe27]
|
||||
- cojson@0.8.36
|
||||
- jazz-tools@0.8.36
|
||||
- jazz-browser@0.8.36
|
||||
|
||||
## 0.8.35
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
{
|
||||
"name": "jazz-browser-auth-clerk",
|
||||
"version": "0.8.35",
|
||||
"version": "0.8.36",
|
||||
"type": "module",
|
||||
"main": "dist/index.js",
|
||||
"types": "src/index.ts",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"cojson": "workspace:0.8.35",
|
||||
"jazz-browser": "workspace:0.8.35",
|
||||
"jazz-tools": "workspace:0.8.35"
|
||||
"cojson": "workspace:0.8.36",
|
||||
"jazz-browser": "workspace:0.8.36",
|
||||
"jazz-tools": "workspace:0.8.36"
|
||||
},
|
||||
"scripts": {
|
||||
"format-and-lint": "biome check .",
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
# jazz-browser-media-images
|
||||
|
||||
## 0.8.36
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [441fe27]
|
||||
- jazz-tools@0.8.36
|
||||
- jazz-browser@0.8.36
|
||||
|
||||
## 0.8.35
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "jazz-browser-media-images",
|
||||
"version": "0.8.35",
|
||||
"version": "0.8.36",
|
||||
"type": "module",
|
||||
"main": "dist/index.js",
|
||||
"types": "src/index.ts",
|
||||
@@ -8,8 +8,8 @@
|
||||
"dependencies": {
|
||||
"@types/image-blob-reduce": "^4.1.1",
|
||||
"image-blob-reduce": "^4.1.0",
|
||||
"jazz-browser": "workspace:0.8.35",
|
||||
"jazz-tools": "workspace:0.8.35",
|
||||
"jazz-browser": "workspace:0.8.36",
|
||||
"jazz-tools": "workspace:0.8.36",
|
||||
"pica": "^9.0.1",
|
||||
"typescript": "^5.3.3"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,16 @@
|
||||
# jazz-browser
|
||||
|
||||
## 0.8.36
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [441fe27]
|
||||
- Updated dependencies [1afbd2c]
|
||||
- cojson@0.8.36
|
||||
- jazz-tools@0.8.36
|
||||
- cojson-storage-indexeddb@0.8.36
|
||||
- cojson-transport-ws@0.8.36
|
||||
|
||||
## 0.8.35
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
{
|
||||
"name": "jazz-browser",
|
||||
"version": "0.8.35",
|
||||
"version": "0.8.36",
|
||||
"type": "module",
|
||||
"main": "dist/index.js",
|
||||
"types": "src/index.ts",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@scure/bip39": "^1.3.0",
|
||||
"cojson": "workspace:0.8.35",
|
||||
"cojson-storage-indexeddb": "workspace:0.8.35",
|
||||
"cojson-transport-ws": "workspace:0.8.35",
|
||||
"jazz-tools": "workspace:0.8.35",
|
||||
"cojson": "workspace:0.8.36",
|
||||
"cojson-storage-indexeddb": "workspace:0.8.36",
|
||||
"cojson-transport-ws": "workspace:0.8.36",
|
||||
"jazz-tools": "workspace:0.8.36",
|
||||
"typescript": "^5.3.3"
|
||||
},
|
||||
"scripts": {
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
# jazz-autosub
|
||||
|
||||
## 0.8.36
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [441fe27]
|
||||
- cojson@0.8.36
|
||||
- jazz-tools@0.8.36
|
||||
- cojson-transport-ws@0.8.36
|
||||
|
||||
## 0.8.35
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -5,11 +5,11 @@
|
||||
"types": "src/index.ts",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
"version": "0.8.35",
|
||||
"version": "0.8.36",
|
||||
"dependencies": {
|
||||
"cojson": "workspace:0.8.35",
|
||||
"cojson-transport-ws": "workspace:0.8.35",
|
||||
"jazz-tools": "workspace:0.8.35",
|
||||
"cojson": "workspace:0.8.36",
|
||||
"cojson-transport-ws": "workspace:0.8.36",
|
||||
"jazz-tools": "workspace:0.8.36",
|
||||
"ws": "^8.14.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -1,5 +1,15 @@
|
||||
# jazz-browser-media-images
|
||||
|
||||
## 0.8.36
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [441fe27]
|
||||
- cojson@0.8.36
|
||||
- jazz-tools@0.8.36
|
||||
- jazz-browser-auth-clerk@0.8.36
|
||||
- jazz-react@0.8.36
|
||||
|
||||
## 0.8.35
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
{
|
||||
"name": "jazz-react-auth-clerk",
|
||||
"version": "0.8.35",
|
||||
"version": "0.8.36",
|
||||
"type": "module",
|
||||
"main": "dist/index.js",
|
||||
"types": "src/index.tsx",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"cojson": "workspace:0.8.35",
|
||||
"jazz-browser-auth-clerk": "workspace:0.8.35",
|
||||
"jazz-react": "workspace:0.8.35",
|
||||
"jazz-tools": "workspace:0.8.35"
|
||||
"cojson": "workspace:0.8.36",
|
||||
"jazz-browser-auth-clerk": "workspace:0.8.36",
|
||||
"jazz-react": "workspace:0.8.36",
|
||||
"jazz-tools": "workspace:0.8.36"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^18.2.0"
|
||||
|
||||
171
packages/jazz-react-native-auth-clerk/.gitignore
vendored
Normal file
171
packages/jazz-react-native-auth-clerk/.gitignore
vendored
Normal file
@@ -0,0 +1,171 @@
|
||||
# Based on https://raw.githubusercontent.com/github/gitignore/main/Node.gitignore
|
||||
|
||||
# Logs
|
||||
|
||||
logs
|
||||
_.log
|
||||
npm-debug.log_
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
lerna-debug.log*
|
||||
.pnpm-debug.log*
|
||||
|
||||
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||
|
||||
report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json
|
||||
|
||||
# Runtime data
|
||||
|
||||
pids
|
||||
_.pid
|
||||
_.seed
|
||||
\*.pid.lock
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
|
||||
coverage
|
||||
\*.lcov
|
||||
|
||||
# nyc test coverage
|
||||
|
||||
.nyc_output
|
||||
|
||||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||
|
||||
.grunt
|
||||
|
||||
# Bower dependency directory (https://bower.io/)
|
||||
|
||||
bower_components
|
||||
|
||||
# node-waf configuration
|
||||
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||
|
||||
build/Release
|
||||
|
||||
# Dependency directories
|
||||
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
|
||||
# Snowpack dependency directory (https://snowpack.dev/)
|
||||
|
||||
web_modules/
|
||||
|
||||
# TypeScript cache
|
||||
|
||||
\*.tsbuildinfo
|
||||
|
||||
# Optional npm cache directory
|
||||
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
|
||||
.eslintcache
|
||||
|
||||
# Optional stylelint cache
|
||||
|
||||
.stylelintcache
|
||||
|
||||
# Microbundle cache
|
||||
|
||||
.rpt2_cache/
|
||||
.rts2_cache_cjs/
|
||||
.rts2_cache_es/
|
||||
.rts2_cache_umd/
|
||||
|
||||
# Optional REPL history
|
||||
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
|
||||
\*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variable files
|
||||
|
||||
.env
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
.env.local
|
||||
|
||||
# parcel-bundler cache (https://parceljs.org/)
|
||||
|
||||
.cache
|
||||
.parcel-cache
|
||||
|
||||
# Next.js build output
|
||||
|
||||
.next
|
||||
out
|
||||
|
||||
# Nuxt.js build / generate output
|
||||
|
||||
.nuxt
|
||||
dist
|
||||
|
||||
# Gatsby files
|
||||
|
||||
.cache/
|
||||
|
||||
# Comment in the public line in if your project uses Gatsby and not Next.js
|
||||
|
||||
# https://nextjs.org/blog/next-9-1#public-directory-support
|
||||
|
||||
# public
|
||||
|
||||
# vuepress build output
|
||||
|
||||
.vuepress/dist
|
||||
|
||||
# vuepress v2.x temp and cache directory
|
||||
|
||||
.temp
|
||||
.cache
|
||||
|
||||
# Docusaurus cache and generated files
|
||||
|
||||
.docusaurus
|
||||
|
||||
# Serverless directories
|
||||
|
||||
.serverless/
|
||||
|
||||
# FuseBox cache
|
||||
|
||||
.fusebox/
|
||||
|
||||
# DynamoDB Local files
|
||||
|
||||
.dynamodb/
|
||||
|
||||
# TernJS port file
|
||||
|
||||
.tern-port
|
||||
|
||||
# Stores VSCode versions used for testing VSCode extensions
|
||||
|
||||
.vscode-test
|
||||
|
||||
# yarn v2
|
||||
|
||||
.yarn/cache
|
||||
.yarn/unplugged
|
||||
.yarn/build-state.yml
|
||||
.yarn/install-state.gz
|
||||
.pnp.\*
|
||||
|
||||
.DS_Store
|
||||
2
packages/jazz-react-native-auth-clerk/.npmignore
Normal file
2
packages/jazz-react-native-auth-clerk/.npmignore
Normal file
@@ -0,0 +1,2 @@
|
||||
coverage
|
||||
node_modules
|
||||
12
packages/jazz-react-native-auth-clerk/CHANGELOG.md
Normal file
12
packages/jazz-react-native-auth-clerk/CHANGELOG.md
Normal file
@@ -0,0 +1,12 @@
|
||||
# jazz-react-native-auth-clerk
|
||||
|
||||
## 0.8.36
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- c84764a: feat: added jazz-react-native-auth-clerk package
|
||||
- Updated dependencies [c84764a]
|
||||
- Updated dependencies [441fe27]
|
||||
- jazz-react-native@0.8.36
|
||||
- cojson@0.8.36
|
||||
- jazz-tools@0.8.36
|
||||
19
packages/jazz-react-native-auth-clerk/LICENSE.txt
Normal file
19
packages/jazz-react-native-auth-clerk/LICENSE.txt
Normal file
@@ -0,0 +1,19 @@
|
||||
Copyright 2024, Garden Computing, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
31
packages/jazz-react-native-auth-clerk/README.md
Normal file
31
packages/jazz-react-native-auth-clerk/README.md
Normal file
@@ -0,0 +1,31 @@
|
||||
# `jazz-react-native-auth-clerk`
|
||||
|
||||
This package provides a [Clerk-based](https://clerk.com/) authentication strategy for Jazz.
|
||||
|
||||
Looking for a React integration? Check out [`jazz-react-auth-clerk`](https://www.npmjs.com/package/jazz-react-native-auth-clerk).
|
||||
|
||||
## Usage
|
||||
|
||||
`ReactNativeClerkAuth` is a class that provides a `JazzAuth` object. Provide a Clerk instance to `ReactNativeClerkAuth`, and it will return the appropriate `JazzAuth` object. Once authenticated, authentication will persist across page reloads, even if the device is offline.
|
||||
|
||||
|
||||
From [the example app](https://github.com/gardencmp/jazz/tree/main/examples/chat-rn-clerk):
|
||||
|
||||
```ts
|
||||
import { ReactNativeClerkAuth } from "jazz-react-native-auth-clerk";
|
||||
|
||||
// ...
|
||||
|
||||
const auth = new ReactNativeClerkAuth(
|
||||
{
|
||||
onError: (error) => {
|
||||
void clerk.signOut();
|
||||
setState((state) => ({
|
||||
...state,
|
||||
errors: [...state.errors, error.toString()],
|
||||
}));
|
||||
},
|
||||
},
|
||||
clerk,
|
||||
);
|
||||
```
|
||||
24
packages/jazz-react-native-auth-clerk/package.json
Normal file
24
packages/jazz-react-native-auth-clerk/package.json
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"name": "jazz-react-native-auth-clerk",
|
||||
"version": "0.8.36",
|
||||
"type": "module",
|
||||
"main": "dist/index.js",
|
||||
"types": "src/index.ts",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"cojson": "workspace:*",
|
||||
"jazz-tools": "workspace:*",
|
||||
"jazz-react-native": "workspace:*"
|
||||
},
|
||||
"scripts": {
|
||||
"format-and-lint": "biome check .",
|
||||
"format-and-lint:fix": "biome check . --write",
|
||||
"build": "rm -rf ./dist && tsc --sourceMap --outDir dist",
|
||||
"prepublishOnly": "npm run build",
|
||||
"test": "vitest --run --root ../../ --project jazz-react-native-auth-clerk",
|
||||
"test:watch": "vitest --watch --root ../../ --project jazz-react-native-auth-clerk"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "^5.3.3"
|
||||
}
|
||||
}
|
||||
168
packages/jazz-react-native-auth-clerk/src/index.ts
Normal file
168
packages/jazz-react-native-auth-clerk/src/index.ts
Normal file
@@ -0,0 +1,168 @@
|
||||
import { AgentSecret } from "cojson";
|
||||
import type { KvStore } from "jazz-react-native";
|
||||
import { Account, AuthMethod, AuthResult, Credentials, ID } from "jazz-tools";
|
||||
|
||||
const localStorageKey = "jazz-clerk-auth";
|
||||
|
||||
export type MinimalClerkClient = {
|
||||
user:
|
||||
| {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
unsafeMetadata: Record<string, any>;
|
||||
fullName: string | null;
|
||||
username: string | null;
|
||||
id: string;
|
||||
update: (args: {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
unsafeMetadata: Record<string, any>;
|
||||
}) => Promise<unknown>;
|
||||
}
|
||||
| null
|
||||
| undefined;
|
||||
signOut: () => Promise<void>;
|
||||
};
|
||||
|
||||
function saveCredentialsToStorage(kvStore: KvStore, credentials: Credentials) {
|
||||
kvStore.set(
|
||||
localStorageKey,
|
||||
JSON.stringify({
|
||||
accountID: credentials.accountID,
|
||||
secret: credentials.secret,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
export class ReactNativeClerkAuth implements AuthMethod {
|
||||
constructor(
|
||||
public driver: ReactNativeClerkAuth.Driver,
|
||||
private readonly clerkClient: MinimalClerkClient,
|
||||
private readonly kvStore: KvStore,
|
||||
) {}
|
||||
|
||||
async start(): Promise<AuthResult> {
|
||||
// Check local storage for credentials
|
||||
const locallyStoredCredentials = await this.kvStore.get(localStorageKey);
|
||||
|
||||
if (locallyStoredCredentials) {
|
||||
try {
|
||||
const credentials = JSON.parse(locallyStoredCredentials) as Credentials;
|
||||
return {
|
||||
type: "existing",
|
||||
credentials,
|
||||
saveCredentials: async () => {}, // No need to save credentials when recovering from local storage
|
||||
onSuccess: () => {},
|
||||
onError: (error: string | Error) => {
|
||||
this.driver.onError(error);
|
||||
},
|
||||
logOut: () => {
|
||||
void this.kvStore.delete(localStorageKey);
|
||||
void this.clerkClient.signOut();
|
||||
},
|
||||
};
|
||||
} catch (e) {
|
||||
console.error("Error parsing local storage credentials", e);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.clerkClient.user) {
|
||||
// Check clerk user metadata for credentials
|
||||
const storedCredentials = this.clerkClient.user.unsafeMetadata;
|
||||
if (storedCredentials.jazzAccountID) {
|
||||
if (!storedCredentials.jazzAccountSecret) {
|
||||
throw new Error("No secret for existing user");
|
||||
}
|
||||
return {
|
||||
type: "existing",
|
||||
credentials: {
|
||||
accountID: storedCredentials.jazzAccountID as ID<Account>,
|
||||
secret: storedCredentials.jazzAccountSecret as AgentSecret,
|
||||
},
|
||||
saveCredentials: async ({ accountID, secret }: Credentials) => {
|
||||
saveCredentialsToStorage(this.kvStore, {
|
||||
accountID,
|
||||
secret,
|
||||
});
|
||||
},
|
||||
onSuccess: () => {},
|
||||
onError: (error: string | Error) => {
|
||||
this.driver.onError(error);
|
||||
},
|
||||
logOut: () => {
|
||||
void this.clerkClient.signOut();
|
||||
},
|
||||
};
|
||||
} else {
|
||||
// No credentials found, so we need to create new credentials
|
||||
return {
|
||||
type: "new",
|
||||
creationProps: {
|
||||
name:
|
||||
this.clerkClient.user.fullName ||
|
||||
this.clerkClient.user.username ||
|
||||
this.clerkClient.user.id,
|
||||
},
|
||||
saveCredentials: async ({ accountID, secret }: Credentials) => {
|
||||
saveCredentialsToStorage(this.kvStore, {
|
||||
accountID,
|
||||
secret,
|
||||
});
|
||||
await this.clerkClient.user?.update({
|
||||
unsafeMetadata: {
|
||||
jazzAccountID: accountID,
|
||||
jazzAccountSecret: secret,
|
||||
},
|
||||
});
|
||||
},
|
||||
onSuccess: () => {},
|
||||
onError: (error: string | Error) => {
|
||||
this.driver.onError(error);
|
||||
},
|
||||
logOut: () => {
|
||||
void this.clerkClient.signOut();
|
||||
},
|
||||
};
|
||||
}
|
||||
} else {
|
||||
// Clerk user not found, so we can't authenticate
|
||||
throw new Error("Not signed in");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-namespace
|
||||
export namespace ReactNativeClerkAuth {
|
||||
export interface Driver {
|
||||
onError: (error: string | Error) => void;
|
||||
}
|
||||
}
|
||||
|
||||
////
|
||||
|
||||
import { useMemo, useState } from "react";
|
||||
|
||||
export function useJazzClerkAuth(
|
||||
clerk: MinimalClerkClient & {
|
||||
signOut: () => Promise<unknown>;
|
||||
},
|
||||
kvStore: KvStore,
|
||||
) {
|
||||
const [state, setState] = useState<{ errors: string[] }>({ errors: [] });
|
||||
|
||||
const authMethod = useMemo(() => {
|
||||
return new ReactNativeClerkAuth(
|
||||
{
|
||||
onError: (error) => {
|
||||
void clerk.signOut();
|
||||
setState((state) => ({
|
||||
...state,
|
||||
errors: [...state.errors, error.toString()],
|
||||
}));
|
||||
},
|
||||
},
|
||||
clerk,
|
||||
kvStore,
|
||||
);
|
||||
}, [clerk.user]);
|
||||
|
||||
return [authMethod, state] as const;
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
import { AgentSecret } from "cojson";
|
||||
import type { KvStore } from "jazz-react-native";
|
||||
import { Account, ID } from "jazz-tools";
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { MinimalClerkClient, ReactNativeClerkAuth } from "../index.js";
|
||||
|
||||
describe("ReactNativeClerkAuth", () => {
|
||||
let mockLocalStorage: { [key: string]: string };
|
||||
let mockClerkClient: MinimalClerkClient;
|
||||
let mockDriver: ReactNativeClerkAuth.Driver;
|
||||
let mockKvStore: KvStore;
|
||||
|
||||
beforeEach(() => {
|
||||
// Mock in-memory NativeStorage
|
||||
mockLocalStorage = {};
|
||||
mockKvStore = {
|
||||
get: vi.fn(async (key: string) => mockLocalStorage[key] || null),
|
||||
set: vi.fn(async (key: string, value: string) => {
|
||||
mockLocalStorage[key] = value;
|
||||
}),
|
||||
delete: vi.fn(async (key: string) => {
|
||||
delete mockLocalStorage[key];
|
||||
}),
|
||||
clearAll: vi.fn(async () => {
|
||||
mockLocalStorage = {};
|
||||
}),
|
||||
};
|
||||
|
||||
// Mock Clerk client
|
||||
mockClerkClient = {
|
||||
user: {
|
||||
unsafeMetadata: {},
|
||||
fullName: "Test User",
|
||||
username: "testuser",
|
||||
id: "test-id",
|
||||
update: vi.fn(),
|
||||
},
|
||||
signOut: vi.fn(),
|
||||
};
|
||||
|
||||
// Mock driver
|
||||
mockDriver = {
|
||||
onError: vi.fn(),
|
||||
};
|
||||
});
|
||||
|
||||
describe("clerk credentials in NativeStorage", () => {
|
||||
it("should get credentials from NativeStorage when clerk user is not signed in", async () => {
|
||||
await mockKvStore.set(
|
||||
"jazz-clerk-auth",
|
||||
JSON.stringify({
|
||||
accountID: "test-account-id",
|
||||
accountSecret: "test-secret",
|
||||
}),
|
||||
);
|
||||
|
||||
const auth = new ReactNativeClerkAuth(
|
||||
mockDriver,
|
||||
{
|
||||
...mockClerkClient,
|
||||
user: null,
|
||||
},
|
||||
mockKvStore,
|
||||
);
|
||||
|
||||
const result = await auth.start();
|
||||
expect(result.type).toBe("existing");
|
||||
});
|
||||
});
|
||||
|
||||
describe("clerk credentials not in NativeStorage", () => {
|
||||
it("should return new credentials when clerk user signs up", async () => {
|
||||
const auth = new ReactNativeClerkAuth(
|
||||
mockDriver,
|
||||
mockClerkClient,
|
||||
mockKvStore,
|
||||
);
|
||||
const result = await auth.start();
|
||||
expect(result.type).toBe("new");
|
||||
});
|
||||
|
||||
it("should return existing credentials when clerk user is signed in", async () => {
|
||||
mockClerkClient = {
|
||||
user: {
|
||||
unsafeMetadata: {
|
||||
jazzAccountID: "test-account-id",
|
||||
jazzAccountSecret: "test-secret",
|
||||
},
|
||||
fullName: "Test User",
|
||||
username: "testuser",
|
||||
id: "test-id",
|
||||
update: vi.fn(),
|
||||
},
|
||||
signOut: vi.fn(),
|
||||
};
|
||||
|
||||
const auth = new ReactNativeClerkAuth(
|
||||
mockDriver,
|
||||
mockClerkClient,
|
||||
mockKvStore,
|
||||
);
|
||||
const result = await auth.start();
|
||||
expect(result.type).toBe("existing");
|
||||
});
|
||||
|
||||
it("should throw error when not signed in", async () => {
|
||||
const auth = new ReactNativeClerkAuth(
|
||||
mockDriver,
|
||||
{
|
||||
...mockClerkClient,
|
||||
user: null,
|
||||
},
|
||||
mockKvStore,
|
||||
);
|
||||
|
||||
await expect(auth.start()).rejects.toThrow("Not signed in");
|
||||
});
|
||||
|
||||
it("should save credentials to NativeStorage", async () => {
|
||||
const auth = new ReactNativeClerkAuth(
|
||||
mockDriver,
|
||||
mockClerkClient,
|
||||
mockKvStore,
|
||||
);
|
||||
const result = await auth.start();
|
||||
if (result.saveCredentials) {
|
||||
await result.saveCredentials({
|
||||
accountID: "test-account-id" as ID<Account>,
|
||||
secret: "test-secret" as AgentSecret,
|
||||
});
|
||||
}
|
||||
|
||||
expect(await mockKvStore.get("jazz-clerk-auth")).toBeDefined();
|
||||
});
|
||||
|
||||
it("should call clerk signOut when logging out", async () => {
|
||||
const auth = new ReactNativeClerkAuth(
|
||||
mockDriver,
|
||||
mockClerkClient,
|
||||
mockKvStore,
|
||||
);
|
||||
const result = await auth.start();
|
||||
result.logOut();
|
||||
|
||||
expect(mockClerkClient.signOut).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
16
packages/jazz-react-native-auth-clerk/tsconfig.json
Normal file
16
packages/jazz-react-native-auth-clerk/tsconfig.json
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"lib": ["ESNext", "DOM"],
|
||||
"module": "esnext",
|
||||
"target": "ES2020",
|
||||
"moduleResolution": "bundler",
|
||||
"moduleDetection": "force",
|
||||
"strict": true,
|
||||
"skipLibCheck": true,
|
||||
"jsx": "react",
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"noUncheckedIndexedAccess": true,
|
||||
"esModuleInterop": true
|
||||
},
|
||||
"include": ["./src/**/*"]
|
||||
}
|
||||
@@ -1,5 +1,12 @@
|
||||
# jazz-browser-media-images
|
||||
|
||||
## 0.8.27
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [441fe27]
|
||||
- jazz-tools@0.8.36
|
||||
|
||||
## 0.8.26
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "jazz-react-native-media-images",
|
||||
"version": "0.8.26",
|
||||
"version": "0.8.27",
|
||||
"type": "module",
|
||||
"main": "dist/index.js",
|
||||
"types": "src/index.ts",
|
||||
|
||||
@@ -1,5 +1,15 @@
|
||||
# jazz-browser
|
||||
|
||||
## 0.8.36
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- c84764a: feat: added jazz-react-native-auth-clerk package
|
||||
- Updated dependencies [441fe27]
|
||||
- cojson@0.8.36
|
||||
- jazz-tools@0.8.36
|
||||
- cojson-transport-ws@0.8.36
|
||||
|
||||
## 0.8.35
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -25,7 +25,7 @@ npx expo prebuild
|
||||
### Install dependencies
|
||||
|
||||
```bash
|
||||
npx expo install expo-linking expo-secure-store expo-file-system @react-native-community/netinfo @bam.tech/react-native-image-resizer
|
||||
npx expo install expo-linking expo-secure-store expo-file-system @react-native-community/netinfo @bam.tech/react-native-image-resizer @azure/core-asynciterator-polyfill
|
||||
|
||||
npm i -S react-native-polyfill-globals react-native-url-polyfill web-streams-polyfill base-64 text-encoding react-native-fetch-api react-native-get-random-values buffer
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "jazz-react-native",
|
||||
"version": "0.8.35",
|
||||
"version": "0.8.36",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
|
||||
@@ -26,27 +26,27 @@ export { RNDemoAuth } from "./auth/DemoAuthMethod.js";
|
||||
import { KvStoreContext } from "./storage/kv-store-context.js";
|
||||
|
||||
/** @category Context Creation */
|
||||
export type BrowserContext<Acc extends Account> = {
|
||||
export type ReactNativeContext<Acc extends Account> = {
|
||||
me: Acc;
|
||||
logOut: () => void;
|
||||
// TODO: Symbol.dispose?
|
||||
done: () => void;
|
||||
};
|
||||
|
||||
export type BrowserGuestContext = {
|
||||
export type ReactNativeGuestContext = {
|
||||
guest: AnonymousJazzAgent;
|
||||
logOut: () => void;
|
||||
done: () => void;
|
||||
};
|
||||
|
||||
export type BrowserContextOptions<Acc extends Account> = {
|
||||
export type ReactNativeContextOptions<Acc extends Account> = {
|
||||
auth: AuthMethod;
|
||||
AccountSchema: CoValueClass<Acc> & {
|
||||
fromNode: (typeof Account)["fromNode"];
|
||||
};
|
||||
} & BaseBrowserContextOptions;
|
||||
} & BaseReactNativeContextOptions;
|
||||
|
||||
export type BaseBrowserContextOptions = {
|
||||
export type BaseReactNativeContextOptions = {
|
||||
peer: `wss://${string}` | `ws://${string}`;
|
||||
reconnectionTimeout?: number;
|
||||
storage?: "indexedDB" | "singleTabOPFS";
|
||||
@@ -55,17 +55,17 @@ export type BaseBrowserContextOptions = {
|
||||
|
||||
/** @category Context Creation */
|
||||
export async function createJazzRNContext<Acc extends Account>(
|
||||
options: BrowserContextOptions<Acc>,
|
||||
): Promise<BrowserContext<Acc>>;
|
||||
options: ReactNativeContextOptions<Acc>,
|
||||
): Promise<ReactNativeContext<Acc>>;
|
||||
export async function createJazzRNContext(
|
||||
options: BaseBrowserContextOptions,
|
||||
): Promise<BrowserGuestContext>;
|
||||
options: BaseReactNativeContextOptions,
|
||||
): Promise<ReactNativeGuestContext>;
|
||||
export async function createJazzRNContext<Acc extends Account>(
|
||||
options: BrowserContextOptions<Acc> | BaseBrowserContextOptions,
|
||||
): Promise<BrowserContext<Acc> | BrowserGuestContext>;
|
||||
options: ReactNativeContextOptions<Acc> | BaseReactNativeContextOptions,
|
||||
): Promise<ReactNativeContext<Acc> | ReactNativeGuestContext>;
|
||||
export async function createJazzRNContext<Acc extends Account>(
|
||||
options: BrowserContextOptions<Acc> | BaseBrowserContextOptions,
|
||||
): Promise<BrowserContext<Acc> | BrowserGuestContext> {
|
||||
options: ReactNativeContextOptions<Acc> | BaseReactNativeContextOptions,
|
||||
): Promise<ReactNativeContext<Acc> | ReactNativeGuestContext> {
|
||||
const firstWsPeer = createWebSocketPeer({
|
||||
websocket: new WebSocket(options.peer),
|
||||
id: options.peer + "@" + new Date().toISOString(),
|
||||
@@ -192,15 +192,6 @@ export async function provideLockSession(
|
||||
});
|
||||
}
|
||||
|
||||
const window = {
|
||||
location: {
|
||||
href: "#",
|
||||
},
|
||||
history: {
|
||||
replaceState: (a: any, b: any, c: any) => {},
|
||||
},
|
||||
};
|
||||
|
||||
/** @category Invite Links */
|
||||
export function createInviteLink<C extends CoValue>(
|
||||
value: C,
|
||||
|
||||
@@ -14,9 +14,10 @@ import {
|
||||
} from "jazz-tools";
|
||||
import { Linking } from "react-native";
|
||||
import {
|
||||
BrowserContext,
|
||||
BrowserGuestContext,
|
||||
KvStore,
|
||||
KvStoreContext,
|
||||
ReactNativeContext,
|
||||
ReactNativeGuestContext,
|
||||
createJazzRNContext,
|
||||
parseInviteLink,
|
||||
} from "./index.js";
|
||||
@@ -28,7 +29,7 @@ export function createJazzRNApp<Acc extends Account>({
|
||||
AccountSchema = Account as unknown as AccountClass<Acc>,
|
||||
} = {}): JazzReactApp<Acc> {
|
||||
const JazzContext = React.createContext<
|
||||
BrowserContext<Acc> | BrowserGuestContext | undefined
|
||||
ReactNativeContext<Acc> | ReactNativeGuestContext | undefined
|
||||
>(undefined);
|
||||
|
||||
if (!kvStore) {
|
||||
@@ -49,7 +50,7 @@ export function createJazzRNApp<Acc extends Account>({
|
||||
storage?: "indexedDB" | "singleTabOPFS";
|
||||
}) {
|
||||
const [ctx, setCtx] = useState<
|
||||
BrowserContext<Acc> | BrowserGuestContext | undefined
|
||||
ReactNativeContext<Acc> | ReactNativeGuestContext | undefined
|
||||
>();
|
||||
|
||||
const [sessionCount, setSessionCount] = useState(0);
|
||||
@@ -80,7 +81,11 @@ export function createJazzRNApp<Acc extends Account>({
|
||||
});
|
||||
|
||||
return () => {
|
||||
void promiseWithDoneCallback.then((done) => done());
|
||||
void promiseWithDoneCallback
|
||||
.then((done) => done())
|
||||
.catch((e) => {
|
||||
console.error("Error in createJazzRNContext", e);
|
||||
});
|
||||
};
|
||||
}, [AccountSchema, auth, peer, storage, sessionCount]);
|
||||
|
||||
@@ -240,6 +245,7 @@ export function createJazzRNApp<Acc extends Account>({
|
||||
useAccountOrGuest,
|
||||
useCoState,
|
||||
useAcceptInvite,
|
||||
kvStore,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -293,6 +299,8 @@ export interface JazzReactApp<Acc extends Account> {
|
||||
onAccept: (projectID: ID<V>) => void;
|
||||
forValueHint?: string;
|
||||
}): void;
|
||||
|
||||
kvStore: KvStore;
|
||||
}
|
||||
|
||||
export * from "./media.js";
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
# jazz-react
|
||||
|
||||
## 0.8.36
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [441fe27]
|
||||
- cojson@0.8.36
|
||||
- jazz-tools@0.8.36
|
||||
- jazz-browser@0.8.36
|
||||
|
||||
## 0.8.35
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
{
|
||||
"name": "jazz-react",
|
||||
"version": "0.8.35",
|
||||
"version": "0.8.36",
|
||||
"type": "module",
|
||||
"main": "dist/index.js",
|
||||
"types": "src/index.ts",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@scure/bip39": "^1.3.0",
|
||||
"cojson": "workspace:0.8.35",
|
||||
"jazz-browser": "workspace:0.8.35",
|
||||
"jazz-tools": "workspace:0.8.35"
|
||||
"cojson": "workspace:0.8.36",
|
||||
"jazz-browser": "workspace:0.8.36",
|
||||
"jazz-tools": "workspace:0.8.36"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react": "^18.2.19",
|
||||
|
||||
@@ -1,5 +1,16 @@
|
||||
# jazz-run
|
||||
|
||||
## 0.8.36
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [441fe27]
|
||||
- Updated dependencies [1afbd2c]
|
||||
- cojson@0.8.36
|
||||
- jazz-tools@0.8.36
|
||||
- cojson-storage-sqlite@0.8.36
|
||||
- cojson-transport-ws@0.8.36
|
||||
|
||||
## 0.8.35
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"bin": "./dist/index.js",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
"version": "0.8.35",
|
||||
"version": "0.8.36",
|
||||
"scripts": {
|
||||
"format-and-lint": "biome check .",
|
||||
"format-and-lint:fix": "biome check . --write",
|
||||
@@ -18,11 +18,11 @@
|
||||
"@effect/printer-ansi": "^0.34.5",
|
||||
"@effect/schema": "^0.71.1",
|
||||
"@effect/typeclass": "^0.25.5",
|
||||
"cojson": "workspace:0.8.35",
|
||||
"cojson-storage-sqlite": "workspace:0.8.35",
|
||||
"cojson-transport-ws": "workspace:0.8.35",
|
||||
"cojson": "workspace:0.8.36",
|
||||
"cojson-storage-sqlite": "workspace:0.8.36",
|
||||
"cojson-transport-ws": "workspace:0.8.36",
|
||||
"effect": "^3.6.5",
|
||||
"jazz-tools": "workspace:0.8.35",
|
||||
"jazz-tools": "workspace:0.8.36",
|
||||
"ws": "^8.14.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
# jazz-svelte
|
||||
|
||||
## 0.0.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [441fe27]
|
||||
- jazz-tools@0.8.36
|
||||
- jazz-browser@0.8.36
|
||||
|
||||
## 0.0.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "jazz-svelte",
|
||||
"version": "0.0.2",
|
||||
"version": "0.0.3",
|
||||
"scripts": {
|
||||
"dev": "vite dev",
|
||||
"build": "vite build && npm run package",
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
# jazz-tools
|
||||
|
||||
## 0.8.36
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 441fe27: Optimise large record-like CoMaps for access of latest value
|
||||
- Updated dependencies [441fe27]
|
||||
- cojson@0.8.36
|
||||
|
||||
## 0.8.35
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
},
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
"version": "0.8.35",
|
||||
"version": "0.8.36",
|
||||
"dependencies": {
|
||||
"cojson": "workspace:*",
|
||||
"fast-check": "^3.17.2"
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user