mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
Decouple do from package
This commit is contained in:
parent
7b72406824
commit
f00069be68
14 changed files with 9 additions and 6604 deletions
|
@ -1,154 +0,0 @@
|
|||
import type {
|
||||
DeltasRepository,
|
||||
CLIENT_DELTA,
|
||||
SERVER_DELTA,
|
||||
SERVER_DELTA_STORAGE,
|
||||
} from "../sync/protocol";
|
||||
import { Network } from "../sync/utils";
|
||||
|
||||
// CFDO II: add senderId, possibly roomId as well
|
||||
export class DurableDeltasRepository implements DeltasRepository {
|
||||
// there is a 2MB row limit, hence working with max payload size of 1.5 MB
|
||||
// and leaving a ~500kB buffer for other row metadata
|
||||
private static readonly MAX_PAYLOAD_SIZE = 1_500_000;
|
||||
|
||||
constructor(private storage: DurableObjectStorage) {
|
||||
// #region DEV ONLY
|
||||
// this.storage.sql.exec(`DROP TABLE IF EXISTS deltas;`);
|
||||
// #endregion
|
||||
|
||||
this.storage.sql.exec(`CREATE TABLE IF NOT EXISTS deltas(
|
||||
id TEXT NOT NULL,
|
||||
version INTEGER NOT NULL,
|
||||
position INTEGER NOT NULL,
|
||||
payload BLOB NOT NULL,
|
||||
createdAt TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (id, version, position)
|
||||
);`);
|
||||
}
|
||||
|
||||
public save(delta: CLIENT_DELTA): SERVER_DELTA | null {
|
||||
return this.storage.transactionSync(() => {
|
||||
const existingDelta = this.getById(delta.id);
|
||||
|
||||
// don't perist the same delta twice
|
||||
if (existingDelta) {
|
||||
return existingDelta;
|
||||
}
|
||||
|
||||
try {
|
||||
const payloadBuffer = Network.toBinary(delta);
|
||||
const payloadSize = payloadBuffer.byteLength;
|
||||
const nextVersion = this.getLastVersion() + 1;
|
||||
const chunksCount = Math.ceil(
|
||||
payloadSize / DurableDeltasRepository.MAX_PAYLOAD_SIZE,
|
||||
);
|
||||
|
||||
for (let position = 0; position < chunksCount; position++) {
|
||||
const start = position * DurableDeltasRepository.MAX_PAYLOAD_SIZE;
|
||||
const end = start + DurableDeltasRepository.MAX_PAYLOAD_SIZE;
|
||||
const chunkedPayload = payloadBuffer.subarray(start, end);
|
||||
|
||||
this.storage.sql.exec(
|
||||
`INSERT INTO deltas (id, version, position, payload) VALUES (?, ?, ?, ?);`,
|
||||
delta.id,
|
||||
nextVersion,
|
||||
position,
|
||||
chunkedPayload,
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
// check if the delta has been already acknowledged
|
||||
// in case client for some reason did not receive acknowledgement
|
||||
// and reconnected while the we still have the delta in the worker
|
||||
// otherwise the client is doomed to full a restore
|
||||
if (e instanceof Error && e.message.includes("SQLITE_CONSTRAINT")) {
|
||||
// continue;
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
const acknowledged = this.getById(delta.id);
|
||||
return acknowledged;
|
||||
});
|
||||
}
|
||||
|
||||
// CFDO: for versioning we need deletions, but not for the "snapshot" update;
|
||||
public getAllSinceVersion(version: number): Array<SERVER_DELTA> {
|
||||
const deltas = this.storage.sql
|
||||
.exec<SERVER_DELTA_STORAGE>(
|
||||
`SELECT id, payload, version, position FROM deltas WHERE version > (?) ORDER BY version, position, createdAt ASC;`,
|
||||
version,
|
||||
)
|
||||
.toArray();
|
||||
|
||||
return this.restorePayloadChunks(deltas);
|
||||
}
|
||||
|
||||
public getLastVersion(): number {
|
||||
// CFDO: might be in memory to reduce number of rows read (or position on version at least, if btree affect rows read)
|
||||
const result = this.storage.sql
|
||||
.exec(`SELECT MAX(version) FROM deltas;`)
|
||||
.one();
|
||||
|
||||
return result ? Number(result["MAX(version)"]) : 0;
|
||||
}
|
||||
|
||||
public getById(id: string): SERVER_DELTA | null {
|
||||
const deltas = this.storage.sql
|
||||
.exec<SERVER_DELTA_STORAGE>(
|
||||
`SELECT id, payload, version, position FROM deltas WHERE id = (?) ORDER BY position ASC`,
|
||||
id,
|
||||
)
|
||||
.toArray();
|
||||
|
||||
if (!deltas.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const restoredDeltas = this.restorePayloadChunks(deltas);
|
||||
|
||||
if (restoredDeltas.length !== 1) {
|
||||
throw new Error(
|
||||
`Expected exactly one restored delta, but received "${restoredDeltas.length}".`,
|
||||
);
|
||||
}
|
||||
|
||||
return restoredDeltas[0];
|
||||
}
|
||||
|
||||
private restorePayloadChunks(
|
||||
deltas: Array<SERVER_DELTA_STORAGE>,
|
||||
): Array<SERVER_DELTA> {
|
||||
return Array.from(
|
||||
deltas
|
||||
.reduce((acc, curr) => {
|
||||
const delta = acc.get(curr.version);
|
||||
|
||||
if (delta) {
|
||||
const currentPayload = new Uint8Array(curr.payload);
|
||||
acc.set(curr.version, {
|
||||
...delta,
|
||||
// glueing the chunks payload back
|
||||
payload: Uint8Array.from([...delta.payload, ...currentPayload]),
|
||||
});
|
||||
} else {
|
||||
// let's not unnecessarily expose more props than these (i.e. position)
|
||||
acc.set(curr.version, {
|
||||
id: curr.id,
|
||||
version: curr.version,
|
||||
payload: new Uint8Array(curr.payload),
|
||||
});
|
||||
}
|
||||
|
||||
return acc;
|
||||
// using Uint8Array instead of ArrayBuffer, as it has nicer methods
|
||||
}, new Map<number, Omit<SERVER_DELTA_STORAGE, "payload" | "position"> & { payload: Uint8Array }>())
|
||||
.values(),
|
||||
).map((delta) => ({
|
||||
...delta,
|
||||
payload: Network.fromBinary(delta.payload),
|
||||
}));
|
||||
}
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
import { DurableObject } from "cloudflare:workers";
|
||||
import { DurableDeltasRepository } from "./repository";
|
||||
import { ExcalidrawSyncServer } from "../sync/server";
|
||||
|
||||
/**
|
||||
* Durable Object impl. of Excalidraw room.
|
||||
*/
|
||||
export class DurableRoom extends DurableObject {
|
||||
private roomId: string | null = null;
|
||||
private sync: ExcalidrawSyncServer;
|
||||
|
||||
constructor(ctx: DurableObjectState, env: Env) {
|
||||
super(ctx, env);
|
||||
|
||||
this.ctx.blockConcurrencyWhile(async () => {
|
||||
this.roomId = (await this.ctx.storage.get("roomId")) || null;
|
||||
});
|
||||
|
||||
const repository = new DurableDeltasRepository(ctx.storage);
|
||||
this.sync = new ExcalidrawSyncServer(repository);
|
||||
|
||||
// in case it hibernates, let's get take active connections
|
||||
for (const ws of this.ctx.getWebSockets()) {
|
||||
this.sync.onConnect(ws);
|
||||
}
|
||||
}
|
||||
|
||||
public fetch = async (request: Request): Promise<Response> =>
|
||||
this.connect(request);
|
||||
|
||||
public webSocketMessage = (client: WebSocket, message: ArrayBuffer) =>
|
||||
this.sync.onMessage(client, message);
|
||||
|
||||
public webSocketClose = (ws: WebSocket) => this.sync.onDisconnect(ws);
|
||||
|
||||
private connect(request: Request) {
|
||||
if (!this.roomId) {
|
||||
const roomId = new URL(request.url).searchParams.get("roomId");
|
||||
|
||||
if (!roomId) {
|
||||
return new Response(null, { status: 400 /* bad request */ });
|
||||
}
|
||||
|
||||
this.ctx.blockConcurrencyWhile(async () => {
|
||||
await this.ctx.storage.put("roomId", roomId);
|
||||
this.roomId = roomId;
|
||||
});
|
||||
}
|
||||
|
||||
const { 0: client, 1: server } = new WebSocketPair();
|
||||
|
||||
this.ctx.acceptWebSocket(client);
|
||||
this.sync.onConnect(client);
|
||||
|
||||
return new Response(null, {
|
||||
status: 101 /* switching protocols */,
|
||||
webSocket: server,
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
export { DurableRoom } from "./room";
|
||||
|
||||
/**
|
||||
* Worker relay for Durable Room.
|
||||
*/
|
||||
export default {
|
||||
async fetch(
|
||||
request: Request,
|
||||
env: Env,
|
||||
ctx: ExecutionContext,
|
||||
): Promise<Response> {
|
||||
// CFDO: only auth user should reach this
|
||||
const upgrade = request.headers.get("upgrade");
|
||||
if (!upgrade || upgrade !== "websocket") {
|
||||
return new Response(null, { status: 426 /* upgrade required */ });
|
||||
}
|
||||
|
||||
if (request.method !== "GET") {
|
||||
return new Response(null, { status: 405 /* method not allowed */ });
|
||||
}
|
||||
|
||||
const url = new URL(request.url);
|
||||
if (url.pathname !== "/connect") {
|
||||
return new Response(null, { status: 403 /* forbidden */ });
|
||||
}
|
||||
|
||||
// CFDO: double check that the scene exists
|
||||
const roomId = url.searchParams.get("roomId");
|
||||
if (!roomId) {
|
||||
return new Response(null, { status: 400 /* bad request */ });
|
||||
}
|
||||
|
||||
const id: DurableObjectId = env.DURABLE_ROOM.idFromName(roomId);
|
||||
const room = env.DURABLE_ROOM.get(id);
|
||||
|
||||
return room.fetch(request);
|
||||
},
|
||||
};
|
|
@ -62,8 +62,6 @@
|
|||
"@excalidraw/random-username": "1.1.0",
|
||||
"@radix-ui/react-popover": "1.0.3",
|
||||
"@radix-ui/react-tabs": "1.0.2",
|
||||
"@types/async-lock": "^1.4.2",
|
||||
"async-lock": "^1.4.1",
|
||||
"browser-fs-access": "0.29.1",
|
||||
"canvas-roundrect-polyfill": "0.0.1",
|
||||
"clsx": "1.1.1",
|
||||
|
@ -74,9 +72,7 @@
|
|||
"image-blob-reduce": "3.0.1",
|
||||
"jotai": "2.11.0",
|
||||
"jotai-scope": "0.7.2",
|
||||
"lodash.debounce": "4.0.8",
|
||||
"lodash.throttle": "4.1.1",
|
||||
"msgpack-lite": "0.1.26",
|
||||
"nanoid": "3.3.3",
|
||||
"open-color": "1.9.1",
|
||||
"pako": "1.0.11",
|
||||
|
@ -87,7 +83,6 @@
|
|||
"png-chunks-extract": "1.0.0",
|
||||
"points-on-curve": "1.0.1",
|
||||
"pwacompat": "2.0.17",
|
||||
"reconnecting-websocket": "4.4.0",
|
||||
"roughjs": "4.6.4",
|
||||
"sass": "1.51.0",
|
||||
"tunnel-rat": "0.1.2"
|
||||
|
@ -101,13 +96,10 @@
|
|||
"@babel/preset-env": "7.24.5",
|
||||
"@babel/preset-react": "7.24.1",
|
||||
"@babel/preset-typescript": "7.24.1",
|
||||
"@cloudflare/workers-types": "4.20241112.0",
|
||||
"@size-limit/preset-big-lib": "9.0.0",
|
||||
"@testing-library/dom": "10.4.0",
|
||||
"@testing-library/jest-dom": "5.16.2",
|
||||
"@testing-library/react": "16.0.0",
|
||||
"@types/async-lock": "^1.4.2",
|
||||
"@types/msgpack-lite": "0.1.11",
|
||||
"@types/pako": "1.0.3",
|
||||
"@types/pica": "5.1.3",
|
||||
"@types/resize-observer-browser": "0.1.7",
|
||||
|
@ -132,8 +124,7 @@
|
|||
"size-limit": "9.0.0",
|
||||
"style-loader": "3.3.3",
|
||||
"ts-loader": "9.3.1",
|
||||
"typescript": "4.9.4",
|
||||
"wrangler": "^3.60.3"
|
||||
"typescript": "4.9.4"
|
||||
},
|
||||
"bugs": "https://github.com/excalidraw/excalidraw/issues",
|
||||
"homepage": "https://github.com/excalidraw/excalidraw/tree/master/packages/excalidraw",
|
||||
|
@ -143,9 +134,6 @@
|
|||
"pack": "yarn build:umd && yarn pack",
|
||||
"start": "node ../../scripts/buildExample.mjs && vite",
|
||||
"build:example": "node ../../scripts/buildExample.mjs",
|
||||
"size": "yarn build:umd && size-limit",
|
||||
"sync:deploy": "wrangler deploy",
|
||||
"sync:dev": "wrangler dev",
|
||||
"sync:typegen": "wrangler types --experimental-include-runtime=\"./worker-runtime.d.ts\""
|
||||
"size": "yarn build:umd && size-limit"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,6 @@ import type {
|
|||
OrderedExcalidrawElement,
|
||||
SceneElementsMap,
|
||||
} from "./element/types";
|
||||
import type { SERVER_DELTA } from "./sync/protocol";
|
||||
import { arrayToMap, assertNever } from "./utils";
|
||||
import { hashElementsVersion } from "./element";
|
||||
import { syncMovedIndices } from "./fractionalIndex";
|
||||
|
@ -453,7 +452,7 @@ export class StoreDelta {
|
|||
public static load({
|
||||
id,
|
||||
elements: { added, removed, updated },
|
||||
}: SERVER_DELTA["payload"]) {
|
||||
}: DTO<StoreDelta>) {
|
||||
const elements = ElementsDelta.create(added, removed, updated, {
|
||||
shouldRedistribute: false,
|
||||
});
|
||||
|
|
|
@ -1,548 +0,0 @@
|
|||
import throttle from "lodash.throttle";
|
||||
import ReconnectingWebSocket, {
|
||||
type Event,
|
||||
type CloseEvent,
|
||||
} from "reconnecting-websocket";
|
||||
import { Network, Utils } from "./utils";
|
||||
import {
|
||||
LocalDeltasQueue,
|
||||
type MetadataRepository,
|
||||
type DeltasRepository,
|
||||
} from "./queue";
|
||||
import { StoreAction, StoreDelta } from "../store";
|
||||
import type { StoreChange } from "../store";
|
||||
import type { ExcalidrawImperativeAPI } from "../types";
|
||||
import type { ExcalidrawElement, SceneElementsMap } from "../element/types";
|
||||
import type {
|
||||
SERVER_DELTA,
|
||||
CLIENT_CHANGE,
|
||||
SERVER_MESSAGE,
|
||||
CLIENT_MESSAGE_BINARY,
|
||||
} from "./protocol";
|
||||
import { debounce } from "../utils";
|
||||
import { randomId } from "../random";
|
||||
import { orderByFractionalIndex } from "../fractionalIndex";
|
||||
import { ENV } from "../constants";
|
||||
|
||||
class SocketMessage implements CLIENT_MESSAGE_BINARY {
|
||||
constructor(
|
||||
public readonly type: "relay" | "pull" | "push",
|
||||
public readonly payload: Uint8Array,
|
||||
public readonly chunkInfo?: {
|
||||
id: string;
|
||||
position: number;
|
||||
count: number;
|
||||
},
|
||||
) {}
|
||||
}
|
||||
|
||||
class SocketClient {
|
||||
// Max size for outgoing messages is 1MiB (due to CFDO limits),
|
||||
// thus working with a slighter smaller limit of 800 kB (leaving 224kB for metadata)
|
||||
private static readonly MAX_MESSAGE_SIZE = 800_000;
|
||||
|
||||
private isOffline = true;
|
||||
private socket: ReconnectingWebSocket | null = null;
|
||||
|
||||
public get isDisconnected() {
|
||||
return !this.socket;
|
||||
}
|
||||
|
||||
constructor(
|
||||
private readonly host: string,
|
||||
private readonly roomId: String,
|
||||
private readonly handlers: {
|
||||
onOpen: (event: Event) => void;
|
||||
onOnline: () => void;
|
||||
onMessage: (message: SERVER_MESSAGE) => void;
|
||||
},
|
||||
) {}
|
||||
|
||||
private onOnline = () => {
|
||||
this.isOffline = false;
|
||||
this.handlers.onOnline();
|
||||
};
|
||||
|
||||
private onOffline = () => {
|
||||
this.isOffline = true;
|
||||
};
|
||||
|
||||
public connect = throttle(
|
||||
() => {
|
||||
if (!this.isDisconnected && !this.isOffline) {
|
||||
return;
|
||||
}
|
||||
|
||||
window.addEventListener("online", this.onOnline);
|
||||
window.addEventListener("offline", this.onOffline);
|
||||
|
||||
// eslint-disable-next-line no-console
|
||||
console.debug(`Connecting to the room "${this.roomId}"...`);
|
||||
this.socket = new ReconnectingWebSocket(
|
||||
`${this.host}/connect?roomId=${this.roomId}`,
|
||||
[],
|
||||
{
|
||||
WebSocket: undefined, // WebSocket constructor, if none provided, defaults to global WebSocket
|
||||
maxReconnectionDelay: 10000, // max delay in ms between reconnections
|
||||
minReconnectionDelay: 1000, // min delay in ms between reconnections
|
||||
reconnectionDelayGrowFactor: 1.3, // how fast the reconnection delay grows
|
||||
minUptime: 5000, // min time in ms to consider connection as stable
|
||||
connectionTimeout: 4000, // retry connect if not connected after this time, in ms
|
||||
maxRetries: Infinity, // maximum number of retries
|
||||
maxEnqueuedMessages: 0, // maximum number of messages to buffer until reconnection
|
||||
startClosed: false, // start websocket in CLOSED state, call `.reconnect()` to connect
|
||||
debug: false, // enables debug output,
|
||||
},
|
||||
);
|
||||
this.socket.addEventListener("message", this.onMessage);
|
||||
this.socket.addEventListener("open", this.onOpen);
|
||||
this.socket.addEventListener("close", this.onClose);
|
||||
this.socket.addEventListener("error", this.onError);
|
||||
},
|
||||
1000,
|
||||
{ leading: true, trailing: false },
|
||||
);
|
||||
|
||||
public disconnect() {
|
||||
if (this.isDisconnected) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
window.removeEventListener("online", this.onOnline);
|
||||
window.removeEventListener("offline", this.onOffline);
|
||||
|
||||
this.socket?.removeEventListener("message", this.onMessage);
|
||||
this.socket?.removeEventListener("open", this.onOpen);
|
||||
this.socket?.removeEventListener("close", this.onClose);
|
||||
this.socket?.removeEventListener("error", this.onError);
|
||||
this.socket?.close();
|
||||
|
||||
// eslint-disable-next-line no-console
|
||||
console.debug(`Disconnected from the room "${this.roomId}".`);
|
||||
} finally {
|
||||
this.socket = null;
|
||||
}
|
||||
}
|
||||
|
||||
public send(message: {
|
||||
type: "relay" | "pull" | "push";
|
||||
payload: Record<string, unknown>;
|
||||
}): void {
|
||||
if (this.isOffline) {
|
||||
// connection opened, don't let the WS buffer the messages,
|
||||
// as we do explicitly buffer unacknowledged deltas
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.isDisconnected) {
|
||||
this.connect();
|
||||
return;
|
||||
}
|
||||
|
||||
const { type, payload } = message;
|
||||
|
||||
const payloadBuffer = Network.toBinary(payload);
|
||||
const payloadSize = payloadBuffer.byteLength;
|
||||
|
||||
if (import.meta.env.DEV || import.meta.env.MODE === ENV.TEST) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.debug("send", message, payloadSize);
|
||||
}
|
||||
|
||||
if (payloadSize < SocketClient.MAX_MESSAGE_SIZE) {
|
||||
const message = new SocketMessage(type, payloadBuffer);
|
||||
return this.sendMessage(message);
|
||||
}
|
||||
|
||||
const chunkId = randomId();
|
||||
const chunkSize = SocketClient.MAX_MESSAGE_SIZE;
|
||||
const chunksCount = Math.ceil(payloadSize / chunkSize);
|
||||
|
||||
for (let position = 0; position < chunksCount; position++) {
|
||||
const start = position * chunkSize;
|
||||
const end = start + chunkSize;
|
||||
const chunkedPayload = payloadBuffer.subarray(start, end);
|
||||
const message = new SocketMessage(type, chunkedPayload, {
|
||||
id: chunkId,
|
||||
position,
|
||||
count: chunksCount,
|
||||
});
|
||||
|
||||
this.sendMessage(message);
|
||||
}
|
||||
}
|
||||
|
||||
private onMessage = (event: MessageEvent) => {
|
||||
this.receiveMessage(event.data).then((message) => {
|
||||
if (!message) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (import.meta.env.DEV || import.meta.env.MODE === ENV.TEST) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.debug("onMessage", message);
|
||||
}
|
||||
|
||||
this.handlers.onMessage(message);
|
||||
});
|
||||
};
|
||||
|
||||
private onOpen = (event: Event) => {
|
||||
// eslint-disable-next-line no-console
|
||||
console.debug(`Connection to the room "${this.roomId}" opened.`);
|
||||
this.isOffline = false;
|
||||
this.handlers.onOpen(event);
|
||||
};
|
||||
|
||||
private onClose = (event: CloseEvent) => {
|
||||
// eslint-disable-next-line no-console
|
||||
console.debug(`Connection to the room "${this.roomId}" closed.`, event);
|
||||
};
|
||||
|
||||
private onError = (event: Event) => {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(
|
||||
`Connection to the room "${this.roomId}" returned an error.`,
|
||||
event,
|
||||
);
|
||||
};
|
||||
|
||||
private sendMessage = (message: CLIENT_MESSAGE_BINARY) => {
|
||||
this.socket?.send(Network.encodeClientMessage(message));
|
||||
};
|
||||
|
||||
// CFDO: should be (runtime) type-safe
|
||||
private async receiveMessage(
|
||||
message: Blob,
|
||||
): Promise<SERVER_MESSAGE | undefined> {
|
||||
const arrayBuffer = await message.arrayBuffer();
|
||||
const uint8Array = new Uint8Array(arrayBuffer);
|
||||
|
||||
const [decodedMessage, decodingError] = Utils.try<SERVER_MESSAGE>(() =>
|
||||
Network.fromBinary(uint8Array),
|
||||
);
|
||||
|
||||
if (decodingError) {
|
||||
console.error("Failed to decode message:", message);
|
||||
return;
|
||||
}
|
||||
|
||||
return decodedMessage;
|
||||
}
|
||||
}
|
||||
|
||||
interface AcknowledgedDelta {
|
||||
delta: StoreDelta;
|
||||
version: number;
|
||||
}
|
||||
|
||||
export class SyncClient {
|
||||
private static readonly HOST_URL = import.meta.env.DEV
|
||||
? "ws://localhost:8787"
|
||||
: "https://excalidraw-sync.marcel-529.workers.dev";
|
||||
|
||||
private static readonly ROOM_ID = import.meta.env.DEV
|
||||
? "test_room_x"
|
||||
: "test_room_prod";
|
||||
|
||||
private readonly api: ExcalidrawImperativeAPI;
|
||||
private readonly localDeltas: LocalDeltasQueue;
|
||||
private readonly metadata: MetadataRepository;
|
||||
private readonly client: SocketClient;
|
||||
|
||||
private relayedElementsVersionsCache = new Map<
|
||||
string,
|
||||
ExcalidrawElement["version"]
|
||||
>();
|
||||
|
||||
// #region ACKNOWLEDGED DELTAS & METADATA
|
||||
// CFDO II: shouldn't be stateful, only request / response
|
||||
private readonly acknowledgedDeltasMap: Map<string, AcknowledgedDelta> =
|
||||
new Map();
|
||||
|
||||
public get acknowledgedDeltas() {
|
||||
return Array.from(this.acknowledgedDeltasMap.values())
|
||||
.sort((a, b) => (a.version < b.version ? -1 : 1))
|
||||
.map((x) => x.delta);
|
||||
}
|
||||
|
||||
private _lastAcknowledgedVersion = 0;
|
||||
|
||||
private get lastAcknowledgedVersion() {
|
||||
return this._lastAcknowledgedVersion;
|
||||
}
|
||||
|
||||
private set lastAcknowledgedVersion(version: number) {
|
||||
this._lastAcknowledgedVersion = version;
|
||||
this.metadata.saveMetadata({ lastAcknowledgedVersion: version });
|
||||
}
|
||||
// #endregion
|
||||
|
||||
private constructor(
|
||||
api: ExcalidrawImperativeAPI,
|
||||
repository: MetadataRepository,
|
||||
queue: LocalDeltasQueue,
|
||||
options: { host: string; roomId: string; lastAcknowledgedVersion: number },
|
||||
) {
|
||||
this.api = api;
|
||||
this.metadata = repository;
|
||||
this.localDeltas = queue;
|
||||
this.lastAcknowledgedVersion = options.lastAcknowledgedVersion;
|
||||
this.client = new SocketClient(options.host, options.roomId, {
|
||||
onOpen: this.onOpen,
|
||||
onOnline: this.onOnline,
|
||||
onMessage: this.onMessage,
|
||||
});
|
||||
}
|
||||
|
||||
// #region SYNC_CLIENT FACTORY
|
||||
public static async create(
|
||||
api: ExcalidrawImperativeAPI,
|
||||
repository: DeltasRepository & MetadataRepository,
|
||||
) {
|
||||
const queue = await LocalDeltasQueue.create(repository);
|
||||
// CFDO: temporary for custom roomId (though E+ will be similar)
|
||||
const roomId = window.location.pathname.split("/").at(-1);
|
||||
|
||||
return new SyncClient(api, repository, queue, {
|
||||
host: SyncClient.HOST_URL,
|
||||
roomId: roomId ?? SyncClient.ROOM_ID,
|
||||
// CFDO II: temporary, so that all deltas are loaded and applied on init
|
||||
lastAcknowledgedVersion: 0,
|
||||
});
|
||||
}
|
||||
// #endregion
|
||||
|
||||
// #region PUBLIC API METHODS
|
||||
public connect() {
|
||||
this.client.connect();
|
||||
}
|
||||
|
||||
public disconnect() {
|
||||
this.client.disconnect();
|
||||
this.relayedElementsVersionsCache.clear();
|
||||
}
|
||||
|
||||
public pull(sinceVersion?: number): void {
|
||||
this.client.send({
|
||||
type: "pull",
|
||||
payload: {
|
||||
lastAcknowledgedVersion: sinceVersion ?? this.lastAcknowledgedVersion,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
public push(delta?: StoreDelta): void {
|
||||
if (delta) {
|
||||
this.localDeltas.add(delta);
|
||||
}
|
||||
|
||||
// re-send all already queued deltas
|
||||
for (const delta of this.localDeltas.getAll()) {
|
||||
this.client.send({
|
||||
type: "push",
|
||||
payload: {
|
||||
...delta,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// CFDO: should be throttled! 16ms (60 fps) for live scenes, not needed at all for single player
|
||||
public relay(change: StoreChange): void {
|
||||
if (this.client.isDisconnected) {
|
||||
// don't reconnect if we're explicitly disconnected
|
||||
// otherwise versioning slider would trigger sync on every slider step
|
||||
return;
|
||||
}
|
||||
|
||||
let shouldRelay = false;
|
||||
|
||||
for (const [id, element] of Object.entries(change.elements)) {
|
||||
const cachedElementVersion = this.relayedElementsVersionsCache.get(id);
|
||||
|
||||
if (!cachedElementVersion || cachedElementVersion < element.version) {
|
||||
this.relayedElementsVersionsCache.set(id, element.version);
|
||||
|
||||
if (!shouldRelay) {
|
||||
// it's enough that a single element is not cached or is outdated in cache
|
||||
// to relay the whole change, otherwise we skip the relay as we've already received this change
|
||||
shouldRelay = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!shouldRelay) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.client.send({
|
||||
type: "relay",
|
||||
payload: { ...change },
|
||||
});
|
||||
}
|
||||
// #endregion
|
||||
|
||||
// #region PRIVATE SOCKET MESSAGE HANDLERS
|
||||
private onOpen = (event: Event) => {
|
||||
// CFDO II: hack to pull everything for on init
|
||||
this.pull(0);
|
||||
this.push();
|
||||
};
|
||||
|
||||
private onOnline = () => {
|
||||
// perform incremental sync
|
||||
this.pull();
|
||||
this.push();
|
||||
};
|
||||
|
||||
private onMessage = (serverMessage: SERVER_MESSAGE) => {
|
||||
const { type, payload } = serverMessage;
|
||||
|
||||
switch (type) {
|
||||
case "relayed":
|
||||
return this.handleRelayed(payload);
|
||||
case "acknowledged":
|
||||
return this.handleAcknowledged(payload);
|
||||
// case "rejected":
|
||||
// return this.handleRejected(payload);
|
||||
default:
|
||||
console.error("Unknown message type:", type);
|
||||
}
|
||||
};
|
||||
|
||||
private handleRelayed = (payload: CLIENT_CHANGE) => {
|
||||
// CFDO I: retrieve the map already
|
||||
const nextElements = new Map(
|
||||
this.api.getSceneElementsIncludingDeleted().map((el) => [el.id, el]),
|
||||
) as SceneElementsMap;
|
||||
|
||||
try {
|
||||
const { elements: relayedElements } = payload;
|
||||
|
||||
for (const [id, relayedElement] of Object.entries(relayedElements)) {
|
||||
const existingElement = nextElements.get(id);
|
||||
|
||||
if (
|
||||
!existingElement || // new element
|
||||
existingElement.version < relayedElement.version // updated element
|
||||
) {
|
||||
nextElements.set(id, relayedElement);
|
||||
this.relayedElementsVersionsCache.set(id, relayedElement.version);
|
||||
}
|
||||
}
|
||||
|
||||
const orderedElements = orderByFractionalIndex(
|
||||
Array.from(nextElements.values()),
|
||||
);
|
||||
|
||||
this.api.updateScene({
|
||||
elements: orderedElements,
|
||||
storeAction: StoreAction.UPDATE,
|
||||
});
|
||||
} catch (e) {
|
||||
console.error("Failed to apply relayed change:", e);
|
||||
}
|
||||
};
|
||||
|
||||
// CFDO: refactor by applying all operations to store, not to the elements
|
||||
private handleAcknowledged = (payload: { deltas: Array<SERVER_DELTA> }) => {
|
||||
let prevSnapshot = this.api.store.snapshot;
|
||||
|
||||
try {
|
||||
const remoteDeltas = Array.from(payload.deltas);
|
||||
const applicableDeltas: Array<StoreDelta> = [];
|
||||
const appState = this.api.getAppState();
|
||||
|
||||
let nextAcknowledgedVersion = this.lastAcknowledgedVersion;
|
||||
let nextElements = new Map(
|
||||
// CFDO: retrieve the map already
|
||||
this.api.getSceneElementsIncludingDeleted().map((el) => [el.id, el]),
|
||||
) as SceneElementsMap;
|
||||
|
||||
for (const { id, version, payload } of remoteDeltas) {
|
||||
// CFDO II: temporary to load all deltas on init
|
||||
this.acknowledgedDeltasMap.set(id, {
|
||||
delta: StoreDelta.load(payload),
|
||||
version,
|
||||
});
|
||||
|
||||
// we've already applied this delta!
|
||||
if (version <= nextAcknowledgedVersion) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// CFDO: strictly checking for out of order deltas; might be relaxed if it becomes a problem
|
||||
if (version !== nextAcknowledgedVersion + 1) {
|
||||
throw new Error(
|
||||
`Received out of order delta, expected "${
|
||||
nextAcknowledgedVersion + 1
|
||||
}", but received "${version}"`,
|
||||
);
|
||||
}
|
||||
|
||||
if (this.localDeltas.has(id)) {
|
||||
// local delta does not have to be applied again
|
||||
this.localDeltas.remove(id);
|
||||
} else {
|
||||
// this is a new remote delta, adding it to the list of applicable deltas
|
||||
const remoteDelta = StoreDelta.load(payload);
|
||||
applicableDeltas.push(remoteDelta);
|
||||
}
|
||||
|
||||
nextAcknowledgedVersion = version;
|
||||
}
|
||||
|
||||
// adding all yet unacknowledged local deltas
|
||||
const localDeltas = this.localDeltas.getAll();
|
||||
applicableDeltas.push(...localDeltas);
|
||||
|
||||
for (const delta of applicableDeltas) {
|
||||
[nextElements] = this.api.store.applyDeltaTo(
|
||||
delta,
|
||||
nextElements,
|
||||
appState,
|
||||
{
|
||||
triggerIncrement: false,
|
||||
updateSnapshot: true,
|
||||
},
|
||||
);
|
||||
|
||||
prevSnapshot = this.api.store.snapshot;
|
||||
}
|
||||
|
||||
const orderedElements = orderByFractionalIndex(
|
||||
Array.from(nextElements.values()),
|
||||
);
|
||||
|
||||
// CFDO: might need to restore first due to potentially stale delta versions
|
||||
this.api.updateScene({
|
||||
elements: orderedElements,
|
||||
// even though the snapshot should be up-to-date already,
|
||||
// still some more updates might be triggered,
|
||||
// i.e. as a result from syncing invalid indices
|
||||
storeAction: StoreAction.UPDATE,
|
||||
});
|
||||
|
||||
this.lastAcknowledgedVersion = nextAcknowledgedVersion;
|
||||
} catch (e) {
|
||||
console.error("Failed to apply acknowledged deltas:", e);
|
||||
// rollback to the previous snapshot, so that we don't end up in an incosistent state
|
||||
this.api.store.snapshot = prevSnapshot;
|
||||
// schedule another fresh pull in case of a failure
|
||||
this.schedulePull();
|
||||
}
|
||||
};
|
||||
|
||||
private handleRejected = (payload: {
|
||||
ids: Array<string>;
|
||||
message: Uint8Array;
|
||||
}) => {
|
||||
// handle rejected deltas
|
||||
console.error("Rejected message received:", payload);
|
||||
};
|
||||
|
||||
private schedulePull = debounce(() => this.pull(), 1000);
|
||||
// #endregion
|
||||
}
|
|
@ -1,68 +0,0 @@
|
|||
import type { StoreChange, StoreDelta } from "../store";
|
||||
import type { DTO } from "../utility-types";
|
||||
|
||||
export type CLIENT_DELTA = DTO<StoreDelta>;
|
||||
export type CLIENT_CHANGE = DTO<StoreChange>;
|
||||
|
||||
export type RESTORE_PAYLOAD = {};
|
||||
export type RELAY_PAYLOAD = CLIENT_CHANGE;
|
||||
export type PUSH_PAYLOAD = CLIENT_DELTA;
|
||||
export type PULL_PAYLOAD = { lastAcknowledgedVersion: number };
|
||||
|
||||
export type CHUNK_INFO = {
|
||||
id: string;
|
||||
position: number;
|
||||
count: number;
|
||||
};
|
||||
|
||||
export type CLIENT_MESSAGE = (
|
||||
| { type: "restore"; payload: RESTORE_PAYLOAD }
|
||||
| { type: "relay"; payload: RELAY_PAYLOAD }
|
||||
| { type: "pull"; payload: PULL_PAYLOAD }
|
||||
| { type: "push"; payload: PUSH_PAYLOAD }
|
||||
) & { chunkInfo?: CHUNK_INFO };
|
||||
|
||||
export type CLIENT_MESSAGE_BINARY = {
|
||||
type: CLIENT_MESSAGE["type"];
|
||||
payload: Uint8Array;
|
||||
chunkInfo?: CHUNK_INFO;
|
||||
};
|
||||
|
||||
export type SERVER_DELTA = {
|
||||
id: CLIENT_DELTA["id"];
|
||||
version: number;
|
||||
payload: CLIENT_DELTA;
|
||||
};
|
||||
|
||||
export type SERVER_DELTA_STORAGE = {
|
||||
id: SERVER_DELTA["id"];
|
||||
version: SERVER_DELTA["version"];
|
||||
position: number;
|
||||
payload: ArrayBuffer;
|
||||
};
|
||||
|
||||
export type SERVER_MESSAGE =
|
||||
| {
|
||||
type: "relayed";
|
||||
payload: RELAY_PAYLOAD;
|
||||
}
|
||||
| { type: "acknowledged"; payload: { deltas: Array<SERVER_DELTA> } }
|
||||
| {
|
||||
type: "rejected";
|
||||
payload: { deltas: Array<CLIENT_DELTA>; message: string };
|
||||
}
|
||||
| { type: "restored"; payload: { elements: Array<ExcalidrawElement> } };
|
||||
|
||||
export interface DeltasRepository {
|
||||
save(delta: CLIENT_DELTA): SERVER_DELTA | null;
|
||||
getAllSinceVersion(version: number): Array<SERVER_DELTA>;
|
||||
getLastVersion(): number;
|
||||
}
|
||||
|
||||
// CFDO: should come from the shared types package (might need a bigger refactor)
|
||||
export type ExcalidrawElement = {
|
||||
id: string;
|
||||
type: any;
|
||||
version: number;
|
||||
[key: string]: any;
|
||||
};
|
|
@ -1,74 +0,0 @@
|
|||
import throttle from "lodash.throttle";
|
||||
import type { StoreDelta } from "../store";
|
||||
|
||||
export interface DeltasRepository {
|
||||
loadDeltas(): Promise<Array<StoreDelta> | null>;
|
||||
saveDeltas(params: StoreDelta[]): Promise<void>;
|
||||
}
|
||||
|
||||
export interface MetadataRepository {
|
||||
loadMetadata(): Promise<{ lastAcknowledgedVersion: number } | null>;
|
||||
saveMetadata(metadata: { lastAcknowledgedVersion: number }): Promise<void>;
|
||||
}
|
||||
|
||||
export class LocalDeltasQueue {
|
||||
private readonly queue: Map<string, StoreDelta>;
|
||||
private readonly repository: DeltasRepository;
|
||||
|
||||
private constructor(
|
||||
queue: Map<string, StoreDelta> = new Map(),
|
||||
repository: DeltasRepository,
|
||||
) {
|
||||
this.queue = queue;
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
public static async create(repository: DeltasRepository) {
|
||||
const deltas = await repository.loadDeltas();
|
||||
|
||||
return new LocalDeltasQueue(
|
||||
new Map(deltas?.map((delta) => [delta.id, delta])),
|
||||
repository,
|
||||
);
|
||||
}
|
||||
|
||||
public getAll() {
|
||||
return Array.from(this.queue.values());
|
||||
}
|
||||
|
||||
public get(id: StoreDelta["id"]) {
|
||||
return this.queue.get(id);
|
||||
}
|
||||
|
||||
public has(id: StoreDelta["id"]) {
|
||||
return this.queue.has(id);
|
||||
}
|
||||
|
||||
public add(...deltas: StoreDelta[]) {
|
||||
for (const delta of deltas) {
|
||||
this.queue.set(delta.id, delta);
|
||||
}
|
||||
|
||||
this.persist();
|
||||
}
|
||||
|
||||
public remove(...ids: StoreDelta["id"][]) {
|
||||
for (const id of ids) {
|
||||
this.queue.delete(id);
|
||||
}
|
||||
|
||||
this.persist();
|
||||
}
|
||||
|
||||
public persist = throttle(
|
||||
async () => {
|
||||
try {
|
||||
await this.repository.saveDeltas(this.getAll());
|
||||
} catch (e) {
|
||||
console.error("Failed to persist the sync queue:", e);
|
||||
}
|
||||
},
|
||||
1000,
|
||||
{ leading: false, trailing: true },
|
||||
);
|
||||
}
|
|
@ -1,308 +0,0 @@
|
|||
import AsyncLock from "async-lock";
|
||||
import { Network, Utils } from "./utils";
|
||||
|
||||
import type {
|
||||
DeltasRepository,
|
||||
PULL_PAYLOAD,
|
||||
PUSH_PAYLOAD,
|
||||
SERVER_MESSAGE,
|
||||
SERVER_DELTA,
|
||||
CHUNK_INFO,
|
||||
RELAY_PAYLOAD,
|
||||
CLIENT_MESSAGE_BINARY,
|
||||
CLIENT_MESSAGE,
|
||||
ExcalidrawElement,
|
||||
} from "./protocol";
|
||||
import { StoreDelta } from "../store";
|
||||
|
||||
/**
|
||||
* Core excalidraw sync logic.
|
||||
*/
|
||||
export class ExcalidrawSyncServer {
|
||||
private readonly lock: AsyncLock = new AsyncLock();
|
||||
private readonly sessions: Set<WebSocket> = new Set();
|
||||
private readonly chunks = new Map<
|
||||
CHUNK_INFO["id"],
|
||||
Map<CHUNK_INFO["position"], CLIENT_MESSAGE_BINARY["payload"]>
|
||||
>();
|
||||
|
||||
// CFDO II: load from the db
|
||||
private elements = new Map<string, ExcalidrawElement>();
|
||||
|
||||
constructor(private readonly repository: DeltasRepository) {
|
||||
// CFDO II: load from the db
|
||||
const deltas = this.repository.getAllSinceVersion(0);
|
||||
|
||||
for (const delta of deltas) {
|
||||
const storeDelta = StoreDelta.load(delta.payload);
|
||||
|
||||
// CFDO II: fix types (everywhere)
|
||||
const [nextElements] = storeDelta.elements.applyTo(this.elements as any);
|
||||
|
||||
this.elements = nextElements;
|
||||
}
|
||||
}
|
||||
|
||||
// CFDO: optimize, should send a message about collaborators (no collaborators => no need to send ephemerals)
|
||||
public onConnect(client: WebSocket) {
|
||||
this.sessions.add(client);
|
||||
}
|
||||
|
||||
public onDisconnect(client: WebSocket) {
|
||||
this.sessions.delete(client);
|
||||
}
|
||||
|
||||
public onMessage(
|
||||
client: WebSocket,
|
||||
message: ArrayBuffer,
|
||||
): Promise<void> | void {
|
||||
const [rawMessage, parsingError] = Utils.try<CLIENT_MESSAGE_BINARY>(() =>
|
||||
Network.decodeClientMessage(message),
|
||||
);
|
||||
|
||||
if (parsingError) {
|
||||
console.error(parsingError);
|
||||
return;
|
||||
}
|
||||
|
||||
// if there is chunkInfo, there are more than 1 chunks => process them first
|
||||
if (rawMessage.chunkInfo) {
|
||||
return this.processChunks(client, {
|
||||
...rawMessage,
|
||||
chunkInfo: rawMessage.chunkInfo,
|
||||
});
|
||||
}
|
||||
|
||||
return this.processMessage(client, rawMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process chunks in case the client-side payload would overflow the 1MiB durable object WS message limit.
|
||||
*/
|
||||
private processChunks(
|
||||
client: WebSocket,
|
||||
message: CLIENT_MESSAGE_BINARY &
|
||||
Required<Pick<CLIENT_MESSAGE_BINARY, "chunkInfo">>,
|
||||
) {
|
||||
let shouldCleanupchunks = true;
|
||||
const {
|
||||
type,
|
||||
payload,
|
||||
chunkInfo: { id, position, count },
|
||||
} = message;
|
||||
|
||||
try {
|
||||
if (!this.chunks.has(id)) {
|
||||
this.chunks.set(id, new Map());
|
||||
}
|
||||
|
||||
const chunks = this.chunks.get(id);
|
||||
|
||||
if (!chunks) {
|
||||
// defensive, shouldn't really happen
|
||||
throw new Error(`Coudn't find a relevant chunk with id "${id}"!`);
|
||||
}
|
||||
|
||||
// set the buffer by order
|
||||
chunks.set(position, payload);
|
||||
|
||||
if (chunks.size !== count) {
|
||||
// we don't have all the chunks, don't cleanup just yet!
|
||||
shouldCleanupchunks = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// hopefully we can fit into the 128 MiB memory limit
|
||||
const restoredPayload = Array.from(chunks)
|
||||
.sort(([positionA], [positionB]) => (positionA <= positionB ? -1 : 1))
|
||||
.reduce(
|
||||
(acc, [_, payload]) => Uint8Array.from([...acc, ...payload]),
|
||||
new Uint8Array(),
|
||||
);
|
||||
|
||||
const rawMessage = {
|
||||
type,
|
||||
payload: restoredPayload,
|
||||
} as Omit<CLIENT_MESSAGE_BINARY, "chunkInfo">;
|
||||
|
||||
return this.processMessage(client, rawMessage);
|
||||
} catch (error) {
|
||||
console.error(`Error while processing chunk "${id}"`, error);
|
||||
} finally {
|
||||
// cleanup the chunks
|
||||
if (shouldCleanupchunks) {
|
||||
this.chunks.delete(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private processMessage(
|
||||
client: WebSocket,
|
||||
{ type, payload }: Omit<CLIENT_MESSAGE_BINARY, "chunkInfo">,
|
||||
) {
|
||||
const [parsedPayload, parsingError] = Utils.try<CLIENT_MESSAGE["payload"]>(
|
||||
() => Network.fromBinary(payload),
|
||||
);
|
||||
|
||||
if (parsingError) {
|
||||
console.error(parsingError);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case "restore":
|
||||
return this.restore(client);
|
||||
case "relay":
|
||||
return this.relay(client, parsedPayload as RELAY_PAYLOAD);
|
||||
case "pull":
|
||||
return this.pull(client, parsedPayload as PULL_PAYLOAD);
|
||||
case "push":
|
||||
// apply each one-by-one to avoid race conditions
|
||||
// CFDO: in theory we do not need to block ephemeral appState (for now we are not even using them)
|
||||
return this.lock.acquire("push", () =>
|
||||
this.push(client, parsedPayload as PUSH_PAYLOAD),
|
||||
);
|
||||
default:
|
||||
console.error(`Unknown message type: ${type}`);
|
||||
}
|
||||
}
|
||||
|
||||
private restore(client: WebSocket) {
|
||||
return this.send(client, {
|
||||
type: "restored",
|
||||
payload: {
|
||||
elements: Array.from(this.elements.values()),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
private relay(client: WebSocket, payload: RELAY_PAYLOAD) {
|
||||
// CFDO I: we should likely apply these to the snapshot
|
||||
return this.broadcast(
|
||||
{
|
||||
type: "relayed",
|
||||
payload,
|
||||
},
|
||||
client,
|
||||
);
|
||||
}
|
||||
|
||||
private pull(client: WebSocket, payload: PULL_PAYLOAD) {
|
||||
// CFDO: test for invalid payload
|
||||
const lastAcknowledgedClientVersion = payload.lastAcknowledgedVersion;
|
||||
const lastAcknowledgedServerVersion = this.repository.getLastVersion();
|
||||
|
||||
const versionΔ =
|
||||
lastAcknowledgedServerVersion - lastAcknowledgedClientVersion;
|
||||
|
||||
if (versionΔ < 0) {
|
||||
// CFDO II: restore the client from the snapshot / deltas?
|
||||
console.error(
|
||||
`Panic! Client claims to have higher acknowledged version than the latest one on the server!`,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const deltas: SERVER_DELTA[] = [];
|
||||
|
||||
if (versionΔ > 0) {
|
||||
deltas.push(
|
||||
...this.repository.getAllSinceVersion(lastAcknowledgedClientVersion),
|
||||
);
|
||||
}
|
||||
|
||||
this.send(client, {
|
||||
type: "acknowledged",
|
||||
payload: {
|
||||
deltas,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
private push(client: WebSocket, delta: PUSH_PAYLOAD) {
|
||||
const [storeDelta, applyingError] = Utils.try(() => {
|
||||
// update the "deleted" delta according to the latest changes (in case of concurrent changes)
|
||||
const storeDelta = StoreDelta.applyLatestChanges(
|
||||
StoreDelta.load(delta),
|
||||
this.elements as any,
|
||||
"deleted",
|
||||
);
|
||||
|
||||
// apply the delta to the elements snapshot
|
||||
const [nextElements] = storeDelta.elements.applyTo(this.elements as any);
|
||||
|
||||
this.elements = nextElements;
|
||||
|
||||
return storeDelta;
|
||||
});
|
||||
|
||||
if (applyingError) {
|
||||
// CFDO: everything should be automatically rolled-back in the db -> double-check
|
||||
return this.send(client, {
|
||||
type: "rejected",
|
||||
payload: {
|
||||
message: applyingError
|
||||
? applyingError.message
|
||||
: "Couldn't apply the delta.",
|
||||
deltas: [delta],
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
const [acknowledged, savingError] = Utils.try(() => {
|
||||
return this.repository.save(storeDelta);
|
||||
});
|
||||
|
||||
if (savingError || !acknowledged) {
|
||||
// CFDO: everything should be automatically rolled-back in the db -> double-check
|
||||
return this.send(client, {
|
||||
type: "rejected",
|
||||
payload: {
|
||||
message: savingError
|
||||
? savingError.message
|
||||
: "Coudn't persist the delta.",
|
||||
deltas: [storeDelta],
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
return this.broadcast({
|
||||
type: "acknowledged",
|
||||
payload: {
|
||||
deltas: [acknowledged],
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
private send(ws: WebSocket, message: SERVER_MESSAGE) {
|
||||
const [encodedMessage, encodingError] = Utils.try(() =>
|
||||
Network.toBinary(message),
|
||||
);
|
||||
|
||||
if (encodingError) {
|
||||
console.error(encodingError);
|
||||
return;
|
||||
}
|
||||
|
||||
ws.send(encodedMessage);
|
||||
}
|
||||
|
||||
private broadcast(message: SERVER_MESSAGE, exclude?: WebSocket) {
|
||||
const [encodedMessage, encodingError] = Utils.try(() =>
|
||||
Network.toBinary(message),
|
||||
);
|
||||
|
||||
if (encodingError) {
|
||||
console.error(encodingError);
|
||||
return;
|
||||
}
|
||||
|
||||
for (const ws of this.sessions) {
|
||||
if (ws === exclude) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ws.send(encodedMessage);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,68 +0,0 @@
|
|||
import msgpack from "msgpack-lite";
|
||||
|
||||
import type { CLIENT_MESSAGE_BINARY } from "./protocol";
|
||||
|
||||
export const Utils = {
|
||||
try<T>(cb: () => T): [T, null] | [null, Error] {
|
||||
try {
|
||||
const result = cb();
|
||||
return [result, null];
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
return [null, error];
|
||||
}
|
||||
|
||||
if (typeof error === "string") {
|
||||
return [null, new Error(error)];
|
||||
}
|
||||
|
||||
return [null, new Error("Unknown error")];
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export const Network = {
|
||||
toBinary: (payload: Record<string, unknown>) => {
|
||||
return new Uint8Array(msgpack.encode(payload));
|
||||
},
|
||||
fromBinary: (payload: Uint8Array) => {
|
||||
return msgpack.decode(payload);
|
||||
},
|
||||
encodeClientMessage: (message: CLIENT_MESSAGE_BINARY) => {
|
||||
const { payload, ...metadata } = message;
|
||||
const metadataBuffer = Network.toBinary(metadata);
|
||||
|
||||
// contains the length of the rest of the message, so that we could chunk the payload and decode it server side
|
||||
const headerBuffer = new ArrayBuffer(4);
|
||||
new DataView(headerBuffer).setUint32(0, metadataBuffer.byteLength);
|
||||
|
||||
// concatenate into [header(4 bytes)][metadata][payload]
|
||||
return Uint8Array.from([
|
||||
...new Uint8Array(headerBuffer),
|
||||
...metadataBuffer,
|
||||
...message.payload,
|
||||
]);
|
||||
},
|
||||
decodeClientMessage: (message: ArrayBuffer) => {
|
||||
const headerLength = 4;
|
||||
const header = new Uint8Array(message, 0, headerLength);
|
||||
const metadataLength = new DataView(
|
||||
header.buffer,
|
||||
header.byteOffset,
|
||||
).getUint32(0);
|
||||
|
||||
const metadata = new Uint8Array(
|
||||
message,
|
||||
headerLength,
|
||||
headerLength + metadataLength,
|
||||
);
|
||||
|
||||
const payload = new Uint8Array(message, headerLength + metadataLength);
|
||||
const rawMessage = {
|
||||
...Network.fromBinary(metadata),
|
||||
payload,
|
||||
} as CLIENT_MESSAGE_BINARY;
|
||||
|
||||
return rawMessage;
|
||||
},
|
||||
};
|
|
@ -1,7 +0,0 @@
|
|||
// Generated by Wrangler by running `wrangler types --experimental-include-runtime=./worker-runtime.d.ts`
|
||||
|
||||
interface Env {
|
||||
DURABLE_ROOM: DurableObjectNamespace<
|
||||
import("./cloudflare/worker").DurableRoom
|
||||
>;
|
||||
}
|
4691
packages/excalidraw/worker-runtime.d.ts
vendored
4691
packages/excalidraw/worker-runtime.d.ts
vendored
File diff suppressed because it is too large
Load diff
|
@ -1,23 +0,0 @@
|
|||
#:schema node_modules/wrangler/config-schema.json
|
||||
name = "excalidraw-sync"
|
||||
main = "cloudflare/worker.ts"
|
||||
compatibility_date = "2024-11-12"
|
||||
|
||||
# Workers Logs
|
||||
# Docs: https://developers.cloudflare.com/workers/observability/logs/workers-logs/
|
||||
# Configuration: https://developers.cloudflare.com/workers/observability/logs/workers-logs/#enable-workers-logs
|
||||
[observability]
|
||||
enabled = true
|
||||
|
||||
# Bind a Durable Object. Durable objects are a scale-to-zero compute primitive based on the actor model.
|
||||
# Durable Objects can live for as long as needed. Use these when you need a long-running "server", such as in realtime apps.
|
||||
# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#durable-objects
|
||||
[[durable_objects.bindings]]
|
||||
name = "DURABLE_ROOM"
|
||||
class_name = "DurableRoom"
|
||||
|
||||
# Durable Object migrations.
|
||||
# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#migrations
|
||||
[[migrations]]
|
||||
tag = "v1"
|
||||
new_sqlite_classes = ["DurableRoom"]
|
555
yarn.lock
555
yarn.lock
|
@ -1506,76 +1506,11 @@
|
|||
resolved "https://registry.yarnpkg.com/@braintree/sanitize-url/-/sanitize-url-6.0.4.tgz#923ca57e173c6b232bbbb07347b1be982f03e783"
|
||||
integrity sha512-s3jaWicZd0pkP0jf5ysyHUI/RE7MHos6qlToFcGWXVp+ykHOy77OUMrfbgJ9it2C5bow7OIQwYYaHjk9XlBQ2A==
|
||||
|
||||
"@cloudflare/kv-asset-handler@0.3.4":
|
||||
version "0.3.4"
|
||||
resolved "https://registry.yarnpkg.com/@cloudflare/kv-asset-handler/-/kv-asset-handler-0.3.4.tgz#5cc152847c8ae4d280ec5d7f4f6ba8c976b585c3"
|
||||
integrity sha512-YLPHc8yASwjNkmcDMQMY35yiWjoKAKnhUbPRszBRS0YgH+IXtsMp61j+yTcnCE3oO2DgP0U3iejLC8FTtKDC8Q==
|
||||
dependencies:
|
||||
mime "^3.0.0"
|
||||
|
||||
"@cloudflare/workerd-darwin-64@1.20241106.1":
|
||||
version "1.20241106.1"
|
||||
resolved "https://registry.yarnpkg.com/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20241106.1.tgz#4f470f98ca12dbc3262ec8a432466e1c1525aad9"
|
||||
integrity sha512-zxvaToi1m0qzAScrxFt7UvFVqU8DxrCO2CinM1yQkv5no7pA1HolpIrwZ0xOhR3ny64Is2s/J6BrRjpO5dM9Zw==
|
||||
|
||||
"@cloudflare/workerd-darwin-arm64@1.20241106.1":
|
||||
version "1.20241106.1"
|
||||
resolved "https://registry.yarnpkg.com/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20241106.1.tgz#c34d6306afc50ae2eee3e538329af7192ae17dd0"
|
||||
integrity sha512-j3dg/42D/bPgfNP3cRUBxF+4waCKO/5YKwXNj+lnVOwHxDu+ne5pFw9TIkKYcWTcwn0ZUkbNZNM5rhJqRn4xbg==
|
||||
|
||||
"@cloudflare/workerd-linux-64@1.20241106.1":
|
||||
version "1.20241106.1"
|
||||
resolved "https://registry.yarnpkg.com/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20241106.1.tgz#42c425137c151348146a70d3f271e5f3293d3b75"
|
||||
integrity sha512-Ih+Ye8E1DMBXcKrJktGfGztFqHKaX1CeByqshmTbODnWKHt6O65ax3oTecUwyC0+abuyraOpAtdhHNpFMhUkmw==
|
||||
|
||||
"@cloudflare/workerd-linux-arm64@1.20241106.1":
|
||||
version "1.20241106.1"
|
||||
resolved "https://registry.yarnpkg.com/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20241106.1.tgz#f3bc7ab9424dafbf1816d8bc2e8aae24646ecad0"
|
||||
integrity sha512-mdQFPk4+14Yywn7n1xIzI+6olWM8Ybz10R7H3h+rk0XulMumCWUCy1CzIDauOx6GyIcSgKIibYMssVHZR30ObA==
|
||||
|
||||
"@cloudflare/workerd-windows-64@1.20241106.1":
|
||||
version "1.20241106.1"
|
||||
resolved "https://registry.yarnpkg.com/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20241106.1.tgz#9e2f1ec0d993c8b12c4cd7f9c5e6b953a0672707"
|
||||
integrity sha512-4rtcss31E/Rb/PeFocZfr+B9i1MdrkhsTBWizh8siNR4KMmkslU2xs2wPaH1z8+ErxkOsHrKRa5EPLh5rIiFeg==
|
||||
|
||||
"@cloudflare/workers-shared@0.7.1":
|
||||
version "0.7.1"
|
||||
resolved "https://registry.yarnpkg.com/@cloudflare/workers-shared/-/workers-shared-0.7.1.tgz#cf32caaf58808d9e36f9ebc8baa84a9699b388f2"
|
||||
integrity sha512-46cP5FCrl3TrvHeoHLb5SRuiDMKH5kc9Yvo36SAfzt8dqJI/qJRoY1GP3ioHn/gP7v2QIoUOTAzIl7Ml7MnfrA==
|
||||
dependencies:
|
||||
mime "^3.0.0"
|
||||
zod "^3.22.3"
|
||||
|
||||
"@cloudflare/workers-types@4.20241112.0":
|
||||
version "4.20241112.0"
|
||||
resolved "https://registry.yarnpkg.com/@cloudflare/workers-types/-/workers-types-4.20241112.0.tgz#174f8ccbfe1cc2e07b86622f82b84698f62d14c7"
|
||||
integrity sha512-Q4p9bAWZrX14bSCKY9to19xl0KMU7nsO5sJ2cTVspHoypsjPUMeQCsjHjmsO2C4Myo8/LPeDvmqFmkyNAPPYZw==
|
||||
|
||||
"@cspotcode/source-map-support@0.8.1":
|
||||
version "0.8.1"
|
||||
resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1"
|
||||
integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==
|
||||
dependencies:
|
||||
"@jridgewell/trace-mapping" "0.3.9"
|
||||
|
||||
"@discoveryjs/json-ext@^0.5.0":
|
||||
version "0.5.7"
|
||||
resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70"
|
||||
integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==
|
||||
|
||||
"@esbuild-plugins/node-globals-polyfill@^0.2.3":
|
||||
version "0.2.3"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild-plugins/node-globals-polyfill/-/node-globals-polyfill-0.2.3.tgz#0e4497a2b53c9e9485e149bc92ddb228438d6bcf"
|
||||
integrity sha512-r3MIryXDeXDOZh7ih1l/yE9ZLORCd5e8vWg02azWRGj5SPTuoh69A2AIyn0Z31V/kHBfZ4HgWJ+OK3GTTwLmnw==
|
||||
|
||||
"@esbuild-plugins/node-modules-polyfill@^0.2.2":
|
||||
version "0.2.2"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild-plugins/node-modules-polyfill/-/node-modules-polyfill-0.2.2.tgz#cefa3dc0bd1c16277a8338b52833420c94987327"
|
||||
integrity sha512-LXV7QsWJxRuMYvKbiznh+U1ilIop3g2TeKRzUxOG5X3YITc8JyyTa90BmLwqqv0YnX4v32CSlG+vsziZp9dMvA==
|
||||
dependencies:
|
||||
escape-string-regexp "^4.0.0"
|
||||
rollup-plugin-node-polyfills "^0.2.1"
|
||||
|
||||
"@esbuild/aix-ppc64@0.19.10":
|
||||
version "0.19.10"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.19.10.tgz#fb3922a0183d27446de00cf60d4f7baaadf98d84"
|
||||
|
@ -1591,11 +1526,6 @@
|
|||
resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz#a70f4ac11c6a1dfc18b8bbb13284155d933b9537"
|
||||
integrity sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==
|
||||
|
||||
"@esbuild/android-arm64@0.17.19":
|
||||
version "0.17.19"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.17.19.tgz#bafb75234a5d3d1b690e7c2956a599345e84a2fd"
|
||||
integrity sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==
|
||||
|
||||
"@esbuild/android-arm64@0.19.10":
|
||||
version "0.19.10"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.19.10.tgz#ef31015416dd79398082409b77aaaa2ade4d531a"
|
||||
|
@ -1611,11 +1541,6 @@
|
|||
resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz#db1c9202a5bc92ea04c7b6840f1bbe09ebf9e6b9"
|
||||
integrity sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==
|
||||
|
||||
"@esbuild/android-arm@0.17.19":
|
||||
version "0.17.19"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.17.19.tgz#5898f7832c2298bc7d0ab53701c57beb74d78b4d"
|
||||
integrity sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==
|
||||
|
||||
"@esbuild/android-arm@0.19.10":
|
||||
version "0.19.10"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.19.10.tgz#1c23c7e75473aae9fb323be5d9db225142f47f52"
|
||||
|
@ -1631,11 +1556,6 @@
|
|||
resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.20.2.tgz#3b488c49aee9d491c2c8f98a909b785870d6e995"
|
||||
integrity sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==
|
||||
|
||||
"@esbuild/android-x64@0.17.19":
|
||||
version "0.17.19"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.17.19.tgz#658368ef92067866d95fb268719f98f363d13ae1"
|
||||
integrity sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==
|
||||
|
||||
"@esbuild/android-x64@0.19.10":
|
||||
version "0.19.10"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.19.10.tgz#df6a4e6d6eb8da5595cfce16d4e3f6bc24464707"
|
||||
|
@ -1651,11 +1571,6 @@
|
|||
resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.20.2.tgz#3b1628029e5576249d2b2d766696e50768449f98"
|
||||
integrity sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==
|
||||
|
||||
"@esbuild/darwin-arm64@0.17.19":
|
||||
version "0.17.19"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.17.19.tgz#584c34c5991b95d4d48d333300b1a4e2ff7be276"
|
||||
integrity sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg==
|
||||
|
||||
"@esbuild/darwin-arm64@0.19.10":
|
||||
version "0.19.10"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.19.10.tgz#8462a55db07c1b2fad61c8244ce04469ef1043be"
|
||||
|
@ -1671,11 +1586,6 @@
|
|||
resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz#6e8517a045ddd86ae30c6608c8475ebc0c4000bb"
|
||||
integrity sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==
|
||||
|
||||
"@esbuild/darwin-x64@0.17.19":
|
||||
version "0.17.19"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.17.19.tgz#7751d236dfe6ce136cce343dce69f52d76b7f6cb"
|
||||
integrity sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==
|
||||
|
||||
"@esbuild/darwin-x64@0.19.10":
|
||||
version "0.19.10"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.19.10.tgz#d1de20bfd41bb75b955ba86a6b1004539e8218c1"
|
||||
|
@ -1691,11 +1601,6 @@
|
|||
resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz#90ed098e1f9dd8a9381695b207e1cff45540a0d0"
|
||||
integrity sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==
|
||||
|
||||
"@esbuild/freebsd-arm64@0.17.19":
|
||||
version "0.17.19"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.19.tgz#cacd171665dd1d500f45c167d50c6b7e539d5fd2"
|
||||
integrity sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==
|
||||
|
||||
"@esbuild/freebsd-arm64@0.19.10":
|
||||
version "0.19.10"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.10.tgz#16904879e34c53a2e039d1284695d2db3e664d57"
|
||||
|
@ -1711,11 +1616,6 @@
|
|||
resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz#d71502d1ee89a1130327e890364666c760a2a911"
|
||||
integrity sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==
|
||||
|
||||
"@esbuild/freebsd-x64@0.17.19":
|
||||
version "0.17.19"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.17.19.tgz#0769456eee2a08b8d925d7c00b79e861cb3162e4"
|
||||
integrity sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==
|
||||
|
||||
"@esbuild/freebsd-x64@0.19.10":
|
||||
version "0.19.10"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.19.10.tgz#8ad9e5ca9786ca3f1ef1411bfd10b08dcd9d4cef"
|
||||
|
@ -1731,11 +1631,6 @@
|
|||
resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz#aa5ea58d9c1dd9af688b8b6f63ef0d3d60cea53c"
|
||||
integrity sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==
|
||||
|
||||
"@esbuild/linux-arm64@0.17.19":
|
||||
version "0.17.19"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.17.19.tgz#38e162ecb723862c6be1c27d6389f48960b68edb"
|
||||
integrity sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==
|
||||
|
||||
"@esbuild/linux-arm64@0.19.10":
|
||||
version "0.19.10"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.19.10.tgz#d82cf2c590faece82d28bbf1cfbe36f22ae25bd2"
|
||||
|
@ -1751,11 +1646,6 @@
|
|||
resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz#055b63725df678379b0f6db9d0fa85463755b2e5"
|
||||
integrity sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==
|
||||
|
||||
"@esbuild/linux-arm@0.17.19":
|
||||
version "0.17.19"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.17.19.tgz#1a2cd399c50040184a805174a6d89097d9d1559a"
|
||||
integrity sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==
|
||||
|
||||
"@esbuild/linux-arm@0.19.10":
|
||||
version "0.19.10"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.19.10.tgz#477b8e7c7bcd34369717b04dd9ee6972c84f4029"
|
||||
|
@ -1771,11 +1661,6 @@
|
|||
resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz#76b3b98cb1f87936fbc37f073efabad49dcd889c"
|
||||
integrity sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==
|
||||
|
||||
"@esbuild/linux-ia32@0.17.19":
|
||||
version "0.17.19"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.17.19.tgz#e28c25266b036ce1cabca3c30155222841dc035a"
|
||||
integrity sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==
|
||||
|
||||
"@esbuild/linux-ia32@0.19.10":
|
||||
version "0.19.10"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.19.10.tgz#d55ff822cf5b0252a57112f86857ff23be6cab0e"
|
||||
|
@ -1791,11 +1676,6 @@
|
|||
resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz#c0e5e787c285264e5dfc7a79f04b8b4eefdad7fa"
|
||||
integrity sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==
|
||||
|
||||
"@esbuild/linux-loong64@0.17.19":
|
||||
version "0.17.19"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.17.19.tgz#0f887b8bb3f90658d1a0117283e55dbd4c9dcf72"
|
||||
integrity sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==
|
||||
|
||||
"@esbuild/linux-loong64@0.19.10":
|
||||
version "0.19.10"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.19.10.tgz#a9ad057d7e48d6c9f62ff50f6f208e331c4543c7"
|
||||
|
@ -1811,11 +1691,6 @@
|
|||
resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz#a6184e62bd7cdc63e0c0448b83801001653219c5"
|
||||
integrity sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==
|
||||
|
||||
"@esbuild/linux-mips64el@0.17.19":
|
||||
version "0.17.19"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.17.19.tgz#f5d2a0b8047ea9a5d9f592a178ea054053a70289"
|
||||
integrity sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==
|
||||
|
||||
"@esbuild/linux-mips64el@0.19.10":
|
||||
version "0.19.10"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.19.10.tgz#b011a96924773d60ebab396fbd7a08de66668179"
|
||||
|
@ -1831,11 +1706,6 @@
|
|||
resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz#d08e39ce86f45ef8fc88549d29c62b8acf5649aa"
|
||||
integrity sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==
|
||||
|
||||
"@esbuild/linux-ppc64@0.17.19":
|
||||
version "0.17.19"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.17.19.tgz#876590e3acbd9fa7f57a2c7d86f83717dbbac8c7"
|
||||
integrity sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==
|
||||
|
||||
"@esbuild/linux-ppc64@0.19.10":
|
||||
version "0.19.10"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.19.10.tgz#5d8b59929c029811e473f2544790ea11d588d4dd"
|
||||
|
@ -1851,11 +1721,6 @@
|
|||
resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz#8d252f0b7756ffd6d1cbde5ea67ff8fd20437f20"
|
||||
integrity sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==
|
||||
|
||||
"@esbuild/linux-riscv64@0.17.19":
|
||||
version "0.17.19"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.17.19.tgz#7f49373df463cd9f41dc34f9b2262d771688bf09"
|
||||
integrity sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==
|
||||
|
||||
"@esbuild/linux-riscv64@0.19.10":
|
||||
version "0.19.10"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.19.10.tgz#292b06978375b271bd8bc0a554e0822957508d22"
|
||||
|
@ -1871,11 +1736,6 @@
|
|||
resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz#19f6dcdb14409dae607f66ca1181dd4e9db81300"
|
||||
integrity sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==
|
||||
|
||||
"@esbuild/linux-s390x@0.17.19":
|
||||
version "0.17.19"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.17.19.tgz#e2afd1afcaf63afe2c7d9ceacd28ec57c77f8829"
|
||||
integrity sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==
|
||||
|
||||
"@esbuild/linux-s390x@0.19.10":
|
||||
version "0.19.10"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.19.10.tgz#d30af63530f8d4fa96930374c9dd0d62bf59e069"
|
||||
|
@ -1891,11 +1751,6 @@
|
|||
resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz#3c830c90f1a5d7dd1473d5595ea4ebb920988685"
|
||||
integrity sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==
|
||||
|
||||
"@esbuild/linux-x64@0.17.19":
|
||||
version "0.17.19"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.17.19.tgz#8a0e9738b1635f0c53389e515ae83826dec22aa4"
|
||||
integrity sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==
|
||||
|
||||
"@esbuild/linux-x64@0.19.10":
|
||||
version "0.19.10"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.19.10.tgz#898c72eeb74d9f2fb43acf316125b475548b75ce"
|
||||
|
@ -1911,11 +1766,6 @@
|
|||
resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz#86eca35203afc0d9de0694c64ec0ab0a378f6fff"
|
||||
integrity sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==
|
||||
|
||||
"@esbuild/netbsd-x64@0.17.19":
|
||||
version "0.17.19"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.17.19.tgz#c29fb2453c6b7ddef9a35e2c18b37bda1ae5c462"
|
||||
integrity sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==
|
||||
|
||||
"@esbuild/netbsd-x64@0.19.10":
|
||||
version "0.19.10"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.19.10.tgz#fd473a5ae261b43eab6dad4dbd5a3155906e6c91"
|
||||
|
@ -1931,11 +1781,6 @@
|
|||
resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz#e771c8eb0e0f6e1877ffd4220036b98aed5915e6"
|
||||
integrity sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==
|
||||
|
||||
"@esbuild/openbsd-x64@0.17.19":
|
||||
version "0.17.19"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.17.19.tgz#95e75a391403cb10297280d524d66ce04c920691"
|
||||
integrity sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==
|
||||
|
||||
"@esbuild/openbsd-x64@0.19.10":
|
||||
version "0.19.10"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.19.10.tgz#96eb8992e526717b5272321eaad3e21f3a608e46"
|
||||
|
@ -1951,11 +1796,6 @@
|
|||
resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz#9a795ae4b4e37e674f0f4d716f3e226dd7c39baf"
|
||||
integrity sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==
|
||||
|
||||
"@esbuild/sunos-x64@0.17.19":
|
||||
version "0.17.19"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.17.19.tgz#722eaf057b83c2575937d3ffe5aeb16540da7273"
|
||||
integrity sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==
|
||||
|
||||
"@esbuild/sunos-x64@0.19.10":
|
||||
version "0.19.10"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.19.10.tgz#c16ee1c167f903eaaa6acf7372bee42d5a89c9bc"
|
||||
|
@ -1971,11 +1811,6 @@
|
|||
resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz#7df23b61a497b8ac189def6e25a95673caedb03f"
|
||||
integrity sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==
|
||||
|
||||
"@esbuild/win32-arm64@0.17.19":
|
||||
version "0.17.19"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.17.19.tgz#9aa9dc074399288bdcdd283443e9aeb6b9552b6f"
|
||||
integrity sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==
|
||||
|
||||
"@esbuild/win32-arm64@0.19.10":
|
||||
version "0.19.10"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.19.10.tgz#7e417d1971dbc7e469b4eceb6a5d1d667b5e3dcc"
|
||||
|
@ -1991,11 +1826,6 @@
|
|||
resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz#f1ae5abf9ca052ae11c1bc806fb4c0f519bacf90"
|
||||
integrity sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==
|
||||
|
||||
"@esbuild/win32-ia32@0.17.19":
|
||||
version "0.17.19"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.17.19.tgz#95ad43c62ad62485e210f6299c7b2571e48d2b03"
|
||||
integrity sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==
|
||||
|
||||
"@esbuild/win32-ia32@0.19.10":
|
||||
version "0.19.10"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.19.10.tgz#2b52dfec6cd061ecb36171c13bae554888b439e5"
|
||||
|
@ -2011,11 +1841,6 @@
|
|||
resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz#241fe62c34d8e8461cd708277813e1d0ba55ce23"
|
||||
integrity sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==
|
||||
|
||||
"@esbuild/win32-x64@0.17.19":
|
||||
version "0.17.19"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.17.19.tgz#8cfaf2ff603e9aabb910e9c0558c26cf32744061"
|
||||
integrity sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==
|
||||
|
||||
"@esbuild/win32-x64@0.19.10":
|
||||
version "0.19.10"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.19.10.tgz#bd123a74f243d2f3a1f046447bb9b363ee25d072"
|
||||
|
@ -2097,11 +1922,6 @@
|
|||
resolved "https://registry.yarnpkg.com/@excalidraw/random-username/-/random-username-1.1.0.tgz#6f388d6a9708cf655b8c9c6aa3fa569ee71ecf0f"
|
||||
integrity sha512-nULYsQxkWHnbmHvcs+efMkJ4/9TtvNyFeLyHdeGxW0zHs6P+jYVqcRff9A6Vq9w9JXeDRnRh2VKvTtS19GW2qA==
|
||||
|
||||
"@fastify/busboy@^2.0.0":
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@fastify/busboy/-/busboy-2.1.1.tgz#b9da6a878a371829a0502c9b6c1c143ef6663f4d"
|
||||
integrity sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==
|
||||
|
||||
"@firebase/analytics-types@0.4.0":
|
||||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/@firebase/analytics-types/-/analytics-types-0.4.0.tgz#d6716f9fa36a6e340bc0ecfe68af325aa6f60508"
|
||||
|
@ -2438,7 +2258,7 @@
|
|||
"@jridgewell/sourcemap-codec" "^1.4.10"
|
||||
"@jridgewell/trace-mapping" "^0.3.24"
|
||||
|
||||
"@jridgewell/resolve-uri@^3.0.3", "@jridgewell/resolve-uri@^3.1.0":
|
||||
"@jridgewell/resolve-uri@^3.1.0":
|
||||
version "3.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6"
|
||||
integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==
|
||||
|
@ -2466,14 +2286,6 @@
|
|||
resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz#3188bcb273a414b0d215fd22a58540b989b9409a"
|
||||
integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==
|
||||
|
||||
"@jridgewell/trace-mapping@0.3.9":
|
||||
version "0.3.9"
|
||||
resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9"
|
||||
integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==
|
||||
dependencies:
|
||||
"@jridgewell/resolve-uri" "^3.0.3"
|
||||
"@jridgewell/sourcemap-codec" "^1.4.10"
|
||||
|
||||
"@jridgewell/trace-mapping@^0.3.20", "@jridgewell/trace-mapping@^0.3.23", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25":
|
||||
version "0.3.25"
|
||||
resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz#15f190e98895f3fc23276ee14bc76b675c2e50f0"
|
||||
|
@ -3273,11 +3085,6 @@
|
|||
resolved "https://registry.yarnpkg.com/@types/aria-query/-/aria-query-5.0.4.tgz#1a31c3d378850d2778dabb6374d036dcba4ba708"
|
||||
integrity sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==
|
||||
|
||||
"@types/async-lock@^1.4.2":
|
||||
version "1.4.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/async-lock/-/async-lock-1.4.2.tgz#c2037ba1d6018de766c2505c3abe3b7b6b244ab4"
|
||||
integrity sha512-HlZ6Dcr205BmNhwkdXqrg2vkFMN2PluI7Lgr8In3B3wE5PiQHhjRqtW/lGdVU9gw+sM0JcIDx2AN+cW8oSWIcw==
|
||||
|
||||
"@types/chai@4.3.0":
|
||||
version "4.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.3.0.tgz#23509ebc1fa32f1b4d50d6a66c4032d5b8eaabdc"
|
||||
|
@ -3412,20 +3219,6 @@
|
|||
resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.34.tgz#10964ba0dee6ac4cd462e2795b6bebd407303433"
|
||||
integrity sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==
|
||||
|
||||
"@types/msgpack-lite@0.1.11":
|
||||
version "0.1.11"
|
||||
resolved "https://registry.yarnpkg.com/@types/msgpack-lite/-/msgpack-lite-0.1.11.tgz#f618e1fc469577f65f36c474ff3309407afef174"
|
||||
integrity sha512-cdCZS/gw+jIN22I4SUZUFf1ZZfVv5JM1//Br/MuZcI373sxiy3eSSoiyLu0oz+BPatTbGGGBO5jrcvd0siCdTQ==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/node-forge@^1.3.0":
|
||||
version "1.3.11"
|
||||
resolved "https://registry.yarnpkg.com/@types/node-forge/-/node-forge-1.3.11.tgz#0972ea538ddb0f4d9c2fa0ec5db5724773a604da"
|
||||
integrity sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/node@*", "@types/node@>=13.7.0", "@types/node@^20":
|
||||
version "20.12.12"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.12.12.tgz#7cbecdf902085cec634fdb362172dfe12b8f2050"
|
||||
|
@ -4015,13 +3808,6 @@ acorn-walk@^8.0.0:
|
|||
resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.3.2.tgz#7703af9415f1b6db9315d6895503862e231d34aa"
|
||||
integrity sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==
|
||||
|
||||
acorn-walk@^8.2.0:
|
||||
version "8.3.4"
|
||||
resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.3.4.tgz#794dd169c3977edf4ba4ea47583587c5866236b7"
|
||||
integrity sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==
|
||||
dependencies:
|
||||
acorn "^8.11.0"
|
||||
|
||||
acorn@^7.4.0:
|
||||
version "7.4.1"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa"
|
||||
|
@ -4032,11 +3818,6 @@ acorn@^8.0.4, acorn@^8.7.1, acorn@^8.8.2:
|
|||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.3.tgz#71e0b14e13a4ec160724b38fb7b0f233b1b81d7a"
|
||||
integrity sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==
|
||||
|
||||
acorn@^8.11.0, acorn@^8.8.0:
|
||||
version "8.14.0"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.14.0.tgz#063e2c70cac5fb4f6467f0b11152e04c682795b0"
|
||||
integrity sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==
|
||||
|
||||
agent-base@6:
|
||||
version "6.0.2"
|
||||
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77"
|
||||
|
@ -4280,13 +4061,6 @@ arraybuffer.prototype.slice@^1.0.3:
|
|||
is-array-buffer "^3.0.4"
|
||||
is-shared-array-buffer "^1.0.2"
|
||||
|
||||
as-table@^1.0.36:
|
||||
version "1.0.55"
|
||||
resolved "https://registry.yarnpkg.com/as-table/-/as-table-1.0.55.tgz#dc984da3937745de902cea1d45843c01bdbbec4f"
|
||||
integrity sha512-xvsWESUJn0JN421Xb9MQw6AsMHRCUknCe0Wjlxvjud80mU4E6hQf1A6NzQKcYNmYw62MfzEtXc+badstZP3JpQ==
|
||||
dependencies:
|
||||
printable-characters "^1.0.42"
|
||||
|
||||
assertion-error@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b"
|
||||
|
@ -4307,11 +4081,6 @@ astral-regex@^2.0.0:
|
|||
resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31"
|
||||
integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==
|
||||
|
||||
async-lock@^1.4.1:
|
||||
version "1.4.1"
|
||||
resolved "https://registry.yarnpkg.com/async-lock/-/async-lock-1.4.1.tgz#56b8718915a9b68b10fce2f2a9a3dddf765ef53f"
|
||||
integrity sha512-Az2ZTpuytrtqENulXwO3GGv1Bztugx6TT37NIo7imr/Qo0gsYiGtSdBa2B6fsXhTpVZDNfu1Qn3pk531e3q+nQ==
|
||||
|
||||
async@^2.6.4:
|
||||
version "2.6.4"
|
||||
resolved "https://registry.yarnpkg.com/async/-/async-2.6.4.tgz#706b7ff6084664cd7eae713f6f965433b5504221"
|
||||
|
@ -4580,11 +4349,6 @@ bl@^4.0.3:
|
|||
inherits "^2.0.4"
|
||||
readable-stream "^3.4.0"
|
||||
|
||||
blake3-wasm@^2.1.5:
|
||||
version "2.1.5"
|
||||
resolved "https://registry.yarnpkg.com/blake3-wasm/-/blake3-wasm-2.1.5.tgz#b22dbb84bc9419ed0159caa76af4b1b132e6ba52"
|
||||
integrity sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==
|
||||
|
||||
boolbase@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e"
|
||||
|
@ -4721,14 +4485,6 @@ canvas-roundrect-polyfill@0.0.1:
|
|||
resolved "https://registry.yarnpkg.com/canvas-roundrect-polyfill/-/canvas-roundrect-polyfill-0.0.1.tgz#70bf107ebe2037f26d839d7f809a26f4a95f5696"
|
||||
integrity sha512-yWq+R3U3jE+coOeEb3a3GgE2j/0MMiDKM/QpLb6h9ihf5fGY9UXtvK9o4vNqjWXoZz7/3EaSVU3IX53TvFFUOw==
|
||||
|
||||
capnp-ts@^0.7.0:
|
||||
version "0.7.0"
|
||||
resolved "https://registry.yarnpkg.com/capnp-ts/-/capnp-ts-0.7.0.tgz#16fd8e76b667d002af8fcf4bf92bf15d1a7b54a9"
|
||||
integrity sha512-XKxXAC3HVPv7r674zP0VC3RTXz+/JKhfyw94ljvF80yynK6VkTnqE3jMuN8b3dUVmmc43TjyxjW4KTsmB3c86g==
|
||||
dependencies:
|
||||
debug "^4.3.1"
|
||||
tslib "^2.2.0"
|
||||
|
||||
chai@4.3.6:
|
||||
version "4.3.6"
|
||||
resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.6.tgz#ffe4ba2d9fa9d6680cc0b370adae709ec9011e9c"
|
||||
|
@ -4821,13 +4577,6 @@ check-error@^2.1.1:
|
|||
optionalDependencies:
|
||||
fsevents "~2.3.2"
|
||||
|
||||
chokidar@^4.0.1:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-4.0.1.tgz#4a6dff66798fb0f72a94f616abbd7e1a19f31d41"
|
||||
integrity sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==
|
||||
dependencies:
|
||||
readdirp "^4.0.1"
|
||||
|
||||
chownr@^1.1.1:
|
||||
version "1.1.4"
|
||||
resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b"
|
||||
|
@ -5002,11 +4751,6 @@ convert-source-map@^2.0.0:
|
|||
resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a"
|
||||
integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==
|
||||
|
||||
cookie@^0.7.1:
|
||||
version "0.7.2"
|
||||
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.7.2.tgz#556369c472a2ba910f2979891b526b3436237ed7"
|
||||
integrity sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==
|
||||
|
||||
core-js-compat@^3.31.0, core-js-compat@^3.36.1:
|
||||
version "3.37.1"
|
||||
resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.37.1.tgz#c844310c7852f4bdf49b8d339730b97e17ff09ee"
|
||||
|
@ -5457,11 +5201,6 @@ damerau-levenshtein@^1.0.8:
|
|||
resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz#b43d286ccbd36bc5b2f7ed41caf2d0aba1f8a6e7"
|
||||
integrity sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==
|
||||
|
||||
data-uri-to-buffer@^2.0.0:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-2.0.2.tgz#d296973d5a4897a5dbe31716d118211921f04770"
|
||||
integrity sha512-ND9qDTLc6diwj+Xe5cdAgVTbLVdXbtxTJRXRhli8Mowuaan+0EJOtdqJ0QCHNSSPyoXGx9HX2/VMnKeC34AChA==
|
||||
|
||||
data-urls@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-4.0.0.tgz#333a454eca6f9a5b7b0f1013ff89074c3f522dd4"
|
||||
|
@ -5498,11 +5237,6 @@ data-view-byte-offset@^1.0.0:
|
|||
es-errors "^1.3.0"
|
||||
is-data-view "^1.0.1"
|
||||
|
||||
date-fns@^4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-4.1.0.tgz#64b3d83fff5aa80438f5b1a633c2e83b8a1c2d14"
|
||||
integrity sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==
|
||||
|
||||
dayjs@^1.11.7:
|
||||
version "1.11.11"
|
||||
resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.11.tgz#dfe0e9d54c5f8b68ccf8ca5f72ac603e7e5ed59e"
|
||||
|
@ -5593,11 +5327,6 @@ define-properties@^1.2.0, define-properties@^1.2.1:
|
|||
has-property-descriptors "^1.0.0"
|
||||
object-keys "^1.1.1"
|
||||
|
||||
defu@^6.1.4:
|
||||
version "6.1.4"
|
||||
resolved "https://registry.yarnpkg.com/defu/-/defu-6.1.4.tgz#4e0c9cf9ff68fe5f3d7f2765cc1a012dfdcb0479"
|
||||
integrity sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==
|
||||
|
||||
delaunator@5:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/delaunator/-/delaunator-5.0.1.tgz#39032b08053923e924d6094fe2cde1a99cc51278"
|
||||
|
@ -5995,34 +5724,6 @@ esbuild-sass-plugin@2.16.0:
|
|||
resolve "^1.22.6"
|
||||
sass "^1.7.3"
|
||||
|
||||
esbuild@0.17.19:
|
||||
version "0.17.19"
|
||||
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.17.19.tgz#087a727e98299f0462a3d0bcdd9cd7ff100bd955"
|
||||
integrity sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==
|
||||
optionalDependencies:
|
||||
"@esbuild/android-arm" "0.17.19"
|
||||
"@esbuild/android-arm64" "0.17.19"
|
||||
"@esbuild/android-x64" "0.17.19"
|
||||
"@esbuild/darwin-arm64" "0.17.19"
|
||||
"@esbuild/darwin-x64" "0.17.19"
|
||||
"@esbuild/freebsd-arm64" "0.17.19"
|
||||
"@esbuild/freebsd-x64" "0.17.19"
|
||||
"@esbuild/linux-arm" "0.17.19"
|
||||
"@esbuild/linux-arm64" "0.17.19"
|
||||
"@esbuild/linux-ia32" "0.17.19"
|
||||
"@esbuild/linux-loong64" "0.17.19"
|
||||
"@esbuild/linux-mips64el" "0.17.19"
|
||||
"@esbuild/linux-ppc64" "0.17.19"
|
||||
"@esbuild/linux-riscv64" "0.17.19"
|
||||
"@esbuild/linux-s390x" "0.17.19"
|
||||
"@esbuild/linux-x64" "0.17.19"
|
||||
"@esbuild/netbsd-x64" "0.17.19"
|
||||
"@esbuild/openbsd-x64" "0.17.19"
|
||||
"@esbuild/sunos-x64" "0.17.19"
|
||||
"@esbuild/win32-arm64" "0.17.19"
|
||||
"@esbuild/win32-ia32" "0.17.19"
|
||||
"@esbuild/win32-x64" "0.17.19"
|
||||
|
||||
esbuild@0.19.10:
|
||||
version "0.19.10"
|
||||
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.19.10.tgz#55e83e4a6b702e3498b9f872d84bfb4ebcb6d16e"
|
||||
|
@ -6420,11 +6121,6 @@ estraverse@^5.1.0, estraverse@^5.2.0, estraverse@^5.3.0:
|
|||
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123"
|
||||
integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==
|
||||
|
||||
estree-walker@^0.6.1:
|
||||
version "0.6.1"
|
||||
resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.6.1.tgz#53049143f40c6eb918b23671d1fe3219f3a1b362"
|
||||
integrity sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==
|
||||
|
||||
estree-walker@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-1.0.1.tgz#31bc5d612c96b704106b477e6dd5d8aa138cb700"
|
||||
|
@ -6447,11 +6143,6 @@ esutils@^2.0.2:
|
|||
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64"
|
||||
integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==
|
||||
|
||||
event-lite@^0.1.1:
|
||||
version "0.1.3"
|
||||
resolved "https://registry.yarnpkg.com/event-lite/-/event-lite-0.1.3.tgz#3dfe01144e808ac46448f0c19b4ab68e403a901d"
|
||||
integrity sha512-8qz9nOz5VeD2z96elrEKD2U433+L3DWdUdDkOINLGOJvx1GsMBbMn0aCeu28y8/e85A6mCigBiFlYMnTBEGlSw==
|
||||
|
||||
eventemitter3@^4.0.0:
|
||||
version "4.0.7"
|
||||
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f"
|
||||
|
@ -6492,11 +6183,6 @@ execa@^8.0.1:
|
|||
signal-exit "^4.1.0"
|
||||
strip-final-newline "^3.0.0"
|
||||
|
||||
exit-hook@^2.2.1:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-2.2.1.tgz#007b2d92c6428eda2b76e7016a34351586934593"
|
||||
integrity sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw==
|
||||
|
||||
expect@^29.0.0:
|
||||
version "29.7.0"
|
||||
resolved "https://registry.yarnpkg.com/expect/-/expect-29.7.0.tgz#578874590dcb3214514084c08115d8aee61e11bc"
|
||||
|
@ -6840,14 +6526,6 @@ get-own-enumerable-property-symbols@^3.0.0:
|
|||
resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664"
|
||||
integrity sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==
|
||||
|
||||
get-source@^2.0.12:
|
||||
version "2.0.12"
|
||||
resolved "https://registry.yarnpkg.com/get-source/-/get-source-2.0.12.tgz#0b47d57ea1e53ce0d3a69f4f3d277eb8047da944"
|
||||
integrity sha512-X5+4+iD+HoSeEED+uwrQ07BOQr0kEDFMVqqpBuI+RaZBpBpHCuXxo70bjar6f0b0u/DQJsJ7ssurpP0V60Az+w==
|
||||
dependencies:
|
||||
data-uri-to-buffer "^2.0.0"
|
||||
source-map "^0.6.1"
|
||||
|
||||
get-stream@^5.1.0:
|
||||
version "5.2.0"
|
||||
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3"
|
||||
|
@ -7170,7 +6848,7 @@ idb@^7.0.1:
|
|||
resolved "https://registry.yarnpkg.com/idb/-/idb-7.1.1.tgz#d910ded866d32c7ced9befc5bfdf36f572ced72b"
|
||||
integrity sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==
|
||||
|
||||
ieee754@^1.1.13, ieee754@^1.1.8:
|
||||
ieee754@^1.1.13:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352"
|
||||
integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==
|
||||
|
@ -7246,11 +6924,6 @@ inherits@2, inherits@^2.0.3, inherits@^2.0.4:
|
|||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
|
||||
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
|
||||
|
||||
int64-buffer@^0.1.9:
|
||||
version "0.1.10"
|
||||
resolved "https://registry.yarnpkg.com/int64-buffer/-/int64-buffer-0.1.10.tgz#277b228a87d95ad777d07c13832022406a473423"
|
||||
integrity sha512-v7cSY1J8ydZ0GyjUHqF+1bshJ6cnEVLo9EnjB8p+4HDRPZc9N5jjmvUV7NvEsqQOKyH0pmIBFWXVQbiS0+OBbA==
|
||||
|
||||
internal-slot@^1.0.7:
|
||||
version "1.0.7"
|
||||
resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.7.tgz#c06dcca3ed874249881007b0a5523b172a190802"
|
||||
|
@ -7513,11 +7186,6 @@ is-weakset@^2.0.3:
|
|||
call-bind "^1.0.7"
|
||||
get-intrinsic "^1.2.4"
|
||||
|
||||
isarray@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
|
||||
integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==
|
||||
|
||||
isarray@^2.0.5:
|
||||
version "2.0.5"
|
||||
resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723"
|
||||
|
@ -7580,11 +7248,6 @@ iterator.prototype@^1.1.2:
|
|||
reflect.getprototypeof "^1.0.4"
|
||||
set-function-name "^2.0.1"
|
||||
|
||||
itty-time@^1.0.6:
|
||||
version "1.0.6"
|
||||
resolved "https://registry.yarnpkg.com/itty-time/-/itty-time-1.0.6.tgz#a6eeda619f19d2f4c480ceddd013b93acb05714d"
|
||||
integrity sha512-+P8IZaLLBtFv8hCkIjcymZOp4UJ+xW6bSlQsXGqrkmJh7vSiMFSlNne0mCYagEE0N7HDNR5jJBRxwN0oYv61Rw==
|
||||
|
||||
jackspeak@^3.1.2:
|
||||
version "3.4.3"
|
||||
resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-3.4.3.tgz#8833a9d89ab4acde6188942bd1c53b6390ed5a8a"
|
||||
|
@ -7986,7 +7649,7 @@ lodash.camelcase@^4.3.0:
|
|||
resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6"
|
||||
integrity sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==
|
||||
|
||||
lodash.debounce@4.0.8, lodash.debounce@^4.0.8:
|
||||
lodash.debounce@^4.0.8:
|
||||
version "4.0.8"
|
||||
resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af"
|
||||
integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==
|
||||
|
@ -8088,7 +7751,7 @@ lz-string@^1.5.0:
|
|||
resolved "https://registry.yarnpkg.com/lz-string/-/lz-string-1.5.0.tgz#c1ab50f77887b712621201ba9fd4e3a6ed099941"
|
||||
integrity sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==
|
||||
|
||||
magic-string@^0.25.0, magic-string@^0.25.3, magic-string@^0.25.7:
|
||||
magic-string@^0.25.0, magic-string@^0.25.7:
|
||||
version "0.25.9"
|
||||
resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.9.tgz#de7f9faf91ef8a1c91d02c2e5314c8277dbcdd1c"
|
||||
integrity sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==
|
||||
|
@ -8412,11 +8075,6 @@ mime@^1.6.0:
|
|||
resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"
|
||||
integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==
|
||||
|
||||
mime@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/mime/-/mime-3.0.0.tgz#b374550dca3a0c18443b0c950a6a58f1931cf7a7"
|
||||
integrity sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==
|
||||
|
||||
mimic-fn@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b"
|
||||
|
@ -8439,24 +8097,6 @@ mini-css-extract-plugin@2.6.1:
|
|||
dependencies:
|
||||
schema-utils "^4.0.0"
|
||||
|
||||
miniflare@3.20241106.1:
|
||||
version "3.20241106.1"
|
||||
resolved "https://registry.yarnpkg.com/miniflare/-/miniflare-3.20241106.1.tgz#2dea3b9bc789b35dde6694948385f3009057f9cd"
|
||||
integrity sha512-dM3RBlJE8rUFxnqlPCaFCq0E7qQqEQvKbYX7W/APGCK+rLcyLmEBzC4GQR/niXdNM/oV6gdg9AA50ghnn2ALuw==
|
||||
dependencies:
|
||||
"@cspotcode/source-map-support" "0.8.1"
|
||||
acorn "^8.8.0"
|
||||
acorn-walk "^8.2.0"
|
||||
capnp-ts "^0.7.0"
|
||||
exit-hook "^2.2.1"
|
||||
glob-to-regexp "^0.4.1"
|
||||
stoppable "^1.1.0"
|
||||
undici "^5.28.4"
|
||||
workerd "1.20241106.1"
|
||||
ws "^8.18.0"
|
||||
youch "^3.2.2"
|
||||
zod "^3.22.3"
|
||||
|
||||
minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2:
|
||||
version "3.1.2"
|
||||
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
|
||||
|
@ -8537,16 +8177,6 @@ ms@^2.1.1:
|
|||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
|
||||
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
|
||||
|
||||
msgpack-lite@0.1.26:
|
||||
version "0.1.26"
|
||||
resolved "https://registry.yarnpkg.com/msgpack-lite/-/msgpack-lite-0.1.26.tgz#dd3c50b26f059f25e7edee3644418358e2a9ad89"
|
||||
integrity sha512-SZ2IxeqZ1oRFGo0xFGbvBJWMp3yLIY9rlIJyxy8CGrwZn1f0ZK4r6jV/AM1r0FZMDUkWkglOk/eeKIL9g77Nxw==
|
||||
dependencies:
|
||||
event-lite "^0.1.1"
|
||||
ieee754 "^1.1.8"
|
||||
int64-buffer "^0.1.9"
|
||||
isarray "^1.0.0"
|
||||
|
||||
multimath@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/multimath/-/multimath-2.0.0.tgz#0d37acf67c328f30e3d8c6b0d3209e6082710302"
|
||||
|
@ -8555,11 +8185,6 @@ multimath@^2.0.0:
|
|||
glur "^1.1.2"
|
||||
object-assign "^4.1.1"
|
||||
|
||||
mustache@^4.2.0:
|
||||
version "4.2.0"
|
||||
resolved "https://registry.yarnpkg.com/mustache/-/mustache-4.2.0.tgz#e5892324d60a12ec9c2a73359edca52972bf6f64"
|
||||
integrity sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==
|
||||
|
||||
nanoid@3.3.3:
|
||||
version "3.3.3"
|
||||
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25"
|
||||
|
@ -8570,7 +8195,7 @@ nanoid@4.0.2:
|
|||
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-4.0.2.tgz#140b3c5003959adbebf521c170f282c5e7f9fb9e"
|
||||
integrity sha512-7ZtY5KTCNheRGfEFxnedV5zFiORN1+Y1N6zvPTnHQd8ENUvfaDBeuJDZb2bN/oXwXxu3qkTXDzy57W5vAmDTBw==
|
||||
|
||||
nanoid@^3.3.2, nanoid@^3.3.3, nanoid@^3.3.6, nanoid@^3.3.7:
|
||||
nanoid@^3.3.2, nanoid@^3.3.6, nanoid@^3.3.7:
|
||||
version "3.3.7"
|
||||
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8"
|
||||
integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==
|
||||
|
@ -8640,11 +8265,6 @@ node-fetch@2.6.7:
|
|||
dependencies:
|
||||
whatwg-url "^5.0.0"
|
||||
|
||||
node-forge@^1:
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3"
|
||||
integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==
|
||||
|
||||
node-html-parser@^5.3.3:
|
||||
version "5.4.2"
|
||||
resolved "https://registry.yarnpkg.com/node-html-parser/-/node-html-parser-5.4.2.tgz#93e004038c17af80226c942336990a0eaed8136a"
|
||||
|
@ -8775,11 +8395,6 @@ object.values@^1.1.6, object.values@^1.1.7:
|
|||
define-properties "^1.2.1"
|
||||
es-object-atoms "^1.0.0"
|
||||
|
||||
ohash@^1.1.4:
|
||||
version "1.1.4"
|
||||
resolved "https://registry.yarnpkg.com/ohash/-/ohash-1.1.4.tgz#ae8d83014ab81157d2c285abf7792e2995fadd72"
|
||||
integrity sha512-FlDryZAahJmEF3VR3w1KogSEdWX3WhA5GPakFx4J81kEAiHyLMpdLLElS8n8dfNadMgAne/MywcvmogzscVt4g==
|
||||
|
||||
once@^1.3.0, once@^1.3.1, once@^1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
|
||||
|
@ -8937,11 +8552,6 @@ path-scurry@^1.11.1:
|
|||
lru-cache "^10.2.0"
|
||||
minipass "^5.0.0 || ^6.0.2 || ^7.0.0"
|
||||
|
||||
path-to-regexp@^6.3.0:
|
||||
version "6.3.0"
|
||||
resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-6.3.0.tgz#2b6a26a337737a8e1416f9272ed0766b1c0389f4"
|
||||
integrity sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==
|
||||
|
||||
path-type@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b"
|
||||
|
@ -9185,11 +8795,6 @@ pretty-format@^29.0.0, pretty-format@^29.7.0:
|
|||
ansi-styles "^5.0.0"
|
||||
react-is "^18.0.0"
|
||||
|
||||
printable-characters@^1.0.42:
|
||||
version "1.0.42"
|
||||
resolved "https://registry.yarnpkg.com/printable-characters/-/printable-characters-1.0.42.tgz#3f18e977a9bd8eb37fcc4ff5659d7be90868b3d8"
|
||||
integrity sha512-dKp+C4iXWK4vVYZmYSd0KBH5F/h1HoZRsbJ82AVKRO3PEo8L4lBS/vLwhVtpwwuYcoIsVY+1JYKR268yn480uQ==
|
||||
|
||||
progress@2.0.3, progress@^2.0.0:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8"
|
||||
|
@ -9405,11 +9010,6 @@ readable-stream@^3.1.1, readable-stream@^3.4.0:
|
|||
string_decoder "^1.1.1"
|
||||
util-deprecate "^1.0.1"
|
||||
|
||||
readdirp@^4.0.1:
|
||||
version "4.0.2"
|
||||
resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-4.0.2.tgz#388fccb8b75665da3abffe2d8f8ed59fe74c230a"
|
||||
integrity sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==
|
||||
|
||||
readdirp@~3.6.0:
|
||||
version "3.6.0"
|
||||
resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7"
|
||||
|
@ -9434,11 +9034,6 @@ rechoir@^0.7.0:
|
|||
dependencies:
|
||||
resolve "^1.9.0"
|
||||
|
||||
reconnecting-websocket@4.4.0:
|
||||
version "4.4.0"
|
||||
resolved "https://registry.yarnpkg.com/reconnecting-websocket/-/reconnecting-websocket-4.4.0.tgz#3b0e5b96ef119e78a03135865b8bb0af1b948783"
|
||||
integrity sha512-D2E33ceRPga0NvTDhJmphEgJ7FUYF0v4lr1ki0csq06OdlxKfugGzN0dSkxM/NfqCxYELK4KcaTOUOjTV6Dcng==
|
||||
|
||||
redent@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/redent/-/redent-3.0.0.tgz#e557b7998316bb53c9f1f56fa626352c6963059f"
|
||||
|
@ -9560,12 +9155,7 @@ resolve-from@^5.0.0:
|
|||
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69"
|
||||
integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==
|
||||
|
||||
resolve.exports@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-2.0.2.tgz#f8c934b8e6a13f539e38b7098e2e36134f01e800"
|
||||
integrity sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==
|
||||
|
||||
resolve@^1.14.2, resolve@^1.19.0, resolve@^1.22.1, resolve@^1.22.4, resolve@^1.22.6, resolve@^1.22.8, resolve@^1.9.0:
|
||||
resolve@^1.14.2, resolve@^1.19.0, resolve@^1.22.1, resolve@^1.22.4, resolve@^1.22.6, resolve@^1.9.0:
|
||||
version "1.22.8"
|
||||
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d"
|
||||
integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==
|
||||
|
@ -9620,29 +9210,6 @@ robust-predicates@^3.0.2:
|
|||
resolved "https://registry.yarnpkg.com/robust-predicates/-/robust-predicates-3.0.2.tgz#d5b28528c4824d20fc48df1928d41d9efa1ad771"
|
||||
integrity sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==
|
||||
|
||||
rollup-plugin-inject@^3.0.0:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/rollup-plugin-inject/-/rollup-plugin-inject-3.0.2.tgz#e4233855bfba6c0c12a312fd6649dff9a13ee9f4"
|
||||
integrity sha512-ptg9PQwzs3orn4jkgXJ74bfs5vYz1NCZlSQMBUA0wKcGp5i5pA1AO3fOUEte8enhGUC+iapTCzEWw2jEFFUO/w==
|
||||
dependencies:
|
||||
estree-walker "^0.6.1"
|
||||
magic-string "^0.25.3"
|
||||
rollup-pluginutils "^2.8.1"
|
||||
|
||||
rollup-plugin-node-polyfills@^0.2.1:
|
||||
version "0.2.1"
|
||||
resolved "https://registry.yarnpkg.com/rollup-plugin-node-polyfills/-/rollup-plugin-node-polyfills-0.2.1.tgz#53092a2744837164d5b8a28812ba5f3ff61109fd"
|
||||
integrity sha512-4kCrKPTJ6sK4/gLL/U5QzVT8cxJcofO0OU74tnB19F40cmuAKSzH5/siithxlofFEjwvw1YAhPmbvGNA6jEroA==
|
||||
dependencies:
|
||||
rollup-plugin-inject "^3.0.0"
|
||||
|
||||
rollup-pluginutils@^2.8.1:
|
||||
version "2.8.2"
|
||||
resolved "https://registry.yarnpkg.com/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz#72f2af0748b592364dbd3389e600e5a9444a351e"
|
||||
integrity sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==
|
||||
dependencies:
|
||||
estree-walker "^0.6.1"
|
||||
|
||||
rollup@^2.43.1:
|
||||
version "2.79.1"
|
||||
resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.79.1.tgz#bedee8faef7c9f93a2647ac0108748f497f081c7"
|
||||
|
@ -9828,14 +9395,6 @@ secure-compare@3.0.1:
|
|||
resolved "https://registry.yarnpkg.com/secure-compare/-/secure-compare-3.0.1.tgz#f1a0329b308b221fae37b9974f3d578d0ca999e3"
|
||||
integrity sha512-AckIIV90rPDcBcglUwXPF3kg0P0qmPsPXAj6BBEENQE1p5yA1xfmDJzfi1Tappj37Pv2mVbKpL3Z1T+Nn7k1Qw==
|
||||
|
||||
selfsigned@^2.0.1:
|
||||
version "2.4.1"
|
||||
resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-2.4.1.tgz#560d90565442a3ed35b674034cec4e95dceb4ae0"
|
||||
integrity sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==
|
||||
dependencies:
|
||||
"@types/node-forge" "^1.3.0"
|
||||
node-forge "^1"
|
||||
|
||||
semver@7.5.4:
|
||||
version "7.5.4"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e"
|
||||
|
@ -10088,24 +9647,11 @@ stackback@0.0.2:
|
|||
resolved "https://registry.yarnpkg.com/stackback/-/stackback-0.0.2.tgz#1ac8a0d9483848d1695e418b6d031a3c3ce68e3b"
|
||||
integrity sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==
|
||||
|
||||
stacktracey@^2.1.8:
|
||||
version "2.1.8"
|
||||
resolved "https://registry.yarnpkg.com/stacktracey/-/stacktracey-2.1.8.tgz#bf9916020738ce3700d1323b32bd2c91ea71199d"
|
||||
integrity sha512-Kpij9riA+UNg7TnphqjH7/CzctQ/owJGNbFkfEeve4Z4uxT5+JapVLFXcsurIfN34gnTWZNJ/f7NMG0E8JDzTw==
|
||||
dependencies:
|
||||
as-table "^1.0.36"
|
||||
get-source "^2.0.12"
|
||||
|
||||
std-env@^3.7.0:
|
||||
version "3.7.0"
|
||||
resolved "https://registry.yarnpkg.com/std-env/-/std-env-3.7.0.tgz#c9f7386ced6ecf13360b6c6c55b8aaa4ef7481d2"
|
||||
integrity sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==
|
||||
|
||||
stoppable@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/stoppable/-/stoppable-1.1.0.tgz#32da568e83ea488b08e4d7ea2c3bcc9d75015d5b"
|
||||
integrity sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==
|
||||
|
||||
streamsearch@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-1.1.0.tgz#404dd1e2247ca94af554e841a8ef0eaa238da764"
|
||||
|
@ -10543,11 +10089,6 @@ tslib@^2.0.0, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.4.0:
|
|||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae"
|
||||
integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==
|
||||
|
||||
tslib@^2.2.0:
|
||||
version "2.8.1"
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f"
|
||||
integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==
|
||||
|
||||
tsutils@^3.21.0:
|
||||
version "3.21.0"
|
||||
resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623"
|
||||
|
@ -10657,11 +10198,6 @@ typeson@^6.0.0, typeson@^6.1.0:
|
|||
resolved "https://registry.yarnpkg.com/typeson/-/typeson-6.1.0.tgz#5b2a53705a5f58ff4d6f82f965917cabd0d7448b"
|
||||
integrity sha512-6FTtyGr8ldU0pfbvW/eOZrEtEkczHRUtduBnA90Jh9kMPCiFNnXIon3vF41N0S4tV1HHQt4Hk1j4srpESziCaA==
|
||||
|
||||
ufo@^1.5.4:
|
||||
version "1.5.4"
|
||||
resolved "https://registry.yarnpkg.com/ufo/-/ufo-1.5.4.tgz#16d6949674ca0c9e0fbbae1fa20a71d7b1ded754"
|
||||
integrity sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==
|
||||
|
||||
unbox-primitive@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e"
|
||||
|
@ -10685,23 +10221,6 @@ undici-types@~5.26.4:
|
|||
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617"
|
||||
integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==
|
||||
|
||||
undici@^5.28.4:
|
||||
version "5.28.4"
|
||||
resolved "https://registry.yarnpkg.com/undici/-/undici-5.28.4.tgz#6b280408edb6a1a604a9b20340f45b422e373068"
|
||||
integrity sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==
|
||||
dependencies:
|
||||
"@fastify/busboy" "^2.0.0"
|
||||
|
||||
"unenv@npm:unenv-nightly@2.0.0-20241111-080453-894aa31":
|
||||
version "2.0.0-20241111-080453-894aa31"
|
||||
resolved "https://registry.yarnpkg.com/unenv-nightly/-/unenv-nightly-2.0.0-20241111-080453-894aa31.tgz#a781d32583a6335a7c76bda694669aed373a61d8"
|
||||
integrity sha512-0W39QQOQ9VE8kVVUpGwEG+pZcsCXk5wqNG6rDPE6Gr+fiA69LR0qERM61hW5KCOkC1/ArCFrfCGjwHyyv/bI0Q==
|
||||
dependencies:
|
||||
defu "^6.1.4"
|
||||
ohash "^1.1.4"
|
||||
pathe "^1.1.2"
|
||||
ufo "^1.5.4"
|
||||
|
||||
unicode-canonical-property-names-ecmascript@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz#301acdc525631670d39f6146e0e77ff6bbdebddc"
|
||||
|
@ -11490,44 +11009,6 @@ workbox-window@7.1.0, workbox-window@^7.0.0:
|
|||
"@types/trusted-types" "^2.0.2"
|
||||
workbox-core "7.1.0"
|
||||
|
||||
workerd@1.20241106.1:
|
||||
version "1.20241106.1"
|
||||
resolved "https://registry.yarnpkg.com/workerd/-/workerd-1.20241106.1.tgz#08f3d63f70cd750a1f2c0652cd76c4844fe06409"
|
||||
integrity sha512-1GdKl0kDw8rrirr/ThcK66Kbl4/jd4h8uHx5g7YHBrnenY5SX1UPuop2cnCzYUxlg55kPjzIqqYslz1muRFgFw==
|
||||
optionalDependencies:
|
||||
"@cloudflare/workerd-darwin-64" "1.20241106.1"
|
||||
"@cloudflare/workerd-darwin-arm64" "1.20241106.1"
|
||||
"@cloudflare/workerd-linux-64" "1.20241106.1"
|
||||
"@cloudflare/workerd-linux-arm64" "1.20241106.1"
|
||||
"@cloudflare/workerd-windows-64" "1.20241106.1"
|
||||
|
||||
wrangler@^3.60.3:
|
||||
version "3.89.0"
|
||||
resolved "https://registry.yarnpkg.com/wrangler/-/wrangler-3.89.0.tgz#d4a66d98545902b1c1e6fa8fa02efd10657f010d"
|
||||
integrity sha512-ix3Rir/cu9Cn6FklvPDIW1QwOMcRU8iPj3IrkBWGdB66K9z1uqyqoTP64UZZyXrBItfrU7SbQT4L5wJ5y10TPA==
|
||||
dependencies:
|
||||
"@cloudflare/kv-asset-handler" "0.3.4"
|
||||
"@cloudflare/workers-shared" "0.7.1"
|
||||
"@esbuild-plugins/node-globals-polyfill" "^0.2.3"
|
||||
"@esbuild-plugins/node-modules-polyfill" "^0.2.2"
|
||||
blake3-wasm "^2.1.5"
|
||||
chokidar "^4.0.1"
|
||||
date-fns "^4.1.0"
|
||||
esbuild "0.17.19"
|
||||
itty-time "^1.0.6"
|
||||
miniflare "3.20241106.1"
|
||||
nanoid "^3.3.3"
|
||||
path-to-regexp "^6.3.0"
|
||||
resolve "^1.22.8"
|
||||
resolve.exports "^2.0.2"
|
||||
selfsigned "^2.0.1"
|
||||
source-map "^0.6.1"
|
||||
unenv "npm:unenv-nightly@2.0.0-20241111-080453-894aa31"
|
||||
workerd "1.20241106.1"
|
||||
xxhash-wasm "^1.0.1"
|
||||
optionalDependencies:
|
||||
fsevents "~2.3.2"
|
||||
|
||||
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0":
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
|
||||
|
@ -11584,11 +11065,6 @@ ws@^8.13.0:
|
|||
resolved "https://registry.yarnpkg.com/ws/-/ws-8.17.0.tgz#d145d18eca2ed25aaf791a183903f7be5e295fea"
|
||||
integrity sha512-uJq6108EgZMAl20KagGkzCKfMEjxmKvZHG7Tlq0Z6nOky7YF7aq4mOx6xK8TJ/i1LeK4Qus7INktacctDgY8Ow==
|
||||
|
||||
ws@^8.18.0:
|
||||
version "8.18.0"
|
||||
resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.0.tgz#0d7505a6eafe2b0e712d232b42279f53bc289bbc"
|
||||
integrity sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==
|
||||
|
||||
ws@~8.11.0:
|
||||
version "8.11.0"
|
||||
resolved "https://registry.yarnpkg.com/ws/-/ws-8.11.0.tgz#6a0d36b8edfd9f96d8b25683db2f8d7de6e8e143"
|
||||
|
@ -11614,11 +11090,6 @@ xmlhttprequest@1.8.0:
|
|||
resolved "https://registry.yarnpkg.com/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz#67fe075c5c24fef39f9d65f5f7b7fe75171968fc"
|
||||
integrity sha512-58Im/U0mlVBLM38NdZjHyhuMtCqa61469k2YP/AaPbvCoV9aQGUpbJBj1QRm2ytRiVQBD/fsw7L2bJGDVQswBA==
|
||||
|
||||
xxhash-wasm@^1.0.1:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/xxhash-wasm/-/xxhash-wasm-1.1.0.tgz#ffe7f0b98220a4afac171e3fb9b6d1f8771f015e"
|
||||
integrity sha512-147y/6YNh+tlp6nd/2pWq38i9h6mz/EuQ6njIrmW8D1BS5nCqs0P6DG+m6zTGnNz5I+uhZ0SHxBs9BsPrwcKDA==
|
||||
|
||||
y18n@^5.0.5:
|
||||
version "5.0.8"
|
||||
resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55"
|
||||
|
@ -11665,20 +11136,6 @@ yauzl@^2.10.0:
|
|||
buffer-crc32 "~0.2.3"
|
||||
fd-slicer "~1.1.0"
|
||||
|
||||
youch@^3.2.2:
|
||||
version "3.3.4"
|
||||
resolved "https://registry.yarnpkg.com/youch/-/youch-3.3.4.tgz#f13ee0966846c6200e7fb9ece89306d95df5e489"
|
||||
integrity sha512-UeVBXie8cA35DS6+nBkls68xaBBXCye0CNznrhszZjTbRVnJKQuNsyLKBTTL4ln1o1rh2PKtv35twV7irj5SEg==
|
||||
dependencies:
|
||||
cookie "^0.7.1"
|
||||
mustache "^4.2.0"
|
||||
stacktracey "^2.1.8"
|
||||
|
||||
zod@^3.22.3:
|
||||
version "3.23.8"
|
||||
resolved "https://registry.yarnpkg.com/zod/-/zod-3.23.8.tgz#e37b957b5d52079769fb8097099b592f0ef4067d"
|
||||
integrity sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==
|
||||
|
||||
zustand@^4.3.2:
|
||||
version "4.5.2"
|
||||
resolved "https://registry.yarnpkg.com/zustand/-/zustand-4.5.2.tgz#fddbe7cac1e71d45413b3682cdb47b48034c3848"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue