@flayerlabs/gamemode-client 0.4.1 → 0.4.2

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/dist/embed.d.ts CHANGED
@@ -1,4 +1,5 @@
1
- import type { Host } from './live.js';
1
+ import { type Host } from './live.js';
2
+ import type { MarketState, Readable } from './index.js';
2
3
  import { type EmbedContext } from '@flayerlabs/gamemode-spec/frame';
3
4
  /**
4
5
  * Where frames come from and go to. The default is the real window; tests inject a pair of these
@@ -20,6 +21,15 @@ export interface ConnectHostOptions {
20
21
  export interface EmbeddedHost {
21
22
  host: Host;
22
23
  context: EmbedContext;
24
+ /**
25
+ * The coin's market as the embedding page sees it, for `joinEconomy`'s `platform.market`.
26
+ *
27
+ * Always present, because "no market yet" is a state a chart can render — it starts
28
+ * `unavailable` and becomes `live` if and when the page pushes one. A page that never sends a
29
+ * `gm:market` frame leaves it `unavailable` forever, which is the honest answer and the one a
30
+ * game should draw an empty chart for rather than waiting on.
31
+ */
32
+ market: Readable<MarketState>;
23
33
  dispose(): void;
24
34
  }
25
35
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"embed.d.ts","sourceRoot":"","sources":["../src/embed.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAmB,MAAM,WAAW,CAAC;AAEvD,OAAO,EAIL,KAAK,YAAY,EAGlB,MAAM,iCAAiC,CAAC;AAuBzC;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,sFAAsF;IACtF,MAAM,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IACtF,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IACnD,2FAA2F;IAC3F,YAAY,IAAI,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,kBAAkB;IACjC,yEAAyE;IACzE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,aAAa,CAAC;CAC1B;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,IAAI,CAAC;IACX,OAAO,EAAE,YAAY,CAAC;IACtB,OAAO,IAAI,IAAI,CAAC;CACjB;AAqCD;;;;;;;GAOG;AACH,wBAAsB,WAAW,CAAC,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CA6HhG"}
1
+ {"version":3,"file":"embed.d.ts","sourceRoot":"","sources":["../src/embed.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,IAAI,EAAwB,MAAM,WAAW,CAAC;AACxE,OAAO,KAAK,EAAa,WAAW,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEnE,OAAO,EAIL,KAAK,YAAY,EAGlB,MAAM,iCAAiC,CAAC;AAuBzC;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,sFAAsF;IACtF,MAAM,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IACtF,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IACnD,2FAA2F;IAC3F,YAAY,IAAI,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,kBAAkB;IACjC,yEAAyE;IACzE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,aAAa,CAAC;CAC1B;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,IAAI,CAAC;IACX,OAAO,EAAE,YAAY,CAAC;IACtB;;;;;;;OAOG;IACH,MAAM,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC;IAC9B,OAAO,IAAI,IAAI,CAAC;CACjB;AAqCD;;;;;;;GAOG;AACH,wBAAsB,WAAW,CAAC,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CA8IhG"}
package/dist/embed.js CHANGED
@@ -1,3 +1,5 @@
1
+ import { marketFrom } from './live.js';
2
+ import { Signal } from './signal.js';
1
3
  import { FRAME_PROTOCOL_VERSION, hostFrameFrom, } from '@flayerlabs/gamemode-spec/frame';
2
4
  /**
3
5
  * The game's end of the frame protocol: a {@link Host} reconstructed over `postMessage`.
@@ -61,6 +63,12 @@ export async function connectHost(options = {}) {
61
63
  const parent = endpoint.parentSource();
62
64
  if (parent === null)
63
65
  return null;
66
+ const marketSignal = new Signal({
67
+ status: 'unavailable',
68
+ prices: [],
69
+ trades: [],
70
+ marketCapUsd: null,
71
+ });
64
72
  const pending = new Map();
65
73
  let unlisten = () => { };
66
74
  let disposed = false;
@@ -95,6 +103,12 @@ export async function connectHost(options = {}) {
95
103
  resolveContext(frame.context);
96
104
  return;
97
105
  }
106
+ if (frame.type === 'gm:market') {
107
+ const market = marketFrom(frame.market);
108
+ if (market)
109
+ marketSignal.set(market);
110
+ return;
111
+ }
98
112
  if (frame.type === 'gm:progress') {
99
113
  const request = pending.get(frame.id);
100
114
  if (request?.kind === 'buy') {
@@ -168,10 +182,15 @@ export async function connectHost(options = {}) {
168
182
  return {
169
183
  host,
170
184
  context,
185
+ market: {
186
+ current: () => marketSignal.current(),
187
+ subscribe: (listener) => marketSignal.subscribe(listener),
188
+ },
171
189
  dispose() {
172
190
  disposed = true;
173
191
  unlisten();
174
192
  pending.clear();
193
+ marketSignal.clear();
175
194
  },
176
195
  };
177
196
  }
package/dist/embed.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"embed.js","sourceRoot":"","sources":["../src/embed.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"embed.js","sourceRoot":"","sources":["../src/embed.ts"],"names":[],"mappings":"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"}
package/dist/host.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import type { Host } from './live.js';
2
2
  import { type EmbedContext, type HostErrorCode } from '@flayerlabs/gamemode-spec/frame';
3
+ import type { WireMarketState } from '@flayerlabs/gamemode-spec/live';
3
4
  /**
4
5
  * The page's end of the frame protocol: service a game iframe's Host calls.
5
6
  *
@@ -31,6 +32,18 @@ export interface PostTarget {
31
32
  export interface HostListenSource {
32
33
  listen(handler: (data: unknown, origin: string, source: unknown) => void): () => void;
33
34
  }
35
+ /**
36
+ * The page's live market, if it has one to share.
37
+ *
38
+ * Structurally a `Signal` (and anything else with these two methods), so a page that already
39
+ * keeps its chart in an observable hands the same one over rather than building a second.
40
+ * `current()` may answer null: "I have no market yet" is not the same claim as an `unavailable`
41
+ * market, and a page should not have to invent one to attach a host.
42
+ */
43
+ export interface MarketSource {
44
+ current(): WireMarketState | null;
45
+ subscribe(listener: (market: WireMarketState) => void): () => void;
46
+ }
34
47
  export interface AttachGameHostOptions {
35
48
  /** The iframe element (or anything with its `contentWindow`). Read at send time, not attach time. */
36
49
  frame: {
@@ -41,6 +54,11 @@ export interface AttachGameHostOptions {
41
54
  /** What the game needs to join its round. A function is read fresh per send. */
42
55
  context: EmbedContext | (() => EmbedContext);
43
56
  host: Host;
57
+ /**
58
+ * Where the coin's market comes from. Optional — a page with no chart of its own attaches
59
+ * exactly as before, and the game's market simply stays `unavailable`.
60
+ */
61
+ market?: MarketSource;
44
62
  endpoint?: HostListenSource;
45
63
  }
46
64
  /** Attach the page's Host to a game iframe. Returns detach; after it, nothing is ever posted again. */
@@ -1 +1 @@
1
- {"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../src/host.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAGL,KAAK,YAAY,EACjB,KAAK,aAAa,EAEnB,MAAM,iCAAiC,CAAC;AAEzC;;;;;;;;;;;;;;GAcG;AAEH;;;GAGG;AACH,qBAAa,WAAY,SAAQ,KAAK;aAElB,IAAI,EAAE,aAAa;gBAAnB,IAAI,EAAE,aAAa,EACnC,OAAO,EAAE,MAAM;CAKlB;AAED,gGAAgG;AAChG,MAAM,WAAW,UAAU;IACzB,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3D;AAED,wFAAwF;AACxF,MAAM,WAAW,gBAAgB;IAC/B,MAAM,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;CACvF;AAED,MAAM,WAAW,qBAAqB;IACpC,qGAAqG;IACrG,KAAK,EAAE;QAAE,aAAa,EAAE,UAAU,GAAG,IAAI,CAAA;KAAE,CAAC;IAC5C,2FAA2F;IAC3F,UAAU,EAAE,MAAM,CAAC;IACnB,gFAAgF;IAChF,OAAO,EAAE,YAAY,GAAG,CAAC,MAAM,YAAY,CAAC,CAAC;IAC7C,IAAI,EAAE,IAAI,CAAC;IACX,QAAQ,CAAC,EAAE,gBAAgB,CAAC;CAC7B;AAiBD,uGAAuG;AACvG,wBAAgB,cAAc,CAAC,OAAO,EAAE,qBAAqB,GAAG,MAAM,IAAI,CAqGzE"}
1
+ {"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../src/host.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAGL,KAAK,YAAY,EACjB,KAAK,aAAa,EAEnB,MAAM,iCAAiC,CAAC;AACzC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAEtE;;;;;;;;;;;;;;GAcG;AAEH;;;GAGG;AACH,qBAAa,WAAY,SAAQ,KAAK;aAElB,IAAI,EAAE,aAAa;gBAAnB,IAAI,EAAE,aAAa,EACnC,OAAO,EAAE,MAAM;CAKlB;AAED,gGAAgG;AAChG,MAAM,WAAW,UAAU;IACzB,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3D;AAED,wFAAwF;AACxF,MAAM,WAAW,gBAAgB;IAC/B,MAAM,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;CACvF;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,YAAY;IAC3B,OAAO,IAAI,eAAe,GAAG,IAAI,CAAC;IAClC,SAAS,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;CACpE;AAED,MAAM,WAAW,qBAAqB;IACpC,qGAAqG;IACrG,KAAK,EAAE;QAAE,aAAa,EAAE,UAAU,GAAG,IAAI,CAAA;KAAE,CAAC;IAC5C,2FAA2F;IAC3F,UAAU,EAAE,MAAM,CAAC;IACnB,gFAAgF;IAChF,OAAO,EAAE,YAAY,GAAG,CAAC,MAAM,YAAY,CAAC,CAAC;IAC7C,IAAI,EAAE,IAAI,CAAC;IACX;;;OAGG;IACH,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,QAAQ,CAAC,EAAE,gBAAgB,CAAC;CAC7B;AAiBD,uGAAuG;AACvG,wBAAgB,cAAc,CAAC,OAAO,EAAE,qBAAqB,GAAG,MAAM,IAAI,CAiHzE"}
package/dist/host.js CHANGED
@@ -54,6 +54,7 @@ export function attachGameHost(options) {
54
54
  const context = typeof options.context === 'function' ? options.context() : options.context;
55
55
  send({ v: FRAME_PROTOCOL_VERSION, type: 'gm:context', context });
56
56
  };
57
+ const sendMarket = (market) => send({ v: FRAME_PROTOCOL_VERSION, type: 'gm:market', market });
57
58
  const unlisten = endpoint.listen((data, origin, source) => {
58
59
  // Both checks, always: origin says who wrote the frame, source says which window sent it.
59
60
  // This listener shares the page's window with every other frame the page hosts.
@@ -64,6 +65,12 @@ export function attachGameHost(options) {
64
65
  return;
65
66
  if (parsed.type === 'gm:hello') {
66
67
  sendContext();
68
+ // A hello means the game has only just started listening, so the market it missed is
69
+ // re-sent alongside the context. Cheap, and it spares the game an empty first chart while
70
+ // it waits for whatever moves the price next.
71
+ const current = options.market?.current();
72
+ if (current)
73
+ sendMarket(current);
67
74
  return;
68
75
  }
69
76
  const { id, call } = parsed;
@@ -134,8 +141,12 @@ export function attachGameHost(options) {
134
141
  });
135
142
  // Unprompted, because the frame may have said hello before this listener existed.
136
143
  sendContext();
144
+ // Subscribing delivers the current value immediately, so this both seeds the game and keeps it
145
+ // current; `send` is a no-op once detached, so a late tick cannot reach a frame we let go of.
146
+ const unsubscribeMarket = options.market?.subscribe(sendMarket) ?? (() => { });
137
147
  return () => {
138
148
  detached = true;
149
+ unsubscribeMarket();
139
150
  unlisten();
140
151
  };
141
152
  }
package/dist/host.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"host.js","sourceRoot":"","sources":["../src/host.ts"],"names":[],"mappings":"AACA,OAAO,EACL,sBAAsB,EACtB,aAAa,GAId,MAAM,iCAAiC,CAAC;AAEzC;;;;;;;;;;;;;;GAcG;AAEH;;;GAGG;AACH,MAAM,OAAO,WAAY,SAAQ,KAAK;IAElB;IADlB,YACkB,IAAmB,EACnC,OAAe;QAEf,KAAK,CAAC,OAAO,CAAC,CAAC;QAHC,SAAI,GAAJ,IAAI,CAAe;QAInC,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC;IAC5B,CAAC;CACF;AAuBD,SAAS,kBAAkB;IACzB,OAAO;QACL,MAAM,CAAC,OAAO;YACZ,MAAM,SAAS,GAAG,CAAC,KAAmB,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;YAC3F,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;YAC9C,OAAO,GAAG,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;QAChE,CAAC;KACF,CAAC;AACJ,CAAC;AAED,MAAM,SAAS,GAAG,CAAC,KAAc,EAA4C,EAAE,CAC7E,KAAK,YAAY,WAAW;IAC1B,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE;IAC9C,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,sBAAsB,EAAE,CAAC;AAEnG,uGAAuG;AACvG,MAAM,UAAU,cAAc,CAAC,OAA8B;IAC3D,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC;IAC5C,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,kBAAkB,EAAE,CAAC;IAC1D,gGAAgG;IAChG,4FAA4F;IAC5F,IAAI,QAAQ,GAAG,KAAK,CAAC;IAErB,MAAM,IAAI,GAAG,CAAC,OAAwB,EAAQ,EAAE;QAC9C,IAAI,QAAQ;YAAE,OAAO;QACrB,KAAK,CAAC,aAAa,EAAE,WAAW,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;IACxD,CAAC,CAAC;IAEF,MAAM,WAAW,GAAG,GAAS,EAAE;QAC7B,MAAM,OAAO,GAAG,OAAO,OAAO,CAAC,OAAO,KAAK,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC;QAC5F,IAAI,CAAC,EAAE,CAAC,EAAE,sBAAsB,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,CAAC,CAAC;IACnE,CAAC,CAAC;IAEF,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE;QACxD,0FAA0F;QAC1F,gFAAgF;QAChF,IAAI,QAAQ,IAAI,MAAM,KAAK,UAAU,IAAI,MAAM,KAAK,KAAK,CAAC,aAAa;YAAE,OAAO;QAChF,MAAM,MAAM,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,CAAC,MAAM;YAAE,OAAO;QAEpB,IAAI,MAAM,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YAC/B,WAAW,EAAE,CAAC;YACd,OAAO;QACT,CAAC;QAED,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,MAAM,CAAC;QAC5B,KAAK,CAAC,KAAK,IAAI,EAAE;YACf,IAAI,CAAC;gBACH,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;oBAC9B,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;oBACrC,IAAI,CAAC,EAAE,CAAC,EAAE,sBAAsB,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC;oBAC1G,OAAO;gBACT,CAAC;gBACD,IAAI,IAAI,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;oBAC7B,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;oBAClD,IAAI,CAAC,EAAE,CAAC,EAAE,sBAAsB,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC;oBAC3G,OAAO;gBACT,CAAC;gBACD,qFAAqF;gBACrF,uFAAuF;gBACvF,wEAAwE;gBACxE,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC,aAAa,CAAC;gBACxC,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;oBAC3B,IAAI,CAAC,EAAE,CAAC,EAAE,sBAAsB,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,wCAAwC,EAAE,EAAE,CAAC,CAAC;oBACjJ,OAAO;gBACT,CAAC;gBACD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,aAAa,EAAE,QAAQ,EAAE,EAAE,CAAC,QAAQ,EAAE,EAAE;oBAC/E,IAAI,CAAC;wBACH,CAAC,EAAE,sBAAsB;wBACzB,IAAI,EAAE,aAAa;wBACnB,EAAE;wBACF,QAAQ,EACN,QAAQ,CAAC,eAAe,KAAK,SAAS;4BACpC,CAAC,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,QAAQ,CAAC,eAAe,EAAE;4BACjE,CAAC,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE;qBAC3B,CAAC,CAAC;gBACL,CAAC,CAAC,CAAC;gBACH,IAAI,UAAU,IAAI,OAAO,EAAE,CAAC;oBAC1B,IAAI,CAAC;wBACH,CAAC,EAAE,sBAAsB;wBACzB,IAAI,EAAE,QAAQ;wBACd,EAAE;wBACF,EAAE,EAAE,IAAI;wBACR,MAAM,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,QAAQ,EAAE,EAAE,EAAE;qBAC9E,CAAC,CAAC;gBACL,CAAC;qBAAM,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,KAAK,KAAK,EAAE,CAAC;oBAC3C,IAAI,CAAC;wBACH,CAAC,EAAE,sBAAsB;wBACzB,IAAI,EAAE,QAAQ;wBACd,EAAE;wBACF,EAAE,EAAE,IAAI;wBACR,MAAM,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,EAAE;qBAC/D,CAAC,CAAC;gBACL,CAAC;qBAAM,CAAC;oBACN,oFAAoF;oBACpF,kDAAkD;oBAClD,IAAI,CAAC;wBACH,CAAC,EAAE,sBAAsB;wBACzB,IAAI,EAAE,QAAQ;wBACd,EAAE;wBACF,EAAE,EAAE,IAAI;wBACR,MAAM,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE,EAAE,EAAE;qBACrF,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,CAAC,EAAE,CAAC,EAAE,sBAAsB,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAC9F,CAAC;QACH,CAAC,CAAC,EAAE,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,kFAAkF;IAClF,WAAW,EAAE,CAAC;IAEd,OAAO,GAAG,EAAE;QACV,QAAQ,GAAG,IAAI,CAAC;QAChB,QAAQ,EAAE,CAAC;IACb,CAAC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"host.js","sourceRoot":"","sources":["../src/host.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flayerlabs/gamemode-client",
3
- "version": "0.4.1",
3
+ "version": "0.4.2",
4
4
  "description": "Browser and mock-room client for Flaunch Game Modes",
5
5
  "license": "MIT",
6
6
  "author": "Flayer Labs",
@@ -33,7 +33,7 @@
33
33
  "ws": "^8.21.3"
34
34
  },
35
35
  "dependencies": {
36
- "@flayerlabs/gamemode-spec": "^0.4.1"
36
+ "@flayerlabs/gamemode-spec": "^0.4.2"
37
37
  },
38
38
  "types": "./dist/index.d.ts",
39
39
  "exports": {
package/src/embed.ts CHANGED
@@ -1,5 +1,6 @@
1
- import type { Host, HostBuyProgress } from './live.js';
2
- import type { BuyResult } from './index.js';
1
+ import { marketFrom, type Host, type HostBuyProgress } from './live.js';
2
+ import type { BuyResult, MarketState, Readable } from './index.js';
3
+ import { Signal } from './signal.js';
3
4
  import {
4
5
  FRAME_PROTOCOL_VERSION,
5
6
  hostFrameFrom,
@@ -52,6 +53,15 @@ export interface ConnectHostOptions {
52
53
  export interface EmbeddedHost {
53
54
  host: Host;
54
55
  context: EmbedContext;
56
+ /**
57
+ * The coin's market as the embedding page sees it, for `joinEconomy`'s `platform.market`.
58
+ *
59
+ * Always present, because "no market yet" is a state a chart can render — it starts
60
+ * `unavailable` and becomes `live` if and when the page pushes one. A page that never sends a
61
+ * `gm:market` frame leaves it `unavailable` forever, which is the honest answer and the one a
62
+ * game should draw an empty chart for rather than waiting on.
63
+ */
64
+ market: Readable<MarketState>;
55
65
  dispose(): void;
56
66
  }
57
67
 
@@ -106,6 +116,12 @@ export async function connectHost(options: ConnectHostOptions = {}): Promise<Emb
106
116
  const parent = endpoint.parentSource();
107
117
  if (parent === null) return null;
108
118
 
119
+ const marketSignal = new Signal<MarketState>({
120
+ status: 'unavailable',
121
+ prices: [],
122
+ trades: [],
123
+ marketCapUsd: null,
124
+ });
109
125
  const pending = new Map<string, Pending>();
110
126
  let unlisten: () => void = () => {};
111
127
  let disposed = false;
@@ -141,6 +157,12 @@ export async function connectHost(options: ConnectHostOptions = {}): Promise<Emb
141
157
  return;
142
158
  }
143
159
 
160
+ if (frame.type === 'gm:market') {
161
+ const market = marketFrom(frame.market);
162
+ if (market) marketSignal.set(market);
163
+ return;
164
+ }
165
+
144
166
  if (frame.type === 'gm:progress') {
145
167
  const request = pending.get(frame.id);
146
168
  if (request?.kind === 'buy') {
@@ -217,10 +239,15 @@ export async function connectHost(options: ConnectHostOptions = {}): Promise<Emb
217
239
  return {
218
240
  host,
219
241
  context,
242
+ market: {
243
+ current: () => marketSignal.current(),
244
+ subscribe: (listener) => marketSignal.subscribe(listener),
245
+ },
220
246
  dispose() {
221
247
  disposed = true;
222
248
  unlisten();
223
249
  pending.clear();
250
+ marketSignal.clear();
224
251
  },
225
252
  };
226
253
  }
package/src/host.ts CHANGED
@@ -6,6 +6,7 @@ import {
6
6
  type HostErrorCode,
7
7
  type HostToGameFrame,
8
8
  } from '@flayerlabs/gamemode-spec/frame';
9
+ import type { WireMarketState } from '@flayerlabs/gamemode-spec/live';
9
10
 
10
11
  /**
11
12
  * The page's end of the frame protocol: service a game iframe's Host calls.
@@ -47,6 +48,19 @@ export interface HostListenSource {
47
48
  listen(handler: (data: unknown, origin: string, source: unknown) => void): () => void;
48
49
  }
49
50
 
51
+ /**
52
+ * The page's live market, if it has one to share.
53
+ *
54
+ * Structurally a `Signal` (and anything else with these two methods), so a page that already
55
+ * keeps its chart in an observable hands the same one over rather than building a second.
56
+ * `current()` may answer null: "I have no market yet" is not the same claim as an `unavailable`
57
+ * market, and a page should not have to invent one to attach a host.
58
+ */
59
+ export interface MarketSource {
60
+ current(): WireMarketState | null;
61
+ subscribe(listener: (market: WireMarketState) => void): () => void;
62
+ }
63
+
50
64
  export interface AttachGameHostOptions {
51
65
  /** The iframe element (or anything with its `contentWindow`). Read at send time, not attach time. */
52
66
  frame: { contentWindow: PostTarget | null };
@@ -55,6 +69,11 @@ export interface AttachGameHostOptions {
55
69
  /** What the game needs to join its round. A function is read fresh per send. */
56
70
  context: EmbedContext | (() => EmbedContext);
57
71
  host: Host;
72
+ /**
73
+ * Where the coin's market comes from. Optional — a page with no chart of its own attaches
74
+ * exactly as before, and the game's market simply stays `unavailable`.
75
+ */
76
+ market?: MarketSource;
58
77
  endpoint?: HostListenSource;
59
78
  }
60
79
 
@@ -91,6 +110,9 @@ export function attachGameHost(options: AttachGameHostOptions): () => void {
91
110
  send({ v: FRAME_PROTOCOL_VERSION, type: 'gm:context', context });
92
111
  };
93
112
 
113
+ const sendMarket = (market: WireMarketState): void =>
114
+ send({ v: FRAME_PROTOCOL_VERSION, type: 'gm:market', market });
115
+
94
116
  const unlisten = endpoint.listen((data, origin, source) => {
95
117
  // Both checks, always: origin says who wrote the frame, source says which window sent it.
96
118
  // This listener shares the page's window with every other frame the page hosts.
@@ -100,6 +122,11 @@ export function attachGameHost(options: AttachGameHostOptions): () => void {
100
122
 
101
123
  if (parsed.type === 'gm:hello') {
102
124
  sendContext();
125
+ // A hello means the game has only just started listening, so the market it missed is
126
+ // re-sent alongside the context. Cheap, and it spares the game an empty first chart while
127
+ // it waits for whatever moves the price next.
128
+ const current = options.market?.current();
129
+ if (current) sendMarket(current);
103
130
  return;
104
131
  }
105
132
 
@@ -170,9 +197,13 @@ export function attachGameHost(options: AttachGameHostOptions): () => void {
170
197
 
171
198
  // Unprompted, because the frame may have said hello before this listener existed.
172
199
  sendContext();
200
+ // Subscribing delivers the current value immediately, so this both seeds the game and keeps it
201
+ // current; `send` is a no-op once detached, so a late tick cannot reach a frame we let go of.
202
+ const unsubscribeMarket = options.market?.subscribe(sendMarket) ?? (() => {});
173
203
 
174
204
  return () => {
175
205
  detached = true;
206
+ unsubscribeMarket();
176
207
  unlisten();
177
208
  };
178
209
  }