screeps-connectivity 0.15.2 → 0.16.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/CHANGELOG.md +6 -0
- package/package.json +1 -1
- package/src/ScreepsClient.ts +9 -0
- package/src/stores/ServerStore.ts +19 -1
- package/tests/stores/ServerStore.test.ts +12 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.16.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- f218429: Embedded clients are now configured from the first frame with no `/api/version` round-trip: both the xxscreeps mod and the classic server mod prefetch the version payload and inline it into the page (`window.__SCREEPS_BOOTSTRAP__`), and the client seeds it into both the pre-login UI and the connection. `ScreepsClient` gains an `initialVersion` option and `ServerStore` a `seedVersion()` method to support this.
|
|
8
|
+
|
|
3
9
|
## 0.15.2
|
|
4
10
|
|
|
5
11
|
### Patch Changes
|
package/package.json
CHANGED
package/src/ScreepsClient.ts
CHANGED
|
@@ -14,6 +14,7 @@ import type { AuthStrategy } from './http/auth/AuthStrategy.js'
|
|
|
14
14
|
import type { StorageAdapter } from './storage/StorageAdapter.js'
|
|
15
15
|
import type { Subscription } from './subscription/index.js'
|
|
16
16
|
import type { ApiRoomDecorationsResponse } from './types/api.js'
|
|
17
|
+
import type { ServerVersion } from './types/game.js'
|
|
17
18
|
|
|
18
19
|
type WsConstructor = typeof globalThis.WebSocket
|
|
19
20
|
|
|
@@ -49,6 +50,12 @@ export interface ScreepsClientOptions {
|
|
|
49
50
|
* active regardless, so enabling this is a pure opt-in bandwidth trade.
|
|
50
51
|
*/
|
|
51
52
|
gzip?: boolean
|
|
53
|
+
/**
|
|
54
|
+
* A pre-known `/api/version` response, seeded into the server store so `connect()`
|
|
55
|
+
* skips the initial version fetch. Used by embedded clients whose host mod inlines
|
|
56
|
+
* the payload into the page. Falls back to a normal fetch if omitted.
|
|
57
|
+
*/
|
|
58
|
+
initialVersion?: ServerVersion
|
|
52
59
|
}
|
|
53
60
|
|
|
54
61
|
export class ScreepsClient {
|
|
@@ -100,6 +107,8 @@ export class ScreepsClient {
|
|
|
100
107
|
navigation: new NavigationStore(50, this.logger.child('navigation')),
|
|
101
108
|
}
|
|
102
109
|
|
|
110
|
+
if (opts.initialVersion) this.stores.server.seedVersion(opts.initialVersion)
|
|
111
|
+
|
|
103
112
|
this.tokenRefreshIntervalMs = opts.tokenRefresh === false
|
|
104
113
|
? null
|
|
105
114
|
: (opts.tokenRefresh?.intervalMs ?? 30_000)
|
|
@@ -43,9 +43,27 @@ export class ServerStore extends TypedStore<ServerStoreEvents> {
|
|
|
43
43
|
this.socketSubs.length = 0
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
+
/**
|
|
47
|
+
* Seed the server version without a network request. Used when the version is
|
|
48
|
+
* already known at construction time — e.g. an embedded client whose host mod
|
|
49
|
+
* inlines the `/api/version` payload into the page, sparing the initial fetch.
|
|
50
|
+
* Does not emit `server:version` (listeners aren't attached yet at that point);
|
|
51
|
+
* the value surfaces via the cache-hit path on the first `version()` call.
|
|
52
|
+
*/
|
|
53
|
+
seedVersion(version: ServerVersion): void {
|
|
54
|
+
this._version = version
|
|
55
|
+
this.cache.set('server/version', version, 5 * 60_000)
|
|
56
|
+
}
|
|
57
|
+
|
|
46
58
|
async version(): Promise<ServerVersion> {
|
|
47
59
|
const cached = this.cache.get<ServerVersion>('server/version')
|
|
48
|
-
if (cached)
|
|
60
|
+
if (cached) {
|
|
61
|
+
// Emit on cache hits too so a seeded version (see `seedVersion`) reaches
|
|
62
|
+
// listeners that only attach after construction. Idempotent for consumers.
|
|
63
|
+
this._version = cached
|
|
64
|
+
this.emit('server:version', cached)
|
|
65
|
+
return cached
|
|
66
|
+
}
|
|
49
67
|
const res = await this.http.request<ServerVersion>('GET', '/api/version')
|
|
50
68
|
this._version = res
|
|
51
69
|
this.cache.set('server/version', res, 5 * 60_000)
|
|
@@ -31,6 +31,18 @@ describe('ServerStore', () => {
|
|
|
31
31
|
expect(http.request).toHaveBeenCalledOnce()
|
|
32
32
|
})
|
|
33
33
|
|
|
34
|
+
it('serves a seeded version without fetching and emits server:version', async () => {
|
|
35
|
+
const { store, http } = makeStore()
|
|
36
|
+
const spy = vi.fn()
|
|
37
|
+
store.on('server:version', spy)
|
|
38
|
+
store.seedVersion({ ...mockVersion })
|
|
39
|
+
const v = await store.version()
|
|
40
|
+
expect(v.protocol).toBe(13)
|
|
41
|
+
expect(http.request).not.toHaveBeenCalled()
|
|
42
|
+
expect(spy).toHaveBeenCalledWith(expect.objectContaining({ protocol: 13 }))
|
|
43
|
+
expect(store.versionInfo?.protocol).toBe(13)
|
|
44
|
+
})
|
|
45
|
+
|
|
34
46
|
it('emits server:connected when socket fires connected event', () => {
|
|
35
47
|
const { socket } = makeStore()
|
|
36
48
|
let connectedCb: (data: unknown) => void = () => {}
|