forked from Kieran/zap.stream
feat: stream forwards
This commit is contained in:
parent
7600d93983
commit
31b8549632
@ -14,8 +14,8 @@
|
|||||||
"@react-hook/resize-observer": "^1.2.6",
|
"@react-hook/resize-observer": "^1.2.6",
|
||||||
"@scure/base": "^1.1.3",
|
"@scure/base": "^1.1.3",
|
||||||
"@snort/shared": "^1.0.10",
|
"@snort/shared": "^1.0.10",
|
||||||
"@snort/system": "^1.1.7",
|
"@snort/system": "^1.1.8",
|
||||||
"@snort/system-react": "^1.1.7",
|
"@snort/system-react": "^1.1.8",
|
||||||
"@snort/system-wasm": "^1.0.1",
|
"@snort/system-wasm": "^1.0.1",
|
||||||
"@snort/system-web": "^1.0.2",
|
"@snort/system-web": "^1.0.2",
|
||||||
"@szhsin/react-menu": "^4.0.2",
|
"@szhsin/react-menu": "^4.0.2",
|
||||||
|
@ -26,7 +26,7 @@ import Copy from "./copy";
|
|||||||
import { openFile } from "@/utils";
|
import { openFile } from "@/utils";
|
||||||
import { LoginType } from "@/login";
|
import { LoginType } from "@/login";
|
||||||
import { DefaultProvider, StreamProviderInfo } from "@/providers";
|
import { DefaultProvider, StreamProviderInfo } from "@/providers";
|
||||||
import { Nip103StreamProvider } from "@/providers/zsz";
|
import { NostrStreamProvider } from "@/providers/zsz";
|
||||||
|
|
||||||
enum Stage {
|
enum Stage {
|
||||||
Login = 0,
|
Login = 0,
|
||||||
@ -109,7 +109,7 @@ export function LoginSignup({ close }: { close: () => void }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function setupProfile() {
|
async function setupProfile() {
|
||||||
const px = new Nip103StreamProvider(DefaultProvider.name, DefaultProvider.url, EventPublisher.privateKey(key));
|
const px = new NostrStreamProvider(DefaultProvider.name, DefaultProvider.url, EventPublisher.privateKey(key));
|
||||||
const info = await px.info();
|
const info = await px.info();
|
||||||
setProviderInfo(info);
|
setProviderInfo(info);
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ import { SnortContext } from "@snort/system-react";
|
|||||||
|
|
||||||
import { Icon } from "./icon";
|
import { Icon } from "./icon";
|
||||||
import { useStreamProvider } from "@/hooks/stream-provider";
|
import { useStreamProvider } from "@/hooks/stream-provider";
|
||||||
import { StreamProvider, StreamProviders } from "@/providers";
|
import { NostrStreamProvider, StreamProvider, StreamProviders } from "@/providers";
|
||||||
import { StreamEditor, StreamEditorProps } from "./stream-editor";
|
import { StreamEditor, StreamEditorProps } from "./stream-editor";
|
||||||
import { eventLink, findTag } from "@/utils";
|
import { eventLink, findTag } from "@/utils";
|
||||||
import { NostrProviderDialog } from "./nostr-provider-dialog";
|
import { NostrProviderDialog } from "./nostr-provider-dialog";
|
||||||
@ -65,11 +65,12 @@ function NewStream({ ev, onFinish }: Omit<StreamEditorProps, "onFinish"> & { onF
|
|||||||
<FormattedMessage defaultMessage="Get stream key" id="KdYELp" />
|
<FormattedMessage defaultMessage="Get stream key" id="KdYELp" />
|
||||||
</button>
|
</button>
|
||||||
<NostrProviderDialog
|
<NostrProviderDialog
|
||||||
provider={currentProvider}
|
provider={currentProvider as NostrStreamProvider}
|
||||||
onFinish={onFinish}
|
onFinish={onFinish}
|
||||||
ev={ev}
|
ev={ev}
|
||||||
showEndpoints={false}
|
showEndpoints={false}
|
||||||
showEditor={true}
|
showEditor={true}
|
||||||
|
showForwards={false}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import { NostrEvent } from "@snort/system";
|
import { NostrEvent } from "@snort/system";
|
||||||
import { useContext, useEffect, useState } from "react";
|
import { useContext, useEffect, useState } from "react";
|
||||||
import { FormattedMessage } from "react-intl";
|
import { FormattedMessage, useIntl } from "react-intl";
|
||||||
import { SnortContext } from "@snort/system-react";
|
import { SnortContext } from "@snort/system-react";
|
||||||
|
|
||||||
import { StreamProvider, StreamProviderEndpoint, StreamProviderInfo } from "@/providers";
|
import { NostrStreamProvider, StreamProviderEndpoint, StreamProviderInfo } from "@/providers";
|
||||||
import { SendZaps } from "./send-zap";
|
import { SendZaps } from "./send-zap";
|
||||||
import { StreamEditor, StreamEditorProps } from "./stream-editor";
|
import { StreamEditor, StreamEditorProps } from "./stream-editor";
|
||||||
import Spinner from "./spinner";
|
import Spinner from "./spinner";
|
||||||
@ -13,8 +13,9 @@ export function NostrProviderDialog({
|
|||||||
provider,
|
provider,
|
||||||
showEndpoints,
|
showEndpoints,
|
||||||
showEditor,
|
showEditor,
|
||||||
|
showForwards,
|
||||||
...others
|
...others
|
||||||
}: { provider: StreamProvider; showEndpoints: boolean; showEditor: boolean } & StreamEditorProps) {
|
}: { provider: NostrStreamProvider; showEndpoints: boolean; showEditor: boolean, showForwards: boolean } & StreamEditorProps) {
|
||||||
const system = useContext(SnortContext);
|
const system = useContext(SnortContext);
|
||||||
const [topup, setTopup] = useState(false);
|
const [topup, setTopup] = useState(false);
|
||||||
const [info, setInfo] = useState<StreamProviderInfo>();
|
const [info, setInfo] = useState<StreamProviderInfo>();
|
||||||
@ -133,7 +134,7 @@ export function NostrProviderDialog({
|
|||||||
</p>
|
</p>
|
||||||
<div className="flex gap-2">
|
<div className="flex gap-2">
|
||||||
{sortEndpoints(info.endpoints).map(a => (
|
{sortEndpoints(info.endpoints).map(a => (
|
||||||
<span className={`pill${ep?.name === a.name ? " active" : ""}`} onClick={() => setEndpoint(a)}>
|
<span className={`pill bg-gray-1${ep?.name === a.name ? " active" : ""}`} onClick={() => setEndpoint(a)}>
|
||||||
{a.name}
|
{a.name}
|
||||||
</span>
|
</span>
|
||||||
))}
|
))}
|
||||||
@ -187,42 +188,101 @@ export function NostrProviderDialog({
|
|||||||
</p>
|
</p>
|
||||||
<div className="flex gap-2">
|
<div className="flex gap-2">
|
||||||
{ep?.capabilities?.map(a => (
|
{ep?.capabilities?.map(a => (
|
||||||
<span className="pill">{parseCapability(a)}</span>
|
<span className="pill bg-gray-1">{parseCapability(a)}</span>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function streamEditor() {
|
||||||
|
if (!info || !showEditor) return;
|
||||||
|
if (info.tosAccepted === false) {
|
||||||
|
return tosInput();
|
||||||
|
}
|
||||||
|
|
||||||
|
return <StreamEditor
|
||||||
|
onFinish={ex => {
|
||||||
|
provider.updateStreamInfo(system, ex);
|
||||||
|
others.onFinish?.(ex);
|
||||||
|
}}
|
||||||
|
ev={
|
||||||
|
{
|
||||||
|
tags: [
|
||||||
|
["title", info.streamInfo?.title ?? ""],
|
||||||
|
["summary", info.streamInfo?.summary ?? ""],
|
||||||
|
["image", info.streamInfo?.image ?? ""],
|
||||||
|
...(info.streamInfo?.goal ? [["goal", info.streamInfo.goal]] : []),
|
||||||
|
...(info.streamInfo?.content_warning ? [["content-warning", info.streamInfo?.content_warning]] : []),
|
||||||
|
...(info.streamInfo?.tags?.map(a => ["t", a]) ?? []),
|
||||||
|
],
|
||||||
|
} as NostrEvent
|
||||||
|
}
|
||||||
|
options={{
|
||||||
|
canSetStream: false,
|
||||||
|
canSetStatus: false,
|
||||||
|
}}
|
||||||
|
/>;
|
||||||
|
}
|
||||||
|
|
||||||
|
function forwardInputs() {
|
||||||
|
if (!info || !showForwards) return;
|
||||||
|
|
||||||
|
return <div className="flex flex-col gap-4">
|
||||||
|
<h3>
|
||||||
|
<FormattedMessage defaultMessage="Stream Forwarding" id="W7DNWx" />
|
||||||
|
</h3>
|
||||||
|
|
||||||
|
<div className="grid grid-cols-3 gap-2">
|
||||||
|
{info.forwards?.map(a => <>
|
||||||
|
<div className="paper">{a.name}</div>
|
||||||
|
<AsyncButton className="btn btn-primary" onClick={async () => {
|
||||||
|
await provider.removeForward(a.id);
|
||||||
|
}}>
|
||||||
|
<FormattedMessage defaultMessage="Remove" id="G/yZLu" />
|
||||||
|
</AsyncButton>
|
||||||
|
<div></div>
|
||||||
|
</>)}
|
||||||
|
<AddForwardInputs provider={provider} onAdd={() => { }} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{showEndpoints && streamEndpoints()}
|
{showEndpoints && streamEndpoints()}
|
||||||
{info.tosAccepted === false ? (
|
{streamEditor()}
|
||||||
tosInput()
|
{forwardInputs()}
|
||||||
) : showEditor ? (
|
|
||||||
<StreamEditor
|
|
||||||
onFinish={ex => {
|
|
||||||
provider.updateStreamInfo(system, ex);
|
|
||||||
others.onFinish?.(ex);
|
|
||||||
}}
|
|
||||||
ev={
|
|
||||||
{
|
|
||||||
tags: [
|
|
||||||
["title", info.streamInfo?.title ?? ""],
|
|
||||||
["summary", info.streamInfo?.summary ?? ""],
|
|
||||||
["image", info.streamInfo?.image ?? ""],
|
|
||||||
...(info.streamInfo?.goal ? [["goal", info.streamInfo.goal]] : []),
|
|
||||||
...(info.streamInfo?.content_warning ? [["content-warning", info.streamInfo?.content_warning]] : []),
|
|
||||||
...(info.streamInfo?.tags?.map(a => ["t", a]) ?? []),
|
|
||||||
],
|
|
||||||
} as NostrEvent
|
|
||||||
}
|
|
||||||
options={{
|
|
||||||
canSetStream: false,
|
|
||||||
canSetStatus: false,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
) : null}
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function AddForwardInputs({ provider, onAdd }: { provider: NostrStreamProvider, onAdd: (name: string, target: string) => void }) {
|
||||||
|
const [name, setName] = useState("");
|
||||||
|
const [target, setTarget] = useState("");
|
||||||
|
const { formatMessage } = useIntl();
|
||||||
|
|
||||||
|
async function doAdd() {
|
||||||
|
await provider.addForward(name, target);
|
||||||
|
setName("");
|
||||||
|
setTarget("");
|
||||||
|
onAdd(name, target);
|
||||||
|
}
|
||||||
|
|
||||||
|
return <>
|
||||||
|
<div className="paper">
|
||||||
|
<input type="text"
|
||||||
|
placeholder={formatMessage({ defaultMessage: "Human readable name", id: 'QuXHCg' })}
|
||||||
|
value={name} onChange={e => setName(e.target.value)} />
|
||||||
|
</div>
|
||||||
|
<div className="paper">
|
||||||
|
<input type="text"
|
||||||
|
placeholder="rtmp://"
|
||||||
|
value={target} onChange={e => setTarget(e.target.value)} />
|
||||||
|
</div>
|
||||||
|
<AsyncButton className="btn btn-primary" onClick={doAdd}>
|
||||||
|
<FormattedMessage defaultMessage="Add" id="2/2yg+" />
|
||||||
|
</AsyncButton>
|
||||||
|
</>
|
||||||
|
}
|
@ -6,7 +6,7 @@ import AsyncButton from "@/element/async-button";
|
|||||||
import { StatePill } from "@/element/state-pill";
|
import { StatePill } from "@/element/state-pill";
|
||||||
import { StreamState } from "@/index";
|
import { StreamState } from "@/index";
|
||||||
import { StreamProviderInfo, StreamProviderStore } from "@/providers";
|
import { StreamProviderInfo, StreamProviderStore } from "@/providers";
|
||||||
import { Nip103StreamProvider } from "@/providers/zsz";
|
import { NostrStreamProvider } from "@/providers/zsz";
|
||||||
|
|
||||||
export function ConfigureNostrType() {
|
export function ConfigureNostrType() {
|
||||||
const [url, setUrl] = useState("");
|
const [url, setUrl] = useState("");
|
||||||
@ -15,7 +15,7 @@ export function ConfigureNostrType() {
|
|||||||
|
|
||||||
async function tryConnect() {
|
async function tryConnect() {
|
||||||
try {
|
try {
|
||||||
const api = new Nip103StreamProvider(new URL(url).host, url);
|
const api = new NostrStreamProvider(new URL(url).host, url);
|
||||||
const inf = await api.info();
|
const inf = await api.info();
|
||||||
setInfo(inf);
|
setInfo(inf);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -58,7 +58,7 @@ export function ConfigureNostrType() {
|
|||||||
<button
|
<button
|
||||||
className="btn btn-border"
|
className="btn btn-border"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
StreamProviderStore.add(new Nip103StreamProvider(new URL(url).host, url));
|
StreamProviderStore.add(new NostrStreamProvider(new URL(url).host, url));
|
||||||
navigate("/");
|
navigate("/");
|
||||||
}}>
|
}}>
|
||||||
<FormattedMessage defaultMessage="Save" id="jvo0vs" />
|
<FormattedMessage defaultMessage="Save" id="jvo0vs" />
|
||||||
|
@ -10,6 +10,7 @@ import { NostrProviderDialog } from "@/element/nostr-provider-dialog";
|
|||||||
import { useStreamProvider } from "@/hooks/stream-provider";
|
import { useStreamProvider } from "@/hooks/stream-provider";
|
||||||
import { Login, StreamState } from "..";
|
import { Login, StreamState } from "..";
|
||||||
import { StatePill } from "@/element/state-pill";
|
import { StatePill } from "@/element/state-pill";
|
||||||
|
import { NostrStreamProvider } from "@/providers";
|
||||||
|
|
||||||
const enum Tab {
|
const enum Tab {
|
||||||
Account,
|
Account,
|
||||||
@ -77,9 +78,10 @@ export function SettingsPage() {
|
|||||||
<FormattedMessage defaultMessage="Stream Key" id="LknBsU" />
|
<FormattedMessage defaultMessage="Stream Key" id="LknBsU" />
|
||||||
</h1>
|
</h1>
|
||||||
<NostrProviderDialog
|
<NostrProviderDialog
|
||||||
provider={unwrap(providers.find(a => a.name === "zap.stream"))}
|
provider={unwrap(providers.find(a => a.name === "zap.stream")) as NostrStreamProvider}
|
||||||
showEndpoints={true}
|
showEndpoints={true}
|
||||||
showEditor={false}
|
showEditor={false}
|
||||||
|
showForwards={true}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
import { StreamState } from "@/index";
|
import { StreamState } from "@/index";
|
||||||
import { NostrEvent, SystemInterface } from "@snort/system";
|
import { NostrEvent, SystemInterface } from "@snort/system";
|
||||||
import { ExternalStore } from "@snort/shared";
|
import { ExternalStore } from "@snort/shared";
|
||||||
import { Nip103StreamProvider } from "./zsz";
|
import { NostrStreamProvider } from "./zsz";
|
||||||
import { ManualProvider } from "./manual";
|
import { ManualProvider } from "./manual";
|
||||||
import { OwncastProvider } from "./owncast";
|
import { OwncastProvider } from "./owncast";
|
||||||
|
|
||||||
|
export { NostrStreamProvider } from "./zsz";
|
||||||
|
|
||||||
export interface StreamProvider {
|
export interface StreamProvider {
|
||||||
get name(): string;
|
get name(): string;
|
||||||
get type(): StreamProviders;
|
get type(): StreamProviders;
|
||||||
@ -54,6 +56,7 @@ export interface StreamProviderInfo {
|
|||||||
endpoints: Array<StreamProviderEndpoint>;
|
endpoints: Array<StreamProviderEndpoint>;
|
||||||
tosAccepted?: boolean;
|
tosAccepted?: boolean;
|
||||||
tosLink?: string;
|
tosLink?: string;
|
||||||
|
forwards?: Array<{ id: string; name: string }>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface StreamProviderEndpoint {
|
export interface StreamProviderEndpoint {
|
||||||
@ -74,7 +77,7 @@ export interface StreamProviderStreamInfo {
|
|||||||
goal?: string;
|
goal?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DefaultProvider = new Nip103StreamProvider("zap.stream", "https://api.zap.stream/api/nostr/");
|
export const DefaultProvider = new NostrStreamProvider("zap.stream", "https://api.zap.stream/api/nostr/");
|
||||||
|
|
||||||
export class ProviderStore extends ExternalStore<Array<StreamProvider>> {
|
export class ProviderStore extends ExternalStore<Array<StreamProvider>> {
|
||||||
#providers: Array<StreamProvider> = [];
|
#providers: Array<StreamProvider> = [];
|
||||||
@ -91,7 +94,7 @@ export class ProviderStore extends ExternalStore<Array<StreamProvider>> {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case StreamProviders.NostrType: {
|
case StreamProviders.NostrType: {
|
||||||
this.#providers.push(new Nip103StreamProvider(new URL(c.url as string).host, c.url as string));
|
this.#providers.push(new NostrStreamProvider(new URL(c.url as string).host, c.url as string));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case StreamProviders.Owncast: {
|
case StreamProviders.Owncast: {
|
||||||
|
@ -11,7 +11,7 @@ import { Login, StreamState } from "@/index";
|
|||||||
import { getPublisher } from "@/login";
|
import { getPublisher } from "@/login";
|
||||||
import { extractStreamInfo } from "@/utils";
|
import { extractStreamInfo } from "@/utils";
|
||||||
|
|
||||||
export class Nip103StreamProvider implements StreamProvider {
|
export class NostrStreamProvider implements StreamProvider {
|
||||||
#publisher?: EventPublisher;
|
#publisher?: EventPublisher;
|
||||||
|
|
||||||
constructor(readonly name: string, readonly url: string, pub?: EventPublisher) {
|
constructor(readonly name: string, readonly url: string, pub?: EventPublisher) {
|
||||||
@ -43,6 +43,7 @@ export class Nip103StreamProvider implements StreamProvider {
|
|||||||
capabilities: a.capabilities,
|
capabilities: a.capabilities,
|
||||||
} as StreamProviderEndpoint;
|
} as StreamProviderEndpoint;
|
||||||
}),
|
}),
|
||||||
|
forwards: rsp.forwards,
|
||||||
} as StreamProviderInfo;
|
} as StreamProviderInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,7 +77,18 @@ export class Nip103StreamProvider implements StreamProvider {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async #getJson<T>(method: "GET" | "POST" | "PATCH", path: string, body?: unknown): Promise<T> {
|
async addForward(name: string, target: string): Promise<void> {
|
||||||
|
await this.#getJson("POST", "account/forward", {
|
||||||
|
name,
|
||||||
|
target,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async removeForward(id: string): Promise<void> {
|
||||||
|
await this.#getJson("DELETE", `account/forward/${id}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
async #getJson<T>(method: "GET" | "POST" | "PATCH" | "DELETE", path: string, body?: unknown): Promise<T> {
|
||||||
const pub = (() => {
|
const pub = (() => {
|
||||||
if (this.#publisher) {
|
if (this.#publisher) {
|
||||||
return this.#publisher;
|
return this.#publisher;
|
||||||
@ -115,6 +127,12 @@ interface AccountResponse {
|
|||||||
accepted: boolean;
|
accepted: boolean;
|
||||||
link: string;
|
link: string;
|
||||||
};
|
};
|
||||||
|
forwards: Array<ForwardDest>;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ForwardDest {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IngestEndpoint {
|
interface IngestEndpoint {
|
||||||
|
40
yarn.lock
40
yarn.lock
@ -2896,14 +2896,14 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@snort/system-react@npm:^1.1.7":
|
"@snort/system-react@npm:^1.1.8":
|
||||||
version: 1.1.7
|
version: 1.1.8
|
||||||
resolution: "@snort/system-react@npm:1.1.7"
|
resolution: "@snort/system-react@npm:1.1.8"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@snort/shared": ^1.0.10
|
"@snort/shared": ^1.0.10
|
||||||
"@snort/system": ^1.1.6
|
"@snort/system": ^1.1.8
|
||||||
react: ^18.2.0
|
react: ^18.2.0
|
||||||
checksum: 6e958a8b03c473c9c7878893cc1c79e678a713ea8ab717b2c56eb2b5702809fcfd9944fd9215db3f4e5336acef2d27959d2cfff27a753630b28b037a1e74b2a1
|
checksum: dfe30788f3c8c24bd7d9bc50f60b924ffc679b2438f172e11e56f8a00942f7bd1add1aa9adcebddba43498a92d7a49a69a5dc566b6fac16575a553ba2923275f
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@ -2943,9 +2943,9 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@snort/system@npm:^1.1.6":
|
"@snort/system@npm:^1.1.8":
|
||||||
version: 1.1.6
|
version: 1.1.8
|
||||||
resolution: "@snort/system@npm:1.1.6"
|
resolution: "@snort/system@npm:1.1.8"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@noble/curves": ^1.2.0
|
"@noble/curves": ^1.2.0
|
||||||
"@noble/hashes": ^1.3.2
|
"@noble/hashes": ^1.3.2
|
||||||
@ -2957,25 +2957,7 @@ __metadata:
|
|||||||
isomorphic-ws: ^5.0.0
|
isomorphic-ws: ^5.0.0
|
||||||
uuid: ^9.0.0
|
uuid: ^9.0.0
|
||||||
ws: ^8.14.0
|
ws: ^8.14.0
|
||||||
checksum: 087c25f72cab8b547e23190f9e3db398366f3dc1965cc5fcd6eee6983aaf3fe15a9b028047edca8080c3d63348e7359a44c42c91b2d6fa2bf36346acc0d69fda
|
checksum: f27685c55cde1b409b763a553c0cbadf972fefc449d22ea045d004da3658000c65587cef2983ba03f45df50f1eec58d9858256a7a809275a625635267b77b482
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"@snort/system@npm:^1.1.7":
|
|
||||||
version: 1.1.7
|
|
||||||
resolution: "@snort/system@npm:1.1.7"
|
|
||||||
dependencies:
|
|
||||||
"@noble/curves": ^1.2.0
|
|
||||||
"@noble/hashes": ^1.3.2
|
|
||||||
"@scure/base": ^1.1.2
|
|
||||||
"@snort/shared": ^1.0.10
|
|
||||||
"@stablelib/xchacha20": ^1.0.1
|
|
||||||
debug: ^4.3.4
|
|
||||||
eventemitter3: ^5.0.1
|
|
||||||
isomorphic-ws: ^5.0.0
|
|
||||||
uuid: ^9.0.0
|
|
||||||
ws: ^8.14.0
|
|
||||||
checksum: 881101fc44babb7b7ff081ac5c67c78afc81377b019bc9316be13789a7eaf5cd55dd6001248c8a3c3f837ac90b5082d3509d83ea63dff69103daf357b353ab9b
|
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@ -7824,8 +7806,8 @@ __metadata:
|
|||||||
"@react-hook/resize-observer": ^1.2.6
|
"@react-hook/resize-observer": ^1.2.6
|
||||||
"@scure/base": ^1.1.3
|
"@scure/base": ^1.1.3
|
||||||
"@snort/shared": ^1.0.10
|
"@snort/shared": ^1.0.10
|
||||||
"@snort/system": ^1.1.7
|
"@snort/system": ^1.1.8
|
||||||
"@snort/system-react": ^1.1.7
|
"@snort/system-react": ^1.1.8
|
||||||
"@snort/system-wasm": ^1.0.1
|
"@snort/system-wasm": ^1.0.1
|
||||||
"@snort/system-web": ^1.0.2
|
"@snort/system-web": ^1.0.2
|
||||||
"@szhsin/react-menu": ^4.0.2
|
"@szhsin/react-menu": ^4.0.2
|
||||||
|
Loading…
Reference in New Issue
Block a user