From 1a545b865d95baa8813f1f97a42597675011211d Mon Sep 17 00:00:00 2001 From: aLIEzsss4 Date: Tue, 29 Aug 2023 01:36:23 +0800 Subject: [PATCH] wip --- packages/client/package.json | 2 + packages/client/src/App.tsx | 2 + .../client/src/LoadingScreen/BootScreen.tsx | 42 ++++++++ .../client/src/LoadingScreen/LoadingBar.tsx | 24 +++++ .../src/LoadingScreen/LoadingScreen.tsx | 54 ++++++++++ packages/client/src/LoadingScreen/index.ts | 1 + packages/client/src/PhaserLayer.tsx | 20 ++++ packages/client/src/artTypes/world.ts | 9 ++ packages/client/src/hooks/useNetworkLayer.tsx | 17 ++++ packages/client/src/hooks/usePhaserLayer.tsx | 93 +++++++++++++++++ packages/client/src/hooks/usePromiseValue.ts | 24 +++++ .../src/layers/network/createNetworkLayer.ts | 15 +++ .../src/layers/phaser/configurePhaser.ts | 99 +++++++++++++++++++ .../client/src/layers/phaser/constants.ts | 22 +++++ .../src/layers/phaser/createPhaserLayer.ts | 40 ++++++++ .../src/layers/phaser/systems/createCamera.ts | 13 +++ .../layers/phaser/systems/createMapSystem.ts | 32 ++++++ .../client/src/layers/phaser/systems/index.ts | 1 + .../layers/phaser/systems/registerSystems.ts | 8 ++ packages/client/src/store.ts | 35 +++++++ pnpm-lock.yaml | 27 ++++- 21 files changed, 577 insertions(+), 3 deletions(-) create mode 100644 packages/client/src/LoadingScreen/BootScreen.tsx create mode 100644 packages/client/src/LoadingScreen/LoadingBar.tsx create mode 100644 packages/client/src/LoadingScreen/LoadingScreen.tsx create mode 100644 packages/client/src/LoadingScreen/index.ts create mode 100644 packages/client/src/PhaserLayer.tsx create mode 100644 packages/client/src/artTypes/world.ts create mode 100644 packages/client/src/hooks/useNetworkLayer.tsx create mode 100644 packages/client/src/hooks/usePhaserLayer.tsx create mode 100644 packages/client/src/hooks/usePromiseValue.ts create mode 100644 packages/client/src/layers/network/createNetworkLayer.ts create mode 100644 packages/client/src/layers/phaser/configurePhaser.ts create mode 100644 packages/client/src/layers/phaser/constants.ts create mode 100644 packages/client/src/layers/phaser/createPhaserLayer.ts create mode 100644 packages/client/src/layers/phaser/systems/createCamera.ts create mode 100644 packages/client/src/layers/phaser/systems/createMapSystem.ts create mode 100644 packages/client/src/layers/phaser/systems/index.ts create mode 100644 packages/client/src/layers/phaser/systems/registerSystems.ts create mode 100644 packages/client/src/store.ts diff --git a/packages/client/package.json b/packages/client/package.json index ed07f2a..b9c3560 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -27,11 +27,13 @@ "contracts": "workspace:*", "dayjs": "^1.11.9", "ethers": "^5.7.2", + "lodash": "^4.17.21", "postcss": "^8.4.28", "react": "^18.2.0", "react-dom": "^18.2.0", "rxjs": "7.5.5", "tailwindcss": "^3.3.3", + "use-resize-observer": "^9.1.0", "viem": "1.6.0" }, "devDependencies": { diff --git a/packages/client/src/App.tsx b/packages/client/src/App.tsx index dc95c02..b98a6dc 100644 --- a/packages/client/src/App.tsx +++ b/packages/client/src/App.tsx @@ -1,5 +1,6 @@ import { useComponentValue } from "@latticexyz/react"; import { useMUD } from "./MUDContext"; +import { PhaserLayer } from "./PhaserLayer"; import AutoChess from "./ui/ChessMain"; import JoinGame from "./ui/JoinGame"; import "./index.css"; @@ -19,6 +20,7 @@ export const App = () => { return ( <> + {isPlay ? : }
diff --git a/packages/client/src/LoadingScreen/BootScreen.tsx b/packages/client/src/LoadingScreen/BootScreen.tsx new file mode 100644 index 0000000..0e5b7a0 --- /dev/null +++ b/packages/client/src/LoadingScreen/BootScreen.tsx @@ -0,0 +1,42 @@ +import React from "react"; +import styled from "styled-components"; + +type Props = { + children: React.ReactNode; +}; + +export const BootScreen = ({ children }: Props) => { + return ( + +
+ <>{children || <> } +
+
+ ); +}; + +const Container = styled.div` + width: 100%; + height: 100%; + position: absolute; + background-color: rgb(0 0 0 / 100%); + display: grid; + align-content: center; + align-items: center; + justify-content: center; + justify-items: center; + transition: all 2s ease; + grid-gap: 50px; + z-index: 100; + pointer-events: none; + color: white; + + div { + font-family: "Lattice Pixel", sans-serif; + } + + img { + transition: all 2s ease; + width: 100px; + } +`; diff --git a/packages/client/src/LoadingScreen/LoadingBar.tsx b/packages/client/src/LoadingScreen/LoadingBar.tsx new file mode 100644 index 0000000..2c05420 --- /dev/null +++ b/packages/client/src/LoadingScreen/LoadingBar.tsx @@ -0,0 +1,24 @@ +import React from "react"; +import styled from "styled-components"; + +export const LoadingBar: React.FC<{ + percentage: number; + className?: string; +}> = ({ percentage, className }) => { + return ( + + + + ); +}; + +const Wrapper = styled.div` + position: relative; + height: 4px; + background-color: #2a2a2a; +`; +const Inner = styled.div<{ percentage: number }>` + height: 100%; + width: ${(p) => p.percentage}%; + background-color: #fff; +`; diff --git a/packages/client/src/LoadingScreen/LoadingScreen.tsx b/packages/client/src/LoadingScreen/LoadingScreen.tsx new file mode 100644 index 0000000..3f42736 --- /dev/null +++ b/packages/client/src/LoadingScreen/LoadingScreen.tsx @@ -0,0 +1,54 @@ +import React from "react"; +import styled from "styled-components"; +import { LoadingBar } from "./LoadingBar"; +import { BootScreen } from "./BootScreen"; +import { useComponentValue } from "@latticexyz/react"; +import { useMUD } from "../../store"; +import { singletonEntity } from "@latticexyz/store-sync/recs"; +import { SyncStep } from "@latticexyz/store-sync"; + +export const LoadingScreen = () => { + const { + networkLayer: { + components: { SyncProgress }, + }, + } = useMUD(); + + const syncProgress = useComponentValue(SyncProgress, singletonEntity, { + message: "Connecting", + percentage: 0, + step: SyncStep.INITIALIZE, + latestBlockNumber: 0n, + lastBlockNumberProcessed: 0n, + }); + + if (syncProgress.step === SyncStep.LIVE) { + return null; + } + + return ( + + {syncProgress.message}… + + {Math.floor(syncProgress.percentage)}% + + + + ); +}; + +const LoadingContainer = styled.div` + display: grid; + justify-items: start; + justify-content: start; + align-items: center; + height: 30px; + width: 100%; + grid-gap: 20px; + grid-template-columns: auto 1fr; +`; + +const Loading = styled(LoadingBar)` + width: 100%; + min-width: 200px; +`; diff --git a/packages/client/src/LoadingScreen/index.ts b/packages/client/src/LoadingScreen/index.ts new file mode 100644 index 0000000..ccaf524 --- /dev/null +++ b/packages/client/src/LoadingScreen/index.ts @@ -0,0 +1 @@ +export * from "./LoadingScreen"; diff --git a/packages/client/src/PhaserLayer.tsx b/packages/client/src/PhaserLayer.tsx new file mode 100644 index 0000000..54f5546 --- /dev/null +++ b/packages/client/src/PhaserLayer.tsx @@ -0,0 +1,20 @@ +import React, { useEffect } from "react"; +import { NetworkLayer } from "../layers/network/createNetworkLayer"; +import { useStore } from "../store"; +import { usePhaserLayer } from "./hooks/usePhaserLayer"; + +type Props = { + networkLayer: NetworkLayer | null; +}; + +export const PhaserLayer = ({ networkLayer }: Props) => { + const { ref: phaserRef, phaserLayer } = usePhaserLayer({ networkLayer }); + + useEffect(() => { + if (phaserLayer) { + useStore.setState({ phaserLayer }); + } + }, [phaserLayer]); + + return
; +}; diff --git a/packages/client/src/artTypes/world.ts b/packages/client/src/artTypes/world.ts new file mode 100644 index 0000000..ba827ee --- /dev/null +++ b/packages/client/src/artTypes/world.ts @@ -0,0 +1,9 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +export enum Tileset { + Grass = 0, + Mountain = 1, + Forest = 2, +} +export enum TileAnimationKey {} +export const TileAnimations: { [key in TileAnimationKey]: number[] } = {}; diff --git a/packages/client/src/hooks/useNetworkLayer.tsx b/packages/client/src/hooks/useNetworkLayer.tsx new file mode 100644 index 0000000..e2e13ab --- /dev/null +++ b/packages/client/src/hooks/useNetworkLayer.tsx @@ -0,0 +1,17 @@ +import { useEffect, useMemo } from "react"; +import { createNetworkLayer } from "../../layers/network/createNetworkLayer"; +import { usePromiseValue } from "./usePromiseValue"; + +export const useNetworkLayer = () => { + const networkLayerPromise = useMemo(() => { + return createNetworkLayer(); + }, []); + + useEffect(() => { + return () => { + networkLayerPromise.then((networkLayer) => networkLayer.world.dispose()); + }; + }, [networkLayerPromise]); + + return usePromiseValue(networkLayerPromise); +}; diff --git a/packages/client/src/hooks/usePhaserLayer.tsx b/packages/client/src/hooks/usePhaserLayer.tsx new file mode 100644 index 0000000..298b274 --- /dev/null +++ b/packages/client/src/hooks/usePhaserLayer.tsx @@ -0,0 +1,93 @@ +import React, { + useCallback, + useEffect, + useMemo, + useRef, + useState, +} from "react"; +import useResizeObserver, { ResizeHandler } from "use-resize-observer"; +import { throttle } from "lodash"; +import { createPhaserLayer } from "../layers/phaser/createPhaserLayer"; +import { NetworkLayer } from "../layers/network/createNetworkLayer"; +import { usePromiseValue } from "./usePromiseValue"; +import { phaserConfig } from "../layers/phaser/configurePhaser"; + +const createContainer = () => { + const container = document.createElement("div"); + container.style.width = "100vw"; + container.style.height = "100vh"; + container.style.pointerEvents = "all"; + container.style.overflow = "hidden"; + return container; +}; + +type Props = { + networkLayer: NetworkLayer | null; +}; + +export const usePhaserLayer = ({ networkLayer }: Props) => { + const parentRef = useRef(null); + const [{ width, height }, setSize] = useState({ width: 0, height: 0 }); + + const { phaserLayerPromise, container } = useMemo(() => { + if (!networkLayer) return { phaserLayerPromise: null, container: null }; + + const container = createContainer(); + if (parentRef.current) { + parentRef.current.appendChild(container); + } + + return { + container, + phaserLayerPromise: createPhaserLayer(networkLayer, { + ...phaserConfig, + scale: { + ...phaserConfig.scale, + parent: container, + mode: Phaser.Scale.NONE, + width, + height, + }, + }), + }; + + // We don't want width/height to recreate phaser layer, so we ignore linter + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [networkLayer]); + + useEffect(() => { + return () => { + phaserLayerPromise?.then((phaserLayer) => phaserLayer.world.dispose()); + container?.remove(); + }; + }, [container, phaserLayerPromise]); + + const phaserLayer = usePromiseValue(phaserLayerPromise); + + const onResize = useMemo(() => { + return throttle(({ width, height }) => { + setSize({ width: width ?? 0, height: height ?? 0 }); + }, 500); + }, []); + + useResizeObserver({ + ref: container, + onResize, + }); + + const ref = useCallback( + (el: HTMLElement | null) => { + parentRef.current = el; + if (container) { + if (parentRef.current) { + parentRef.current.appendChild(container); + } else { + container.remove(); + } + } + }, + [container] + ); + + return useMemo(() => ({ ref, phaserLayer }), [ref, phaserLayer]); +}; diff --git a/packages/client/src/hooks/usePromiseValue.ts b/packages/client/src/hooks/usePromiseValue.ts new file mode 100644 index 0000000..bd71492 --- /dev/null +++ b/packages/client/src/hooks/usePromiseValue.ts @@ -0,0 +1,24 @@ +import { useEffect, useState, useRef } from "react"; + +export const usePromiseValue = (promise: Promise | null) => { + const promiseRef = useRef(promise); + const [value, setValue] = useState(null); + useEffect(() => { + if (!promise) return; + let isMounted = true; + promiseRef.current = promise; + // TODO: do something with promise errors? + promise.then((resolvedValue) => { + // skip if unmounted (state changes will cause errors otherwise) + if (!isMounted) return; + // If our promise was replaced before it resolved, ignore the result + if (promiseRef.current !== promise) return; + + setValue(resolvedValue); + }); + return () => { + isMounted = false; + }; + }, [promise]); + return value; +}; diff --git a/packages/client/src/layers/network/createNetworkLayer.ts b/packages/client/src/layers/network/createNetworkLayer.ts new file mode 100644 index 0000000..2904fce --- /dev/null +++ b/packages/client/src/layers/network/createNetworkLayer.ts @@ -0,0 +1,15 @@ +import { world } from "../../mud/world"; +import { setup } from "../../mud/setup"; + +export type NetworkLayer = Awaited>; + +export const createNetworkLayer = async () => { + const { components, systemCalls, network } = await setup(); + + return { + world, + systemCalls, + components, + network, + }; +}; diff --git a/packages/client/src/layers/phaser/configurePhaser.ts b/packages/client/src/layers/phaser/configurePhaser.ts new file mode 100644 index 0000000..30359b8 --- /dev/null +++ b/packages/client/src/layers/phaser/configurePhaser.ts @@ -0,0 +1,99 @@ +import { + defineSceneConfig, + AssetType, + defineScaleConfig, + defineMapConfig, + defineCameraConfig, +} from "@latticexyz/phaserx"; +import worldTileset from "../../../public/assets/tilesets/world.png"; +import { TileAnimations, Tileset } from "../../artTypes/world"; +import { + Sprites, + Assets, + Maps, + Scenes, + TILE_HEIGHT, + TILE_WIDTH, + Animations, +} from "./constants"; + +const ANIMATION_INTERVAL = 200; + +const mainMap = defineMapConfig({ + chunkSize: TILE_WIDTH * 64, // tile size * tile amount + tileWidth: TILE_WIDTH, + tileHeight: TILE_HEIGHT, + backgroundTile: [Tileset.Grass], + animationInterval: ANIMATION_INTERVAL, + tileAnimations: TileAnimations, + layers: { + layers: { + Background: { tilesets: ["Default"] }, + Foreground: { tilesets: ["Default"] }, + }, + defaultLayer: "Background", + }, +}); + +export const phaserConfig = { + sceneConfig: { + [Scenes.Main]: defineSceneConfig({ + assets: { + [Assets.Tileset]: { + type: AssetType.Image, + key: Assets.Tileset, + path: worldTileset, + }, + [Assets.MainAtlas]: { + type: AssetType.MultiAtlas, + key: Assets.MainAtlas, + // Add a timestamp to the end of the path to prevent caching + path: `/assets/atlases/atlas.json?timestamp=${Date.now()}`, + options: { + imagePath: "/assets/atlases/", + }, + }, + }, + maps: { + [Maps.Main]: mainMap, + }, + sprites: { + [Sprites.Soldier]: { + assetKey: Assets.MainAtlas, + frame: "sprites/soldier/idle/0.png", + }, + }, + animations: [ + { + key: Animations.SwordsmanIdle, + assetKey: Assets.MainAtlas, + startFrame: 0, + endFrame: 3, + frameRate: 6, + repeat: -1, + prefix: "sprites/soldier/idle/", + suffix: ".png", + }, + ], + tilesets: { + Default: { + assetKey: Assets.Tileset, + tileWidth: TILE_WIDTH, + tileHeight: TILE_HEIGHT, + }, + }, + }), + }, + scale: defineScaleConfig({ + parent: "phaser-game", + zoom: 1, + mode: Phaser.Scale.NONE, + }), + cameraConfig: defineCameraConfig({ + pinchSpeed: 1, + wheelSpeed: 1, + maxZoom: 3, + minZoom: 1, + }), + cullingChunkSize: TILE_HEIGHT * 16, +}; diff --git a/packages/client/src/layers/phaser/constants.ts b/packages/client/src/layers/phaser/constants.ts new file mode 100644 index 0000000..61c8d67 --- /dev/null +++ b/packages/client/src/layers/phaser/constants.ts @@ -0,0 +1,22 @@ +export enum Scenes { + Main = "Main", +} + +export enum Maps { + Main = "Main", +} + +export enum Animations { + SwordsmanIdle = "SwordsmanIdle", +} +export enum Sprites { + Soldier, +} + +export enum Assets { + MainAtlas = "MainAtlas", + Tileset = "Tileset", +} + +export const TILE_HEIGHT = 32; +export const TILE_WIDTH = 32; diff --git a/packages/client/src/layers/phaser/createPhaserLayer.ts b/packages/client/src/layers/phaser/createPhaserLayer.ts new file mode 100644 index 0000000..4832483 --- /dev/null +++ b/packages/client/src/layers/phaser/createPhaserLayer.ts @@ -0,0 +1,40 @@ +import { createPhaserEngine } from "@latticexyz/phaserx"; +import { namespaceWorld } from "@latticexyz/recs"; +import { NetworkLayer } from "../network/createNetworkLayer"; +import { registerSystems } from "./systems"; + +export type PhaserLayer = Awaited>; +type PhaserEngineConfig = Parameters[0]; + +export const createPhaserLayer = async ( + networkLayer: NetworkLayer, + phaserConfig: PhaserEngineConfig +) => { + const world = namespaceWorld(networkLayer.world, "phaser"); + + const { + game, + scenes, + dispose: disposePhaser, + } = await createPhaserEngine(phaserConfig); + world.registerDisposer(disposePhaser); + + const { camera } = scenes.Main; + + camera.phaserCamera.setBounds(-1000, -1000, 2000, 2000); + camera.phaserCamera.centerOn(0, 0); + + const components = {}; + + const layer = { + networkLayer, + world, + game, + scenes, + components, + }; + + registerSystems(layer); + + return layer; +}; diff --git a/packages/client/src/layers/phaser/systems/createCamera.ts b/packages/client/src/layers/phaser/systems/createCamera.ts new file mode 100644 index 0000000..df74282 --- /dev/null +++ b/packages/client/src/layers/phaser/systems/createCamera.ts @@ -0,0 +1,13 @@ +import { PhaserLayer } from "../createPhaserLayer"; + +export const createCamera = (layer: PhaserLayer) => { + const { + scenes: { + Main: { + camera: { phaserCamera }, + }, + }, + } = layer; + + phaserCamera.centerOn(0, 0); +}; diff --git a/packages/client/src/layers/phaser/systems/createMapSystem.ts b/packages/client/src/layers/phaser/systems/createMapSystem.ts new file mode 100644 index 0000000..f847f3e --- /dev/null +++ b/packages/client/src/layers/phaser/systems/createMapSystem.ts @@ -0,0 +1,32 @@ +import { Tileset } from "../../../artTypes/world"; +import { PhaserLayer } from "../createPhaserLayer"; +import { createNoise2D } from "simplex-noise"; + +export function createMapSystem(layer: PhaserLayer) { + const { + scenes: { + Main: { + maps: { + Main: { putTileAt }, + }, + }, + }, + } = layer; + + const noise = createNoise2D(); + + for (let x = -500; x < 500; x++) { + for (let y = -500; y < 500; y++) { + const coord = { x, y }; + const seed = noise(x, y); + + putTileAt(coord, Tileset.Grass, "Background"); + + if (seed >= 0.45) { + putTileAt(coord, Tileset.Mountain, "Foreground"); + } else if (seed < -0.45) { + putTileAt(coord, Tileset.Forest, "Foreground"); + } + } + } +} diff --git a/packages/client/src/layers/phaser/systems/index.ts b/packages/client/src/layers/phaser/systems/index.ts new file mode 100644 index 0000000..7b5a4bd --- /dev/null +++ b/packages/client/src/layers/phaser/systems/index.ts @@ -0,0 +1 @@ +export * from "./registerSystems"; diff --git a/packages/client/src/layers/phaser/systems/registerSystems.ts b/packages/client/src/layers/phaser/systems/registerSystems.ts new file mode 100644 index 0000000..5db82c6 --- /dev/null +++ b/packages/client/src/layers/phaser/systems/registerSystems.ts @@ -0,0 +1,8 @@ +import { PhaserLayer } from "../createPhaserLayer"; +import { createCamera } from "./createCamera"; +import { createMapSystem } from "./createMapSystem"; + +export const registerSystems = (layer: PhaserLayer) => { + createCamera(layer); + createMapSystem(layer); +}; diff --git a/packages/client/src/store.ts b/packages/client/src/store.ts new file mode 100644 index 0000000..051050d --- /dev/null +++ b/packages/client/src/store.ts @@ -0,0 +1,35 @@ +import { create } from "zustand"; +import { NetworkLayer } from "./layers/network/createNetworkLayer"; +import { PhaserLayer } from "./layers/phaser/createPhaserLayer"; + +export type Store = { + networkLayer: NetworkLayer | null; + phaserLayer: PhaserLayer | null; + devMode: boolean; +}; + +export type UIStore = { + networkLayer: NetworkLayer; + phaserLayer: PhaserLayer; + devMode: boolean; +}; + +export const useStore = create(() => ({ + networkLayer: null, + phaserLayer: null, + devMode: false, +})); + +export const usePhaserMud = () => { + const { networkLayer, phaserLayer, devMode } = useStore(); + + if (networkLayer === null || phaserLayer === null) { + throw new Error("Store not initialized"); + } + + return { + networkLayer, + phaserLayer, + devMode, + } as UIStore; +}; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c5899d8..2a086ca 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -96,6 +96,9 @@ importers: ethers: specifier: ^5.7.2 version: 5.7.2 + lodash: + specifier: ^4.17.21 + version: 4.17.21 postcss: specifier: ^8.4.28 version: 8.4.28 @@ -111,6 +114,9 @@ importers: tailwindcss: specifier: ^3.3.3 version: 3.3.3 + use-resize-observer: + specifier: ^9.1.0 + version: 9.1.0(react-dom@18.2.0)(react@18.2.0) viem: specifier: 1.6.0 version: 1.6.0(typescript@4.9.5)(zod@3.21.4) @@ -1052,6 +1058,10 @@ packages: '@jridgewell/resolve-uri': 3.1.1 '@jridgewell/sourcemap-codec': 1.4.15 + /@juggle/resize-observer@3.4.0: + resolution: {integrity: sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==} + dev: false + /@latticexyz/block-logs-stream@2.0.0-next.4(typescript@4.9.5)(zod@3.21.4): resolution: {integrity: sha512-8QRMkkMhwxdAd6ifky2latt7qopcoHf3d3bGVz0pwdv48H3iZTK1xWRavf+chCHYddMuW+C8QprNU9wp/U19Zg==} dependencies: @@ -6282,6 +6292,17 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: false + /use-resize-observer@9.1.0(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-R25VqO9Wb3asSD4eqtcxk8sJalvIOYBqS8MNZlpDSQ4l4xMQxC/J7Id9HoTqPq8FwULIn0PVW+OAqF2dyYbjow==} + peerDependencies: + react: 16.8.0 - 18 + react-dom: 16.8.0 - 18 + dependencies: + '@juggle/resize-observer': 3.4.0 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + /use-sync-external-store@1.2.0(react@18.2.0): resolution: {integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==} peerDependencies: @@ -6579,19 +6600,19 @@ packages: dev: false github.com/dapphub/ds-test/c9ce3f25bde29fc5eb9901842bf02850dfd2d084: - resolution: {tarball: https://codeload.github.com/dapphub/ds-test/tar.gz/c9ce3f25bde29fc5eb9901842bf02850dfd2d084} + resolution: {commit: c9ce3f25bde29fc5eb9901842bf02850dfd2d084, repo: git+ssh://git@github.com/dapphub/ds-test.git, type: git} name: ds-test version: 1.0.0 dev: true github.com/dk1a/memmove/ffd71cd77b1708574ef46a667b23ca3a5cc9fa27: - resolution: {tarball: https://codeload.github.com/dk1a/memmove/tar.gz/ffd71cd77b1708574ef46a667b23ca3a5cc9fa27} + resolution: {commit: ffd71cd77b1708574ef46a667b23ca3a5cc9fa27, repo: git+ssh://git@github.com/dk1a/memmove.git, type: git} name: memmove version: 0.1.0 dev: true github.com/transmissions11/solmate/9cf1428245074e39090dceacb0c28b1f684f584c: - resolution: {tarball: https://codeload.github.com/transmissions11/solmate/tar.gz/9cf1428245074e39090dceacb0c28b1f684f584c} + resolution: {commit: 9cf1428245074e39090dceacb0c28b1f684f584c, repo: git+ssh://git@github.com/transmissions11/solmate.git, type: git} name: solmate version: 6.5.0 dev: true