Compare commits

..

34 Commits

Author SHA1 Message Date
Anselm
b09e35e372 release 2024-07-29 10:40:10 +01:00
Anselm
d2c8121c9c Fix storage option in jazz-react 2024-07-29 10:34:39 +01:00
Anselm
380bb88ffa Mostly complete OPFS implementation (single-tab only) 2024-07-29 10:33:18 +01:00
Anselm
6ab53c263d Release 2024-07-26 17:23:02 +01:00
Anselm
e7f3e4e242 Increase disconnect timeout for now 2024-07-26 17:21:06 +01:00
Anselm Eickhoff
8bb5201647 Merge pull request #236 from timolins/patch-1
[Homepage] Make current year dynamic in footer
2024-07-22 15:55:16 +01:00
Timo Lins
a9fc94f53d Make current year dynamic in footer 2024-07-22 10:06:48 +02:00
Anselm Eickhoff
ca7c0510d1 Merge pull request #234 from Schniz/schniz/co-optional 2024-07-21 10:14:41 +01:00
Gal Schlezinger
1bf16f0859 add co.optional syntax 2024-07-21 09:10:44 +03:00
Anselm Eickhoff
21b503c188 Merge pull request #224 from datner/datner/give-it-a-try
cojson-transport-ws: reuse runtime and use fibers instead of setTimeout
2024-07-15 14:35:18 +01:00
Anselm
0053e9796c Release 2024-07-15 11:01:31 +01:00
Anselm
e84941b1b1 Fix another bug in CoMap 'has' proxy trap 2024-07-15 10:59:14 +01:00
Anselm
57f6f8d67e Release 2024-07-14 17:55:47 +01:00
Anselm
5b8e69d973 Fix bug in CoMap 'has' trap 2024-07-14 17:55:05 +01:00
Anselm
7213b1bfa3 Release 2024-07-13 13:32:50 +01:00
Anselm Eickhoff
11f0770f08 Merge pull request #230 from tobiaslins/add-support-for-in
Add support for property existence
2024-07-13 13:30:15 +01:00
Tobias Lins
44e6dc3ae8 Remove useless check 2024-07-13 13:57:37 +02:00
Tobias Lins
b5d20d2488 Better implementation 2024-07-13 13:26:28 +02:00
Tobias Lins
0185545838 Add support for property existence 2024-07-13 12:26:10 +02:00
Yuval Datner
8c8f85859c style: prettier 2024-07-12 15:42:52 +03:00
Yuval Datner
104384409e refactor: change to yieldable error 2024-07-12 15:42:27 +03:00
Yuval Datner
179827ae56 small refactor for readability 2024-07-12 15:13:25 +03:00
Yuval Datner
6645829876 do stream stuff 2024-07-12 15:13:23 +03:00
Gal Schlezinger
68cb302722 store jazzPings on global 2024-07-12 15:13:22 +03:00
Gal Schlezinger
8dc33f2790 fix bugs because I misindented things 2024-07-12 15:13:21 +03:00
Gal Schlezinger
5f64ba326c jazzPings 2024-07-12 15:13:20 +03:00
Gal Schlezinger
7ccb15107c cojson-transport-ws: reuse runtime and use fibers instead of setTimeout
when calling Effect.runFork we don't propagate layers
and using fibers can allow us to interrupt ongoing requests
when the pings fail
2024-07-12 15:13:16 +03:00
Anselm
b102964743 Get rid of husky for now 2024-07-12 11:56:54 +01:00
Anselm
216d50a09c Remove old homepage build 2024-07-12 11:55:44 +01:00
Anselm
07ea59fdcb Release 2024-07-12 11:14:15 +01:00
Anselm
932a84a47f Update to Effect 3.5.2 2024-07-12 11:13:41 +01:00
Anselm
34dda7bdbd Release 2024-07-05 11:18:53 +01:00
Anselm
49fa153581 Merge branch 'fix-fs' 2024-07-05 11:17:54 +01:00
Anselm
0ddceac4c0 Fix FS bugs 2024-06-26 13:45:09 +01:00
52 changed files with 1246 additions and 600 deletions

View File

@@ -53,53 +53,6 @@ jobs:
cache-from: type=gha
cache-to: type=gha,mode=max
build-homepage:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
submodules: true
- uses: pnpm/action-setup@v2
with:
version: 8
- uses: actions/setup-node@v3
with:
node-version: 16
cache: 'pnpm'
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Login to GitHub Container Registry
uses: docker/login-action@v2
with:
registry: ghcr.io
username: gardencmp
password: ${{ secrets.GITHUB_TOKEN }}
- name: Pnpm Install (root)
run: |
pnpm install
working-directory: .
- name: Pnpm Install & Build (homepage)
run: |
pnpm install
pnpm build;
working-directory: ./homepage/homepage
- name: Docker Build & Push
uses: docker/build-push-action@v4
with:
context: ./homepage
push: true
tags: ghcr.io/gardencmp/${{github.event.repository.name}}-homepage-jazz:${{github.head_ref || github.ref_name}}-${{github.sha}}-${{github.run_number}}-${{github.run_attempt}}
cache-from: type=gha
cache-to: type=gha,mode=max
deploy-examples:
runs-on: ubuntu-latest
needs: build-examples
@@ -135,37 +88,4 @@ jobs:
envsubst '${DOCKER_USER} ${DOCKER_PASSWORD} ${DOCKER_TAG} ${BRANCH_SUFFIX} ${BRANCH_SUBDOMAIN}' < job-template.nomad > job-instance.nomad;
cat job-instance.nomad;
NOMAD_ADDR=${{ secrets.NOMAD_ADDR }} nomad job run job-instance.nomad;
working-directory: ./examples/${{ matrix.example }}
deploy-homepage:
runs-on: ubuntu-latest
needs: build-homepage
steps:
- uses: actions/checkout@v3
with:
submodules: true
- uses: gacts/install-nomad@v1
- name: Tailscale
uses: tailscale/github-action@v1
with:
authkey: ${{ secrets.TAILSCALE_AUTHKEY }}
- name: Deploy on Nomad
run: |
if [ "${{github.ref_name}}" == "main" ]; then
export BRANCH_SUFFIX="";
export BRANCH_SUBDOMAIN="";
else
export BRANCH_SUFFIX=-${{github.head_ref || github.ref_name}};
export BRANCH_SUBDOMAIN=${{github.head_ref || github.ref_name}}.;
fi
export DOCKER_USER=gardencmp;
export DOCKER_PASSWORD=${{ secrets.DOCKER_PULL_PAT }};
export DOCKER_TAG=ghcr.io/gardencmp/${{github.event.repository.name}}-homepage-jazz:${{github.head_ref || github.ref_name}}-${{github.sha}}-${{github.run_number}}-${{github.run_attempt}};
envsubst '${DOCKER_USER} ${DOCKER_PASSWORD} ${DOCKER_TAG} ${BRANCH_SUFFIX} ${BRANCH_SUBDOMAIN}' < job-template.nomad > job-instance.nomad;
cat job-instance.nomad;
NOMAD_ADDR=${{ secrets.NOMAD_ADDR }} nomad job run job-instance.nomad;
working-directory: ./homepage
working-directory: ./examples/${{ matrix.example }}

View File

@@ -1,2 +0,0 @@
#!/usr/bin/env sh
. "$(dirname "$0")/_/husky.sh"

View File

@@ -1,5 +1,62 @@
# jazz-example-chat
## 0.0.70
### Patch Changes
- Updated dependencies
- cojson@0.7.23
- jazz-react@0.7.23
- jazz-tools@0.7.23
## 0.0.69
### Patch Changes
- jazz-react@0.7.22
## 0.0.68
### Patch Changes
- Updated dependencies
- jazz-tools@0.7.21
- jazz-react@0.7.21
## 0.0.67
### Patch Changes
- Updated dependencies
- jazz-tools@0.7.20
- jazz-react@0.7.20
## 0.0.66
### Patch Changes
- Updated dependencies
- jazz-tools@0.7.19
- jazz-react@0.7.19
## 0.0.65
### Patch Changes
- Updated dependencies
- cojson@0.7.18
- jazz-react@0.7.18
- jazz-tools@0.7.18
## 0.0.64
### Patch Changes
- Updated dependencies
- cojson@0.7.17
- jazz-react@0.7.17
- jazz-tools@0.7.17
## 0.0.63
### Patch Changes

View File

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

View File

@@ -1,5 +1,36 @@
# jazz-example-chat
## 0.0.51
### Patch Changes
- Updated dependencies
- cojson@0.7.23
- cojson-transport-ws@0.7.23
## 0.0.50
### Patch Changes
- Updated dependencies
- cojson-transport-ws@0.7.22
## 0.0.49
### Patch Changes
- Updated dependencies
- cojson@0.7.18
- cojson-transport-ws@0.7.18
## 0.0.48
### Patch Changes
- Updated dependencies
- cojson@0.7.17
- cojson-transport-ws@0.7.17
## 0.0.47
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "jazz-inspector",
"private": true,
"version": "0.0.47",
"version": "0.0.51",
"type": "module",
"scripts": {
"dev": "vite",
@@ -19,7 +19,7 @@
"hash-slash": "workspace:*",
"cojson": "workspace:*",
"cojson-transport-ws": "workspace:*",
"effect": "^3.1.5",
"effect": "^3.5.2",
"lucide-react": "^0.274.0",
"qrcode": "^1.5.3",
"react": "^18.2.0",

View File

@@ -1,5 +1,64 @@
# jazz-example-pets
## 0.0.88
### Patch Changes
- Updated dependencies
- jazz-react@0.7.23
- jazz-tools@0.7.23
- jazz-browser-media-images@0.7.23
## 0.0.87
### Patch Changes
- jazz-browser-media-images@0.7.22
- jazz-react@0.7.22
## 0.0.86
### Patch Changes
- Updated dependencies
- jazz-tools@0.7.21
- jazz-browser-media-images@0.7.21
- jazz-react@0.7.21
## 0.0.85
### Patch Changes
- Updated dependencies
- jazz-tools@0.7.20
- jazz-browser-media-images@0.7.20
- jazz-react@0.7.20
## 0.0.84
### Patch Changes
- Updated dependencies
- jazz-tools@0.7.19
- jazz-browser-media-images@0.7.19
- jazz-react@0.7.19
## 0.0.83
### Patch Changes
- jazz-react@0.7.18
- jazz-tools@0.7.18
- jazz-browser-media-images@0.7.18
## 0.0.82
### Patch Changes
- jazz-react@0.7.17
- jazz-tools@0.7.17
- jazz-browser-media-images@0.7.17
## 0.0.81
### Patch Changes

View File

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

View File

@@ -1,5 +1,57 @@
# jazz-example-todo
## 0.0.87
### Patch Changes
- Updated dependencies
- jazz-react@0.7.23
- jazz-tools@0.7.23
## 0.0.86
### Patch Changes
- jazz-react@0.7.22
## 0.0.85
### Patch Changes
- Updated dependencies
- jazz-tools@0.7.21
- jazz-react@0.7.21
## 0.0.84
### Patch Changes
- Updated dependencies
- jazz-tools@0.7.20
- jazz-react@0.7.20
## 0.0.83
### Patch Changes
- Updated dependencies
- jazz-tools@0.7.19
- jazz-react@0.7.19
## 0.0.82
### Patch Changes
- jazz-react@0.7.18
- jazz-tools@0.7.18
## 0.0.81
### Patch Changes
- jazz-react@0.7.17
- jazz-tools@0.7.17
## 0.0.80
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "jazz-example-todo",
"private": true,
"version": "0.0.80",
"version": "0.0.87",
"type": "module",
"scripts": {
"dev": "vite",

View File

@@ -11,8 +11,8 @@ import { SiGithub, SiDiscord, SiTwitter } from "@icons-pack/react-simple-icons";
import { Nav, NavLink, Newsletter, NewsletterButton } from "@/components/nav";
import { DocNav } from "@/components/docs/nav";
import { SpeedInsights } from "@vercel/speed-insights/next"
import { Analytics } from "@vercel/analytics/react"
import { SpeedInsights } from "@vercel/speed-insights/next";
import { Analytics } from "@vercel/analytics/react";
// If loading a variable font, you don't need to specify the font weight
const manrope = Manrope({
@@ -50,8 +50,8 @@ export default function RootLayout({
"flex flex-col items-center bg-stone-50 dark:bg-stone-950 overflow-x-hidden",
].join(" ")}
>
<SpeedInsights/>
<Analytics/>
<SpeedInsights />
<Analytics />
<ThemeProvider
attribute="class"
defaultTheme="system"
@@ -112,7 +112,7 @@ export default function RootLayout({
<div className="col-span-full md:col-span-1 sm:row-start-4 md:row-start-auto lg:col-span-2 md:row-span-2 md:flex-1 flex flex-row md:flex-col max-sm:mt-4 justify-between max-sm:items-start gap-2 text-sm min-w-[10rem]">
<GcmpLogo monochrome className="w-32" />
<p className="max-sm:text-right">
© 2023
© {new Date().getFullYear()}
<br />
Garden Computing, Inc.
</p>

View File

@@ -83,4 +83,4 @@ export function GcmpLogo({
</defs>
</svg>
);
}
}

View File

@@ -9,8 +9,6 @@
"packageManager": "pnpm@9.1.4",
"devDependencies": {
"@changesets/cli": "^2.27.3",
"husky": "^9.0.11",
"lint-staged": "^15.2.2",
"prettier": "^3.1.1",
"ts-node": "^10.9.1",
"turbo": "^1.11.2",
@@ -25,8 +23,7 @@
"format": "pnpm run -r format && cd homepage/homepage && pnpm run format",
"changeset": "changeset",
"changeset-version": "changeset version",
"release": "pnpm changeset publish && git push --follow-tags",
"prepare": "husky"
"release": "pnpm changeset publish && git push --follow-tags"
},
"lint-staged": {},
"version": "0.0.0"

View File

@@ -1,5 +1,26 @@
# cojson-storage-indexeddb
## 0.7.23
### Patch Changes
- Updated dependencies
- cojson@0.7.23
## 0.7.18
### Patch Changes
- Updated dependencies
- cojson@0.7.18
## 0.7.17
### Patch Changes
- Updated dependencies
- cojson@0.7.17
## 0.7.14
### Patch Changes

View File

@@ -1,13 +1,13 @@
{
"name": "cojson-storage-indexeddb",
"version": "0.7.14",
"version": "0.7.23",
"main": "dist/index.js",
"type": "module",
"types": "src/index.ts",
"license": "MIT",
"dependencies": {
"cojson": "workspace:*",
"effect": "^3.1.5",
"effect": "^3.5.2",
"typescript": "^5.1.6"
},
"devDependencies": {

View File

@@ -1,5 +1,26 @@
# cojson-storage-sqlite
## 0.7.23
### Patch Changes
- Updated dependencies
- cojson@0.7.23
## 0.7.18
### Patch Changes
- Updated dependencies
- cojson@0.7.18
## 0.7.17
### Patch Changes
- Updated dependencies
- cojson@0.7.17
## 0.7.14
### Patch Changes

View File

@@ -1,14 +1,14 @@
{
"name": "cojson-storage-sqlite",
"type": "module",
"version": "0.7.14",
"version": "0.7.23",
"main": "dist/index.js",
"types": "src/index.ts",
"license": "MIT",
"dependencies": {
"better-sqlite3": "^8.5.2",
"cojson": "workspace:*",
"effect": "^3.1.5",
"effect": "^3.5.2",
"typescript": "^5.1.6"
},
"devDependencies": {

View File

@@ -1,5 +1,32 @@
# cojson-transport-nodejs-ws
## 0.7.23
### Patch Changes
- Updated dependencies
- cojson@0.7.23
## 0.7.22
### Patch Changes
- Increase disconnect timeout for now
## 0.7.18
### Patch Changes
- Updated dependencies
- cojson@0.7.18
## 0.7.17
### Patch Changes
- Updated dependencies
- cojson@0.7.17
## 0.7.14
### Patch Changes

View File

@@ -1,13 +1,13 @@
{
"name": "cojson-transport-ws",
"type": "module",
"version": "0.7.14",
"version": "0.7.23",
"main": "dist/index.js",
"types": "src/index.ts",
"license": "MIT",
"dependencies": {
"cojson": "workspace:*",
"effect": "^3.1.5",
"effect": "^3.5.2",
"typescript": "^5.1.6"
},
"scripts": {

View File

@@ -1,20 +1,37 @@
import { DisconnectedError, Peer, PingTimeoutError, SyncMessage } from "cojson";
import { Either, Stream, Queue, Effect, Exit } from "effect";
import { Stream, Queue, Effect, Console } from "effect";
interface WebsocketEvents {
close: { code: number; reason: string };
message: { data: unknown };
open: void;
}
interface PingMsg {
time: number;
dc: string;
}
interface AnyWebSocket {
addEventListener(
type: "close",
listener: (event: { code: number; reason: string }) => void,
addEventListener<K extends keyof WebsocketEvents>(
type: K,
listener: (event: WebsocketEvents[K]) => void,
): void;
addEventListener(
type: "message",
listener: (event: { data: string | unknown }) => void,
removeEventListener<K extends keyof WebsocketEvents>(
type: K,
listener: (event: WebsocketEvents[K]) => void,
): void;
addEventListener(type: "open", listener: () => void): void;
close(): void;
send(data: string): void;
}
const g: typeof globalThis & {
jazzPings?: {
received: number;
sent: number;
dc: string;
}[];
} = globalThis;
export function createWebSocketPeer(options: {
id: string;
websocket: AnyWebSocket;
@@ -22,87 +39,81 @@ export function createWebSocketPeer(options: {
}): Effect.Effect<Peer> {
return Effect.gen(function* () {
const ws = options.websocket;
const ws_ = ws as unknown as Stream.EventListener<WebsocketEvents["message"]>;
const incoming =
yield* Queue.unbounded<
Either.Either<SyncMessage, DisconnectedError | PingTimeoutError>
>();
const outgoing = yield* Queue.unbounded<SyncMessage>();
ws.addEventListener("close", (event) => {
void Effect.runPromiseExit(
Queue.offer(
incoming,
Either.left(
new DisconnectedError(`${event.code}: ${event.reason}`),
const closed = once(ws, "close").pipe(
Effect.flatMap(
(event) =>
new DisconnectedError({
message: `${event.code}: ${event.reason}`,
}),
),
Stream.fromEffect,
);
const isSyncMessage = (msg: unknown): msg is SyncMessage => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
if ((msg as any)?.type === "ping") {
const ping = msg as PingMsg;
g.jazzPings ||= [];
g.jazzPings.push({
received: Date.now(),
sent: ping.time,
dc: ping.dc,
});
return false;
}
return true;
};
yield* Effect.forkDaemon(Effect.gen(function* () {
yield* once(ws, "open");
yield* Queue.take(outgoing).pipe(
Effect.andThen((message) => ws.send(JSON.stringify(message))),
Effect.forever,
);
}));
type E = WebsocketEvents["message"];
const messages = Stream.fromEventListener<E>(ws_, "message").pipe(
Stream.timeoutFail(() => new PingTimeoutError(), "10 seconds"),
Stream.tapError((_e) =>
Console.warn("Ping timeout").pipe(
Effect.andThen(Effect.try(() => ws.close())),
Effect.catchAll((e) =>
Console.error(
"Error while trying to close ws on ping timeout",
e,
),
),
),
).then((e) => {
if (Exit.isFailure(e) && !Exit.isInterrupted(e)) {
console.warn("Failed closing ws", e);
}
});
});
let pingTimeout: ReturnType<typeof setTimeout> | undefined;
ws.addEventListener("message", (event) => {
const msg = JSON.parse(event.data as string);
if (pingTimeout) {
clearTimeout(pingTimeout);
}
pingTimeout = setTimeout(() => {
console.debug("Ping timeout");
void Effect.runPromise(
Queue.offer(incoming, Either.left(new PingTimeoutError())),
);
try {
ws.close();
} catch (e) {
console.error(
"Error while trying to close ws on ping timeout",
e,
);
}
}, 2500);
if (msg.type === "ping") {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(globalThis as any).jazzPings =
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(globalThis as any).jazzPings || [];
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(globalThis as any).jazzPings.push({
received: Date.now(),
sent: msg.time,
dc: msg.dc,
});
return;
} else {
void Effect.runPromise(
Queue.offer(incoming, Either.right(msg)),
);
}
});
ws.addEventListener("open", () => {
void Stream.fromQueue(outgoing).pipe(
Stream.runForEach((msg) =>
Effect.sync(() => ws.send(JSON.stringify(msg))),
),
Effect.runPromise,
);
});
),
Stream.mergeLeft(closed),
Stream.map((_) => JSON.parse(_.data as string)),
Stream.filter(isSyncMessage),
Stream.buffer({ capacity: "unbounded" }),
Stream.onDone(() => Queue.shutdown(outgoing)),
);
return {
id: options.id,
incoming: Stream.fromQueue(incoming, { shutdown: true }).pipe(
Stream.mapEffect((either) => either),
),
incoming: messages,
outgoing,
role: options.role,
};
});
}
const once = <Event extends keyof WebsocketEvents>(
ws: AnyWebSocket,
event: Event,
) =>
Effect.async<WebsocketEvents[Event]>((register) => {
const cb = (msg: WebsocketEvents[Event]) => {
ws.removeEventListener(event, cb);
register(Effect.succeed(msg));
};
ws.addEventListener(event, cb);
});

View File

@@ -1,5 +1,23 @@
# cojson
## 0.7.23
### Patch Changes
- Mostly complete OPFS implementation (single-tab only)
## 0.7.18
### Patch Changes
- Update to Effect 3.5.2
## 0.7.17
### Patch Changes
- Fix bugs in new storage interface
## 0.7.14
### Patch Changes

View File

@@ -5,7 +5,7 @@
"types": "src/index.ts",
"type": "module",
"license": "MIT",
"version": "0.7.14",
"version": "0.7.23",
"devDependencies": {
"@types/jest": "^29.5.3",
"@typescript-eslint/eslint-plugin": "^6.2.1",
@@ -22,7 +22,7 @@
"@noble/ciphers": "^0.1.3",
"@noble/hashes": "^1.4.0",
"@scure/base": "^1.1.1",
"effect": "^3.1.5",
"effect": "^3.5.2",
"hash-wasm": "^4.9.0"
},
"scripts": {

View File

@@ -3,7 +3,7 @@ import { CoValueChunk } from "./index.js";
import { RawCoID } from "../ids.js";
import { CryptoProvider, StreamingHash } from "../crypto/crypto.js";
export type BlockFilename = `${string}-L${number}-H${number}.jsonl`;
export type BlockFilename = `L${number}-${string}-${string}-H${number}.jsonl`;
export type BlockHeader = { id: RawCoID; start: number; length: number }[];
@@ -78,8 +78,9 @@ export function readHeader<RH, FS extends FileSystem<unknown, RH>>(
export function writeBlock<WH, RH, FS extends FileSystem<WH, RH>>(
chunks: Map<RawCoID, CoValueChunk>,
level: number,
blockNumber: number,
fs: FS,
): Effect.Effect<void, FSErr> {
): Effect.Effect<BlockFilename, FSErr> {
if (chunks.size === 0) {
return Effect.die(new Error("No chunks to write"));
}
@@ -118,20 +119,26 @@ export function writeBlock<WH, RH, FS extends FileSystem<WH, RH>>(
const headerBytes = textEncoder.encode(JSON.stringify(blockHeader));
yield* $(fs.append(file, headerBytes));
console.log(
"full file",
yield* $(
fs.read(file as unknown as RH, 0, offset + headerBytes.length),
),
);
// console.log(
// "full file",
// yield* $(
// fs.read(file as unknown as RH, 0, offset + headerBytes.length),
// ),
// );
const filename: BlockFilename = `${hash.digest()}-L${level}-H${
headerBytes.length
}.jsonl`;
console.log("renaming to" + filename);
const filename: BlockFilename = `L${level}-${(
blockNumber + ""
).padStart(3, "0")}-${hash
.digest()
.replace("hash_", "")
.slice(0, 15)}-H${headerBytes.length}.jsonl`;
// console.log("renaming to" + filename);
yield* $(fs.closeAndRename(file, filename));
console.log("Wrote block", filename, blockHeader);
return filename;
// console.log("Wrote block", filename, blockHeader);
// console.log("IDs in block", blockHeader.map(e => e.id));
});
}
@@ -147,6 +154,7 @@ export function writeToWal<WH, RH, FS extends FileSystem<WH, RH>>(
...chunk,
};
const bytes = textEncoder.encode(JSON.stringify(walEntry) + "\n");
console.log("writing to WAL", handle, id, bytes.length);
yield* $(fs.append(handle, bytes));
});
}

View File

@@ -126,10 +126,12 @@ export function mergeChunks(
} else {
const lastNewEntry = newEntries[newEntries.length - 1]!;
lastNewEntry.transactions.push(...entry.transactions);
lastNewEntry.lastSignature = entry.lastSignature;
bytesSinceLastSignature += entry.transactions.length;
}
}
newSessions[sessionID] = newEntries;
} else {
return Either.right("nonContigous" as const);
}

View File

@@ -1,4 +1,11 @@
import { Effect, Either, Queue, Stream, SynchronizedRef } from "effect";
import {
Effect,
Either,
Queue,
Stream,
SynchronizedRef,
Deferred,
} from "effect";
import { RawCoID } from "../ids.js";
import { CoValueHeader, Transaction } from "../coValueCore.js";
import { Signature } from "../crypto/crypto.js";
@@ -30,6 +37,8 @@ import {
} from "./FileSystem.js";
export type { FSErr, BlockFilename, WalFilename } from "./FileSystem.js";
const MAX_N_LEVELS = 3;
export type CoValueChunk = {
header?: CoValueHeader;
sessionEntries: {
@@ -51,6 +60,10 @@ export class LSMStorage<WH, RH, FS extends FileSystem<WH, RH>> {
BlockFilename,
{ [id: RawCoID]: { start: number; length: number } }
>();
blockFileHandles = new Map<
BlockFilename,
Deferred.Deferred<{ handle: RH; size: number }, FSErr>
>();
constructor(
public fs: FS,
@@ -192,7 +205,7 @@ export class LSMStorage<WH, RH, FS extends FileSystem<WH, RH>> {
let newWal = wal;
if (!newWal) {
newWal = yield* this.fs.createFile(
`wal-${new Date().toISOString()}-${Math.random()
`wal-${Date.now()}-${Math.random()
.toString(36)
.slice(2)}.jsonl`,
);
@@ -232,7 +245,7 @@ export class LSMStorage<WH, RH, FS extends FileSystem<WH, RH>> {
if (!coValue) {
if (newContent.header) {
console.log("Creating in WAL", newContent.id);
// console.log("Creating in WAL", newContent.id);
yield* this.withWAL((wal) =>
writeToWal(
wal,
@@ -258,7 +271,7 @@ export class LSMStorage<WH, RH, FS extends FileSystem<WH, RH>> {
// })
// )
// );
console.warn(
yield* Effect.logWarning(
"Incontiguous incoming update for " + newContent.id,
);
return coValues;
@@ -268,6 +281,23 @@ export class LSMStorage<WH, RH, FS extends FileSystem<WH, RH>> {
if (Either.isRight(merged)) {
yield* Effect.logWarning(
"Non-contigous new content for " + newContent.id,
Object.entries(coValue.sessionEntries).map(
([session, entries]) =>
entries.map((entry) => ({
session: session,
after: entry.after,
length: entry.transactions.length,
})),
),
Object.entries(
newContentAsChunk.sessionEntries,
).map(([session, entries]) =>
entries.map((entry) => ({
session: session,
after: entry.after,
length: entry.transactions.length,
})),
),
);
// yield* Effect.promise(() =>
@@ -280,7 +310,7 @@ export class LSMStorage<WH, RH, FS extends FileSystem<WH, RH>> {
return coValues;
} else {
console.log("Appending to WAL", newContent.id);
// console.log("Appending to WAL", newContent.id);
yield* this.withWAL((wal) =>
writeToWal(
wal,
@@ -297,24 +327,65 @@ export class LSMStorage<WH, RH, FS extends FileSystem<WH, RH>> {
);
}
loadCoValue<WH, RH, FS extends FileSystem<WH, RH>>(
getBlockHandle(
blockFile: BlockFilename,
fs: FS,
): Effect.Effect<{ handle: RH; size: number }, FSErr> {
return Effect.gen(this, function* () {
let handleAndSize = this.blockFileHandles.get(blockFile);
if (!handleAndSize) {
handleAndSize = yield* Deferred.make<
{ handle: RH; size: number },
FSErr
>();
this.blockFileHandles.set(blockFile, handleAndSize);
yield* Deferred.complete(
handleAndSize,
fs.openToRead(blockFile),
);
}
return yield* Deferred.await(handleAndSize);
});
}
loadCoValue(
id: RawCoID,
fs: FS,
): Effect.Effect<CoValueChunk | undefined, FSErr> {
// return _loadChunkFromWal(id, fs);
return Effect.gen(this, function* () {
const files = this.fileCache || (yield* fs.listFiles());
this.fileCache = files;
const blockFiles = files.filter((name) =>
name.startsWith("hash_"),
) as BlockFilename[];
const blockFiles = (
files.filter((name) => name.startsWith("L")) as BlockFilename[]
).sort();
let result;
for (const blockFile of blockFiles) {
let cachedHeader:
| { [id: RawCoID]: { start: number; length: number } }
| undefined = this.headerCache.get(blockFile);
const { handle, size } = yield* fs.openToRead(blockFile);
let handleAndSize = this.blockFileHandles.get(blockFile);
if (!handleAndSize) {
handleAndSize = yield* Deferred.make<
{ handle: RH; size: number },
FSErr
>();
this.blockFileHandles.set(blockFile, handleAndSize);
yield* Deferred.complete(
handleAndSize,
fs.openToRead(blockFile),
);
}
const { handle, size } = yield* this.getBlockHandle(
blockFile,
fs,
);
// console.log("Attempting to load", id, blockFile);
if (!cachedHeader) {
cachedHeader = {};
@@ -335,17 +406,31 @@ export class LSMStorage<WH, RH, FS extends FileSystem<WH, RH>> {
}
const headerEntry = cachedHeader[id];
let result;
// console.log("Header entry", id, headerEntry);
if (headerEntry) {
result = yield* readChunk(handle, headerEntry, fs);
const nextChunk = yield* readChunk(handle, headerEntry, fs);
if (result) {
const merged = mergeChunks(result, nextChunk);
if (Either.isRight(merged)) {
yield* Effect.logWarning(
"Non-contigous chunks while loading " + id,
result,
nextChunk,
);
} else {
result = merged.left;
}
} else {
result = nextChunk;
}
}
yield* fs.close(handle);
return result;
// yield* fs.close(handle);
}
return undefined;
return result;
});
}
@@ -361,7 +446,7 @@ export class LSMStorage<WH, RH, FS extends FileSystem<WH, RH>> {
const coValues = new Map<RawCoID, CoValueChunk>();
console.log("Compacting WAL files", walFiles);
yield* Effect.log("Compacting WAL files", walFiles);
if (walFiles.length === 0) return;
yield* SynchronizedRef.updateEffect(this.currentWal, (wal) =>
@@ -374,7 +459,7 @@ export class LSMStorage<WH, RH, FS extends FileSystem<WH, RH>> {
);
for (const fileName of walFiles) {
const { handle, size } =
const { handle, size }: { handle: RH; size: number } =
yield* this.fs.openToRead(fileName);
if (size === 0) {
yield* this.fs.close(handle);
@@ -394,7 +479,7 @@ export class LSMStorage<WH, RH, FS extends FileSystem<WH, RH>> {
if (existingChunk) {
const merged = mergeChunks(existingChunk, chunk);
if (Either.isRight(merged)) {
console.warn(
yield* Effect.logWarning(
"Non-contigous chunks in " +
chunk.id +
", " +
@@ -413,11 +498,150 @@ export class LSMStorage<WH, RH, FS extends FileSystem<WH, RH>> {
yield* this.fs.close(handle);
}
yield* writeBlock(coValues, 0, this.fs);
const highestBlockNumber = fileNames.reduce((acc, name) => {
if (name.startsWith("L" + MAX_N_LEVELS)) {
const num = parseInt(name.split("-")[1]!);
if (num > acc) {
return num;
}
}
return acc;
}, 0);
console.log(
[...coValues.keys()],
fileNames,
highestBlockNumber,
);
yield* writeBlock(
coValues,
MAX_N_LEVELS,
highestBlockNumber + 1,
this.fs,
);
for (const walFile of walFiles) {
yield* this.fs.removeFile(walFile);
}
this.fileCache = undefined;
const fileNames2 = yield* this.fs.listFiles();
const blockFiles = (
fileNames2.filter((name) =>
name.startsWith("L"),
) as BlockFilename[]
).sort();
const blockFilesByLevelInOrder: {
[level: number]: BlockFilename[];
} = {};
for (const blockFile of blockFiles) {
const level = parseInt(blockFile.split("-")[0]!.slice(1));
if (!blockFilesByLevelInOrder[level]) {
blockFilesByLevelInOrder[level] = [];
}
blockFilesByLevelInOrder[level]!.push(blockFile);
}
console.log(blockFilesByLevelInOrder);
for (let level = MAX_N_LEVELS; level > 0; level--) {
const nBlocksDesired = Math.pow(2, level);
const blocksInLevel = blockFilesByLevelInOrder[level];
if (
blocksInLevel &&
blocksInLevel.length > nBlocksDesired
) {
yield* Effect.log("Compacting blocks in level", level, blocksInLevel);
const coValues = new Map<RawCoID, CoValueChunk>();
for (const blockFile of blocksInLevel) {
const {
handle,
size,
}: { handle: RH; size: number } =
yield* this.getBlockHandle(blockFile, this.fs);
if (size === 0) {
continue;
}
const header = yield* readHeader(
blockFile,
handle,
size,
this.fs,
);
for (const entry of header) {
const chunk = yield* readChunk(
handle,
entry,
this.fs,
);
const existingChunk = coValues.get(entry.id);
if (existingChunk) {
const merged = mergeChunks(
existingChunk,
chunk,
);
if (Either.isRight(merged)) {
yield* Effect.logWarning(
"Non-contigous chunks in " +
entry.id +
", " +
blockFile,
existingChunk,
chunk,
);
} else {
coValues.set(entry.id, merged.left);
}
} else {
coValues.set(entry.id, chunk);
}
}
}
let levelBelow = blockFilesByLevelInOrder[level - 1];
if (!levelBelow) {
levelBelow = [];
blockFilesByLevelInOrder[level - 1] = levelBelow;
}
const highestBlockNumberInLevelBelow =
levelBelow.reduce((acc, name) => {
const num = parseInt(name.split("-")[1]!);
if (num > acc) {
return num;
}
return acc;
}, 0);
const newBlockName = yield* writeBlock(
coValues,
level - 1,
highestBlockNumberInLevelBelow + 1,
this.fs,
);
levelBelow.push(newBlockName);
// delete blocks that went into this one
for (const blockFile of blocksInLevel) {
const handle = yield* this.getBlockHandle(
blockFile,
this.fs,
);
yield* this.fs.close(handle.handle);
yield* this.fs.removeFile(blockFile);
}
}
}
}),
);

View File

@@ -47,18 +47,24 @@ export function newQueuePair(
const queue = yield* Queue.unbounded<SyncMessage>();
if (options.traceAs) {
return [Stream.fromQueue(queue).pipe(Stream.tap((msg) => Console.debug(
options.traceAs,
JSON.stringify(
msg,
(k, v) =>
k === "changes" ||
k === "encryptedChanges"
? v.slice(0, 20) + "..."
: v,
2,
return [
Stream.fromQueue(queue).pipe(
Stream.tap((msg) =>
Console.debug(
options.traceAs,
JSON.stringify(
msg,
(k, v) =>
k === "changes" || k === "encryptedChanges"
? v.slice(0, 20) + "..."
: v,
2,
),
),
),
),
))), queue];
queue,
];
} else {
return [Stream.fromQueue(queue), queue];
}

View File

@@ -3,7 +3,7 @@ import { CoValueHeader, Transaction } from "./coValueCore.js";
import { CoValueCore } from "./coValueCore.js";
import { LocalNode, newLoadingState } from "./localNode.js";
import { RawCoID, SessionID } from "./ids.js";
import { Effect, Queue, Stream } from "effect";
import { Data, Effect, Queue, Stream } from "effect";
export type CoValueKnownState = {
id: RawCoID;
@@ -56,12 +56,9 @@ export type DoneMessage = {
export type PeerID = string;
export class DisconnectedError extends Error {
readonly _tag = "DisconnectedError";
constructor(public message: string) {
super(message);
}
}
export class DisconnectedError extends Data.TaggedError("DisconnectedError")<{
message: string;
}> {}
export class PingTimeoutError extends Error {
readonly _tag = "PingTimeoutError";

View File

@@ -53,13 +53,15 @@ test("Can create account with one node, and then load it on another", async () =
map.set("foo", "bar", "private");
expect(map.get("foo")).toEqual("bar");
const [node1asPeer, node2asPeer] = await Effect.runPromise(connectedPeers("node1", "node2", {
trace: true,
peer1role: "server",
peer2role: "client",
}));
const [node1asPeer, node2asPeer] = await Effect.runPromise(
connectedPeers("node1", "node2", {
trace: true,
peer1role: "server",
peer2role: "client",
}),
);
console.log("After connected peers")
console.log("After connected peers");
node.syncManager.addPeer(node2asPeer);

View File

@@ -1,5 +1,57 @@
# jazz-browser-media-images
## 0.7.23
### Patch Changes
- Updated dependencies
- jazz-tools@0.7.23
- jazz-browser@0.7.23
## 0.7.22
### Patch Changes
- jazz-browser@0.7.22
## 0.7.21
### Patch Changes
- Updated dependencies
- jazz-tools@0.7.21
- jazz-browser@0.7.21
## 0.7.20
### Patch Changes
- Updated dependencies
- jazz-tools@0.7.20
- jazz-browser@0.7.20
## 0.7.19
### Patch Changes
- Updated dependencies
- jazz-tools@0.7.19
- jazz-browser@0.7.19
## 0.7.18
### Patch Changes
- jazz-browser@0.7.18
- jazz-tools@0.7.18
## 0.7.17
### Patch Changes
- jazz-browser@0.7.17
- jazz-tools@0.7.17
## 0.7.16
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "jazz-browser-media-images",
"version": "0.7.16",
"version": "0.7.23",
"type": "module",
"main": "dist/index.js",
"types": "src/index.ts",

View File

@@ -1,5 +1,63 @@
# jazz-browser
## 0.7.23
### Patch Changes
- Updated dependencies
- cojson@0.7.23
- jazz-tools@0.7.23
- cojson-storage-indexeddb@0.7.23
- cojson-transport-ws@0.7.23
## 0.7.22
### Patch Changes
- Updated dependencies
- cojson-transport-ws@0.7.22
## 0.7.21
### Patch Changes
- Updated dependencies
- jazz-tools@0.7.21
## 0.7.20
### Patch Changes
- Updated dependencies
- jazz-tools@0.7.20
## 0.7.19
### Patch Changes
- Updated dependencies
- jazz-tools@0.7.19
## 0.7.18
### Patch Changes
- Updated dependencies
- cojson@0.7.18
- cojson-storage-indexeddb@0.7.18
- cojson-transport-ws@0.7.18
- jazz-tools@0.7.18
## 0.7.17
### Patch Changes
- Updated dependencies
- cojson@0.7.17
- cojson-storage-indexeddb@0.7.17
- cojson-transport-ws@0.7.17
- jazz-tools@0.7.17
## 0.7.16
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "jazz-browser",
"version": "0.7.16",
"version": "0.7.23",
"type": "module",
"main": "dist/index.js",
"types": "src/index.ts",
@@ -10,7 +10,7 @@
"cojson": "workspace:*",
"cojson-storage-indexeddb": "workspace:*",
"cojson-transport-ws": "workspace:*",
"effect": "^3.1.5",
"effect": "^3.5.2",
"jazz-tools": "workspace:*",
"typescript": "^5.1.6"
},

View File

@@ -7,7 +7,7 @@ import {
} from "cojson";
import { Effect } from "effect";
export class OPFSFilesystem implements FileSystem<number, number> {
export class OPFSFilesystem implements FileSystem<{id: number, filename: string}, {id: number, filename: string}> {
opfsWorker: Worker;
callbacks: Map<number, (event: MessageEvent) => void> = new Map();
nextRequestId = 0;
@@ -31,13 +31,13 @@ export class OPFSFilesystem implements FileSystem<number, number> {
listFiles(): Effect.Effect<string[], FSErr, never> {
return Effect.async((cb) => {
const requestId = this.nextRequestId++;
performance.mark("listFiles" + requestId);
performance.mark("listFiles" + requestId + "_listFiles");
this.callbacks.set(requestId, (event) => {
performance.mark("listFilesEnd" + requestId);
performance.mark("listFilesEnd" + requestId + "_listFiles");
performance.measure(
"listFiles" + requestId,
"listFiles" + requestId,
"listFilesEnd" + requestId,
"listFiles" + requestId + "_listFiles",
"listFiles" + requestId + "_listFiles",
"listFilesEnd" + requestId + "_listFiles",
);
cb(Effect.succeed(event.data.fileNames));
});
@@ -47,22 +47,22 @@ export class OPFSFilesystem implements FileSystem<number, number> {
openToRead(
filename: string,
): Effect.Effect<{ handle: number; size: number }, FSErr, never> {
): Effect.Effect<{ handle: {id: number, filename: string}; size: number }, FSErr, never> {
return Effect.async((cb) => {
const requestId = this.nextRequestId++;
performance.mark("openToRead" + requestId);
performance.mark("openToRead" + "_" + filename);
this.callbacks.set(requestId, (event) => {
cb(
Effect.succeed({
handle: event.data.handle,
handle: {id: event.data.handle, filename},
size: event.data.size,
}),
);
performance.mark("openToReadEnd" + requestId);
performance.mark("openToReadEnd" + "_" + filename);
performance.measure(
"openToRead" + requestId,
"openToRead" + requestId,
"openToReadEnd" + requestId,
"openToRead" + "_" + filename,
"openToRead" + "_" + filename,
"openToReadEnd" + "_" + filename,
);
});
this.opfsWorker.postMessage({
@@ -73,18 +73,18 @@ export class OPFSFilesystem implements FileSystem<number, number> {
});
}
createFile(filename: string): Effect.Effect<number, FSErr, never> {
createFile(filename: string): Effect.Effect<{id: number, filename: string}, FSErr, never> {
return Effect.async((cb) => {
const requestId = this.nextRequestId++;
performance.mark("createFile" + requestId);
performance.mark("createFile" + "_" + filename);
this.callbacks.set(requestId, (event) => {
performance.mark("createFileEnd" + requestId);
performance.mark("createFileEnd" + "_" + filename);
performance.measure(
"createFile" + requestId,
"createFile" + requestId,
"createFileEnd" + requestId,
"createFile" + "_" + filename,
"createFile" + "_" + filename,
"createFileEnd" + "_" + filename,
);
cb(Effect.succeed(event.data.handle));
cb(Effect.succeed({id: event.data.handle, filename}));
});
this.opfsWorker.postMessage({
type: "createFile",
@@ -96,18 +96,18 @@ export class OPFSFilesystem implements FileSystem<number, number> {
openToWrite(
filename: string,
): Effect.Effect<FileSystemFileHandle, FSErr, never> {
): Effect.Effect<{id: number, filename: string}, FSErr, never> {
return Effect.async((cb) => {
const requestId = this.nextRequestId++;
performance.mark("openToWrite" + requestId);
performance.mark("openToWrite" + "_" + filename);
this.callbacks.set(requestId, (event) => {
performance.mark("openToWriteEnd" + requestId);
performance.mark("openToWriteEnd" + "_" + filename);
performance.measure(
"openToWrite" + requestId,
"openToWrite" + requestId,
"openToWriteEnd" + requestId,
"openToWrite" + "_" + filename,
"openToWrite" + "_" + filename,
"openToWriteEnd" + "_" + filename,
);
cb(Effect.succeed(event.data.handle));
cb(Effect.succeed({id: event.data.handle, filename}));
});
this.opfsWorker.postMessage({
type: "openToWrite",
@@ -118,24 +118,24 @@ export class OPFSFilesystem implements FileSystem<number, number> {
}
append(
handle: number,
handle: {id: number, filename: string},
data: Uint8Array,
): Effect.Effect<void, FSErr, never> {
return Effect.async((cb) => {
const requestId = this.nextRequestId++;
performance.mark("append" + requestId);
performance.mark("append" + "_" + handle.filename);
this.callbacks.set(requestId, (_) => {
performance.mark("appendEnd" + requestId);
performance.mark("appendEnd" + "_" + handle.filename);
performance.measure(
"append" + requestId,
"append" + requestId,
"appendEnd" + requestId,
"append" + "_" + handle.filename,
"append" + "_" + handle.filename,
"appendEnd" + "_" + handle.filename,
);
cb(Effect.succeed(undefined));
});
this.opfsWorker.postMessage({
type: "append",
handle,
handle: handle.id,
data,
requestId,
});
@@ -143,25 +143,25 @@ export class OPFSFilesystem implements FileSystem<number, number> {
}
read(
handle: number,
handle: {id: number, filename: string},
offset: number,
length: number,
): Effect.Effect<Uint8Array, FSErr, never> {
return Effect.async((cb) => {
const requestId = this.nextRequestId++;
performance.mark("read" + requestId);
performance.mark("read" + "_" + handle.filename);
this.callbacks.set(requestId, (event) => {
performance.mark("readEnd" + requestId);
performance.mark("readEnd" + "_" + handle.filename);
performance.measure(
"read" + requestId,
"read" + requestId,
"readEnd" + requestId,
"read" + "_" + handle.filename,
"read" + "_" + handle.filename,
"readEnd" + "_" + handle.filename,
);
cb(Effect.succeed(event.data.data));
});
this.opfsWorker.postMessage({
type: "read",
handle,
handle: handle.id,
offset,
length,
requestId,
@@ -169,46 +169,48 @@ export class OPFSFilesystem implements FileSystem<number, number> {
});
}
close(handle: number): Effect.Effect<void, FSErr, never> {
close(handle: {id: number, filename: string}): Effect.Effect<void, FSErr, never> {
return Effect.async((cb) => {
const requestId = this.nextRequestId++;
performance.mark("close" + requestId);
performance.mark("close" + "_" + handle.filename);
this.callbacks.set(requestId, (_) => {
performance.mark("closeEnd" + requestId);
performance.mark("closeEnd" + "_" + handle.filename);
performance.measure(
"close" + requestId,
"close" + requestId,
"closeEnd" + requestId,
"close" + "_" + handle.filename,
"close" + "_" + handle.filename,
"closeEnd" + "_" + handle.filename,
);
cb(Effect.succeed(undefined));
});
this.opfsWorker.postMessage({
type: "close",
handle,
handle: handle.id,
requestId,
});
});
}
closeAndRename(
handle: number,
handle: {id: number, filename: string},
filename: BlockFilename,
): Effect.Effect<void, FSErr, never> {
return Effect.async((cb) => {
const requestId = this.nextRequestId++;
performance.mark("closeAndRename" + requestId);
performance.mark("closeAndRename" + "_" + handle.filename);
this.callbacks.set(requestId, () => {
performance.mark("closeAndRenameEnd" + requestId);
performance.mark(
"closeAndRenameEnd" + "_" + handle.filename,
);
performance.measure(
"closeAndRename" + requestId,
"closeAndRename" + requestId,
"closeAndRenameEnd" + requestId,
"closeAndRename" + "_" + handle.filename,
"closeAndRename" + "_" + handle.filename,
"closeAndRenameEnd" + "_" + handle.filename,
);
cb(Effect.succeed(undefined));
});
this.opfsWorker.postMessage({
type: "closeAndRename",
handle,
handle: handle.id,
filename,
requestId,
});
@@ -220,13 +222,13 @@ export class OPFSFilesystem implements FileSystem<number, number> {
): Effect.Effect<void, FSErr, never> {
return Effect.async((cb) => {
const requestId = this.nextRequestId++;
performance.mark("removeFile" + requestId);
performance.mark("removeFile" + "_" + filename);
this.callbacks.set(requestId, () => {
performance.mark("removeFileEnd" + requestId);
performance.mark("removeFileEnd" + "_" + filename);
performance.measure(
"removeFile" + requestId,
"removeFile" + requestId,
"removeFileEnd" + requestId,
"removeFile" + "_" + filename,
"removeFile" + "_" + filename,
"removeFileEnd" + "_" + filename,
);
cb(Effect.succeed(undefined));
});
@@ -309,7 +311,7 @@ const opfsWorkerJSSrc = `
postMessage({requestId: event.data.requestId, data: buffer, result: "done"});
} else if (event.data.type === "close") {
const handle = handlesByRequest.get(event.data.handle);
console.log("Closing handle", filenamesForHandles.get(handle), event.data.handle, handle);
// console.log("Closing handle", filenamesForHandles.get(handle), event.data.handle, handle);
handle.flush();
handle.close();
handlesByRequest.delete(handle);

View File

@@ -10,10 +10,7 @@ import {
WasmCrypto,
CryptoProvider,
} from "jazz-tools";
import {
AccountID,
LSMStorage,
} from "cojson";
import { AccountID, LSMStorage } from "cojson";
import { AuthProvider } from "./auth/auth.js";
import { OPFSFilesystem } from "./OPFSFilesystem.js";
import { IDBStorage } from "cojson-storage-indexeddb";
@@ -39,7 +36,7 @@ export async function createJazzBrowserContext<Acc extends Account>({
auth: AuthProvider<Acc>;
peer: `wss://${string}` | `ws://${string}`;
reconnectionTimeout?: number;
storage?: "indexedDB" | "experimentalOPFSdoNotUseOrYouWillBeFired";
storage?: "indexedDB" | "singleTabOPFS";
crypto?: CryptoProvider;
}): Promise<BrowserContext<Acc>> {
const crypto = customCrypto || (await WasmCrypto.create());

View File

@@ -1,5 +1,60 @@
# jazz-autosub
## 0.7.23
### Patch Changes
- Updated dependencies
- cojson@0.7.23
- jazz-tools@0.7.23
- cojson-transport-ws@0.7.23
## 0.7.22
### Patch Changes
- Updated dependencies
- cojson-transport-ws@0.7.22
## 0.7.21
### Patch Changes
- Updated dependencies
- jazz-tools@0.7.21
## 0.7.20
### Patch Changes
- Updated dependencies
- jazz-tools@0.7.20
## 0.7.19
### Patch Changes
- Updated dependencies
- jazz-tools@0.7.19
## 0.7.18
### Patch Changes
- Updated dependencies
- cojson@0.7.18
- cojson-transport-ws@0.7.18
- jazz-tools@0.7.18
## 0.7.17
### Patch Changes
- Updated dependencies
- cojson@0.7.17
- cojson-transport-ws@0.7.17
- jazz-tools@0.7.17
## 0.7.16
### Patch Changes

View File

@@ -5,11 +5,11 @@
"types": "src/index.ts",
"type": "module",
"license": "MIT",
"version": "0.7.16",
"version": "0.7.23",
"dependencies": {
"cojson": "workspace:*",
"cojson-transport-ws": "workspace:*",
"effect": "^3.1.5",
"effect": "^3.5.2",
"jazz-tools": "workspace:*",
"ws": "^8.14.2"
},

View File

@@ -1,5 +1,63 @@
# jazz-react
## 0.7.23
### Patch Changes
- Mostly complete OPFS implementation (single-tab only)
- Updated dependencies
- cojson@0.7.23
- jazz-tools@0.7.23
- jazz-browser@0.7.23
## 0.7.22
### Patch Changes
- jazz-browser@0.7.22
## 0.7.21
### Patch Changes
- Updated dependencies
- jazz-tools@0.7.21
- jazz-browser@0.7.21
## 0.7.20
### Patch Changes
- Updated dependencies
- jazz-tools@0.7.20
- jazz-browser@0.7.20
## 0.7.19
### Patch Changes
- Updated dependencies
- jazz-tools@0.7.19
- jazz-browser@0.7.19
## 0.7.18
### Patch Changes
- Updated dependencies
- cojson@0.7.18
- jazz-browser@0.7.18
- jazz-tools@0.7.18
## 0.7.17
### Patch Changes
- Updated dependencies
- cojson@0.7.17
- jazz-browser@0.7.17
- jazz-tools@0.7.17
## 0.7.16
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "jazz-react",
"version": "0.7.16",
"version": "0.7.23",
"type": "module",
"main": "dist/index.js",
"types": "src/index.ts",

View File

@@ -104,7 +104,10 @@ const DemoAuthBasicUI = ({
signUp: (username: string) => void;
}) => {
const [username, setUsername] = useState<string>("");
const darkMode = typeof window !== 'undefined' ? window.matchMedia("(prefers-color-scheme: dark)").matches : false;
const darkMode =
typeof window !== "undefined"
? window.matchMedia("(prefers-color-scheme: dark)").matches
: false;
return (
<div

View File

@@ -23,7 +23,7 @@ export function createJazzReactContext<Acc extends Account>({
}: {
auth: ReactAuthHook<Acc>;
peer: `wss://${string}` | `ws://${string}`;
storage?: "indexedDB" | "experimentalOPFSdoNotUseOrYouWillBeFired";
storage?: "indexedDB" | "singleTabOPFS";
}): JazzReactContext<Acc> {
const JazzContext = React.createContext<
| {

View File

@@ -1,5 +1,60 @@
# jazz-autosub
## 0.7.23
### Patch Changes
- Updated dependencies
- cojson@0.7.23
- jazz-tools@0.7.23
- cojson-transport-ws@0.7.23
## 0.7.22
### Patch Changes
- Updated dependencies
- cojson-transport-ws@0.7.22
## 0.7.21
### Patch Changes
- Updated dependencies
- jazz-tools@0.7.21
## 0.7.20
### Patch Changes
- Updated dependencies
- jazz-tools@0.7.20
## 0.7.19
### Patch Changes
- Updated dependencies
- jazz-tools@0.7.19
## 0.7.18
### Patch Changes
- Updated dependencies
- cojson@0.7.18
- cojson-transport-ws@0.7.18
- jazz-tools@0.7.18
## 0.7.17
### Patch Changes
- Updated dependencies
- cojson@0.7.17
- cojson-transport-ws@0.7.17
- jazz-tools@0.7.17
## 0.7.16
### Patch Changes

View File

@@ -3,7 +3,7 @@
"bin": "./dist/index.js",
"type": "module",
"license": "MIT",
"version": "0.7.16",
"version": "0.7.23",
"scripts": {
"lint": "eslint . --ext ts,tsx",
"format": "prettier --write './src/**/*.{ts,tsx}'",
@@ -16,7 +16,7 @@
"@effect/schema": "^0.66.16",
"cojson": "workspace:*",
"cojson-transport-ws": "workspace:*",
"effect": "^3.1.5",
"effect": "^3.5.2",
"fast-check": "^3.17.2",
"jazz-tools": "workspace:*",
"ws": "^8.14.2"

View File

@@ -3,7 +3,7 @@ import { Command, Options } from "@effect/cli";
import { NodeContext, NodeRuntime } from "@effect/platform-node";
import { Console, Effect } from "effect";
import { createWebSocketPeer } from "cojson-transport-ws";
import { WebSocket } from "ws"
import { WebSocket } from "ws";
import {
Account,
WasmCrypto,

View File

@@ -1,5 +1,45 @@
# jazz-autosub
## 0.7.23
### Patch Changes
- Mostly complete OPFS implementation (single-tab only)
- Updated dependencies
- cojson@0.7.23
## 0.7.21
### Patch Changes
- Fix another bug in CoMap 'has' proxy trap
## 0.7.20
### Patch Changes
- Fix bug in CoMap 'has' trap
## 0.7.19
### Patch Changes
- Add support for "in" operator in CoMaps
## 0.7.18
### Patch Changes
- Updated dependencies
- cojson@0.7.18
## 0.7.17
### Patch Changes
- Updated dependencies
- cojson@0.7.17
## 0.7.16
### Patch Changes

View File

@@ -5,11 +5,11 @@
"types": "./src/index.ts",
"type": "module",
"license": "MIT",
"version": "0.7.16",
"version": "0.7.23",
"dependencies": {
"@effect/schema": "^0.66.16",
"cojson": "workspace:*",
"effect": "^3.1.5",
"effect": "^3.5.2",
"fast-check": "^3.17.2"
},
"scripts": {

View File

@@ -224,11 +224,13 @@ export class Account extends CoValueBase implements CoValue {
},
) {
// TODO: is there a cleaner way to do this?
const connectedPeers = await Effect.runPromise(cojsonInternals.connectedPeers(
"creatingAccount",
"createdAccount",
{ peer1role: "server", peer2role: "client" },
));
const connectedPeers = await Effect.runPromise(
cojsonInternals.connectedPeers(
"creatingAccount",
"createdAccount",
{ peer1role: "server", peer2role: "client" },
),
);
as._raw.core.node.syncManager.addPeer(connectedPeers[1]);

View File

@@ -610,6 +610,16 @@ const CoMapProxyHandler: ProxyHandler<CoMap> = {
}
}
},
has(target, key) {
const descriptor = (target._schema?.[key as keyof CoMap["_schema"]] ||
target._schema?.[ItemsSym]) as Schema;
if (target._raw && typeof key === "string" && descriptor) {
return target._raw.get(key) !== undefined;
} else {
return Reflect.has(target, key);
}
},
deleteProperty(target, key) {
const descriptor = (target._schema[key as keyof CoMap["_schema"]] ||
target._schema[ItemsSym]) as Schema;

View File

@@ -17,6 +17,36 @@ export type IfCo<C, R> = C extends infer _A | infer B
: never;
export type UnCo<T> = T extends co<infer A> ? A : T;
const optional = {
ref: optionalRef,
json<T extends JsonValue>(): co<T | undefined> {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
return { [SchemaInit]: "json" satisfies Schema } as any;
},
encoded<T>(arg: OptionalEncoder<T>): co<T> {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
return { [SchemaInit]: { encoded: arg } satisfies Schema } as any;
},
string: {
[SchemaInit]: "json" satisfies Schema,
} as unknown as co<string | undefined>,
number: {
[SchemaInit]: "json" satisfies Schema,
} as unknown as co<number | undefined>,
boolean: {
[SchemaInit]: "json" satisfies Schema,
} as unknown as co<boolean | undefined>,
null: {
[SchemaInit]: "json" satisfies Schema,
} as unknown as co<null | undefined>,
literal<T extends (string | number | boolean)[]>(
..._lit: T
): co<T[number] | undefined> {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
return { [SchemaInit]: "json" satisfies Schema } as any;
},
};
/** @category Schema definition */
export const co = {
string: {
@@ -48,8 +78,15 @@ export const co = {
ref,
items: ItemsSym as ItemsSym,
members: MembersSym as MembersSym,
optional,
};
function optionalRef<C extends CoValueClass>(
arg: C | ((_raw: InstanceType<C>["_raw"]) => C),
): co<InstanceType<C> | null | undefined> {
return ref(arg, { optional: true });
}
function ref<C extends CoValueClass>(
arg: C | ((_raw: InstanceType<C>["_raw"]) => C),
): co<InstanceType<C> | null>;
@@ -131,6 +168,10 @@ export type EffectSchemaWithInputAndOutput<A, I = A> = EffectSchema<
};
export type Encoder<V> = EffectSchemaWithInputAndOutput<V, JsonValue>;
export type OptionalEncoder<V> = EffectSchemaWithInputAndOutput<
V,
JsonValue | undefined
>;
import { Date } from "@effect/schema/Schema";
import { SchemaInit, ItemsSym, MembersSym } from "./symbols.js";

View File

@@ -157,11 +157,12 @@ describe("CoList resolution", async () => {
test("Loading and availability", async () => {
const { me, list } = await initNodeAndList();
const [initialAsPeer, secondPeer] = await Effect.runPromise(connectedPeers(
"initial",
"second",
{ peer1role: "server", peer2role: "client" },
));
const [initialAsPeer, secondPeer] = await Effect.runPromise(
connectedPeers("initial", "second", {
peer1role: "server",
peer2role: "client",
}),
);
if (!isControlledAccount(me)) {
throw "me is not a controlled account";
}
@@ -216,11 +217,12 @@ describe("CoList resolution", async () => {
test("Subscription & auto-resolution", async () => {
const { me, list } = await initNodeAndList();
const [initialAsPeer, secondPeer] = await Effect.runPromise(connectedPeers(
"initial",
"second",
{ peer1role: "server", peer2role: "client" },
));
const [initialAsPeer, secondPeer] = await Effect.runPromise(
connectedPeers("initial", "second", {
peer1role: "server",
peer2role: "client",
}),
);
if (!isControlledAccount(me)) {
throw "me is not a controlled account";
}

View File

@@ -25,7 +25,7 @@ describe("Simple CoMap operations", async () => {
_height = co.number;
birthday = co.encoded(Encoders.Date);
name? = co.string;
nullable = co.encoded(Schema.NullOr(Schema.String));
nullable = co.optional.encoded(Schema.NullishOr(Schema.String));
get roughColor() {
return this.color + "ish";
@@ -94,6 +94,8 @@ describe("Simple CoMap operations", async () => {
map.nullable = "not null";
map.nullable = null;
delete map.nullable;
map.nullable = undefined;
map.name = "Secret name";
expect(map.name).toEqual("Secret name");
@@ -106,6 +108,21 @@ describe("Simple CoMap operations", async () => {
});
});
describe("property existence", () => {
class TestMap extends CoMap.Record(co.string) {}
test("CoMap", () => {
const map = TestMap.create(
{ name: "test" },
{
owner: me,
},
);
expect("name" in map).toBe(true);
expect("something" in map).toBe(false);
});
});
class RecursiveMap extends CoMap {
name = co.string;
next?: co<RecursiveMap | null> = co.ref(RecursiveMap);
@@ -427,7 +444,7 @@ describe("CoMap resolution", async () => {
class TestMapWithOptionalRef extends CoMap {
color = co.string;
nested = co.ref(NestedMap, { optional: true });
nested = co.optional.ref(NestedMap);
}
test("Construction with optional", async () => {

View File

@@ -39,10 +39,12 @@ describe("Deep loading with depth arg", async () => {
crypto: Crypto,
});
const [initialAsPeer, secondPeer] = await Effect.runPromise(connectedPeers("initial", "second", {
peer1role: "server",
peer2role: "client",
}));
const [initialAsPeer, secondPeer] = await Effect.runPromise(
connectedPeers("initial", "second", {
peer1role: "server",
peer2role: "client",
}),
);
if (!isControlledAccount(me)) {
throw "me is not a controlled account";
}
@@ -252,10 +254,12 @@ test("Deep loading a record-like coMap", async () => {
crypto: Crypto,
});
const [initialAsPeer, secondPeer] = await Effect.runPromise(connectedPeers("initial", "second", {
peer1role: "server",
peer2role: "client",
}));
const [initialAsPeer, secondPeer] = await Effect.runPromise(
connectedPeers("initial", "second", {
peer1role: "server",
peer2role: "client",
}),
);
if (!isControlledAccount(me)) {
throw "me is not a controlled account";
}

305
pnpm-lock.yaml generated
View File

@@ -11,12 +11,6 @@ importers:
'@changesets/cli':
specifier: ^2.27.3
version: 2.27.3
husky:
specifier: ^9.0.11
version: 9.0.11
lint-staged:
specifier: ^15.2.2
version: 15.2.2
prettier:
specifier: ^3.1.1
version: 3.1.1
@@ -163,8 +157,8 @@ importers:
specifier: workspace:*
version: link:../../packages/cojson-transport-ws
effect:
specifier: ^3.1.5
version: 3.2.1
specifier: ^3.5.2
version: 3.5.2
hash-slash:
specifier: workspace:*
version: link:../../packages/hash-slash
@@ -451,8 +445,8 @@ importers:
specifier: ^1.1.1
version: 1.1.5
effect:
specifier: ^3.1.5
version: 3.2.1
specifier: ^3.5.2
version: 3.5.2
hash-wasm:
specifier: ^4.9.0
version: 4.11.0
@@ -488,8 +482,8 @@ importers:
specifier: workspace:*
version: link:../cojson
effect:
specifier: ^3.1.5
version: 3.2.1
specifier: ^3.5.2
version: 3.5.2
typescript:
specifier: ^5.1.6
version: 5.3.3
@@ -513,8 +507,8 @@ importers:
specifier: workspace:*
version: link:../cojson
effect:
specifier: ^3.1.5
version: 3.2.1
specifier: ^3.5.2
version: 3.5.2
typescript:
specifier: ^5.1.6
version: 5.3.3
@@ -529,8 +523,8 @@ importers:
specifier: workspace:*
version: link:../cojson
effect:
specifier: ^3.1.5
version: 3.2.1
specifier: ^3.5.2
version: 3.5.2
typescript:
specifier: ^5.1.6
version: 5.3.3
@@ -566,8 +560,8 @@ importers:
specifier: workspace:*
version: link:../cojson-transport-ws
effect:
specifier: ^3.1.5
version: 3.2.1
specifier: ^3.5.2
version: 3.5.2
jazz-tools:
specifier: workspace:*
version: link:../jazz-tools
@@ -609,8 +603,8 @@ importers:
specifier: workspace:*
version: link:../cojson-transport-ws
effect:
specifier: ^3.1.5
version: 3.2.1
specifier: ^3.5.2
version: 3.5.2
jazz-tools:
specifier: workspace:*
version: link:../jazz-tools
@@ -657,13 +651,13 @@ importers:
dependencies:
'@effect/cli':
specifier: ^0.36.21
version: 0.36.21(@effect/platform@0.53.2(@effect/schema@0.66.16(effect@3.2.1)(fast-check@3.17.2))(effect@3.2.1))(@effect/printer-ansi@0.33.12(@effect/typeclass@0.24.12(effect@3.2.1))(effect@3.2.1))(@effect/printer@0.33.12(@effect/typeclass@0.24.12(effect@3.2.1))(effect@3.2.1))(@effect/schema@0.66.16(effect@3.2.1)(fast-check@3.17.2))(effect@3.2.1)
version: 0.36.21(@effect/platform@0.53.2(@effect/schema@0.66.16(effect@3.5.2)(fast-check@3.17.2))(effect@3.5.2))(@effect/printer-ansi@0.33.12(@effect/typeclass@0.24.12(effect@3.5.2))(effect@3.5.2))(@effect/printer@0.33.12(@effect/typeclass@0.24.12(effect@3.5.2))(effect@3.5.2))(@effect/schema@0.66.16(effect@3.5.2)(fast-check@3.17.2))(effect@3.5.2)
'@effect/platform-node':
specifier: ^0.49.2
version: 0.49.2(@effect/platform@0.53.2(@effect/schema@0.66.16(effect@3.2.1)(fast-check@3.17.2))(effect@3.2.1))(effect@3.2.1)
version: 0.49.2(@effect/platform@0.53.2(@effect/schema@0.66.16(effect@3.5.2)(fast-check@3.17.2))(effect@3.5.2))(effect@3.5.2)
'@effect/schema':
specifier: ^0.66.16
version: 0.66.16(effect@3.2.1)(fast-check@3.17.2)
version: 0.66.16(effect@3.5.2)(fast-check@3.17.2)
cojson:
specifier: workspace:*
version: link:../cojson
@@ -671,8 +665,8 @@ importers:
specifier: workspace:*
version: link:../cojson-transport-ws
effect:
specifier: ^3.1.5
version: 3.2.1
specifier: ^3.5.2
version: 3.5.2
fast-check:
specifier: ^3.17.2
version: 3.17.2
@@ -697,13 +691,13 @@ importers:
dependencies:
'@effect/schema':
specifier: ^0.66.16
version: 0.66.16(effect@3.2.1)(fast-check@3.17.2)
version: 0.66.16(effect@3.5.2)(fast-check@3.17.2)
cojson:
specifier: workspace:*
version: link:../cojson
effect:
specifier: ^3.1.5
version: 3.2.1
specifier: ^3.5.2
version: 3.5.2
fast-check:
specifier: ^3.17.2
version: 3.17.2
@@ -1947,10 +1941,6 @@ packages:
resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==}
engines: {node: '>=6'}
ansi-escapes@6.2.1:
resolution: {integrity: sha512-4nJ3yixlEthEJ9Rk4vPcdBRkZvQZlYyu8j4/Mqz5sgIkddmEnH2Yj2ZrnP9S3tQOvSNRUIgVNF/1yPpRAGNRig==}
engines: {node: '>=14.16'}
ansi-regex@5.0.1:
resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
engines: {node: '>=8'}
@@ -2200,14 +2190,6 @@ packages:
class-variance-authority@0.7.0:
resolution: {integrity: sha512-jFI8IQw4hczaL4ALINxqLEXQbWcNjoSkloa4IaufXCJr6QawJyw7tuRysRsrE8w2p/4gGaxKIt/hX3qz/IbD1A==}
cli-cursor@4.0.0:
resolution: {integrity: sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
cli-truncate@4.0.0:
resolution: {integrity: sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==}
engines: {node: '>=18'}
cliui@6.0.0:
resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==}
@@ -2236,13 +2218,6 @@ packages:
color-name@1.1.4:
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
colorette@2.0.20:
resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==}
commander@11.1.0:
resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==}
engines: {node: '>=16'}
commander@4.1.1:
resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==}
engines: {node: '>= 6'}
@@ -2461,15 +2436,12 @@ packages:
resolution: {integrity: sha512-G0wNgFMFRDnFfKaXG2R6HiyVHqhKwdQ3EgoxW3wPlns2wKqem7F+HgkWBcevN7Vz0nN4AXtskID7/6jsYDXcKw==}
hasBin: true
effect@3.2.1:
resolution: {integrity: sha512-WnM7QyHekA+oWkJyD1g99BDqD3atAXKjarcDnUX9alIKLd8EFXdY333wpgcNJkSqtvXDsx8qYWOMbuivdwoN2w==}
effect@3.5.2:
resolution: {integrity: sha512-jZAZAgHHrnkqrRaaLBU/a6zEFm3+uOimr+ZJqvCqiHtw5k2AE6F0jiEPuM/MNJOe4r16JDo4SYa3IULIQuXvAw==}
electron-to-chromium@1.4.615:
resolution: {integrity: sha512-/bKPPcgZVUziECqDc+0HkT87+0zhaWSZHNXqF8FLd2lQcptpmUFwoCSWjCdOng9Gdq+afKArPdEg/0ZW461Eng==}
emoji-regex@10.3.0:
resolution: {integrity: sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==}
emoji-regex@8.0.0:
resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
@@ -2617,9 +2589,6 @@ packages:
resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
engines: {node: '>=0.10.0'}
eventemitter3@5.0.1:
resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==}
execa@8.0.1:
resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==}
engines: {node: '>=16.17'}
@@ -2784,10 +2753,6 @@ packages:
resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==}
engines: {node: 6.* || 8.* || >= 10.*}
get-east-asian-width@1.2.0:
resolution: {integrity: sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==}
engines: {node: '>=18'}
get-func-name@2.0.2:
resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==}
@@ -2942,11 +2907,6 @@ packages:
resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==}
engines: {node: '>=16.17.0'}
husky@9.0.11:
resolution: {integrity: sha512-AB6lFlbwwyIqMdHYhwPe+kjOC3Oc5P3nThEoW/AaO2BX3vJDjWPFxYLxokUZOo6RNX20He3AaT8sESs9NJcmEw==}
engines: {node: '>=18'}
hasBin: true
hyphenate-style-name@1.0.4:
resolution: {integrity: sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ==}
@@ -3046,14 +3006,6 @@ packages:
resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
engines: {node: '>=8'}
is-fullwidth-code-point@4.0.0:
resolution: {integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==}
engines: {node: '>=12'}
is-fullwidth-code-point@5.0.0:
resolution: {integrity: sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==}
engines: {node: '>=18'}
is-glob@4.0.3:
resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
engines: {node: '>=0.10.0'}
@@ -3227,18 +3179,9 @@ packages:
lines-and-columns@1.2.4:
resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
lint-staged@15.2.2:
resolution: {integrity: sha512-TiTt93OPh1OZOsb5B7k96A/ATl2AjIZo+vnzFZ6oHK5FuTk63ByDtxGQpHm+kFETjEWqgkF95M8FRXKR/LEBcw==}
engines: {node: '>=18.12.0'}
hasBin: true
listenercount@1.0.1:
resolution: {integrity: sha512-3mk/Zag0+IJxeDrxSgaDPy4zZ3w05PRZeJNnlWhzFz5OkX49J4krc+A8X2d2M69vGMBEX0uyl8M+W+8gH+kBqQ==}
listr2@8.0.1:
resolution: {integrity: sha512-ovJXBXkKGfq+CwmKTjluEqFi3p4h8xvkxGQQAQan22YCgef4KZ1mKGjzfGh6PL6AW5Csw0QiQPNuQyH+6Xk3hA==}
engines: {node: '>=18.0.0'}
load-yaml-file@0.2.0:
resolution: {integrity: sha512-OfCBkGEw4nN6JLtgRidPX6QxjBQGQf72q3si2uvqyFEMbycSFFHwAZeXx6cJgFM9wmLrf9zBwCP3Ivqa+LLZPw==}
engines: {node: '>=6'}
@@ -3277,10 +3220,6 @@ packages:
lodash@4.17.21:
resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
log-update@6.0.0:
resolution: {integrity: sha512-niTvB4gqvtof056rRIrTZvjNYE4rCUzO6X/X+kYjd7WFxXeJ0NwEFnRxX6ehkvv3jTwrXnNdtAak5XYZuIyPFw==}
engines: {node: '>=18'}
loglevel-plugin-prefix@0.8.4:
resolution: {integrity: sha512-WpG9CcFAOjz/FtNht+QJeGpvVl/cdR6P0z6OcXSkr8wFJOsV2GRj2j10JLfjuA4aYkcKCNIEqRGCyTife9R8/g==}
@@ -3365,10 +3304,6 @@ packages:
engines: {node: '>=10.0.0'}
hasBin: true
mimic-fn@2.1.0:
resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==}
engines: {node: '>=6'}
mimic-fn@4.0.0:
resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==}
engines: {node: '>=12'}
@@ -3539,10 +3474,6 @@ packages:
once@1.4.0:
resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
onetime@5.1.2:
resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==}
engines: {node: '>=6'}
onetime@6.0.0:
resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==}
engines: {node: '>=12'}
@@ -3663,11 +3594,6 @@ packages:
resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
engines: {node: '>=8.6'}
pidtree@0.6.0:
resolution: {integrity: sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==}
engines: {node: '>=0.10'}
hasBin: true
pify@2.3.0:
resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==}
engines: {node: '>=0.10.0'}
@@ -3938,17 +3864,10 @@ packages:
resq@1.11.0:
resolution: {integrity: sha512-G10EBz+zAAy3zUd/CDoBbXRL6ia9kOo3xRHrMDsHljI0GDkhYlyjwoCx5+3eCC4swi1uCoZQhskuJkj7Gp57Bw==}
restore-cursor@4.0.0:
resolution: {integrity: sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
reusify@1.0.4:
resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==}
engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
rfdc@1.3.1:
resolution: {integrity: sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg==}
rgb2hex@0.2.5:
resolution: {integrity: sha512-22MOP1Rh7sAo1BZpDG6R5RFYzR2lYEgwq7HEmyW2qcsOqR2lQKmn+O//xV3YG/0rrhMC6KVX2hU+ZXuaw9a5bw==}
@@ -4081,14 +4000,6 @@ packages:
resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
engines: {node: '>=8'}
slice-ansi@5.0.0:
resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==}
engines: {node: '>=12'}
slice-ansi@7.1.0:
resolution: {integrity: sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==}
engines: {node: '>=18'}
smart-buffer@4.2.0:
resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==}
engines: {node: '>= 6.0.0', npm: '>= 3.0.0'}
@@ -4168,10 +4079,6 @@ packages:
streamx@2.15.6:
resolution: {integrity: sha512-q+vQL4AAz+FdfT137VF69Cc/APqUbxy+MDOImRrMvchJpigHj9GksgDU2LYbO9rx7RX6osWgxJB2WxhYv4SZAw==}
string-argv@0.3.2:
resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==}
engines: {node: '>=0.6.19'}
string-width@4.2.3:
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
engines: {node: '>=8'}
@@ -4180,10 +4087,6 @@ packages:
resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==}
engines: {node: '>=12'}
string-width@7.1.0:
resolution: {integrity: sha512-SEIJCWiX7Kg4c129n48aDRwLbFb2LJmXXFrWBG4NGaRtMQ3myKPKbwrD1BKqQn74oCoNMBVrfDEr5M9YxCsrkw==}
engines: {node: '>=18'}
string.prototype.trim@1.2.9:
resolution: {integrity: sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==}
engines: {node: '>= 0.4'}
@@ -4736,10 +4639,6 @@ packages:
resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==}
engines: {node: '>=12'}
wrap-ansi@9.0.0:
resolution: {integrity: sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==}
engines: {node: '>=18'}
wrappy@1.0.2:
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
@@ -5015,29 +4914,29 @@ snapshots:
dependencies:
'@jridgewell/trace-mapping': 0.3.9
'@effect/cli@0.36.21(@effect/platform@0.53.2(@effect/schema@0.66.16(effect@3.2.1)(fast-check@3.17.2))(effect@3.2.1))(@effect/printer-ansi@0.33.12(@effect/typeclass@0.24.12(effect@3.2.1))(effect@3.2.1))(@effect/printer@0.33.12(@effect/typeclass@0.24.12(effect@3.2.1))(effect@3.2.1))(@effect/schema@0.66.16(effect@3.2.1)(fast-check@3.17.2))(effect@3.2.1)':
'@effect/cli@0.36.21(@effect/platform@0.53.2(@effect/schema@0.66.16(effect@3.5.2)(fast-check@3.17.2))(effect@3.5.2))(@effect/printer-ansi@0.33.12(@effect/typeclass@0.24.12(effect@3.5.2))(effect@3.5.2))(@effect/printer@0.33.12(@effect/typeclass@0.24.12(effect@3.5.2))(effect@3.5.2))(@effect/schema@0.66.16(effect@3.5.2)(fast-check@3.17.2))(effect@3.5.2)':
dependencies:
'@effect/platform': 0.53.2(@effect/schema@0.66.16(effect@3.2.1)(fast-check@3.17.2))(effect@3.2.1)
'@effect/printer': 0.33.12(@effect/typeclass@0.24.12(effect@3.2.1))(effect@3.2.1)
'@effect/printer-ansi': 0.33.12(@effect/typeclass@0.24.12(effect@3.2.1))(effect@3.2.1)
'@effect/schema': 0.66.16(effect@3.2.1)(fast-check@3.17.2)
effect: 3.2.1
'@effect/platform': 0.53.2(@effect/schema@0.66.16(effect@3.5.2)(fast-check@3.17.2))(effect@3.5.2)
'@effect/printer': 0.33.12(@effect/typeclass@0.24.12(effect@3.5.2))(effect@3.5.2)
'@effect/printer-ansi': 0.33.12(@effect/typeclass@0.24.12(effect@3.5.2))(effect@3.5.2)
'@effect/schema': 0.66.16(effect@3.5.2)(fast-check@3.17.2)
effect: 3.5.2
ini: 4.1.2
toml: 3.0.0
yaml: 2.4.2
'@effect/platform-node-shared@0.4.21(@effect/platform@0.53.2(@effect/schema@0.66.16(effect@3.2.1)(fast-check@3.17.2))(effect@3.2.1))(effect@3.2.1)':
'@effect/platform-node-shared@0.4.21(@effect/platform@0.53.2(@effect/schema@0.66.16(effect@3.5.2)(fast-check@3.17.2))(effect@3.5.2))(effect@3.5.2)':
dependencies:
'@effect/platform': 0.53.2(@effect/schema@0.66.16(effect@3.2.1)(fast-check@3.17.2))(effect@3.2.1)
'@effect/platform': 0.53.2(@effect/schema@0.66.16(effect@3.5.2)(fast-check@3.17.2))(effect@3.5.2)
'@parcel/watcher': 2.4.1
effect: 3.2.1
effect: 3.5.2
multipasta: 0.2.1
'@effect/platform-node@0.49.2(@effect/platform@0.53.2(@effect/schema@0.66.16(effect@3.2.1)(fast-check@3.17.2))(effect@3.2.1))(effect@3.2.1)':
'@effect/platform-node@0.49.2(@effect/platform@0.53.2(@effect/schema@0.66.16(effect@3.5.2)(fast-check@3.17.2))(effect@3.5.2))(effect@3.5.2)':
dependencies:
'@effect/platform': 0.53.2(@effect/schema@0.66.16(effect@3.2.1)(fast-check@3.17.2))(effect@3.2.1)
'@effect/platform-node-shared': 0.4.21(@effect/platform@0.53.2(@effect/schema@0.66.16(effect@3.2.1)(fast-check@3.17.2))(effect@3.2.1))(effect@3.2.1)
effect: 3.2.1
'@effect/platform': 0.53.2(@effect/schema@0.66.16(effect@3.5.2)(fast-check@3.17.2))(effect@3.5.2)
'@effect/platform-node-shared': 0.4.21(@effect/platform@0.53.2(@effect/schema@0.66.16(effect@3.5.2)(fast-check@3.17.2))(effect@3.5.2))(effect@3.5.2)
effect: 3.5.2
mime: 3.0.0
undici: 6.16.1
ws: 8.17.0
@@ -5045,33 +4944,33 @@ snapshots:
- bufferutil
- utf-8-validate
'@effect/platform@0.53.2(@effect/schema@0.66.16(effect@3.2.1)(fast-check@3.17.2))(effect@3.2.1)':
'@effect/platform@0.53.2(@effect/schema@0.66.16(effect@3.5.2)(fast-check@3.17.2))(effect@3.5.2)':
dependencies:
'@effect/schema': 0.66.16(effect@3.2.1)(fast-check@3.17.2)
effect: 3.2.1
'@effect/schema': 0.66.16(effect@3.5.2)(fast-check@3.17.2)
effect: 3.5.2
find-my-way-ts: 0.1.2
multipasta: 0.2.1
path-browserify: 1.0.1
'@effect/printer-ansi@0.33.12(@effect/typeclass@0.24.12(effect@3.2.1))(effect@3.2.1)':
'@effect/printer-ansi@0.33.12(@effect/typeclass@0.24.12(effect@3.5.2))(effect@3.5.2)':
dependencies:
'@effect/printer': 0.33.12(@effect/typeclass@0.24.12(effect@3.2.1))(effect@3.2.1)
'@effect/typeclass': 0.24.12(effect@3.2.1)
effect: 3.2.1
'@effect/printer': 0.33.12(@effect/typeclass@0.24.12(effect@3.5.2))(effect@3.5.2)
'@effect/typeclass': 0.24.12(effect@3.5.2)
effect: 3.5.2
'@effect/printer@0.33.12(@effect/typeclass@0.24.12(effect@3.2.1))(effect@3.2.1)':
'@effect/printer@0.33.12(@effect/typeclass@0.24.12(effect@3.5.2))(effect@3.5.2)':
dependencies:
'@effect/typeclass': 0.24.12(effect@3.2.1)
effect: 3.2.1
'@effect/typeclass': 0.24.12(effect@3.5.2)
effect: 3.5.2
'@effect/schema@0.66.16(effect@3.2.1)(fast-check@3.17.2)':
'@effect/schema@0.66.16(effect@3.5.2)(fast-check@3.17.2)':
dependencies:
effect: 3.2.1
effect: 3.5.2
fast-check: 3.17.2
'@effect/typeclass@0.24.12(effect@3.2.1)':
'@effect/typeclass@0.24.12(effect@3.5.2)':
dependencies:
effect: 3.2.1
effect: 3.5.2
'@esbuild/aix-ppc64@0.19.10':
optional: true
@@ -6168,8 +6067,6 @@ snapshots:
ansi-colors@4.1.3: {}
ansi-escapes@6.2.1: {}
ansi-regex@5.0.1: {}
ansi-regex@6.0.1: {}
@@ -6444,15 +6341,6 @@ snapshots:
dependencies:
clsx: 2.0.0
cli-cursor@4.0.0:
dependencies:
restore-cursor: 4.0.0
cli-truncate@4.0.0:
dependencies:
slice-ansi: 5.0.0
string-width: 7.1.0
cliui@6.0.0:
dependencies:
string-width: 4.2.3
@@ -6481,10 +6369,6 @@ snapshots:
color-name@1.1.4: {}
colorette@2.0.20: {}
commander@11.1.0: {}
commander@4.1.1: {}
commander@9.5.0: {}
@@ -6684,12 +6568,10 @@ snapshots:
unzipper: 0.10.14
which: 4.0.0
effect@3.2.1: {}
effect@3.5.2: {}
electron-to-chromium@1.4.615: {}
emoji-regex@10.3.0: {}
emoji-regex@8.0.0: {}
emoji-regex@9.2.2: {}
@@ -6947,8 +6829,6 @@ snapshots:
esutils@2.0.3: {}
eventemitter3@5.0.1: {}
execa@8.0.1:
dependencies:
cross-spawn: 7.0.3
@@ -7142,8 +7022,6 @@ snapshots:
get-caller-file@2.0.5: {}
get-east-asian-width@1.2.0: {}
get-func-name@2.0.2: {}
get-intrinsic@1.2.4:
@@ -7323,8 +7201,6 @@ snapshots:
human-signals@5.0.0: {}
husky@9.0.11: {}
hyphenate-style-name@1.0.4: {}
iconv-lite@0.4.24:
@@ -7414,12 +7290,6 @@ snapshots:
is-fullwidth-code-point@3.0.0: {}
is-fullwidth-code-point@4.0.0: {}
is-fullwidth-code-point@5.0.0:
dependencies:
get-east-asian-width: 1.2.0
is-glob@4.0.3:
dependencies:
is-extglob: 2.1.1
@@ -7578,32 +7448,8 @@ snapshots:
lines-and-columns@1.2.4: {}
lint-staged@15.2.2:
dependencies:
chalk: 5.3.0
commander: 11.1.0
debug: 4.3.4
execa: 8.0.1
lilconfig: 3.0.0
listr2: 8.0.1
micromatch: 4.0.5
pidtree: 0.6.0
string-argv: 0.3.2
yaml: 2.3.4
transitivePeerDependencies:
- supports-color
listenercount@1.0.1: {}
listr2@8.0.1:
dependencies:
cli-truncate: 4.0.0
colorette: 2.0.20
eventemitter3: 5.0.1
log-update: 6.0.0
rfdc: 1.3.1
wrap-ansi: 9.0.0
load-yaml-file@0.2.0:
dependencies:
graceful-fs: 4.2.11
@@ -7642,14 +7488,6 @@ snapshots:
lodash@4.17.21: {}
log-update@6.0.0:
dependencies:
ansi-escapes: 6.2.1
cli-cursor: 4.0.0
slice-ansi: 7.1.0
strip-ansi: 7.1.0
wrap-ansi: 9.0.0
loglevel-plugin-prefix@0.8.4: {}
loglevel@1.8.1: {}
@@ -7722,8 +7560,6 @@ snapshots:
mime@3.0.0: {}
mimic-fn@2.1.0: {}
mimic-fn@4.0.0: {}
mimic-response@3.1.0: {}
@@ -7876,10 +7712,6 @@ snapshots:
dependencies:
wrappy: 1.0.2
onetime@5.1.2:
dependencies:
mimic-fn: 2.1.0
onetime@6.0.0:
dependencies:
mimic-fn: 4.0.0
@@ -7997,8 +7829,6 @@ snapshots:
picomatch@2.3.1: {}
pidtree@0.6.0: {}
pify@2.3.0: {}
pify@4.0.1: {}
@@ -8327,15 +8157,8 @@ snapshots:
dependencies:
fast-deep-equal: 2.0.1
restore-cursor@4.0.0:
dependencies:
onetime: 5.1.2
signal-exit: 3.0.7
reusify@1.0.4: {}
rfdc@1.3.1: {}
rgb2hex@0.2.5: {}
rimraf@2.7.1:
@@ -8482,16 +8305,6 @@ snapshots:
slash@3.0.0: {}
slice-ansi@5.0.0:
dependencies:
ansi-styles: 6.2.1
is-fullwidth-code-point: 4.0.0
slice-ansi@7.1.0:
dependencies:
ansi-styles: 6.2.1
is-fullwidth-code-point: 5.0.0
smart-buffer@4.2.0: {}
smartwrap@2.0.2:
@@ -8579,8 +8392,6 @@ snapshots:
fast-fifo: 1.3.2
queue-tick: 1.0.1
string-argv@0.3.2: {}
string-width@4.2.3:
dependencies:
emoji-regex: 8.0.0
@@ -8593,12 +8404,6 @@ snapshots:
emoji-regex: 9.2.2
strip-ansi: 7.1.0
string-width@7.1.0:
dependencies:
emoji-regex: 10.3.0
get-east-asian-width: 1.2.0
strip-ansi: 7.1.0
string.prototype.trim@1.2.9:
dependencies:
call-bind: 1.0.7
@@ -9307,12 +9112,6 @@ snapshots:
string-width: 5.1.2
strip-ansi: 7.1.0
wrap-ansi@9.0.0:
dependencies:
ansi-styles: 6.2.1
string-width: 7.1.0
strip-ansi: 7.1.0
wrappy@1.0.2: {}
ws@8.13.0: {}