Enable routing to env variable
This commit is contained in:
parent
8acfa11bf1
commit
79205efae3
@ -3,10 +3,10 @@ import useWebSocket from 'react-use-websocket'
|
||||
|
||||
import assertNever from '~/common/assertNever.ts'
|
||||
|
||||
import { useUser } from '../user.tsx'
|
||||
|
||||
import { AsyncHandle, GameCommand, GameAction } from './types.ts'
|
||||
|
||||
const WS_URL = Deno.env.get("WS_URL")
|
||||
|
||||
const MY_ID = (function(){
|
||||
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
|
||||
var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
|
||||
@ -81,10 +81,9 @@ interface SocketHandle {
|
||||
export default function useServerSocket(
|
||||
onUpdate: (action: GameAction) => void
|
||||
): AsyncHandle<SocketHandle> {
|
||||
const profile = useUser()
|
||||
const [state, dispatch] = React.useReducer(reducer, initialState)
|
||||
|
||||
// prep socket
|
||||
/* prep socket */
|
||||
|
||||
const onMessage = React.useCallback((message: WebSocketEventMap['message']) => {
|
||||
const data = JSON.parse(message.data)
|
||||
@ -157,13 +156,8 @@ export default function useServerSocket(
|
||||
dispatch({type: 'close'})
|
||||
}, [])
|
||||
|
||||
const url = React.useMemo(
|
||||
() => `ws://localhost:7636/ws`,
|
||||
[profile],
|
||||
)
|
||||
|
||||
const {sendJsonMessage} = useWebSocket(
|
||||
url,
|
||||
WS_URL,
|
||||
{onMessage, onOpen, onError, onClose, shouldReconnect},
|
||||
)
|
||||
|
||||
@ -182,7 +176,7 @@ export default function useServerSocket(
|
||||
})
|
||||
}, [state, sendJson])
|
||||
|
||||
// effects to push the coordinator along
|
||||
/* effects to push the coordinator along */
|
||||
|
||||
React.useEffect(() => {
|
||||
if (state.status !== 'finding-game') return
|
||||
@ -194,7 +188,7 @@ export default function useServerSocket(
|
||||
sendJson({command: 'join', player_id: state.playerId, match_id: state.matchId})
|
||||
}, [sendJson, state])
|
||||
|
||||
// return game command handler in wrapper
|
||||
/* return game command handler in wrapper */
|
||||
|
||||
const handle = React.useMemo<AsyncHandle<SocketHandle>>(() => {
|
||||
switch (state.status) {
|
||||
|
1
run-local.sh
Executable file
1
run-local.sh
Executable file
@ -0,0 +1 @@
|
||||
WS_URL=ws://localhost:7636 deno run --allow-read --allow-write --unstable --allow-env --allow-net --import-map import_map.json ./server/server.ts
|
@ -5,6 +5,66 @@ import { Router } from 'oak'
|
||||
|
||||
// import App from '~/client/App.tsx'
|
||||
|
||||
function indexOfAll(source: string, query: string): number[] {
|
||||
let currentPosition = 0
|
||||
const buffer: number[] = []
|
||||
while (currentPosition !== -1) {
|
||||
const lastPosition = currentPosition
|
||||
currentPosition = source.indexOf(query, lastPosition + 1)
|
||||
if (currentPosition !== -1) buffer.push(currentPosition)
|
||||
}
|
||||
// ensure it's sorted in case while loop betrays us
|
||||
return buffer.sort()
|
||||
}
|
||||
|
||||
interface ResolvedEnvVar {
|
||||
callsiteBounds: [number, number]
|
||||
varname: string
|
||||
value?: string
|
||||
}
|
||||
|
||||
const ENV_SEARCH_STRING = "Deno.env.get(\""
|
||||
const ENV_SEARCH_END_STRING = "\")"
|
||||
|
||||
function resolveClientDenoEnvVars(source: string): string {
|
||||
const startIndices = indexOfAll(source, ENV_SEARCH_STRING)
|
||||
const resolved = startIndices.map((startIndex) => {
|
||||
const endIndex = source.indexOf(ENV_SEARCH_END_STRING, startIndex)
|
||||
const varname = source.slice(startIndex + ENV_SEARCH_STRING.length, endIndex)
|
||||
const bounds = [startIndex, endIndex + ENV_SEARCH_END_STRING.length]
|
||||
const value = Deno.env.get(varname)
|
||||
return {
|
||||
callsiteBounds: bounds,
|
||||
varname,
|
||||
value: `"${value}"`,
|
||||
}
|
||||
})
|
||||
|
||||
function replaceBounds(input: string, newText: string | undefined, start: number, end: number) {
|
||||
return `${input.slice(0, start)}${newText}${input.slice(end)}`
|
||||
}
|
||||
|
||||
// reassemble source code by reversing the order and replacing strings
|
||||
const reassembledSource = resolved.reverse().reduce(
|
||||
(currentSource, {callsiteBounds, value, varname}) => {
|
||||
if (value === undefined)
|
||||
throw new Error(`Deno env variable ${varname} found in client code but not provided to server.`)
|
||||
return replaceBounds(currentSource, value, callsiteBounds[0], callsiteBounds[1])
|
||||
},
|
||||
source,
|
||||
)
|
||||
return reassembledSource
|
||||
}
|
||||
|
||||
function mapDict<T, U>(
|
||||
dict: Record<string, T>,
|
||||
fn: (entry: [string, T], index: number) => [string, U],
|
||||
): Record<string, U> {
|
||||
return Object.fromEntries(
|
||||
Object.entries(dict).map(fn)
|
||||
)
|
||||
}
|
||||
|
||||
async function createClientBundle() {
|
||||
const {files} = await Deno.emit('server/client.tsx', {
|
||||
bundle: 'module',
|
||||
@ -16,7 +76,15 @@ async function createClientBundle() {
|
||||
strictPropertyInitialization: false,
|
||||
},
|
||||
})
|
||||
return files
|
||||
const bundle = mapDict(files, ([path, source], i) => {
|
||||
const resolved = resolveClientDenoEnvVars(source)
|
||||
if (Deno.env.get("DEBUG")) {
|
||||
Deno.writeTextFileSync(`debug/output${i}.js`, source)
|
||||
Deno.writeTextFileSync(`debug/resolved${i}.js`, resolved)
|
||||
}
|
||||
return [path, resolved]
|
||||
})
|
||||
return bundle
|
||||
}
|
||||
|
||||
const bundle = await createClientBundle()
|
||||
|
Loading…
Reference in New Issue
Block a user