Compare commits

..

12 Commits

Author SHA1 Message Date
Guido D'Orsi
36273b3114 chore: changeset 2024-11-04 23:09:34 +01:00
Guido D'Orsi
51a0a9f23f perf: optimize _loadedAs in CoList and CoValueBase 2024-11-04 23:07:51 +01:00
Anselm Eickhoff
fc24a65264 Merge pull request #685 from gardencmp/changeset-release/main
Version Packages
2024-11-04 20:10:10 +00:00
github-actions[bot]
fa0b9003dc Version Packages 2024-11-04 20:05:27 +00:00
Anselm Eickhoff
8a0da655e8 Merge pull request #686 from gardencmp/optimize-account-loadas
perf: cache the account refs resolution
2024-11-04 20:04:15 +00:00
Guido D'Orsi
fff11daca7 test: add tests for cache 2024-11-04 20:41:36 +01:00
Guido D'Orsi
fd011d76f4 chore: changeset 2024-11-04 20:21:32 +01:00
Guido D'Orsi
0681a8301e perf: cache the account refs resolution 2024-11-04 20:09:34 +01:00
Anselm Eickhoff
8823957c6e Merge pull request #677 from gardencmp/feature/websocker-unique-name
feat(browser): refactor the WebSocket reconnection to assign the peer as id
2024-11-04 16:58:17 +00:00
Guido D'Orsi
e0dd0065fb chore: changeset 2024-11-04 15:06:33 +01:00
Guido D'Orsi
98d7d402eb feat(browser): refactor the WebSocket reconnection to assign the peer as id 2024-11-04 14:28:11 +01:00
Anselm
d2ad2db930 Fix anselm's bluesky 2024-11-01 15:17:55 +00:00
62 changed files with 781 additions and 257 deletions

View File

@@ -0,0 +1,5 @@
---
"jazz-tools": patch
---
Cache other usages of Account.fromRaw

View File

@@ -1,5 +1,13 @@
# @jazz-e2e/binarycostream
## 0.0.91
### Patch Changes
- Updated dependencies [fd011d7]
- jazz-tools@0.8.13
- jazz-react@0.8.13
## 0.0.90
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "@jazz-e2e/binarycostream",
"private": true,
"version": "0.0.90",
"version": "0.0.91",
"type": "module",
"scripts": {
"dev": "vite",
@@ -17,8 +17,8 @@
"cojson": "workspace:0.8.12",
"hash-slash": "workspace:0.2.1",
"is-ci": "^3.0.1",
"jazz-react": "workspace:0.8.12",
"jazz-tools": "workspace:0.8.12",
"jazz-react": "workspace:0.8.13",
"jazz-tools": "workspace:0.8.13",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},

View File

