Skip to content

Commit

Permalink
fix(one): improve import / code env isolation to avoid server code ge…
Browse files Browse the repository at this point in the history
…tting into client
  • Loading branch information
natew committed Jan 23, 2025
1 parent c5f029f commit 0bad641
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 12 deletions.
4 changes: 3 additions & 1 deletion packages/one/src/utils/serverContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -113,5 +113,7 @@ export function getServerData(key: keyof One.ClientData) {
if (process.env.VITE_ENVIRONMENT === 'ssr') {
throw new Error(`Cannot getServerData on the server`)
}
return getServerContext()?.postRenderData?.[key]
if (process.env.VITE_ENVIRONMENT !== 'ssr') {
return getServerContext()?.postRenderData?.[key]
}
}
33 changes: 23 additions & 10 deletions packages/one/src/vite/server.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,39 @@
import { AsyncLocalStorage } from 'node:async_hooks'
import { ensureAsyncLocalID } from '../utils/one__ensureAsyncLocalID'

const newContext = new AsyncLocalStorage()
const existing = globalThis['__vxrnrequestAsyncLocalStore'] as typeof newContext
export const requestAsyncLocalStore = existing ?? newContext

const newCache = new WeakMap<any, Headers>()
export const asyncHeadersCache =
(globalThis['__vxrnasyncHeadersCache'] as typeof newCache) ?? newCache

// NOTE: we have a big issue right now, we have "one" in optimizeDeps
// because otherwise you get an error when Root imports Text/View from react-native
// even though react-native is in optimizeDeps, it seems thats not working
// but what happens is that somehow one is imported directly by node right away
// and then later its imported through optimizeDeps, a seaprate instance, creating a separate requestAsyncLocalStore
globalThis['__vxrnrequestAsyncLocalStore'] ||= requestAsyncLocalStore
type ALSInstance = AsyncLocalStorage<unknown>

const key = '__vxrnrequestAsyncLocalStore'
const read = () => globalThis[key] as ALSInstance | undefined

const ASYNC_LOCAL_STORE = {
get current() {
if (read()) return read()
const _ = new AsyncLocalStorage()
globalThis[key] = _
return _
},
}

export const requestAsyncLocalStore =
process.env.VITE_ENVIRONMENT === 'ssr' ? ASYNC_LOCAL_STORE.current : null

const newCache = new WeakMap<any, Headers>()

export const asyncHeadersCache =
(globalThis['__vxrnasyncHeadersCache'] as typeof newCache) ?? newCache

globalThis['__vxrnasyncHeadersCache'] ||= asyncHeadersCache

export async function runWithAsyncLocalContext<A>(cb: (id: Object) => Promise<A>): Promise<A> {
const id = { _id: Math.random() }
let out: A = null as any
await requestAsyncLocalStore.run(id, async () => {
await ASYNC_LOCAL_STORE.current!.run(id, async () => {
out = await cb(id)
})
return out
Expand Down
4 changes: 3 additions & 1 deletion packages/one/types/vite/server.d.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { AsyncLocalStorage } from 'node:async_hooks';
export declare const requestAsyncLocalStore: AsyncLocalStorage<unknown>;
type ALSInstance = AsyncLocalStorage<unknown>;
export declare const requestAsyncLocalStore: ALSInstance | null | undefined;
export declare const asyncHeadersCache: WeakMap<any, Headers>;
export declare function runWithAsyncLocalContext<A>(cb: (id: Object) => Promise<A>): Promise<A>;
export declare function setResponseHeaders(cb: (headers: Headers) => void): Promise<void>;
export declare function mergeHeaders(onto: Headers, from: Headers): void;
export {};
//# sourceMappingURL=server.d.ts.map

0 comments on commit 0bad641

Please sign in to comment.