|
|
@@ -36,6 +36,7 @@ vi.mock('node:crypto', async (importOriginal) => {
|
|
|
|
|
|
const randomUuid = vi.mocked(randomUUID)
|
|
|
const browserCookies = new WeakMap<Context, string>()
|
|
|
+const REMOTE_HOST = { home: '/home/fixture' } as const
|
|
|
type AgentWireId = TypertContextWire<TypertContextMap['agent']>
|
|
|
const agentId = (value: string): AgentWireId => value as AgentWireId
|
|
|
|
|
|
@@ -386,8 +387,8 @@ describe('Typert Remote streams', () => {
|
|
|
}
|
|
|
})()
|
|
|
}
|
|
|
- const unregister = ctx.typertGateway.registerRemoteEvents(source)
|
|
|
- expect(() => { ctx.typertGateway.registerRemoteEvents(source) })
|
|
|
+ const unregister = ctx.typertGateway.registerRemoteEvents(source, REMOTE_HOST)
|
|
|
+ expect(() => { ctx.typertGateway.registerRemoteEvents(source, REMOTE_HOST) })
|
|
|
.toThrow('forwarded Remote event source is already registered')
|
|
|
|
|
|
const socket = new WebSocket(`ws://127.0.0.1:${String(ctx.webServer.port)}/api/remote.mux`, {
|
|
|
@@ -402,7 +403,7 @@ describe('Typert Remote streams', () => {
|
|
|
const eventFrames = frames.filter(frame => frame.streamId === 'events')
|
|
|
expect(eventFrames).toHaveLength(1)
|
|
|
expect(eventFrames[0]).toMatchObject({
|
|
|
- type: 'item', streamId: 'events', value: { type: 'ready' },
|
|
|
+ type: 'item', streamId: 'events', value: { type: 'ready', host: REMOTE_HOST },
|
|
|
})
|
|
|
expect(typeof Reflect.get(eventFrames[0]!.value as object, 'clientId')).toBe('string')
|
|
|
})
|
|
|
@@ -411,7 +412,7 @@ describe('Typert Remote streams', () => {
|
|
|
const eventFrames = frames.filter(frame => frame.streamId === 'events').slice(0, 2)
|
|
|
expect(eventFrames).toHaveLength(2)
|
|
|
expect(eventFrames[0]).toMatchObject({
|
|
|
- type: 'item', streamId: 'events', value: { type: 'ready' },
|
|
|
+ type: 'item', streamId: 'events', value: { type: 'ready', host: REMOTE_HOST },
|
|
|
})
|
|
|
expect(typeof Reflect.get(eventFrames[0]!.value as object, 'clientId')).toBe('string')
|
|
|
expect(eventFrames[1]).toEqual({
|
|
|
@@ -429,9 +430,9 @@ describe('Typert Remote streams', () => {
|
|
|
expect(frames).toContainEqual({ type: 'end', streamId: 'events' })
|
|
|
})
|
|
|
|
|
|
- const unregisterReplacement = ctx.typertGateway.registerRemoteEvents(source)
|
|
|
+ const unregisterReplacement = ctx.typertGateway.registerRemoteEvents(source, REMOTE_HOST)
|
|
|
await unregister()
|
|
|
- expect(() => { ctx.typertGateway.registerRemoteEvents(source) })
|
|
|
+ expect(() => { ctx.typertGateway.registerRemoteEvents(source, REMOTE_HOST) })
|
|
|
.toThrow('forwarded Remote event source is already registered')
|
|
|
await unregisterReplacement()
|
|
|
socket.close()
|
|
|
@@ -446,7 +447,7 @@ describe('Typert Remote streams', () => {
|
|
|
await publish.promise
|
|
|
yield pending.dispatch
|
|
|
})()
|
|
|
- const unregister = ctx.typertGateway.registerRemoteEvents(source)
|
|
|
+ const unregister = ctx.typertGateway.registerRemoteEvents(source, REMOTE_HOST)
|
|
|
const rejected = expect(pending.outcome).rejects.toThrow(
|
|
|
'forwarded Remote event source was removed',
|
|
|
)
|
|
|
@@ -479,7 +480,7 @@ describe('Typert Remote streams', () => {
|
|
|
else signal.addEventListener('abort', () => { resolve() }, { once: true })
|
|
|
})
|
|
|
throw new Error('fixture source rejected during removal')
|
|
|
- })())
|
|
|
+ })(), REMOTE_HOST)
|
|
|
const client = await openEventClient(ctx, 'events-removal')
|
|
|
await vi.waitFor(() => { expect(deliveredInvocation(client)).toBeDefined() })
|
|
|
|
|
|
@@ -496,7 +497,7 @@ describe('Typert Remote streams', () => {
|
|
|
it('delegates unavailable Contexts and rejects malformed scoped invocations', async () => {
|
|
|
const { ctx } = await setup(false)
|
|
|
const source = new RemoteEventSourceProbe()
|
|
|
- const unregister = ctx.typertGateway.registerRemoteEvents(source.source)
|
|
|
+ const unregister = ctx.typertGateway.registerRemoteEvents(source.source, REMOTE_HOST)
|
|
|
|
|
|
for (const event of [42, ''] as const) {
|
|
|
const invalidName = pendingInvocation(ctx)
|
|
|
@@ -579,7 +580,7 @@ describe('Typert Remote streams', () => {
|
|
|
return (async function* () {
|
|
|
yield frame as unknown as TypertRemoteEventDispatch
|
|
|
})()
|
|
|
- })
|
|
|
+ }, REMOTE_HOST)
|
|
|
await vi.waitFor(() => { expect(sourceSignal?.aborted).toBe(true) })
|
|
|
const reason: unknown = sourceSignal?.reason
|
|
|
if (!(reason instanceof Error)) throw new Error('Remote event source did not fail with an Error')
|
|
|
@@ -591,7 +592,7 @@ describe('Typert Remote streams', () => {
|
|
|
it('retries a colliding Remote event id before publishing the second waterfall', async () => {
|
|
|
const { ctx } = await setup(false)
|
|
|
const source = new RemoteEventSourceProbe()
|
|
|
- const unregister = ctx.typertGateway.registerRemoteEvents(source.source)
|
|
|
+ const unregister = ctx.typertGateway.registerRemoteEvents(source.source, REMOTE_HOST)
|
|
|
const agent = ctx.extend()
|
|
|
ctx.typert.contexts.registerHost('agent', {
|
|
|
wire: 'agentId',
|
|
|
@@ -626,7 +627,7 @@ describe('Typert Remote streams', () => {
|
|
|
it('retries a colliding Remote event Client id before opening the second generation', async () => {
|
|
|
const { ctx } = await setup(true)
|
|
|
const source = new RemoteEventSourceProbe()
|
|
|
- const unregister = ctx.typertGateway.registerRemoteEvents(source.source)
|
|
|
+ const unregister = ctx.typertGateway.registerRemoteEvents(source.source, REMOTE_HOST)
|
|
|
const firstId = '00000000-0000-4000-8000-000000000011' as ReturnType<typeof randomUUID>
|
|
|
const secondId = '00000000-0000-4000-8000-000000000012' as ReturnType<typeof randomUUID>
|
|
|
randomUuid.mockReturnValueOnce(firstId).mockReturnValueOnce(firstId).mockReturnValueOnce(secondId)
|
|
|
@@ -645,7 +646,7 @@ describe('Typert Remote streams', () => {
|
|
|
it('fans one scoped waterfall out and accepts the first Client result', async () => {
|
|
|
const { ctx } = await setup(true)
|
|
|
const source = new RemoteEventSourceProbe()
|
|
|
- const unregister = ctx.typertGateway.registerRemoteEvents(source.source)
|
|
|
+ const unregister = ctx.typertGateway.registerRemoteEvents(source.source, REMOTE_HOST)
|
|
|
const agent = ctx.extend()
|
|
|
ctx.typert.contexts.registerHost('agent', {
|
|
|
wire: 'agentId',
|
|
|
@@ -699,7 +700,7 @@ describe('Typert Remote streams', () => {
|
|
|
it('rejects the Host waterfall with the first Client listener rejection', async () => {
|
|
|
const { ctx } = await setup(true)
|
|
|
const source = new RemoteEventSourceProbe()
|
|
|
- const unregister = ctx.typertGateway.registerRemoteEvents(source.source)
|
|
|
+ const unregister = ctx.typertGateway.registerRemoteEvents(source.source, REMOTE_HOST)
|
|
|
const agent = ctx.extend()
|
|
|
ctx.typert.contexts.registerHost('agent', {
|
|
|
wire: 'agentId',
|
|
|
@@ -739,7 +740,7 @@ describe('Typert Remote streams', () => {
|
|
|
it('delegates to the Host only after every active Client returns next', async () => {
|
|
|
const { ctx } = await setup(true)
|
|
|
const source = new RemoteEventSourceProbe()
|
|
|
- const unregister = ctx.typertGateway.registerRemoteEvents(source.source)
|
|
|
+ const unregister = ctx.typertGateway.registerRemoteEvents(source.source, REMOTE_HOST)
|
|
|
const agent = ctx.extend()
|
|
|
ctx.typert.contexts.registerHost('agent', {
|
|
|
wire: 'agentId',
|
|
|
@@ -772,7 +773,7 @@ describe('Typert Remote streams', () => {
|
|
|
it('delivers a pending waterfall to the first Client that connects', async () => {
|
|
|
const { ctx } = await setup(true)
|
|
|
const source = new RemoteEventSourceProbe()
|
|
|
- const unregister = ctx.typertGateway.registerRemoteEvents(source.source)
|
|
|
+ const unregister = ctx.typertGateway.registerRemoteEvents(source.source, REMOTE_HOST)
|
|
|
const agent = ctx.extend()
|
|
|
ctx.typert.contexts.registerHost('agent', {
|
|
|
wire: 'agentId',
|
|
|
@@ -805,7 +806,7 @@ describe('Typert Remote streams', () => {
|
|
|
it('replays a pending event id to a replacement Client generation', async () => {
|
|
|
const { ctx } = await setup(true)
|
|
|
const source = new RemoteEventSourceProbe()
|
|
|
- const unregister = ctx.typertGateway.registerRemoteEvents(source.source)
|
|
|
+ const unregister = ctx.typertGateway.registerRemoteEvents(source.source, REMOTE_HOST)
|
|
|
const agent = ctx.extend()
|
|
|
ctx.typert.contexts.registerHost('agent', {
|
|
|
wire: 'agentId',
|
|
|
@@ -839,7 +840,7 @@ describe('Typert Remote streams', () => {
|
|
|
it('cancels pending deliveries when the Host signal or Context ends', async () => {
|
|
|
const { ctx } = await setup(true)
|
|
|
const source = new RemoteEventSourceProbe()
|
|
|
- const unregister = ctx.typertGateway.registerRemoteEvents(source.source)
|
|
|
+ const unregister = ctx.typertGateway.registerRemoteEvents(source.source, REMOTE_HOST)
|
|
|
const signalAgent = ctx.extend()
|
|
|
const contextFiber = ctx.plugin(() => {})
|
|
|
await contextFiber
|
|
|
@@ -929,7 +930,7 @@ describe('Typert Remote streams', () => {
|
|
|
const unregister = ctx.typertGateway.registerRemoteEvents(() => {
|
|
|
sourceCalls += 1
|
|
|
return (async function *(): AsyncIterable<never> {})()
|
|
|
- })
|
|
|
+ }, REMOTE_HOST)
|
|
|
const invalidPayloads: readonly unknown[] = [
|
|
|
null,
|
|
|
[],
|