1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206 | /**
* The deep-import surface: names the v1.3.0 file tree exported that the package
* ROOT never did.
*
* These are declared here, not in types/index.d.ts, for a reason that matters:
* `dist/index.js` genuinely does not export them, so declaring them on the root
* would let `import { boardStateOf } from "ardegazu-peer-kit"` type-check and
* then fail at runtime. Each deep declaration file re-exports from whichever of
* `index.js` / `internals.js` actually provides the name — mirroring
* scripts/gen-subpaths.mjs, and checked against the real module exports by
* test/subpaths.test.mjs.
*/
import type { ActivePiece, BoardState, Cell, PeerIdent, PieceType, RelayInfo } from "./index.js";
import type { Libp2p } from "libp2p";
/* ------------------------------------------------------- core/room-crypto -- */
/** Bytes always backed by a plain ArrayBuffer (what WebCrypto's types demand). */
export type Bytes = Uint8Array;
export interface Envelope {
v: 2;
iv: string;
ct: string;
}
/** All derivations for one room; peer ids are libp2p PeerId base58 strings. */
export declare class RoomCrypto {
readonly roomId: string;
static create(secretB64url: string, appSalt: string): Promise<RoomCrypto>;
/**
* Seal my hello for `to`. `extra` fields ride inside the sealed plaintext
* next to `v` — old clients validate only `v === 2` and ignore them.
*/
sealHello(from: string, to: string, extra?: Record<string, unknown>): Promise<Envelope>;
/** The decrypted plaintext, or null when it isn't a valid room hello. */
openHello(from: string, to: string, env: Envelope): Promise<Record<string, unknown> | null>;
}
export declare function randomBytes(n: number): Bytes;
export declare function toB64(bytes: Bytes): string;
export declare function fromB64(s: string): Bytes;
export declare function toB64url(bytes: Bytes): string;
export declare function fromB64url(s: string): Bytes;
/* -------------------------------------- core/bootstrap, core/turn, core/node */
export declare function fetchRelayInfo(
descriptorUrl: string,
fallback: RelayInfo,
timeoutMs?: number,
): Promise<RelayInfo>;
/** Ephemeral TURN credentials, cached until 5 minutes before expiry. */
export declare class IceConfig {
constructor(endpoint: string, forceRelay?: boolean);
get(): Promise<RTCConfiguration>;
}
export declare class NetNode {
readonly node: Libp2p;
readonly relayId: string;
/** True when the WebRTC transport actually loaded in this runtime. */
readonly webrtcEnabled: boolean;
static create(relay: RelayInfo, ice: IceConfig, opts?: { webrtc?: boolean }): Promise<NetNode>;
relayConnected(): boolean;
/** Dial (or re-dial after a network flap) the relay. */
redialRelay(): Promise<void>;
}
/* -------------------------------------------------------------- core/peers -- */
export interface PeerEvents {
peerOpen(id: string): void;
peerGone(id: string): void;
message(from: string, payload: unknown): void;
membersChanged(members: string[]): void;
/** A member's suite identity verified (fired after peerOpen; best-effort). */
peerIdentity?(id: string, ident: PeerIdent): void;
}
/** My own hello identity block + the verifier for remote ones. */
export interface HelloIdentity {
/** Fields to embed in my sealed hello as `id`. */
mine: Record<string, unknown> | null;
/** Validate + verify a remote `id` block; null = invalid/absent. */
verify(peerId: string, id: unknown): Promise<PeerIdent | null>;
}
export declare class PeerManager {
readonly protocol: string;
constructor(
node: Libp2p,
rc: RoomCrypto,
relayId: string,
protocolPrefix: string,
ev: PeerEvents,
helloId?: HelloIdentity | null,
);
start(): Promise<void>;
members(): string[];
openPeers(): string[];
openCount(): number;
identityOf(id: string): PeerIdent | null;
sendTo(id: string, frame: unknown): void;
broadcast(frame: unknown): void;
/** Post-suspend kick: re-dial members whose streams died while we slept. */
wake(): void;
}
/* ---------------------------------------------------------------- node/env -- */
/**
* Every libp2p node this PROCESS runs, by peer id — shared across kits via a
* global so sibling nodes never dial each other.
*/
export declare function selfPeerIds(): Set<string>;
export declare function installOriginWebSocket(origin: string, hosts?: RegExp[]): void;
export declare function installOriginFetch(origin: string, hosts?: RegExp[]): void;
/* --------------------------------------------------------------- host/sim --- */
export declare const NO_EMIT: { frames: never[] };
/* -------------------------------------------------------- host/seance-sim --- */
export declare const CANDLES: number;
export declare const REVEAL_MS: number;
/** Walk-phase duration: 25s on the first bell, shrinking to a 12s floor. */
export declare function walkMs(bell: number): number;
export declare const START_BELL_MS: number;
export declare const OVER_LOBBY_MS: number;
/** Grace beyond the client countdown so last-second taps still land. */
export declare const PICK_GRACE_MS: number;
/* ----------------------------------------------------- host/neon-grid-sim --- */
export declare const GW: number;
export declare const GH: number;
export declare const WIN_SCORE: number;
/** 0=up 1=right 2=down 3=left */
export declare const DX: readonly number[];
export declare const DY: readonly number[];
export declare const COUNTDOWN_MS: number;
export declare const OVER_ROUND_MS: number;
export declare const OVER_MATCH_MS: number;
export declare const MATCH_LOBBY_MS: number;
/* -------------------------------------------------- host/valley-blocks-core - */
export declare const PIECE_TYPES: PieceType[];
export declare function cellsFor(
type: PieceType,
rotation: number,
): ReadonlyArray<readonly [number, number]>;
export declare function kicksFor(
type: PieceType,
from: number,
cw: boolean,
): ReadonlyArray<readonly [number, number]>;
export declare class Board {
grid: Cell[][];
collides(piece: ActivePiece): boolean;
lock(piece: ActivePiece): void;
/** Removes full rows and returns the indices (in grid space) that cleared. */
clearLines(): number[];
/** True when locked cells reach into the hidden spawn rows. */
isToppedOut(): boolean;
}
/** 7-bag randomizer: each set of 7 pieces contains every tetromino once. */
export declare class Bag {
constructor(rng: () => number);
next(): PieceType;
peek(count: number): PieceType[];
}
export declare const COLS: number;
export declare const ROWS: number;
export declare const HIDDEN_ROWS: number;
export declare const TOTAL_ROWS: number;
export declare const LINES_PER_LEVEL: number;
export declare function pointsForLines(lines: number, level: number): number;
export declare const SOFT_DROP_POINTS: number;
export declare const HARD_DROP_POINTS: number;
/** Seconds a piece takes to fall one row at a given level. */
export declare function gravitySeconds(level: number): number;
export declare function levelForLines(lines: number): number;
export declare function snakeInterval(level: number): number;
export declare function snakeDuration(level: number): number;
/* ---------------------------------------------- host/valley-blocks-protocol - */
export declare const MAX_PLAYERS: number;
export declare const STATE_INTERVAL_MS: number;
export declare const PING_INTERVAL_MS: number;
export declare function serializeGrid(grid: Cell[][]): string;
export declare function boardStateOf(game: import("./index.js").ValleyBlocksEngine): BoardState;
/* --------------------------------------------------- host/valley-blocks-sim - */
/** Roundover interstitial before the host returns everyone to the lobby. */
export declare const ROUND_LOBBY_MS: number;
export declare const DEFAULT_MODE: import("./index.js").PartyMode;
export declare const DEFAULT_TARGET: number;
|