@@ -1,5 +1,13 @@
# @jazz-e2e/covalues
## 0.0.90
### Patch Changes
- Updated dependencies [fd011d7]
- jazz-tools@0.8.13
- jazz-react@0.8.13
## 0.0.89
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "@jazz-e2e/covalues",
"private": true,
"version": "0.0.89",
"version": "0.0.90",
"type": "module",
"scripts": {
"dev": "vite",

View File

@@ -1,5 +1,14 @@
# jazz-example-book-shelf
## 0.1.6
### Patch Changes
- Updated dependencies [fd011d7]
- jazz-tools@0.8.13
- jazz-browser-media-images@0.8.13
- jazz-react@0.8.13
## 0.1.5
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "jazz-example-book-shelf",
"version": "0.1.5",
"version": "0.1.6",
"private": true,
"scripts": {
"dev": "next dev",
@@ -11,9 +11,9 @@
},
"dependencies": {
"clsx": "^2.0.0",
"jazz-browser-media-images": "workspace:0.8.12",
"jazz-react": "workspace:0.8.12",
"jazz-tools": "workspace:0.8.12",
"jazz-browser-media-images": "workspace:0.8.13",
"jazz-react": "workspace:0.8.13",
"jazz-tools": "workspace:0.8.13",
"next": "14.2.5",
"react": "^18.2.0",
"react-dom": "^18.2.0"

View File

@@ -1,5 +1,14 @@
# jazz-example-chat
## 0.0.90
### Patch Changes
- Updated dependencies [fd011d7]
- jazz-tools@0.8.13
- jazz-react@0.8.13
- jazz-react-auth-clerk@0.8.13
## 0.0.89
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "jazz-example-chat-clerk",
"private": true,
"version": "0.0.89",
"version": "0.0.90",
"type": "module",
"scripts": {
"dev": "vite",
@@ -23,9 +23,9 @@
"clsx": "^2.0.0",
"cojson": "workspace:0.8.12",
"hash-slash": "workspace:0.2.1",
"jazz-react": "workspace:0.8.12",
"jazz-react-auth-clerk": "workspace:0.8.12",
"jazz-tools": "workspace:0.8.12",
"jazz-react": "workspace:0.8.13",
"jazz-react-auth-clerk": "workspace:0.8.13",
"jazz-tools": "workspace:0.8.13",
"lucide-react": "^0.274.0",
"qrcode": "^1.5.3",
"react": "^18.2.0",

View File

@@ -1,5 +1,15 @@
# chat-rn-clerk
## 1.0.6
### Patch Changes
- Updated dependencies [fd011d7]
- jazz-tools@0.8.13
- jazz-react-auth-clerk@0.8.13
- jazz-react-native@0.8.13
- jazz-react-native-media-images@0.8.9
## 1.0.5
### Patch Changes

View File

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

View File

@@ -1,5 +1,13 @@
# chat-rn
## 1.0.8
### Patch Changes
- Updated dependencies [fd011d7]
- jazz-tools@0.8.13
- jazz-react-native@0.8.13
## 1.0.7
### Patch Changes

View File

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

View File

@@ -1,5 +1,13 @@
# jazz-example-chat
## 0.0.92
### Patch Changes
- Updated dependencies [fd011d7]
- jazz-tools@0.8.13
- jazz-react@0.8.13
## 0.0.91
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "jazz-example-chat",
"private": true,
"version": "0.0.91",
"version": "0.0.92",
"type": "module",
"scripts": {
"dev": "vite",
@@ -24,8 +24,8 @@
"clsx": "^2.0.0",
"cojson": "workspace:0.8.12",
"hash-slash": "workspace:0.2.1",
"jazz-react": "workspace:0.8.12",
"jazz-tools": "workspace:0.8.12",
"jazz-react": "workspace:0.8.13",
"jazz-tools": "workspace:0.8.13",
"lucide-react": "^0.274.0",
"qrcode": "^1.5.3",
"react": "^18.2.0",

View File

@@ -1,5 +1,12 @@
# jazz-example-inspector
## 0.0.68
### Patch Changes
- Updated dependencies [e0dd006]
- cojson-transport-ws@0.8.13
## 0.0.67
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "jazz-inspector",
"private": true,
"version": "0.0.67",
"version": "0.0.68",
"type": "module",
"scripts": {
"dev": "vite",
@@ -16,7 +16,7 @@
"class-variance-authority": "^0.7.0",
"clsx": "^2.0.0",
"cojson": "workspace:0.8.12",
"cojson-transport-ws": "workspace:0.8.12",
"cojson-transport-ws": "workspace:0.8.13",
"hash-slash": "workspace:0.2.1",
"lucide-react": "^0.274.0",
"qrcode": "^1.5.3",

View File

@@ -1,5 +1,13 @@
# jazz-example-musicplayer
## 0.0.12
### Patch Changes
- Updated dependencies [fd011d7]
- jazz-tools@0.8.13
- jazz-react@0.8.13
## 0.0.11
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "jazz-example-music-player",
"private": true,
"version": "0.0.11",
"version": "0.0.12",
"type": "module",
"scripts": {
"dev": "vite",
@@ -22,8 +22,8 @@
"@radix-ui/react-toast": "^1.1.4",
"class-variance-authority": "^0.7.0",
"clsx": "^2.0.0",
"jazz-react": "workspace:0.8.12",
"jazz-tools": "workspace:0.8.12",
"jazz-react": "workspace:0.8.13",
"jazz-tools": "workspace:0.8.13",
"lucide-react": "^0.274.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",

View File

@@ -1,5 +1,13 @@
# jazz-password-manager
## 0.0.11
### Patch Changes
- Updated dependencies [fd011d7]
- jazz-tools@0.8.13
- jazz-react@0.8.13
## 0.0.10
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "jazz-password-manager",
"private": true,
"version": "0.0.10",
"version": "0.0.11",
"type": "module",
"scripts": {
"dev": "vite",
@@ -11,8 +11,8 @@
"clean-install": "rm -rf node_modules pnpm-lock.yaml && pnpm install"
},
"dependencies": {
"jazz-react": "workspace:0.8.12",
"jazz-tools": "workspace:0.8.12",
"jazz-react": "workspace:0.8.13",
"jazz-tools": "workspace:0.8.13",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-hook-form": "^7.41.5",

View File

@@ -1,5 +1,14 @@
# jazz-example-pets
## 0.0.109
### Patch Changes
- Updated dependencies [fd011d7]
- jazz-tools@0.8.13
- jazz-browser-media-images@0.8.13
- jazz-react@0.8.13
## 0.0.108
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "jazz-example-pets",
"private": true,
"version": "0.0.108",
"version": "0.0.109",
"type": "module",
"scripts": {
"dev": "vite",
@@ -23,9 +23,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.12",
"jazz-react": "workspace:0.8.12",
"jazz-tools": "workspace:0.8.12",
"jazz-browser-media-images": "workspace:0.8.13",
"jazz-react": "workspace:0.8.13",
"jazz-tools": "workspace:0.8.13",
"lucide-react": "^0.274.0",
"qrcode": "^1.5.3",
"react": "^18.2.0",
@@ -50,7 +50,7 @@
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.3",
"is-ci": "^3.0.1",
"jazz-run": "workspace:0.8.12",
"jazz-run": "workspace:0.8.13",
"postcss": "^8.4.27",
"tailwindcss": "3.3.2",
"typescript": "^5.3.3",

View File

@@ -1,5 +1,13 @@
# jazz-example-todo
## 0.0.108
### Patch Changes
- Updated dependencies [fd011d7]
- jazz-tools@0.8.13
- jazz-react@0.8.13
## 0.0.107
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "jazz-example-todo",
"private": true,
"version": "0.0.107",
"version": "0.0.108",
"type": "module",
"scripts": {
"dev": "vite",
@@ -20,8 +20,8 @@
"@radix-ui/react-toast": "^1.1.4",
"class-variance-authority": "^0.7.0",
"clsx": "^2.0.0",
"jazz-react": "workspace:0.8.12",
"jazz-tools": "workspace:0.8.12",
"jazz-react": "workspace:0.8.13",
"jazz-tools": "workspace:0.8.13",
"lucide-react": "^0.274.0",
"qrcode": "^1.5.3",
"react": "^18.2.0",

View File

@@ -31,7 +31,7 @@ const team: Array<TeamMember> = [
x: "anselm_io",
github: "aeplay",
website: "http://anselm.io",
bluesky: "anselm-io",
bluesky: "anselm.io",
},
{
name: "Andrei Popa",
@@ -141,7 +141,7 @@ function Person({ person }: { person: TeamMember }) {
)}
{person.bluesky && (
<SocialLink
link={`https://bsky.app/profile/${person.bluesky}.bsky.social`}
link={`https://bsky.app/profile/${person.bluesky}`}
icon={SiBluesky}
label="Bluesky profile"
/>

View File

@@ -12,6 +12,7 @@
"@changesets/cli": "^2.27.3",
"@vitest/coverage-istanbul": "1.5.3",
"@vitest/ui": "1.5.3",
"happy-dom": "^15.8.3",
"prettier": "^3.1.1",
"ts-node": "^10.9.1",
"turbo": "^1.11.2",

View File

@@ -1,5 +1,11 @@
# cojson-transport-nodejs-ws
## 0.8.13
### Patch Changes
- e0dd006: Add the onClose handler and improve the closing operation
## 0.8.12
### Patch Changes

View File

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

View File

@@ -18,87 +18,54 @@ export type CreateWebSocketPeerOpts = {
role: Peer["role"];
expectPings?: boolean;
batchingByDefault?: boolean;
onClose?: () => void;
};
export function createWebSocketPeer({
id,
websocket,
role,
expectPings = true,
batchingByDefault = true,
}: CreateWebSocketPeerOpts): Peer {
const incoming = new cojsonInternals.Channel<
SyncMessage | DisconnectedError | PingTimeoutError
>();
websocket.addEventListener("close", function handleClose() {
incoming
.push("Disconnected")
.catch((e) =>
console.error("Error while pushing disconnect msg", e),
);
});
function createPingTimeoutListener(enabled: boolean, callback: () => void) {
if (!enabled) {
return {
reset() {},
clear() {}
}
}
let pingTimeout: ReturnType<typeof setTimeout> | null = null;
let supportsBatching = batchingByDefault;
websocket.addEventListener("message", function handleIncomingMsg(event) {
const result = deserializeMessages(event.data as string);
if (!result.ok) {
console.error("Error while deserializing messages", event.data, result.error);
return;
}
const { messages } = result;
if (!supportsBatching && messages.length > 1) {
// If more than one message is received, the other peer supports batching
supportsBatching = true;
}
if (expectPings) {
return {
reset() {
pingTimeout && clearTimeout(pingTimeout);
pingTimeout = setTimeout(() => {
incoming
.push("PingTimeout")
.catch((e) =>
console.error("Error while pushing ping timeout", e),
);
callback();
}, 10_000);
},
clear() {
pingTimeout && clearTimeout(pingTimeout);
}
};
}
for (const msg of messages) {
if (msg && "action" in msg) {
incoming
.push(msg)
.catch((e) =>
console.error("Error while pushing incoming msg", e),
);
}
}
});
const websocketOpen = new Promise<void>((resolve) => {
function waitForWebSocketOpen(websocket: AnyWebSocket) {
return new Promise<void>((resolve) => {
if (websocket.readyState === 1) {
resolve();
} else {
websocket.addEventListener("open", resolve, { once: true });
}
});
}
function createOutgoingMessagesManager(websocket: AnyWebSocket, batchingByDefault: boolean) {
const outgoingMessages = new BatchedOutgoingMessages((messages) => {
if (websocket.readyState === 1) {
websocket.send(
messages,
);
websocket.send(messages);
}
});
async function pushMessage(msg: SyncMessage) {
let batchingEnabled = batchingByDefault;
async function sendMessage(msg: SyncMessage) {
if (websocket.readyState !== 1) {
await websocketOpen;
await waitForWebSocketOpen(websocket);
}
while (
@@ -114,23 +81,114 @@ export function createWebSocketPeer({
return;
}
if (!supportsBatching) {
if (!batchingEnabled) {
websocket.send(JSON.stringify(msg));
} else {
outgoingMessages.push(msg);
}
}
return {
sendMessage,
setBatchingEnabled(enabled: boolean) {
batchingEnabled = enabled;
},
close() {
outgoingMessages.close();
},
};
}
function createClosedEventEmitter(callback = () => {}) {
let disconnected = false;
return () => {
if (disconnected) return;
disconnected = true;
callback();
}
}
export function createWebSocketPeer({
id,
websocket,
role,
expectPings = true,
batchingByDefault = true,
onClose,
}: CreateWebSocketPeerOpts): Peer {
const incoming = new cojsonInternals.Channel<
SyncMessage | DisconnectedError | PingTimeoutError
>();
const emitClosedEvent = createClosedEventEmitter(onClose);
function handleClose() {
incoming
.push("Disconnected")
.catch((e) =>
console.error("Error while pushing disconnect msg", e),
);
emitClosedEvent();
}
websocket.addEventListener("close", handleClose);
const pingTimeout = createPingTimeoutListener(expectPings, () => {
incoming
.push("PingTimeout")
.catch((e) => console.error("Error while pushing ping timeout", e));
emitClosedEvent();
});
const outgoingMessages = createOutgoingMessagesManager(websocket, batchingByDefault);
function handleIncomingMsg(event: { data: unknown }) {
const result = deserializeMessages(event.data);
if (!result.ok) {
console.error(
"Error while deserializing messages",
event.data,
result.error,
);
return;
}
const { messages } = result;
if (messages.length > 1) {
// If more than one message is received, the other peer supports batching
outgoingMessages.setBatchingEnabled(true);
}
pingTimeout.reset();
for (const msg of messages) {
if (msg && "action" in msg) {
incoming
.push(msg)
.catch((e) =>
console.error("Error while pushing incoming msg", e),
);
}
}
}
websocket.addEventListener("message", handleIncomingMsg);
return {
id,
incoming,
outgoing: {
push: pushMessage,
push: outgoingMessages.sendMessage,
close() {
console.log("Trying to close", id, websocket.readyState);
if (supportsBatching) {
outgoingMessages.close();
}
outgoingMessages.close();
websocket.removeEventListener("message", handleIncomingMsg);
websocket.removeEventListener("close", handleClose);
pingTimeout.clear();
emitClosedEvent();
if (websocket.readyState === 0) {
websocket.addEventListener(

View File

@@ -8,7 +8,14 @@ export function addMessageToBacklog(backlog: string, message: SyncMessage) {
return `${backlog}\n${JSON.stringify(message)}`;
}
export function deserializeMessages(messages: string) {
export function deserializeMessages(messages: unknown) {
if (typeof messages !== "string") {
return {
ok: false,
error: new Error("Expected a string"),
} as const;
}
try {
return {
ok: true,

View File

@@ -18,6 +18,9 @@ function setup(opts: Partial<CreateWebSocketPeerOpts> = {}) {
addEventListener: vi.fn().mockImplementation((type, listener) => {
listeners.set(type, listener);
}),
removeEventListener: vi.fn().mockImplementation((type) => {
listeners.delete(type);
}),
close: vi.fn(),
send: vi.fn(),
} as unknown as Mocked<AnyWebSocket>;

View File

@@ -1,5 +1,14 @@
# jazz-browser-media-images
## 0.8.13
### Patch Changes
- Updated dependencies [fd011d7]
- Updated dependencies [e0dd006]
- jazz-tools@0.8.13
- jazz-browser@0.8.13
## 0.8.12
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "jazz-browser-auth-clerk",
"version": "0.8.12",
"version": "0.8.13",
"type": "module",
"main": "dist/index.js",
"types": "src/index.ts",
@@ -11,8 +11,8 @@
},
"dependencies": {
"cojson": "workspace:0.8.12",
"jazz-browser": "workspace:0.8.12",
"jazz-tools": "workspace:0.8.12"
"jazz-browser": "workspace:0.8.13",
"jazz-tools": "workspace:0.8.13"
},
"scripts": {
"lint": "eslint . --ext ts,tsx",

View File

@@ -1,5 +1,14 @@
# jazz-browser-media-images
## 0.8.13
### Patch Changes
- Updated dependencies [fd011d7]
- Updated dependencies [e0dd006]
- jazz-tools@0.8.13
- jazz-browser@0.8.13
## 0.8.12
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "jazz-browser-media-images",
"version": "0.8.12",
"version": "0.8.13",
"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.12",
"jazz-tools": "workspace:0.8.12",
"jazz-browser": "workspace:0.8.13",
"jazz-tools": "workspace:0.8.13",
"pica": "^9.0.1",
"typescript": "^5.3.3"
},

View File

@@ -1,5 +1,15 @@
# jazz-browser
## 0.8.13
### Patch Changes
- e0dd006: Improve the WebSocket reconnect logic
- Updated dependencies [fd011d7]
- Updated dependencies [e0dd006]
- jazz-tools@0.8.13
- cojson-transport-ws@0.8.13
## 0.8.12
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "jazz-browser",
"version": "0.8.12",
"version": "0.8.13",
"type": "module",
"main": "dist/index.js",
"types": "src/index.ts",
@@ -9,8 +9,8 @@
"@scure/bip39": "^1.3.0",
"cojson": "workspace:0.8.12",
"cojson-storage-indexeddb": "workspace:0.8.12",
"cojson-transport-ws": "workspace:0.8.12",
"jazz-tools": "workspace:0.8.12",
"cojson-transport-ws": "workspace:0.8.13",
"jazz-tools": "workspace:0.8.13",
"typescript": "^5.3.3"
},
"scripts": {

View File

@@ -0,0 +1,69 @@
import { Peer } from "cojson";
import { createWebSocketPeer } from "cojson-transport-ws";
export function createWebSocketPeerWithReconnection(peer: string, reconnectionTimeout: number | undefined, addPeer: (peer: Peer) => void) {
const firstWsPeer = createWebSocketPeer({
websocket: new WebSocket(peer),
id: peer,
role: "server",
onClose: reconnectWebSocket,
});
let shouldTryToReconnect = true;
let currentReconnectionTimeout = reconnectionTimeout || 500;
function onOnline() {
console.log("Online, resetting reconnection timeout");
currentReconnectionTimeout = reconnectionTimeout || 500;
}
window.addEventListener("online", onOnline);
async function reconnectWebSocket() {
if (!shouldTryToReconnect) return;
console.log(
"Websocket disconnected, trying to reconnect in " +
currentReconnectionTimeout +
"ms"
);
currentReconnectionTimeout = Math.min(
currentReconnectionTimeout * 2,
30000
);
await waitForOnline(currentReconnectionTimeout);
if (!shouldTryToReconnect) return;
addPeer(
createWebSocketPeer({
websocket: new WebSocket(peer),
id: peer,
role: "server",
onClose: reconnectWebSocket,
})
);
}
return {
peer: firstWsPeer,
done: () => {
shouldTryToReconnect = false;
window.removeEventListener("online", onOnline);
}
};
}
function waitForOnline(timeout: number) {
return new Promise<void>((resolve) => {
function handleTimeoutOrOnline() {
clearTimeout(timer);
window.removeEventListener('online', handleTimeoutOrOnline);
resolve();
}
const timer = setTimeout(handleTimeoutOrOnline, timeout);
window.addEventListener('online', handleTimeoutOrOnline);
});
}

View File

@@ -16,7 +16,7 @@ import {
import { RawAccountID, LSMStorage } from "cojson";
import { OPFSFilesystem } from "./OPFSFilesystem.js";
import { IDBStorage } from "cojson-storage-indexeddb";
import { createWebSocketPeer } from "cojson-transport-ws";
import { createWebSocketPeerWithReconnection } from "./createWebSocketPeerWithReconnection.js";
export { BrowserDemoAuth } from "./auth/DemoAuth.js";
export { BrowserPasskeyAuth } from "./auth/PasskeyAuth.js";
export { BrowserPassphraseAuth } from "./auth/PassphraseAuth.js";
@@ -64,21 +64,9 @@ export async function createJazzBrowserContext<Acc extends Account>(
): Promise<BrowserContext<Acc> | BrowserGuestContext> {
const crypto = options.crypto || (await WasmCrypto.create());
const firstWsPeer = createWebSocketPeer({
websocket: new WebSocket(options.peer),
id: options.peer + "@" + new Date().toISOString(),
role: "server",
const wsPeer = createWebSocketPeerWithReconnection(options.peer, options.reconnectionTimeout, (peer) => {
node.syncManager.addPeer(peer);
});
let shouldTryToReconnect = true;
let currentReconnectionTimeout = options.reconnectionTimeout || 500;
function onOnline() {
console.log("Online, resetting reconnection timeout");
currentReconnectionTimeout = options.reconnectionTimeout || 500;
}
window.addEventListener("online", onOnline);
const context =
"auth" in options
@@ -93,7 +81,7 @@ export async function createJazzBrowserContext<Acc extends Account>(
// trace: true,
})
: await IDBStorage.asPeer(),
firstWsPeer,
wsPeer.peer,
],
sessionProvider: provideBrowserLockSession,
})
@@ -106,7 +94,7 @@ export async function createJazzBrowserContext<Acc extends Account>(
// trace: true,
})
: await IDBStorage.asPeer(),
firstWsPeer,
wsPeer.peer,
],
});
@@ -115,58 +103,11 @@ export async function createJazzBrowserContext<Acc extends Account>(
? context.account._raw.core.node
: context.agent.node;
async function websocketReconnectLoop() {
while (shouldTryToReconnect) {
if (
Object.keys(node.syncManager.peers).some((peerId) =>
peerId.includes(options.peer),
)
) {
// TODO: this might drain battery, use listeners instead
await new Promise((resolve) => setTimeout(resolve, 100));
} else {
console.log(
"Websocket disconnected, trying to reconnect in " +
currentReconnectionTimeout +
"ms",
);
currentReconnectionTimeout = Math.min(
currentReconnectionTimeout * 2,
30000,
);
await new Promise<void>((resolve) => {
setTimeout(resolve, currentReconnectionTimeout);
window.addEventListener(
"online",
() => {
console.log(
"Online, trying to reconnect immediately",
);
resolve();
},
{ once: true },
);
});
node.syncManager.addPeer(
createWebSocketPeer({
websocket: new WebSocket(options.peer),
id: options.peer + "@" + new Date().toISOString(),
role: "server",
}),
);
}
}
}
void websocketReconnectLoop();
return "account" in context
? {
me: context.account,
done: () => {
shouldTryToReconnect = false;
window.removeEventListener("online", onOnline);
wsPeer.done();
context.done();
},
logOut: () => {
@@ -176,8 +117,7 @@ export async function createJazzBrowserContext<Acc extends Account>(
: {
guest: context.agent,
done: () => {
shouldTryToReconnect = false;
window.removeEventListener("online", onOnline);
wsPeer.done();
context.done();
},
logOut: () => {
@@ -360,3 +300,4 @@ export function consumeInviteLinkFromWindowLocation<V extends CoValue>({
}
});
}

View File

@@ -0,0 +1,148 @@
// @vitest-environment happy-dom
import { describe, test, expect, vi, beforeEach, afterEach } from "vitest";
import { createWebSocketPeer } from "cojson-transport-ws";
import { createWebSocketPeerWithReconnection } from "../createWebSocketPeerWithReconnection.js";
// Mock WebSocket
class MockWebSocket {
addEventListener = vi.fn();
removeEventListener = vi.fn();
close = vi.fn();
readyState = 1;
}
vi.stubGlobal("WebSocket", MockWebSocket);
vi.stubGlobal("window", global);
vi.stubGlobal("navigator", {
onLine: true,
});
vi.mock("cojson-transport-ws", () => ({
createWebSocketPeer: vi.fn().mockImplementation(({ onClose }) => ({
id: "test-peer",
incoming: { push: vi.fn() },
outgoing: { push: vi.fn(), close: vi.fn() },
onClose,
})),
}));
describe("createWebSocketPeerWithReconnection", () => {
beforeEach(() => {
vi.clearAllMocks();
vi.stubGlobal("WebSocket", MockWebSocket);
vi.stubGlobal("removeEventListener", vi.fn());
});
afterEach(() => {
vi.useRealTimers();
});
test("should reset reconnection timeout when coming online", async () => {
vi.useFakeTimers();
const addPeerMock = vi.fn();
const { done } = createWebSocketPeerWithReconnection(
"ws://localhost:8080",
500,
addPeerMock,
);
// Simulate multiple disconnections to increase timeout
const initialPeer =
vi.mocked(createWebSocketPeer).mock.results[0]!.value;
initialPeer.onClose();
await vi.advanceTimersByTimeAsync(1000);
expect(addPeerMock).toHaveBeenCalledTimes(1);
vi.mocked(createWebSocketPeer).mock.results[1]!.value.onClose();
await vi.advanceTimersByTimeAsync(2000);
expect(addPeerMock).toHaveBeenCalledTimes(2);
// Resets the timeout to initial value
window.dispatchEvent(new Event("online"));
// Next reconnection should use initial timeout
vi.mocked(createWebSocketPeer).mock.results[2]!.value.onClose();
await vi.advanceTimersByTimeAsync(1000);
expect(addPeerMock).toHaveBeenCalledTimes(3);
done();
});
test("should wait for online event or timeout before reconnecting", async () => {
vi.useFakeTimers();
const addPeerMock = vi.fn();
const { done } = createWebSocketPeerWithReconnection(
"ws://localhost:8080",
500,
addPeerMock,
);
const initialPeer =
vi.mocked(createWebSocketPeer).mock.results[0]!.value;
// Simulate offline state
vi.stubGlobal("navigator", { onLine: false });
initialPeer.onClose();
// Advance timer but not enough to trigger reconnection
await vi.advanceTimersByTimeAsync(500);
expect(createWebSocketPeer).toHaveBeenCalledTimes(1);
// Simulate coming back online
window.dispatchEvent(new Event("online"));
// Wait for event loop to settle
await Promise.resolve().then();
// Should reconnect immediately after coming online
expect(createWebSocketPeer).toHaveBeenCalledTimes(2);
done();
});
test("should clean up event listeners when done", () => {
const addPeerMock = vi.fn();
const { done } = createWebSocketPeerWithReconnection(
"ws://localhost:8080",
1000,
addPeerMock,
);
done();
expect(window.removeEventListener).toHaveBeenCalledWith(
"online",
expect.any(Function),
);
});
test("should not attempt reconnection after done is called", async () => {
vi.useFakeTimers();
const addPeerMock = vi.fn();
const { done } = createWebSocketPeerWithReconnection(
"ws://localhost:8080",
500,
addPeerMock,
);
const initialPeer =
vi.mocked(createWebSocketPeer).mock.results[0]!.value;
done();
initialPeer.onClose();
await vi.advanceTimersByTimeAsync(1000);
expect(createWebSocketPeer).toHaveBeenCalledTimes(1);
});
});

View File

@@ -1,5 +1,14 @@
# jazz-autosub
## 0.8.13
### Patch Changes
- Updated dependencies [fd011d7]
- Updated dependencies [e0dd006]
- jazz-tools@0.8.13
- cojson-transport-ws@0.8.13
## 0.8.12
### Patch Changes

View File

@@ -5,11 +5,11 @@
"types": "src/index.ts",
"type": "module",
"license": "MIT",
"version": "0.8.12",
"version": "0.8.13",
"dependencies": {
"cojson": "workspace:0.8.12",
"cojson-transport-ws": "workspace:0.8.12",
"jazz-tools": "workspace:0.8.12",
"cojson-transport-ws": "workspace:0.8.13",
"jazz-tools": "workspace:0.8.13",
"ws": "^8.14.2"
},
"devDependencies": {

View File

@@ -1,5 +1,14 @@
# jazz-browser-media-images
## 0.8.13
### Patch Changes
- Updated dependencies [fd011d7]
- jazz-tools@0.8.13
- jazz-browser-auth-clerk@0.8.13
- jazz-react@0.8.13
## 0.8.12
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "jazz-react-auth-clerk",
"version": "0.8.12",
"version": "0.8.13",
"type": "module",
"main": "dist/index.js",
"types": "src/index.tsx",
@@ -11,9 +11,9 @@
},
"dependencies": {
"cojson": "workspace:0.8.12",
"jazz-browser-auth-clerk": "workspace:0.8.12",
"jazz-react": "workspace:0.8.12",
"jazz-tools": "workspace:0.8.12"
"jazz-browser-auth-clerk": "workspace:0.8.13",
"jazz-react": "workspace:0.8.13",
"jazz-tools": "workspace:0.8.13"
},
"peerDependencies": {
"react": "^18.2.0"

View File

@@ -1,5 +1,12 @@
# jazz-browser-media-images
## 0.8.9
### Patch Changes
- Updated dependencies [fd011d7]
- jazz-tools@0.8.13
## 0.8.8
### Patch Changes

View File

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

View File

@@ -1,5 +1,14 @@
# jazz-browser
## 0.8.13
### Patch Changes
- Updated dependencies [fd011d7]
- Updated dependencies [e0dd006]
- jazz-tools@0.8.13
- cojson-transport-ws@0.8.13
## 0.8.12
### Patch Changes

View File

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

View File

@@ -1,5 +1,14 @@
# jazz-react
## 0.8.13
### Patch Changes
- Updated dependencies [fd011d7]
- Updated dependencies [e0dd006]
- jazz-tools@0.8.13
- jazz-browser@0.8.13
## 0.8.12
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "jazz-react",
"version": "0.8.12",
"version": "0.8.13",
"type": "module",
"main": "dist/index.js",
"types": "src/index.ts",
@@ -8,8 +8,8 @@
"dependencies": {
"@scure/bip39": "^1.3.0",
"cojson": "workspace:0.8.12",
"jazz-browser": "workspace:0.8.12",
"jazz-tools": "workspace:0.8.12",
"jazz-browser": "workspace:0.8.13",
"jazz-tools": "workspace:0.8.13",
"typescript": "^5.3.3"
},
"devDependencies": {

View File

@@ -1,5 +1,14 @@
# jazz-run
## 0.8.13
### Patch Changes
- Updated dependencies [fd011d7]
- Updated dependencies [e0dd006]
- jazz-tools@0.8.13
- cojson-transport-ws@0.8.13
## 0.8.12
### Patch Changes

View File

@@ -3,7 +3,7 @@
"bin": "./dist/index.js",
"type": "module",
"license": "MIT",
"version": "0.8.12",
"version": "0.8.13",
"scripts": {
"lint": "eslint . --ext ts,tsx",
"format": "prettier --write './src/**/*.{ts,tsx}'",
@@ -19,9 +19,9 @@
"@effect/typeclass": "^0.25.5",
"cojson": "workspace:0.8.12",
"cojson-storage-sqlite": "workspace:0.8.12",
"cojson-transport-ws": "workspace:0.8.12",
"cojson-transport-ws": "workspace:0.8.13",
"effect": "^3.6.5",
"jazz-tools": "workspace:0.8.12",
"jazz-tools": "workspace:0.8.13",
"ws": "^8.14.2"
},
"devDependencies": {

View File

@@ -1,5 +1,11 @@
# jazz-tools
## 0.8.13
### Patch Changes
- fd011d7: Add a cache layer on the loadedAs account reads
## 0.8.12
### Patch Changes

View File

@@ -19,7 +19,7 @@
},
"type": "module",
"license": "MIT",
"version": "0.8.12",
"version": "0.8.13",
"dependencies": {
"cojson": "workspace:*",
"fast-check": "^3.17.2"

View File

@@ -37,6 +37,7 @@ import {
ensureCoValueLoaded,
subscribeToExistingCoValue,
} from "../internal.js";
import { coValuesCache } from "../lib/cache.js";
/** @category Identity & Permissions */
export class Account extends CoValueBase implements CoValue {
@@ -71,9 +72,12 @@ export class Account extends CoValueBase implements CoValue {
get _loadedAs(): Account | AnonymousJazzAgent {
if (this.isMe) return this;
if (this._raw.core.node.account instanceof RawAccount) {
return Account.fromRaw(this._raw.core.node.account);
const rawAccount = this._raw.core.node.account;
if (rawAccount instanceof RawAccount) {
return coValuesCache.get(rawAccount, () => Account.fromRaw(rawAccount)) ;
}
return new AnonymousJazzAgent(this._raw.core.node);
}

View File

@@ -29,6 +29,7 @@ import {
subscribeToExistingCoValue,
subscriptionsScopes,
} from "../internal.js";
import { coValuesCache } from "../lib/cache.js";
/**
* CoLists are collaborative versions of plain arrays.
@@ -164,9 +165,12 @@ export class CoList<Item = any> extends Array<Item> implements CoValue {
}
get _loadedAs() {
if (this._raw.core.node.account instanceof RawAccount) {
return Account.fromRaw(this._raw.core.node.account);
const rawAccount = this._raw.core.node.account;
if (rawAccount instanceof RawAccount) {
return coValuesCache.get(rawAccount, () => Account.fromRaw(rawAccount)) ;
}
return new AnonymousJazzAgent(this._raw.core.node);
}

View File

@@ -11,6 +11,7 @@ import {
AnonymousJazzAgent,
} from "../internal.js";
import { fulfillsDepth } from "./deepLoading.js";
import { coValuesCache } from "../lib/cache.js";
/** @category Abstract interfaces */
// eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -87,9 +88,12 @@ export class CoValueBase implements CoValue {
/** @private */
get _loadedAs() {
if (this._raw.core.node.account instanceof RawAccount) {
return Account.fromRaw(this._raw.core.node.account);
const rawAccount = this._raw.core.node.account;
if (rawAccount instanceof RawAccount) {
return coValuesCache.get(rawAccount, () => Account.fromRaw(rawAccount)) ;
}
return new AnonymousJazzAgent(this._raw.core.node);
}

View File

@@ -12,8 +12,7 @@ import {
isRefEncoded,
subscriptionsScopes,
} from "../internal.js";
const refCache = new WeakMap<RawCoValue, CoValue>();
import { coValuesCache } from "../lib/cache.js";
const TRACE_ACCESSES = false;
@@ -35,14 +34,9 @@ export class Ref<out V extends CoValue> {
: this.controlledAccount._raw.core.node;
const raw = node.getLoaded(this.id as unknown as CoID<RawCoValue>);
if (raw) {
let value = refCache.get(raw);
if (value) {
// console.log("Using cached value for " + this.id);
} else {
value = instantiateRefEncoded(this.schema, raw);
refCache.set(raw, value);
}
return value as V;
return coValuesCache.get(raw, () =>
instantiateRefEncoded(this.schema, raw),
);
} else {
return null;
}

View File

@@ -0,0 +1,64 @@
import { expect, describe, test } from "vitest";
import { coValuesCache } from "./cache.js";
import { RawCoValue } from "cojson";
import { CoValue } from "../internal.js";
describe("coValuesCache", () => {
test("should return computed value when not cached", () => {
const mockRawValue = { type: "comap" } as RawCoValue;
const mockCoValue = { id: "test" } as unknown as CoValue;
let computeCalls = 0;
const result = coValuesCache.get(mockRawValue, () => {
computeCalls++;
return mockCoValue;
});
expect(result).toBe(mockCoValue);
expect(computeCalls).toBe(1);
});
test("should return cached value on subsequent calls", () => {
const mockRawValue = { type: "comap" } as RawCoValue;
const mockCoValue = { id: "test" } as unknown as CoValue;
let computeCalls = 0;
// First call
const result1 = coValuesCache.get(mockRawValue, () => {
computeCalls++;
return mockCoValue;
});
// Second call with same raw value
const result2 = coValuesCache.get(mockRawValue, () => {
computeCalls++;
return mockCoValue;
});
expect(result1).toBe(mockCoValue);
expect(result2).toBe(mockCoValue);
expect(computeCalls).toBe(1); // Compute should only be called once
});
test("should cache different values for different raw values", () => {
const mockRawValue1 = { type: "comap" } as RawCoValue;
const mockRawValue2 = { type: "colist" } as RawCoValue;
const mockCoValue1 = { id: "test1" } as unknown as CoValue;
const mockCoValue2 = { id: "test2" } as unknown as CoValue;
let computeCalls = 0;
const result1 = coValuesCache.get(mockRawValue1, () => {
computeCalls++;
return mockCoValue1;
});
const result2 = coValuesCache.get(mockRawValue2, () => {
computeCalls++;
return mockCoValue2;
});
expect(result1).toBe(mockCoValue1);
expect(result2).toBe(mockCoValue2);
expect(computeCalls).toBe(2); // Should compute once for each unique raw value
});
});

View File

@@ -0,0 +1,16 @@
import { RawCoValue } from "cojson";
import { CoValue } from "../internal.js";
const weakMap = new WeakMap<RawCoValue, CoValue>();
export const coValuesCache = {
get: <V extends CoValue>(raw: RawCoValue, compute: () => V) => {
const cached = weakMap.get(raw);
if (cached) {
return cached as V;
}
const computed = compute();
weakMap.set(raw, computed);
return computed;
},
};

112
pnpm-lock.yaml generated
View File

@@ -17,10 +17,13 @@ importers:
version: 2.27.3
'@vitest/coverage-istanbul':
specifier: 1.5.3
version: 1.5.3(vitest@1.5.3(@types/node@22.5.1)(@vitest/ui@1.5.3)(jsdom@20.0.3)(terser@5.33.0))
version: 1.5.3(vitest@1.5.3(@types/node@22.5.1)(@vitest/ui@1.5.3)(happy-dom@15.8.3)(jsdom@20.0.3)(terser@5.33.0))
'@vitest/ui':
specifier: 1.5.3
version: 1.5.3(vitest@1.5.3)
happy-dom:
specifier: ^15.8.3
version: 15.8.3
prettier:
specifier: ^3.1.1
version: 3.1.1
@@ -35,7 +38,7 @@ importers:
version: 0.25.13(typescript@5.6.2)
vitest:
specifier: 1.5.3
version: 1.5.3(@types/node@22.5.1)(@vitest/browser@0.34.6)(@vitest/ui@1.5.3)(jsdom@20.0.3)(terser@5.33.0)
version: 1.5.3(@types/node@22.5.1)(@vitest/browser@0.34.6)(@vitest/ui@1.5.3)(happy-dom@15.8.3)(jsdom@20.0.3)(terser@5.33.0)
e2e/BinaryCoStream:
dependencies:
@@ -49,10 +52,10 @@ importers:
specifier: ^3.0.1
version: 3.0.1
jazz-react:
specifier: workspace:0.8.12
specifier: workspace:0.8.13
version: link:../../packages/jazz-react
jazz-tools:
specifier: workspace:0.8.12
specifier: workspace:0.8.13
version: link:../../packages/jazz-tools
react:
specifier: 18.3.1
@@ -144,13 +147,13 @@ importers:
specifier: ^2.0.0
version: 2.0.0
jazz-browser-media-images:
specifier: workspace:0.8.12
specifier: workspace:0.8.13
version: link:../../packages/jazz-browser-media-images
jazz-react:
specifier: workspace:0.8.12
specifier: workspace:0.8.13
version: link:../../packages/jazz-react
jazz-tools:
specifier: workspace:0.8.12
specifier: workspace:0.8.13
version: link:../../packages/jazz-tools
next:
specifier: 14.2.5
@@ -223,10 +226,10 @@ importers:
specifier: workspace:0.2.1
version: link:../../packages/hash-slash
jazz-react:
specifier: workspace:0.8.12
specifier: workspace:0.8.13
version: link:../../packages/jazz-react
jazz-tools:
specifier: workspace:0.8.12
specifier: workspace:0.8.13
version: link:../../packages/jazz-tools
lucide-react:
specifier: ^0.274.0
@@ -335,13 +338,13 @@ importers:
specifier: workspace:0.2.1
version: link:../../packages/hash-slash
jazz-react:
specifier: workspace:0.8.12
specifier: workspace:0.8.13
version: link:../../packages/jazz-react
jazz-react-auth-clerk:
specifier: workspace:0.8.12
specifier: workspace:0.8.13
version: link:../../packages/jazz-react-auth-clerk
jazz-tools:
specifier: workspace:0.8.12
specifier: workspace:0.8.13
version: link:../../packages/jazz-tools
lucide-react:
specifier: ^0.274.0
@@ -725,7 +728,7 @@ importers:
specifier: workspace:0.8.12
version: link:../../packages/cojson
cojson-transport-ws:
specifier: workspace:0.8.12
specifier: workspace:0.8.13
version: link:../../packages/cojson-transport-ws
hash-slash:
specifier: workspace:0.2.1
@@ -822,10 +825,10 @@ importers:
specifier: ^2.0.0
version: 2.0.0
jazz-react:
specifier: workspace:0.8.12
specifier: workspace:0.8.13
version: link:../../packages/jazz-react
jazz-tools:
specifier: workspace:0.8.12
specifier: workspace:0.8.13
version: link:../../packages/jazz-tools
lucide-react:
specifier: ^0.274.0
@@ -898,10 +901,10 @@ importers:
examples/password-manager:
dependencies:
jazz-react:
specifier: workspace:0.8.12
specifier: workspace:0.8.13
version: link:../../packages/jazz-react
jazz-tools:
specifier: workspace:0.8.12
specifier: workspace:0.8.13
version: link:../../packages/jazz-tools
react:
specifier: 18.3.1
@@ -977,13 +980,13 @@ importers:
specifier: ^2.0.0
version: 2.0.0
jazz-browser-media-images:
specifier: workspace:0.8.12
specifier: workspace:0.8.13
version: link:../../packages/jazz-browser-media-images
jazz-react:
specifier: workspace:0.8.12
specifier: workspace:0.8.13
version: link:../../packages/jazz-react
jazz-tools:
specifier: workspace:0.8.12
specifier: workspace:0.8.13
version: link:../../packages/jazz-tools
lucide-react:
specifier: ^0.274.0
@@ -1053,7 +1056,7 @@ importers:
specifier: ^3.0.1
version: 3.0.1
jazz-run:
specifier: workspace:0.8.12
specifier: workspace:0.8.13
version: link:../../packages/jazz-run
postcss:
specifier: ^8.4.27
@@ -1091,10 +1094,10 @@ importers:
specifier: ^2.0.0
version: 2.0.0
jazz-react:
specifier: workspace:0.8.12
specifier: workspace:0.8.13
version: link:../../packages/jazz-react
jazz-tools:
specifier: workspace:0.8.12
specifier: workspace:0.8.13
version: link:../../packages/jazz-tools
lucide-react:
specifier: ^0.274.0
@@ -1223,7 +1226,7 @@ importers:
version: 5.3.3
vitest:
specifier: 1.5.3
version: 1.5.3(@types/node@22.5.1)(@vitest/browser@0.34.6)(@vitest/ui@1.5.3)(jsdom@20.0.3)(terser@5.33.0)
version: 1.5.3(@types/node@22.5.1)(@vitest/browser@0.34.6)(@vitest/ui@1.5.3)(happy-dom@15.8.3)(jsdom@20.0.3)(terser@5.33.0)
packages/cojson-storage-indexeddb:
dependencies:
@@ -1242,7 +1245,7 @@ importers:
version: 6.0.0
vitest:
specifier: 1.5.3
version: 1.5.3(@types/node@22.5.1)(@vitest/browser@0.34.6)(@vitest/ui@1.5.3)(jsdom@20.0.3)(terser@5.33.0)
version: 1.5.3(@types/node@22.5.1)(@vitest/browser@0.34.6)(@vitest/ui@1.5.3)(happy-dom@15.8.3)(jsdom@20.0.3)(terser@5.33.0)
webdriverio:
specifier: ^8.15.0
version: 8.26.3(typescript@5.3.3)
@@ -1300,10 +1303,10 @@ importers:
specifier: workspace:0.8.12
version: link:../cojson-storage-indexeddb
cojson-transport-ws:
specifier: workspace:0.8.12
specifier: workspace:0.8.13
version: link:../cojson-transport-ws
jazz-tools:
specifier: workspace:0.8.12
specifier: workspace:0.8.13
version: link:../jazz-tools
typescript:
specifier: ^5.3.3
@@ -1315,10 +1318,10 @@ importers:
specifier: workspace:0.8.12
version: link:../cojson
jazz-browser:
specifier: workspace:0.8.12
specifier: workspace:0.8.13
version: link:../jazz-browser
jazz-tools:
specifier: workspace:0.8.12
specifier: workspace:0.8.13
version: link:../jazz-tools
devDependencies:
typescript:
@@ -1334,10 +1337,10 @@ importers:
specifier: ^4.1.0
version: 4.1.0
jazz-browser:
specifier: workspace:0.8.12
specifier: workspace:0.8.13
version: link:../jazz-browser
jazz-tools:
specifier: workspace:0.8.12
specifier: workspace:0.8.13
version: link:../jazz-tools
pica:
specifier: ^9.0.1
@@ -1356,10 +1359,10 @@ importers:
specifier: workspace:0.8.12
version: link:../cojson
cojson-transport-ws:
specifier: workspace:0.8.12
specifier: workspace:0.8.13
version: link:../cojson-transport-ws
jazz-tools:
specifier: workspace:0.8.12
specifier: workspace:0.8.13
version: link:../jazz-tools
ws:
specifier: ^8.14.2
@@ -1381,10 +1384,10 @@ importers:
specifier: workspace:0.8.12
version: link:../cojson
jazz-browser:
specifier: workspace:0.8.12
specifier: workspace:0.8.13
version: link:../jazz-browser
jazz-tools:
specifier: workspace:0.8.12
specifier: workspace:0.8.13
version: link:../jazz-tools
typescript:
specifier: ^5.3.3
@@ -1406,13 +1409,13 @@ importers:
specifier: workspace:0.8.12
version: link:../cojson
jazz-browser-auth-clerk:
specifier: workspace:0.8.12
specifier: workspace:0.8.13
version: link:../jazz-browser-auth-clerk
jazz-react:
specifier: workspace:0.8.12
specifier: workspace:0.8.13
version: link:../jazz-react
jazz-tools:
specifier: workspace:0.8.12
specifier: workspace:0.8.13
version: link:../jazz-tools
react:
specifier: 18.3.1
@@ -1502,13 +1505,13 @@ importers:
specifier: workspace:0.8.12
version: link:../cojson-storage-sqlite
cojson-transport-ws:
specifier: workspace:0.8.12
specifier: workspace:0.8.13
version: link:../cojson-transport-ws
effect:
specifier: ^3.6.5
version: 3.6.5
jazz-tools:
specifier: workspace:0.8.12
specifier: workspace:0.8.13
version: link:../jazz-tools
ws:
specifier: ^8.14.2
@@ -1535,7 +1538,7 @@ importers:
version: 5.3.3
vitest:
specifier: 1.5.3
version: 1.5.3(@types/node@22.5.1)(@vitest/browser@0.34.6)(@vitest/ui@1.5.3)(jsdom@20.0.3)(terser@5.33.0)
version: 1.5.3(@types/node@22.5.1)(@vitest/browser@0.34.6)(@vitest/ui@1.5.3)(happy-dom@15.8.3)(jsdom@20.0.3)(terser@5.33.0)
packages:
@@ -6579,6 +6582,10 @@ packages:
resolution: {integrity: sha512-5gghUc24tP9HRznNpV2+FIoq3xKkj5dTQqf4v0CpdPbFVwFkWoxOM+o+2OC9ZSvjEMTjfmG9QT+gcvggTwW1zw==}
engines: {node: '>= 10.x'}
happy-dom@15.8.3:
resolution: {integrity: sha512-YR9nUWN/T2bH7pPLEYMhTp4DQExPH+mC4KulJDgimCb+FY3Er0Vp6SOOcBXrNfMTri3lAk9uSZqUTG2hgZOYwg==}
engines: {node: '>=18.0.0'}
hard-rejection@2.1.0:
resolution: {integrity: sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==}
engines: {node: '>=6'}
@@ -14212,12 +14219,12 @@ snapshots:
magic-string: 0.30.5
modern-node-polyfills: 1.0.0(esbuild@0.19.10)(rollup@4.9.1)
sirv: 2.0.4
vitest: 1.5.3(@types/node@22.5.1)(@vitest/browser@0.34.6)(@vitest/ui@1.5.3)(jsdom@20.0.3)(terser@5.33.0)
vitest: 1.5.3(@types/node@22.5.1)(@vitest/browser@0.34.6)(@vitest/ui@1.5.3)(happy-dom@15.8.3)(jsdom@20.0.3)(terser@5.33.0)
transitivePeerDependencies:
- esbuild
- rollup
'@vitest/coverage-istanbul@1.5.3(vitest@1.5.3(@types/node@22.5.1)(@vitest/ui@1.5.3)(jsdom@20.0.3)(terser@5.33.0))':
'@vitest/coverage-istanbul@1.5.3(vitest@1.5.3(@types/node@22.5.1)(@vitest/ui@1.5.3)(happy-dom@15.8.3)(jsdom@20.0.3)(terser@5.33.0))':
dependencies:
debug: 4.3.7
istanbul-lib-coverage: 3.2.2
@@ -14228,7 +14235,7 @@ snapshots:
magicast: 0.3.5
picocolors: 1.1.0
test-exclude: 6.0.0
vitest: 1.5.3(@types/node@22.5.1)(@vitest/browser@0.34.6)(@vitest/ui@1.5.3)(jsdom@20.0.3)(terser@5.33.0)
vitest: 1.5.3(@types/node@22.5.1)(@vitest/browser@0.34.6)(@vitest/ui@1.5.3)(happy-dom@15.8.3)(jsdom@20.0.3)(terser@5.33.0)
transitivePeerDependencies:
- supports-color
@@ -14263,7 +14270,7 @@ snapshots:
pathe: 1.1.2
picocolors: 1.1.0
sirv: 2.0.4
vitest: 1.5.3(@types/node@22.5.1)(@vitest/browser@0.34.6)(@vitest/ui@1.5.3)(jsdom@20.0.3)(terser@5.33.0)
vitest: 1.5.3(@types/node@22.5.1)(@vitest/browser@0.34.6)(@vitest/ui@1.5.3)(happy-dom@15.8.3)(jsdom@20.0.3)(terser@5.33.0)
'@vitest/utils@1.5.3':
dependencies:
@@ -15740,7 +15747,7 @@ snapshots:
eslint: 8.57.1
eslint-import-resolver-node: 0.3.9
eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@6.15.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(eslint@8.57.1))(eslint@8.57.1)
eslint-plugin-import: 2.31.0(@typescript-eslint/parser@6.15.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1)
eslint-plugin-import: 2.31.0(@typescript-eslint/parser@6.15.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.15.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1)
eslint-plugin-jsx-a11y: 6.10.0(eslint@8.57.1)
eslint-plugin-react: 7.37.1(eslint@8.57.1)
eslint-plugin-react-hooks: 4.6.0(eslint@8.57.1)
@@ -15779,7 +15786,7 @@ snapshots:
is-bun-module: 1.2.1
is-glob: 4.0.3
optionalDependencies:
eslint-plugin-import: 2.31.0(@typescript-eslint/parser@6.15.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1)
eslint-plugin-import: 2.31.0(@typescript-eslint/parser@6.15.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.15.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1)
transitivePeerDependencies:
- '@typescript-eslint/parser'
- eslint-import-resolver-node
@@ -15836,7 +15843,7 @@ snapshots:
- supports-color
- typescript
eslint-plugin-import@2.31.0(@typescript-eslint/parser@6.15.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1):
eslint-plugin-import@2.31.0(@typescript-eslint/parser@6.15.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.15.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1):
dependencies:
'@rtsao/scc': 1.1.0
array-includes: 3.1.8
@@ -16834,6 +16841,12 @@ snapshots:
graphql@15.8.0: {}
happy-dom@15.8.3:
dependencies:
entities: 4.5.0
webidl-conversions: 7.0.0
whatwg-mimetype: 3.0.0
hard-rejection@2.1.0: {}
has-bigints@1.0.2: {}
@@ -20714,7 +20727,7 @@ snapshots:
fsevents: 2.3.3
terser: 5.33.0
vitest@1.5.3(@types/node@22.5.1)(@vitest/browser@0.34.6)(@vitest/ui@1.5.3)(jsdom@20.0.3)(terser@5.33.0):
vitest@1.5.3(@types/node@22.5.1)(@vitest/browser@0.34.6)(@vitest/ui@1.5.3)(happy-dom@15.8.3)(jsdom@20.0.3)(terser@5.33.0):
dependencies:
'@vitest/expect': 1.5.3
'@vitest/runner': 1.5.3
@@ -20740,6 +20753,7 @@ snapshots:
'@types/node': 22.5.1
'@vitest/browser': 0.34.6(esbuild@0.19.10)(rollup@4.9.1)(vitest@1.5.3)
'@vitest/ui': 1.5.3(vitest@1.5.3)
happy-dom: 15.8.3
jsdom: 20.0.3
transitivePeerDependencies:
- less