Skip to content

Commit eb98845

Browse files
committed
refactor(stage-tamagotchi): better formatting and naming
1 parent 1ae161c commit eb98845

8 files changed

Lines changed: 100 additions & 124 deletions

File tree

apps/stage-tamagotchi/src/main/services/airi/plugins/features/static-assets/index.test.ts

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import type { StaticAssetService } from '../../../http-server/static-assets'
22
import type { StaticAssetSession } from '../../../http-server/static-assets/types'
3-
import type { PluginAssetCookie, PluginAssetCookieAdapter } from './index'
3+
import type { ExtensionAssetCookie, ExtensionAssetCookieAdapter } from './index'
44

55
import { beforeEach, describe, expect, it, vi } from 'vitest'
66

7-
import { createPluginAssetService } from './index'
7+
import { createExtensionAssetService } from './index'
88

99
const mockState = vi.hoisted(() => ({
1010
createStaticAssetService: vi.fn(),
@@ -45,8 +45,8 @@ function createFakeServer(options: {
4545
}
4646

4747
function createFakeCookieAdapter() {
48-
const setCookies: PluginAssetCookie[] = []
49-
const removedCookies: PluginAssetCookie[] = []
48+
const setCookies: ExtensionAssetCookie[] = []
49+
const removedCookies: ExtensionAssetCookie[] = []
5050

5151
return {
5252
adapter: {
@@ -56,13 +56,13 @@ function createFakeCookieAdapter() {
5656
removeCookie: vi.fn(async (cookie) => {
5757
removedCookies.push(cookie)
5858
}),
59-
} satisfies PluginAssetCookieAdapter,
59+
} satisfies ExtensionAssetCookieAdapter,
6060
removedCookies,
6161
setCookies,
6262
}
6363
}
6464

65-
describe('createPluginAssetService', () => {
65+
describe('createExtensionAssetService', () => {
6666
beforeEach(() => {
6767
mockState.createStaticAssetService.mockReset()
6868
})
@@ -75,7 +75,7 @@ describe('createPluginAssetService', () => {
7575
const { adapter, setCookies } = createFakeCookieAdapter()
7676
mockState.createStaticAssetService.mockReturnValue(server)
7777

78-
const service = createPluginAssetService({
78+
const service = createExtensionAssetService({
7979
getManifestEntryByName: () => new Map(),
8080
cookieAdapter: adapter,
8181
})
@@ -122,7 +122,7 @@ describe('createPluginAssetService', () => {
122122
const { adapter, setCookies } = createFakeCookieAdapter()
123123
mockState.createStaticAssetService.mockReturnValue(server)
124124

125-
const service = createPluginAssetService({
125+
const service = createExtensionAssetService({
126126
getManifestEntryByName: () => new Map(),
127127
cookieAdapter: adapter,
128128
})
@@ -134,7 +134,7 @@ describe('createPluginAssetService', () => {
134134
routeAssetPath: 'assets/app.js',
135135
pathPrefix: 'assets/',
136136
ttlMs: 60_000,
137-
})).rejects.toThrow('Plugin asset server base URL is unavailable')
137+
})).rejects.toThrow('Extension asset server base URL is unavailable')
138138

139139
expect(server.revokeSession).toHaveBeenCalledWith('asset-session-2')
140140
expect(adapter.setCookie).not.toHaveBeenCalled()
@@ -148,7 +148,7 @@ describe('createPluginAssetService', () => {
148148
})
149149
const { adapter } = createFakeCookieAdapter()
150150
mockState.createStaticAssetService.mockReturnValue(server)
151-
const service = createPluginAssetService({
151+
const service = createExtensionAssetService({
152152
getManifestEntryByName: () => new Map(),
153153
cookieAdapter: adapter,
154154
})
@@ -160,7 +160,7 @@ describe('createPluginAssetService', () => {
160160
routeAssetPath: '../secret.txt',
161161
pathPrefix: '',
162162
ttlMs: 60_000,
163-
})).rejects.toThrow('Plugin asset session routeAssetPath must be a safe plugin asset path')
163+
})).rejects.toThrow('Extension asset session routeAssetPath must be a safe extension asset path')
164164

165165
expect(server.revokeSession).toHaveBeenCalledWith('asset-session-3')
166166
expect(adapter.setCookie).not.toHaveBeenCalled()
@@ -195,14 +195,14 @@ describe('createPluginAssetService', () => {
195195
const { adapter, removedCookies } = createFakeCookieAdapter()
196196
mockState.createStaticAssetService.mockReturnValue(server)
197197

198-
const service = createPluginAssetService({
198+
const service = createExtensionAssetService({
199199
getManifestEntryByName: () => new Map(),
200200
cookieAdapter: adapter,
201201
})
202202

203203
await service.revokeSession('direct-asset-session')
204204
await service.revokeByOwnerSessionId('owner-session-1')
205-
await service.revokeByPluginId('airi-plugin-game-chess')
205+
await service.revokeByExtensionId('airi-plugin-game-chess')
206206
await service.revokeAll()
207207

208208
expect(server.revokeSession).toHaveBeenCalledWith('direct-asset-session')
@@ -251,7 +251,7 @@ describe('createPluginAssetService', () => {
251251
const { adapter, removedCookies } = createFakeCookieAdapter()
252252
mockState.createStaticAssetService.mockReturnValue(server)
253253

254-
const service = createPluginAssetService({
254+
const service = createExtensionAssetService({
255255
getManifestEntryByName: () => new Map(),
256256
cookieAdapter: adapter,
257257
})

apps/stage-tamagotchi/src/main/services/airi/plugins/features/static-assets/index.ts

Lines changed: 43 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ import { createStaticAssetService } from '../../../http-server/static-assets'
66
import { buildMountedStaticAssetPath } from '../../../http-server/static-assets/paths'
77

88
/**
9-
* Describes one plugin asset session creation request.
9+
* Describes one extension asset session creation request.
1010
*
1111
* Use when:
12-
* - A extension-owned asset URL must be mounted behind the local loopback server with cookie auth
13-
* - Snapshot builders need a transport-agnostic way to authorize one plugin asset route before iframe load
12+
* - An extension-owned asset URL must be mounted behind the local loopback server with cookie auth
13+
* - Snapshot builders need a transport-agnostic way to authorize one extension asset route before iframe load
1414
*
1515
* Expects:
1616
* - `pluginId` matches a manifest entry registered in the asset host
@@ -20,10 +20,10 @@ import { buildMountedStaticAssetPath } from '../../../http-server/static-assets/
2020
* Returns:
2121
* - N/A
2222
*/
23-
export interface PluginAssetSessionInput {
24-
/** Plugin id that owns the static asset root. */
23+
export interface ExtensionAssetSessionInput {
24+
/** Extension/plugin manifest id that owns the static asset root. */
2525
pluginId: string
26-
/** Plugin version expected by the server-side session validator. */
26+
/** Extension/plugin version expected by the server-side session validator. */
2727
version: string
2828
/** Parent extension session id used for owner-scoped revocation. */
2929
ownerSessionId: string
@@ -36,7 +36,7 @@ export interface PluginAssetSessionInput {
3636
}
3737

3838
/**
39-
* Describes the cookie material Electron must apply before loading a plugin asset URL.
39+
* Describes the cookie material Electron must apply before loading an extension asset URL.
4040
*
4141
* Use when:
4242
* - Main process bridges server-side asset sessions into Electron's cookie jar
@@ -49,7 +49,7 @@ export interface PluginAssetSessionInput {
4949
* Returns:
5050
* - N/A
5151
*/
52-
export interface PluginAssetCookie {
52+
export interface ExtensionAssetCookie {
5353
/** Cookie name generated for the asset session. */
5454
name: string
5555
/** Opaque cookie value required by the static asset route. */
@@ -63,7 +63,7 @@ export interface PluginAssetCookie {
6363
}
6464

6565
/**
66-
* Applies and removes plugin asset cookies from the Electron host.
66+
* Applies and removes extension asset cookies from the Electron host.
6767
*
6868
* Use when:
6969
* - Asset sessions must exist in Electron's cookie jar before an iframe navigates to its URL
@@ -76,13 +76,13 @@ export interface PluginAssetCookie {
7676
* Returns:
7777
* - N/A
7878
*/
79-
export interface PluginAssetCookieAdapter {
80-
setCookie: (cookie: PluginAssetCookie) => Promise<void>
81-
removeCookie: (cookie: PluginAssetCookie) => Promise<void>
79+
export interface ExtensionAssetCookieAdapter {
80+
setCookie: (cookie: ExtensionAssetCookie) => Promise<void>
81+
removeCookie: (cookie: ExtensionAssetCookie) => Promise<void>
8282
}
8383

8484
/**
85-
* Describes the plugin asset methods needed while building renderer-facing snapshots.
85+
* Describes the extension asset methods needed while building renderer-facing snapshots.
8686
*
8787
* Use when:
8888
* - Snapshot builders must request route-scoped asset sessions without depending on HTTP server internals
@@ -95,13 +95,13 @@ export interface PluginAssetCookieAdapter {
9595
* Returns:
9696
* - A mounted asset URL and cookie-backed session metadata
9797
*/
98-
export interface PluginAssetSnapshotService {
98+
export interface ExtensionAssetSnapshotService {
9999
getBaseUrl: () => string | undefined
100-
createAssetSession: (input: Omit<PluginAssetSessionInput, 'ttlMs'>) => Promise<PluginAssetSession>
100+
createAssetSession: (input: Omit<ExtensionAssetSessionInput, 'ttlMs'>) => Promise<ExtensionAssetSession>
101101
}
102102

103103
/**
104-
* Describes a plugin asset session prepared for renderer iframe navigation.
104+
* Describes an extension asset session prepared for renderer iframe navigation.
105105
*
106106
* Use when:
107107
* - A plugin iframe needs a mounted static asset URL and pre-applied cookie state
@@ -113,13 +113,13 @@ export interface PluginAssetSnapshotService {
113113
* Returns:
114114
* - Renderer-facing URL plus server and cookie metadata
115115
*/
116-
export interface PluginAssetSession {
116+
export interface ExtensionAssetSession {
117117
/** Absolute mounted asset URL safe to hand to a renderer iframe after cookie setup. */
118118
url: string
119119
/** Opaque server-side asset session id embedded in mounted asset routes. */
120120
assetSessionId: string
121121
/** Cookie data that was applied through the host adapter. */
122-
cookie: PluginAssetCookie
122+
cookie: ExtensionAssetCookie
123123
/** Unix timestamp in milliseconds when the cookie-backed asset session expires. */
124124
expiresAt: number
125125
}
@@ -129,24 +129,24 @@ export interface PluginAssetSession {
129129
*
130130
* Use when:
131131
* - Plugin snapshots need mounted asset URLs without depending on the H3 server shape
132-
* - Host teardown must revoke plugin asset access independently from widget/gamelet logic
132+
* - Host teardown must revoke extension asset access independently from widget/gamelet logic
133133
*
134134
* Expects:
135135
* - Implementations own the underlying transport, cookie, and session lifecycle
136136
*
137137
* Returns:
138-
* - A startable/stoppable asset-hosting service with generic plugin-facing methods
138+
* - A startable/stoppable asset-hosting service with generic extension-facing methods
139139
*/
140-
export interface PluginAssetService extends ServerManager {
140+
export interface ExtensionAssetService extends ServerManager {
141141
getBaseUrl: () => string | undefined
142-
createAssetSession: (input: PluginAssetSessionInput) => Promise<PluginAssetSession>
142+
createAssetSession: (input: ExtensionAssetSessionInput) => Promise<ExtensionAssetSession>
143143
revokeSession: (assetSessionId: string) => Promise<void>
144144
revokeByOwnerSessionId: (ownerSessionId: string) => Promise<void>
145-
revokeByPluginId: (pluginId: string) => Promise<void>
145+
revokeByExtensionId: (extensionId: string) => Promise<void>
146146
revokeAll: () => Promise<void>
147147
}
148148

149-
function createPluginAssetCookie(baseUrl: string, session: StaticAssetSession): PluginAssetCookie {
149+
function createExtensionAssetCookie(baseUrl: string, session: StaticAssetSession): ExtensionAssetCookie {
150150
return {
151151
name: session.cookieName,
152152
value: session.cookieValue,
@@ -156,36 +156,24 @@ function createPluginAssetCookie(baseUrl: string, session: StaticAssetSession):
156156
}
157157
}
158158

159-
function requireBaseUrl(baseUrl: string | undefined) {
160-
if (!baseUrl) {
161-
throw new Error('Plugin asset server base URL is unavailable; start the asset server before creating asset sessions')
162-
}
163-
164-
return baseUrl
165-
}
166-
167-
async function removeCookies(cookieAdapter: PluginAssetCookieAdapter, baseUrl: string, sessions: readonly StaticAssetSession[]) {
168-
await Promise.all(sessions.map(session => cookieAdapter.removeCookie(createPluginAssetCookie(baseUrl, session))))
169-
}
170-
171159
/**
172-
* Creates the plugin asset host service backed by the extension static asset server.
160+
* Creates the extension asset host service backed by the extension static asset server.
173161
*
174162
* Use when:
175163
* - The extension host needs to expose mounted asset URLs to renderer snapshots
176-
* - Asset session lifecycle should stay inside the plugin domain instead of the HTTP server layer
164+
* - Asset session lifecycle should stay inside the extension domain instead of the HTTP server layer
177165
*
178166
* Expects:
179167
* - `getManifestEntryByName` returns the latest extension root/version map
180168
* - `cookieAdapter` writes and removes cookies in the Electron host session used by plugin iframes
181169
*
182170
* Returns:
183-
* - A plugin-facing asset host service with generic plugin asset methods
171+
* - An extension-facing asset host service with generic extension asset methods
184172
*/
185-
export function createPluginAssetService(options: {
173+
export function createExtensionAssetService(options: {
186174
getManifestEntryByName: () => Map<string, StaticAssetManifestEntry>
187-
cookieAdapter: PluginAssetCookieAdapter
188-
}): PluginAssetService {
175+
cookieAdapter: ExtensionAssetCookieAdapter
176+
}): ExtensionAssetService {
189177
const server = createStaticAssetService({ getManifestEntryByName: options.getManifestEntryByName })
190178
let lastBaseUrl: string | undefined
191179

@@ -201,11 +189,13 @@ export function createPluginAssetService(options: {
201189
return
202190
}
203191

204-
await removeCookies(options.cookieAdapter, baseUrl, sessions)
192+
await Promise.all(
193+
sessions.map(session => options.cookieAdapter.removeCookie(createExtensionAssetCookie(baseUrl, session))),
194+
)
205195
}
206196

207197
return {
208-
key: 'plugin-assets',
198+
key: 'extension-assets',
209199
async start() {
210200
await server.start()
211201
},
@@ -226,18 +216,22 @@ export function createPluginAssetService(options: {
226216
})
227217

228218
try {
229-
const baseUrl = requireBaseUrl(readBaseUrl())
219+
const baseUrl = readBaseUrl()
220+
if (!baseUrl) {
221+
throw new Error('Extension asset server base URL is unavailable; start the asset server before creating asset sessions')
222+
}
223+
230224
const mountedPath = buildMountedStaticAssetPath({
231225
extensionId: input.pluginId,
232226
assetSessionId: session.assetSessionId,
233227
assetPath: input.routeAssetPath,
234228
})
235229

236230
if (!mountedPath) {
237-
throw new RangeError('Plugin asset session routeAssetPath must be a safe plugin asset path')
231+
throw new RangeError('Extension asset session routeAssetPath must be a safe extension asset path')
238232
}
239233

240-
const cookie = createPluginAssetCookie(baseUrl, session)
234+
const cookie = createExtensionAssetCookie(baseUrl, session)
241235
await options.cookieAdapter.setCookie(cookie)
242236

243237
return {
@@ -263,8 +257,8 @@ export function createPluginAssetService(options: {
263257
async revokeByOwnerSessionId(ownerSessionId) {
264258
await revokeSessions(server.revokeByOwnerSessionId(ownerSessionId))
265259
},
266-
async revokeByPluginId(pluginId) {
267-
await revokeSessions(server.revokeByExtensionId(pluginId))
260+
async revokeByExtensionId(extensionId) {
261+
await revokeSessions(server.revokeByExtensionId(extensionId))
268262
},
269263
async revokeAll() {
270264
await revokeSessions(server.revokeAll())

0 commit comments

Comments
 (0)