@flayerlabs/gamemode-client 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +9 -0
- package/README.md +93 -0
- package/dist/embed.d.ts +45 -0
- package/dist/embed.d.ts.map +1 -0
- package/dist/embed.js +329 -0
- package/dist/embed.js.map +1 -0
- package/dist/identity.d.ts +13 -0
- package/dist/identity.d.ts.map +1 -0
- package/dist/identity.js +49 -0
- package/dist/identity.js.map +1 -0
- package/dist/index.d.ts +144 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/live.d.ts +59 -0
- package/dist/live.d.ts.map +1 -0
- package/dist/live.js +526 -0
- package/dist/live.js.map +1 -0
- package/dist/mock.d.ts +55 -0
- package/dist/mock.d.ts.map +1 -0
- package/dist/mock.js +216 -0
- package/dist/mock.js.map +1 -0
- package/dist/replay-market.d.ts +61 -0
- package/dist/replay-market.d.ts.map +1 -0
- package/dist/replay-market.js +99 -0
- package/dist/replay-market.js.map +1 -0
- package/dist/signal.d.ts +11 -0
- package/dist/signal.d.ts.map +1 -0
- package/dist/signal.js +27 -0
- package/dist/signal.js.map +1 -0
- package/package.json +53 -0
- package/src/embed.ts +395 -0
- package/src/identity.ts +51 -0
- package/src/index.ts +172 -0
- package/src/live.ts +609 -0
- package/src/mock.ts +249 -0
- package/src/replay-market.ts +150 -0
- package/src/signal.ts +26 -0
package/dist/live.js
ADDED
|
@@ -0,0 +1,526 @@
|
|
|
1
|
+
import { LIVE_PROTOCOL_VERSION, isReactionId, isLaunchContext, } from '@flayerlabs/gamemode-spec/live';
|
|
2
|
+
import { Signal } from './signal.js';
|
|
3
|
+
import { CachedIdentityResolver } from './identity.js';
|
|
4
|
+
/** Long enough not to hammer a gate that is restarting, short enough to feel instant. */
|
|
5
|
+
const RECONNECT_MS = 1_000;
|
|
6
|
+
const FIRST_SNAPSHOT_TIMEOUT_MS = 15_000;
|
|
7
|
+
export async function joinRoom(options) {
|
|
8
|
+
const room = new LiveRoom(options);
|
|
9
|
+
try {
|
|
10
|
+
await room.start();
|
|
11
|
+
return room;
|
|
12
|
+
}
|
|
13
|
+
catch (error) {
|
|
14
|
+
room.dispose();
|
|
15
|
+
throw error;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
class LiveRoom {
|
|
19
|
+
options;
|
|
20
|
+
socket = null;
|
|
21
|
+
token = null;
|
|
22
|
+
me = null;
|
|
23
|
+
latest = null;
|
|
24
|
+
/** Server time minus our time. Every countdown is drawn through this. */
|
|
25
|
+
skew = 0;
|
|
26
|
+
closed = false;
|
|
27
|
+
claimSequence = 0;
|
|
28
|
+
balanceRevision = 0;
|
|
29
|
+
activeBuy = null;
|
|
30
|
+
initialSnapshot;
|
|
31
|
+
resolveInitialSnapshot;
|
|
32
|
+
rejectInitialSnapshot;
|
|
33
|
+
connectionSignal = new Signal('connecting');
|
|
34
|
+
launchSignal;
|
|
35
|
+
economySignal = new Signal(emptyEconomy());
|
|
36
|
+
marketSignal;
|
|
37
|
+
presenceSignal = new Signal({ connectedCount: 1 });
|
|
38
|
+
stopMarket;
|
|
39
|
+
listeners = new Set();
|
|
40
|
+
reactionListeners = new Set();
|
|
41
|
+
/** Told when the connection is unhappy, so a game can say so rather than look frozen. */
|
|
42
|
+
trouble = null;
|
|
43
|
+
identity;
|
|
44
|
+
constructor(options) {
|
|
45
|
+
this.options = options;
|
|
46
|
+
this.initialSnapshot = new Promise((resolve, reject) => {
|
|
47
|
+
this.resolveInitialSnapshot = resolve;
|
|
48
|
+
this.rejectInitialSnapshot = reject;
|
|
49
|
+
});
|
|
50
|
+
this.launchSignal = new Signal(options.launch ? immutableLaunch(options.launch) : null);
|
|
51
|
+
this.marketSignal = new Signal(options.platform?.market?.current() ?? { status: 'unavailable', prices: [], trades: [], marketCapUsd: null });
|
|
52
|
+
this.stopMarket = options.platform?.market?.subscribe((state) => this.marketSignal.set(state)) ?? (() => { });
|
|
53
|
+
this.identity = new CachedIdentityResolver(options.platform?.identity);
|
|
54
|
+
}
|
|
55
|
+
async start() {
|
|
56
|
+
const address = await this.options.host.address();
|
|
57
|
+
if (!address)
|
|
58
|
+
throw new NoWallet();
|
|
59
|
+
const challenge = await this.post('/session/challenge', { address });
|
|
60
|
+
const signature = await this.options.host.signIn(challenge.message);
|
|
61
|
+
const evidence = await this.options.host.sessionEvidence?.();
|
|
62
|
+
const session = await this.post('/session', {
|
|
63
|
+
address,
|
|
64
|
+
signature,
|
|
65
|
+
nonce: challenge.nonce,
|
|
66
|
+
...(evidence === undefined ? {} : { evidence }),
|
|
67
|
+
});
|
|
68
|
+
this.token = session.token;
|
|
69
|
+
this.me = address.toLowerCase();
|
|
70
|
+
await this.post(`/rounds/${this.options.roundId}/join`, {});
|
|
71
|
+
this.connect();
|
|
72
|
+
let timeout;
|
|
73
|
+
try {
|
|
74
|
+
await Promise.race([
|
|
75
|
+
this.initialSnapshot,
|
|
76
|
+
new Promise((_, reject) => {
|
|
77
|
+
timeout = setTimeout(() => reject(new Error('the room did not send its first snapshot in time')), FIRST_SNAPSHOT_TIMEOUT_MS);
|
|
78
|
+
}),
|
|
79
|
+
]);
|
|
80
|
+
if (this.launchSignal.current() === null) {
|
|
81
|
+
throw new Error('the room did not provide launch context');
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
this.dispose();
|
|
86
|
+
throw error;
|
|
87
|
+
}
|
|
88
|
+
finally {
|
|
89
|
+
if (timeout !== undefined)
|
|
90
|
+
clearTimeout(timeout);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
connect() {
|
|
94
|
+
if (this.closed)
|
|
95
|
+
return;
|
|
96
|
+
const url = new URL(`/rounds/${this.options.roundId}/live`, this.options.gateUrl);
|
|
97
|
+
url.protocol = url.protocol === 'https:' ? 'wss:' : 'ws:';
|
|
98
|
+
if (this.token)
|
|
99
|
+
url.searchParams.set('token', this.token);
|
|
100
|
+
const socket = new WebSocket(url.toString());
|
|
101
|
+
this.socket = socket;
|
|
102
|
+
socket.onmessage = (event) => this.receive(String(event.data));
|
|
103
|
+
// Without this a failed upgrade is silent, and the game shows an empty room forever with
|
|
104
|
+
// nothing anywhere saying why.
|
|
105
|
+
socket.onerror = () => {
|
|
106
|
+
if (!this.closed)
|
|
107
|
+
this.connectionSignal.set('reconnecting');
|
|
108
|
+
this.trouble?.('connection');
|
|
109
|
+
};
|
|
110
|
+
// A dropped socket is normal — a laptop lid, a tunnel, a deploy. Reconnecting silently and
|
|
111
|
+
// taking a fresh snapshot is the whole recovery story, because the gate sends whole state.
|
|
112
|
+
socket.onclose = (event) => {
|
|
113
|
+
if (this.socket === socket)
|
|
114
|
+
this.socket = null;
|
|
115
|
+
if (this.closed)
|
|
116
|
+
return;
|
|
117
|
+
if (event.code === 4009 || event.code === 4409) {
|
|
118
|
+
this.closed = true;
|
|
119
|
+
this.connectionSignal.set('superseded');
|
|
120
|
+
this.rejectInitialSnapshot(new Error('this room connection was superseded'));
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
if (event.code === 4404 || event.code === 4410) {
|
|
124
|
+
this.closed = true;
|
|
125
|
+
this.connectionSignal.set('ended');
|
|
126
|
+
this.rejectInitialSnapshot(new Error('this room has ended'));
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
this.connectionSignal.set('reconnecting');
|
|
130
|
+
setTimeout(() => this.connect(), RECONNECT_MS);
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
receive(data) {
|
|
134
|
+
let frame;
|
|
135
|
+
try {
|
|
136
|
+
const parsed = JSON.parse(data);
|
|
137
|
+
if (typeof parsed !== 'object' || parsed === null)
|
|
138
|
+
return;
|
|
139
|
+
frame = parsed;
|
|
140
|
+
}
|
|
141
|
+
catch {
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
if (frame.type === 'reaction') {
|
|
145
|
+
const reaction = reactionFrom(frame.reaction);
|
|
146
|
+
if (reaction)
|
|
147
|
+
for (const listener of this.reactionListeners)
|
|
148
|
+
listener(reaction);
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
if (frame.type === 'market') {
|
|
152
|
+
const market = marketFrom(frame.market);
|
|
153
|
+
if (market)
|
|
154
|
+
this.marketSignal.set(market);
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
if (frame.type === 'presence') {
|
|
158
|
+
const presence = presenceFrom(frame.presence);
|
|
159
|
+
if (presence)
|
|
160
|
+
this.presenceSignal.set(presence);
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
if (frame.type !== undefined && frame.type !== 'snapshot')
|
|
164
|
+
return;
|
|
165
|
+
if (typeof frame.now === 'number')
|
|
166
|
+
this.skew = frame.now - Date.now();
|
|
167
|
+
const economy = economyFrom(frame.economy);
|
|
168
|
+
if (economy)
|
|
169
|
+
this.setBalance(economy);
|
|
170
|
+
if (this.launchSignal.current() === null && isLaunchContext(frame.launch)) {
|
|
171
|
+
this.launchSignal.set(immutableLaunch(frame.launch));
|
|
172
|
+
}
|
|
173
|
+
const presence = presenceFrom(frame.presence);
|
|
174
|
+
if (presence)
|
|
175
|
+
this.presenceSignal.set(presence);
|
|
176
|
+
if (!('view' in frame))
|
|
177
|
+
return;
|
|
178
|
+
this.latest = { publicView: frame.view, playerView: (frame.you ?? null) };
|
|
179
|
+
this.connectionSignal.set('connected');
|
|
180
|
+
for (const listener of this.listeners)
|
|
181
|
+
listener(this.latest);
|
|
182
|
+
this.resolveInitialSnapshot();
|
|
183
|
+
}
|
|
184
|
+
async post(path, body) {
|
|
185
|
+
const response = await fetch(new URL(path, this.options.gateUrl), {
|
|
186
|
+
method: 'POST',
|
|
187
|
+
headers: {
|
|
188
|
+
'content-type': 'application/json',
|
|
189
|
+
...(this.token ? { authorization: `Bearer ${this.token}` } : {}),
|
|
190
|
+
},
|
|
191
|
+
body: JSON.stringify(body),
|
|
192
|
+
});
|
|
193
|
+
const payload = await response.json().catch(() => ({}));
|
|
194
|
+
if (!response.ok)
|
|
195
|
+
throw new GateRefused(response.status, payload);
|
|
196
|
+
return payload;
|
|
197
|
+
}
|
|
198
|
+
subscribe(listener) {
|
|
199
|
+
this.listeners.add(listener);
|
|
200
|
+
if (this.latest)
|
|
201
|
+
listener(this.latest);
|
|
202
|
+
return () => this.listeners.delete(listener);
|
|
203
|
+
}
|
|
204
|
+
launch = {
|
|
205
|
+
current: () => this.requiredLaunch(),
|
|
206
|
+
subscribe: (listener) => this.launchSignal.subscribe((value) => {
|
|
207
|
+
if (value)
|
|
208
|
+
listener(value);
|
|
209
|
+
}),
|
|
210
|
+
};
|
|
211
|
+
connection = {
|
|
212
|
+
current: () => this.connectionSignal.current(),
|
|
213
|
+
subscribe: (listener) => this.connectionSignal.subscribe(listener),
|
|
214
|
+
};
|
|
215
|
+
market = {
|
|
216
|
+
current: () => this.marketSignal.current(),
|
|
217
|
+
subscribe: (listener) => this.marketSignal.subscribe(listener),
|
|
218
|
+
};
|
|
219
|
+
presence = {
|
|
220
|
+
current: () => this.presenceSignal.current(),
|
|
221
|
+
subscribe: (listener) => this.presenceSignal.subscribe(listener),
|
|
222
|
+
};
|
|
223
|
+
async send(action) {
|
|
224
|
+
try {
|
|
225
|
+
await this.post(`/rounds/${this.options.roundId}/actions`, { action });
|
|
226
|
+
return { accepted: true };
|
|
227
|
+
}
|
|
228
|
+
catch (error) {
|
|
229
|
+
if (error instanceof GateRefused)
|
|
230
|
+
return { accepted: false, refuse: error.refuse };
|
|
231
|
+
throw error;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
now() {
|
|
235
|
+
return Date.now() + this.skew;
|
|
236
|
+
}
|
|
237
|
+
economy = {
|
|
238
|
+
current: () => this.economySignal.current(),
|
|
239
|
+
subscribe: (listener) => this.economySignal.subscribe(listener),
|
|
240
|
+
available: () => this.economySignal.current().availableWei,
|
|
241
|
+
buy: (maxSpendWei) => this.buy(maxSpendWei),
|
|
242
|
+
};
|
|
243
|
+
async buy(maxSpendWei) {
|
|
244
|
+
// Set the token before the first await. Two clicks in the same turn must not both reserve the
|
|
245
|
+
// same allowance, and the losing call must not replace the lifecycle the active call renders.
|
|
246
|
+
if (this.activeBuy !== null)
|
|
247
|
+
return { bought: false, reason: 'try-again' };
|
|
248
|
+
const attempt = Symbol('buy');
|
|
249
|
+
this.activeBuy = attempt;
|
|
250
|
+
try {
|
|
251
|
+
return await this.performBuy(maxSpendWei, attempt);
|
|
252
|
+
}
|
|
253
|
+
finally {
|
|
254
|
+
if (this.activeBuy === attempt)
|
|
255
|
+
this.activeBuy = null;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
async performBuy(maxSpendWei, attempt) {
|
|
259
|
+
if (maxSpendWei <= 0n)
|
|
260
|
+
return this.failBuy(attempt, 'nothing-to-spend');
|
|
261
|
+
const balanceRevision = this.balanceRevision;
|
|
262
|
+
const requestId = this.nextRequestId();
|
|
263
|
+
let authorisation;
|
|
264
|
+
try {
|
|
265
|
+
authorisation = await this.postClaim(`/rounds/${this.options.roundId}/claim`, {
|
|
266
|
+
maxSpendWei: maxSpendWei.toString(),
|
|
267
|
+
requestId,
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
catch (error) {
|
|
271
|
+
if (error instanceof GateRefused)
|
|
272
|
+
return this.failBuy(attempt, claimFailure(error.refuse));
|
|
273
|
+
return this.failBuy(attempt, 'try-again');
|
|
274
|
+
}
|
|
275
|
+
let spendWei;
|
|
276
|
+
try {
|
|
277
|
+
spendWei = BigInt(authorisation.maxSpendWei);
|
|
278
|
+
}
|
|
279
|
+
catch {
|
|
280
|
+
return this.failBuy(attempt, 'try-again');
|
|
281
|
+
}
|
|
282
|
+
if (this.activeBuy !== attempt)
|
|
283
|
+
return { bought: false, reason: 'try-again' };
|
|
284
|
+
const before = this.economySignal.current();
|
|
285
|
+
this.economySignal.set({
|
|
286
|
+
...before,
|
|
287
|
+
...(this.balanceRevision === balanceRevision
|
|
288
|
+
? {
|
|
289
|
+
heldWei: before.heldWei + spendWei,
|
|
290
|
+
availableWei: before.availableWei > spendWei ? before.availableWei - spendWei : 0n,
|
|
291
|
+
}
|
|
292
|
+
: {}),
|
|
293
|
+
buy: { state: 'signing', spendWei },
|
|
294
|
+
});
|
|
295
|
+
let transactionHash;
|
|
296
|
+
let hostSettled = false;
|
|
297
|
+
// The page builds and submits. This game has no way to say what the transaction should be.
|
|
298
|
+
let result;
|
|
299
|
+
try {
|
|
300
|
+
result = await this.options.host.buy(authorisation, (progress) => {
|
|
301
|
+
if (hostSettled || this.activeBuy !== attempt)
|
|
302
|
+
return;
|
|
303
|
+
transactionHash = progress.transactionHash;
|
|
304
|
+
const current = this.economySignal.current();
|
|
305
|
+
this.economySignal.set({
|
|
306
|
+
...current,
|
|
307
|
+
buy: transactionHash === undefined
|
|
308
|
+
? { state: 'pending', spendWei }
|
|
309
|
+
: { state: 'pending', spendWei, transactionHash },
|
|
310
|
+
});
|
|
311
|
+
});
|
|
312
|
+
hostSettled = true;
|
|
313
|
+
}
|
|
314
|
+
catch {
|
|
315
|
+
hostSettled = true;
|
|
316
|
+
return this.failBuy(attempt, 'try-again');
|
|
317
|
+
}
|
|
318
|
+
if ('failed' in result) {
|
|
319
|
+
if (result.failed.bought)
|
|
320
|
+
return this.failBuy(attempt, 'try-again');
|
|
321
|
+
return this.failBuy(attempt, result.failed.reason);
|
|
322
|
+
}
|
|
323
|
+
if (this.activeBuy !== attempt)
|
|
324
|
+
return { bought: false, reason: 'try-again' };
|
|
325
|
+
const current = this.economySignal.current();
|
|
326
|
+
const confirmed = transactionHash === undefined
|
|
327
|
+
? { state: 'confirmed', spentWei: result.spentWei }
|
|
328
|
+
: { state: 'confirmed', spentWei: result.spentWei, transactionHash };
|
|
329
|
+
// The signed allowance remains held until the gate observes chain settlement or it expires.
|
|
330
|
+
this.economySignal.set({ ...current, buy: confirmed });
|
|
331
|
+
return { bought: true, spentWei: result.spentWei };
|
|
332
|
+
}
|
|
333
|
+
social = {
|
|
334
|
+
react: (id) => {
|
|
335
|
+
if (!isReactionId(id))
|
|
336
|
+
return;
|
|
337
|
+
this.sendFrame({ v: LIVE_PROTOCOL_VERSION, type: 'reaction', id });
|
|
338
|
+
},
|
|
339
|
+
onReaction: (listener) => {
|
|
340
|
+
this.reactionListeners.add(listener);
|
|
341
|
+
return () => this.reactionListeners.delete(listener);
|
|
342
|
+
},
|
|
343
|
+
};
|
|
344
|
+
dispose() {
|
|
345
|
+
this.closed = true;
|
|
346
|
+
this.activeBuy = null;
|
|
347
|
+
this.socket?.close();
|
|
348
|
+
this.connectionSignal.set('ended');
|
|
349
|
+
this.stopMarket();
|
|
350
|
+
this.listeners.clear();
|
|
351
|
+
this.reactionListeners.clear();
|
|
352
|
+
this.connectionSignal.clear();
|
|
353
|
+
this.launchSignal.clear();
|
|
354
|
+
this.economySignal.clear();
|
|
355
|
+
this.marketSignal.clear();
|
|
356
|
+
this.presenceSignal.clear();
|
|
357
|
+
}
|
|
358
|
+
setBalance(balance) {
|
|
359
|
+
this.balanceRevision += 1;
|
|
360
|
+
this.economySignal.set({ ...balance, buy: this.economySignal.current().buy });
|
|
361
|
+
}
|
|
362
|
+
failBuy(attempt, reason) {
|
|
363
|
+
if (this.activeBuy === attempt) {
|
|
364
|
+
const current = this.economySignal.current();
|
|
365
|
+
this.economySignal.set({ ...current, buy: { state: 'failed', reason } });
|
|
366
|
+
}
|
|
367
|
+
return { bought: false, reason };
|
|
368
|
+
}
|
|
369
|
+
nextRequestId() {
|
|
370
|
+
this.claimSequence += 1;
|
|
371
|
+
return `${globalThis.crypto.randomUUID()}:${this.claimSequence}`;
|
|
372
|
+
}
|
|
373
|
+
requiredLaunch() {
|
|
374
|
+
const launch = this.launchSignal.current();
|
|
375
|
+
if (launch === null)
|
|
376
|
+
throw new Error('launch context is not ready');
|
|
377
|
+
return launch;
|
|
378
|
+
}
|
|
379
|
+
/** Claims are idempotent by request id, so a lost response can be retried exactly once. */
|
|
380
|
+
async postClaim(path, body) {
|
|
381
|
+
try {
|
|
382
|
+
return await this.post(path, body);
|
|
383
|
+
}
|
|
384
|
+
catch (error) {
|
|
385
|
+
if (error instanceof GateRefused && error.status < 500)
|
|
386
|
+
throw error;
|
|
387
|
+
return this.post(path, body);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
sendFrame(frame) {
|
|
391
|
+
if (this.socket?.readyState === WebSocket.OPEN)
|
|
392
|
+
this.socket.send(JSON.stringify(frame));
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
function emptyEconomy() {
|
|
396
|
+
return {
|
|
397
|
+
weiPerPoint: 0n,
|
|
398
|
+
earnedWei: 0n,
|
|
399
|
+
heldWei: 0n,
|
|
400
|
+
spentWei: 0n,
|
|
401
|
+
availableWei: 0n,
|
|
402
|
+
holdExpiresAt: null,
|
|
403
|
+
buy: null,
|
|
404
|
+
};
|
|
405
|
+
}
|
|
406
|
+
function economyFrom(input) {
|
|
407
|
+
if (typeof input !== 'object' || input === null)
|
|
408
|
+
return null;
|
|
409
|
+
const value = input;
|
|
410
|
+
try {
|
|
411
|
+
const amounts = {
|
|
412
|
+
weiPerPoint: BigInt(value.weiPerPoint ?? '0'),
|
|
413
|
+
earnedWei: BigInt(value.earnedWei ?? '-1'),
|
|
414
|
+
heldWei: BigInt(value.heldWei ?? '-1'),
|
|
415
|
+
spentWei: BigInt(value.spentWei ?? '-1'),
|
|
416
|
+
availableWei: BigInt(value.availableWei ?? '-1'),
|
|
417
|
+
};
|
|
418
|
+
if (amounts.weiPerPoint <= 0n || Object.values(amounts).some((amount) => amount < 0n))
|
|
419
|
+
return null;
|
|
420
|
+
// A deadline is either a whole millisecond timestamp or absent. Anything else — a string, a
|
|
421
|
+
// fraction, Infinity — is a malformed frame, and a countdown drawn from one would run to a
|
|
422
|
+
// moment that never arrives.
|
|
423
|
+
const holdExpiresAt = value.holdExpiresAt;
|
|
424
|
+
if (holdExpiresAt !== null && holdExpiresAt !== undefined && !Number.isSafeInteger(holdExpiresAt)) {
|
|
425
|
+
return null;
|
|
426
|
+
}
|
|
427
|
+
return { ...amounts, holdExpiresAt: holdExpiresAt ?? null };
|
|
428
|
+
}
|
|
429
|
+
catch {
|
|
430
|
+
return null;
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
function presenceFrom(input) {
|
|
434
|
+
if (typeof input !== 'object' || input === null)
|
|
435
|
+
return null;
|
|
436
|
+
const value = input;
|
|
437
|
+
if (typeof value.connectedCount !== 'number' ||
|
|
438
|
+
!Number.isSafeInteger(value.connectedCount) ||
|
|
439
|
+
value.connectedCount < 0)
|
|
440
|
+
return null;
|
|
441
|
+
return { connectedCount: value.connectedCount };
|
|
442
|
+
}
|
|
443
|
+
function reactionFrom(input) {
|
|
444
|
+
if (typeof input !== 'object' || input === null)
|
|
445
|
+
return null;
|
|
446
|
+
const value = input;
|
|
447
|
+
return typeof value.player === 'string' && typeof value.id === 'string' && isReactionId(value.id)
|
|
448
|
+
? { player: value.player, id: value.id }
|
|
449
|
+
: null;
|
|
450
|
+
}
|
|
451
|
+
export function marketFrom(input) {
|
|
452
|
+
if (typeof input !== 'object' || input === null)
|
|
453
|
+
return null;
|
|
454
|
+
const value = input;
|
|
455
|
+
if (!['unavailable', 'loading', 'live', 'stale'].includes(String(value.status)))
|
|
456
|
+
return null;
|
|
457
|
+
if (!Array.isArray(value.prices) ||
|
|
458
|
+
!Array.isArray(value.trades) ||
|
|
459
|
+
value.prices.length > 1_000 ||
|
|
460
|
+
value.trades.length > 500)
|
|
461
|
+
return null;
|
|
462
|
+
const prices = value.prices.filter((price) => typeof price?.at === 'number' &&
|
|
463
|
+
Number.isFinite(price.at) &&
|
|
464
|
+
typeof price.priceEth === 'number' &&
|
|
465
|
+
Number.isFinite(price.priceEth) &&
|
|
466
|
+
price.priceEth > 0);
|
|
467
|
+
const trades = value.trades.flatMap((trade) => {
|
|
468
|
+
try {
|
|
469
|
+
if (typeof trade?.id !== 'string' ||
|
|
470
|
+
typeof trade.at !== 'number' ||
|
|
471
|
+
!Number.isFinite(trade.at) ||
|
|
472
|
+
(trade.player !== null && typeof trade.player !== 'string') ||
|
|
473
|
+
(trade.side !== 'buy' && trade.side !== 'sell') ||
|
|
474
|
+
(trade.priceEth !== null && (typeof trade.priceEth !== 'number' || !Number.isFinite(trade.priceEth))))
|
|
475
|
+
return [];
|
|
476
|
+
const spendWei = BigInt(trade.spendWei);
|
|
477
|
+
if (spendWei < 0n)
|
|
478
|
+
return [];
|
|
479
|
+
return [{
|
|
480
|
+
id: trade.id,
|
|
481
|
+
at: trade.at,
|
|
482
|
+
player: trade.player,
|
|
483
|
+
side: trade.side,
|
|
484
|
+
spendWei,
|
|
485
|
+
priceEth: trade.priceEth,
|
|
486
|
+
...(typeof trade.transactionHash === 'string' ? { transactionHash: trade.transactionHash } : {}),
|
|
487
|
+
}];
|
|
488
|
+
}
|
|
489
|
+
catch {
|
|
490
|
+
return [];
|
|
491
|
+
}
|
|
492
|
+
});
|
|
493
|
+
const marketCapUsd = typeof value.marketCapUsd === 'number' && Number.isFinite(value.marketCapUsd)
|
|
494
|
+
? value.marketCapUsd
|
|
495
|
+
: null;
|
|
496
|
+
return { status: value.status, prices, trades, marketCapUsd };
|
|
497
|
+
}
|
|
498
|
+
export function immutableLaunch(launch) {
|
|
499
|
+
return Object.freeze({ ...launch });
|
|
500
|
+
}
|
|
501
|
+
function claimFailure(refuse) {
|
|
502
|
+
if (refuse === 'claim.nothing_earned' || refuse === 'claim.nothing_available')
|
|
503
|
+
return 'nothing-to-spend';
|
|
504
|
+
if (refuse === 'claim.not_open_yet' || refuse === 'claim.window_closed')
|
|
505
|
+
return 'window-closed';
|
|
506
|
+
return 'try-again';
|
|
507
|
+
}
|
|
508
|
+
/** No wallet is connected to the page. A game should ask the player to connect one. */
|
|
509
|
+
export class NoWallet extends Error {
|
|
510
|
+
constructor() {
|
|
511
|
+
super('no wallet is connected');
|
|
512
|
+
this.name = 'NoWallet';
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
/** A refusal from the gate, carrying its stable code for the client to turn into words. */
|
|
516
|
+
class GateRefused extends Error {
|
|
517
|
+
status;
|
|
518
|
+
refuse;
|
|
519
|
+
constructor(status, payload) {
|
|
520
|
+
super(payload.message ?? payload.refuse ?? `request failed (${status})`);
|
|
521
|
+
this.status = status;
|
|
522
|
+
this.name = 'GateRefused';
|
|
523
|
+
this.refuse = payload.refuse ?? 'request.failed';
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
//# sourceMappingURL=live.js.map
|
package/dist/live.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"live.js","sourceRoot":"","sources":["../src/live.ts"],"names":[],"mappings":"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"}
|
package/dist/mock.d.ts
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { type GameModule } from '@flayerlabs/gamemode-spec';
|
|
2
|
+
import type { Economy, MockOptions, Room, SendResult, Snapshot, Social } from './index.js';
|
|
3
|
+
import { type ConnectionState, type LaunchContext, type MarketState, type PresenceState } from '@flayerlabs/gamemode-spec/live';
|
|
4
|
+
import { CachedIdentityResolver } from './identity.js';
|
|
5
|
+
export declare class MockRoom<Config, State, Event, Action, PublicView, PlayerView> implements Room<PublicView, PlayerView, Action> {
|
|
6
|
+
private readonly game;
|
|
7
|
+
private readonly round;
|
|
8
|
+
private readonly player;
|
|
9
|
+
private readonly weiPerPoint;
|
|
10
|
+
private readonly allowedReactions;
|
|
11
|
+
private readonly listeners;
|
|
12
|
+
private readonly reactionListeners;
|
|
13
|
+
private readonly timer;
|
|
14
|
+
private spentWei;
|
|
15
|
+
private heldWei;
|
|
16
|
+
/** Mirrors the gate's five-minute hold, so a game can build the countdown against the mock. */
|
|
17
|
+
private holdExpiresAt;
|
|
18
|
+
private buyProgress;
|
|
19
|
+
private disposed;
|
|
20
|
+
private readonly connectionSignal;
|
|
21
|
+
private readonly launchSignal;
|
|
22
|
+
private readonly presenceSignal;
|
|
23
|
+
private readonly marketSignal;
|
|
24
|
+
private readonly stopMarket;
|
|
25
|
+
constructor(game: GameModule<Config, State, Event, Action, PublicView, PlayerView>, options: MockOptions<Config>);
|
|
26
|
+
private tick;
|
|
27
|
+
private emit;
|
|
28
|
+
subscribe(listener: (snapshot: Snapshot<PublicView, PlayerView>) => void): () => void;
|
|
29
|
+
send(action: Action): Promise<SendResult>;
|
|
30
|
+
now(): number;
|
|
31
|
+
readonly launch: {
|
|
32
|
+
current: () => LaunchContext;
|
|
33
|
+
subscribe: (listener: (value: LaunchContext) => void) => () => void;
|
|
34
|
+
};
|
|
35
|
+
readonly connection: {
|
|
36
|
+
current: () => ConnectionState;
|
|
37
|
+
subscribe: (listener: (value: ConnectionState) => void) => () => void;
|
|
38
|
+
};
|
|
39
|
+
readonly market: {
|
|
40
|
+
current: () => MarketState;
|
|
41
|
+
subscribe: (listener: (value: MarketState) => void) => () => void;
|
|
42
|
+
};
|
|
43
|
+
readonly identity: CachedIdentityResolver;
|
|
44
|
+
readonly presence: {
|
|
45
|
+
current: () => PresenceState;
|
|
46
|
+
subscribe: (listener: (value: PresenceState) => void) => () => void;
|
|
47
|
+
};
|
|
48
|
+
private economyState;
|
|
49
|
+
private readonly economySignal;
|
|
50
|
+
private publishEconomy;
|
|
51
|
+
readonly economy: Economy;
|
|
52
|
+
readonly social: Social;
|
|
53
|
+
dispose(): void;
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=mock.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mock.d.ts","sourceRoot":"","sources":["../src/mock.ts"],"names":[],"mappings":"AACA,OAAO,EAAa,KAAK,UAAU,EAAiB,MAAM,2BAA2B,CAAC;AACtF,OAAO,KAAK,EAA0B,OAAO,EAAgB,WAAW,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AACjI,OAAO,EAEL,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,aAAa,EAEnB,MAAM,gCAAgC,CAAC;AAExC,OAAO,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AAWvD,qBAAa,QAAQ,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,CACxE,YAAW,IAAI,CAAC,UAAU,EAAE,UAAU,EAAE,MAAM,CAAC;IAsB7C,OAAO,CAAC,QAAQ,CAAC,IAAI;IApBvB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA8D;IACpF,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAW;IAClC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAsB;IACvD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA4D;IACtF,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAoC;IACtE,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAiC;IACvD,OAAO,CAAC,QAAQ,CAAM;IACtB,OAAO,CAAC,OAAO,CAAM;IACrB,+FAA+F;IAC/F,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,WAAW,CAA4B;IAC/C,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAA4C;IAC7E,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAwB;IACrD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAoD;IACnF,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAsB;IACnD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAa;gBAGrB,IAAI,EAAE,UAAU,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,CAAC,EACvF,OAAO,EAAE,WAAW,CAAC,MAAM,CAAC;IAoC9B,OAAO,CAAC,IAAI;IAIZ,OAAO,CAAC,IAAI;IASZ,SAAS,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC,KAAK,IAAI,GAAG,MAAM,IAAI;IAQ/E,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAW/C,GAAG,IAAI,MAAM;IAMb,QAAQ,CAAC,MAAM;;8BAES,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI;MACpD;IAEF,QAAQ,CAAC,UAAU;;8BAEK,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI;MACtD;IAEF,QAAQ,CAAC,MAAM;;8BAES,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI;MAClD;IAEF,QAAQ,CAAC,QAAQ,EAAE,sBAAsB,CAAC;IAE1C,QAAQ,CAAC,QAAQ;;8BAEO,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI;MACpD;IAEF,OAAO,CAAC,YAAY;IAcpB,OAAO,CAAC,QAAQ,CAAC,aAAa,CAQ3B;IAEH,OAAO,CAAC,cAAc;IAItB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAkDvB;IAEF,QAAQ,CAAC,MAAM,EAAE,MAAM,CAUrB;IAEF,OAAO,IAAI,IAAI;CAahB"}
|