|
@@ -30,10 +30,16 @@ interface TestSnapshot {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
class TestEventDefinitions {
|
|
class TestEventDefinitions {
|
|
|
|
|
+ readonly definitions: readonly ConversationNodeDefinition[]
|
|
|
|
|
+ readonly fallback: ConversationNodeDefinition | undefined
|
|
|
|
|
+
|
|
|
constructor(
|
|
constructor(
|
|
|
- readonly definitions: readonly ConversationNodeDefinition[],
|
|
|
|
|
- readonly fallback?: ConversationNodeDefinition,
|
|
|
|
|
- ) {}
|
|
|
|
|
|
|
+ definitions: readonly ConversationNodeDefinition[],
|
|
|
|
|
+ fallback?: ConversationNodeDefinition,
|
|
|
|
|
+ ) {
|
|
|
|
|
+ this.definitions = definitions
|
|
|
|
|
+ this.fallback = fallback
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
entries(): readonly ConversationNodeDefinition[] {
|
|
entries(): readonly ConversationNodeDefinition[] {
|
|
|
return this.definitions
|
|
return this.definitions
|
|
@@ -93,7 +99,10 @@ function chatSnapshot(assembler: ConversationNodeAssembler): TestSnapshot | unde
|
|
|
return assembler.snapshot('chat') as TestSnapshot | undefined
|
|
return assembler.snapshot('chat') as TestSnapshot | undefined
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-function node(context: Parameters<ConversationNodeDefinition['buildViewNode']>[0], data: unknown): ConversationViewNode {
|
|
|
|
|
|
|
+function node(
|
|
|
|
|
+ context: Parameters<NonNullable<ConversationNodeDefinition['buildViewNode']>>[0],
|
|
|
|
|
+ data: unknown,
|
|
|
|
|
+): ConversationViewNode {
|
|
|
return {
|
|
return {
|
|
|
key: context.key,
|
|
key: context.key,
|
|
|
kind: context.kind,
|
|
kind: context.kind,
|
|
@@ -103,6 +112,17 @@ function node(context: Parameters<ConversationNodeDefinition['buildViewNode']>[0
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+function fallbackDefinition(start: () => string): ConversationNodeDefinition<string> {
|
|
|
|
|
+ return {
|
|
|
|
|
+ kind: 'fallback',
|
|
|
|
|
+ target: 'chat',
|
|
|
|
|
+ match: event => ({ id: String(event.seq), role: 'start' }),
|
|
|
|
|
+ start,
|
|
|
|
|
+ update: context => context.state,
|
|
|
|
|
+ buildViewNode: context => node(context, context.state),
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
describe('ConversationNodeAssembler', () => {
|
|
describe('ConversationNodeAssembler', () => {
|
|
|
it('appends through an exact business-id Context without replaying unrelated Contexts', () => {
|
|
it('appends through an exact business-id Context without replaying unrelated Contexts', () => {
|
|
|
const starts = vi.fn((
|
|
const starts = vi.fn((
|
|
@@ -122,6 +142,7 @@ describe('ConversationNodeAssembler', () => {
|
|
|
},
|
|
},
|
|
|
start: starts,
|
|
start: starts,
|
|
|
update: updates,
|
|
update: updates,
|
|
|
|
|
+ target: 'chat',
|
|
|
buildViewNode: context => node(context, context.state),
|
|
buildViewNode: context => node(context, context.state),
|
|
|
}
|
|
}
|
|
|
const assembler = new ConversationNodeAssembler(
|
|
const assembler = new ConversationNodeAssembler(
|
|
@@ -173,6 +194,7 @@ describe('ConversationNodeAssembler', () => {
|
|
|
matchCollections.add(context.matches)
|
|
matchCollections.add(context.matches)
|
|
|
return updates(context)
|
|
return updates(context)
|
|
|
},
|
|
},
|
|
|
|
|
+ target: 'chat',
|
|
|
buildViewNode: context => node(context, context.state),
|
|
buildViewNode: context => node(context, context.state),
|
|
|
}
|
|
}
|
|
|
const assembler = new ConversationNodeAssembler(
|
|
const assembler = new ConversationNodeAssembler(
|
|
@@ -208,6 +230,7 @@ describe('ConversationNodeAssembler', () => {
|
|
|
},
|
|
},
|
|
|
start: starts,
|
|
start: starts,
|
|
|
update: updates,
|
|
update: updates,
|
|
|
|
|
+ target: 'chat',
|
|
|
buildViewNode: context => node(context, context.state),
|
|
buildViewNode: context => node(context, context.state),
|
|
|
}
|
|
}
|
|
|
const assembler = new ConversationNodeAssembler(
|
|
const assembler = new ConversationNodeAssembler(
|
|
@@ -247,6 +270,7 @@ describe('ConversationNodeAssembler', () => {
|
|
|
},
|
|
},
|
|
|
start: () => ({ settled: false }),
|
|
start: () => ({ settled: false }),
|
|
|
update: updates,
|
|
update: updates,
|
|
|
|
|
+ target: 'chat',
|
|
|
buildViewNode: context => node(context, context.state ?? { pendingStart: true }),
|
|
buildViewNode: context => node(context, context.state ?? { pendingStart: true }),
|
|
|
}
|
|
}
|
|
|
const assembler = new ConversationNodeAssembler(
|
|
const assembler = new ConversationNodeAssembler(
|
|
@@ -280,6 +304,7 @@ describe('ConversationNodeAssembler', () => {
|
|
|
: event.type === 'turn/start' ? { id: 'one', role: 'update' } : null,
|
|
: event.type === 'turn/start' ? { id: 'one', role: 'update' } : null,
|
|
|
start: () => null,
|
|
start: () => null,
|
|
|
update: context => context.state,
|
|
update: context => context.state,
|
|
|
|
|
+ target: 'chat',
|
|
|
buildViewNode: () => null,
|
|
buildViewNode: () => null,
|
|
|
}
|
|
}
|
|
|
const assembler = new ConversationNodeAssembler(
|
|
const assembler = new ConversationNodeAssembler(
|
|
@@ -301,6 +326,7 @@ describe('ConversationNodeAssembler', () => {
|
|
|
: null,
|
|
: null,
|
|
|
start: (_context, match) => Number((match.event.data as { value?: unknown }).value ?? 0),
|
|
start: (_context, match) => Number((match.event.data as { value?: unknown }).value ?? 0),
|
|
|
update: context => context.state,
|
|
update: context => context.state,
|
|
|
|
|
+ target: 'chat',
|
|
|
buildViewNode: () => null,
|
|
buildViewNode: () => null,
|
|
|
}
|
|
}
|
|
|
const consumerStart = vi.fn((
|
|
const consumerStart = vi.fn((
|
|
@@ -315,6 +341,7 @@ describe('ConversationNodeAssembler', () => {
|
|
|
: null,
|
|
: null,
|
|
|
start: consumerStart,
|
|
start: consumerStart,
|
|
|
update: context => context.state,
|
|
update: context => context.state,
|
|
|
|
|
+ target: 'chat',
|
|
|
buildViewNode: context => node(context, context.state),
|
|
buildViewNode: context => node(context, context.state),
|
|
|
}
|
|
}
|
|
|
const assembler = new ConversationNodeAssembler(
|
|
const assembler = new ConversationNodeAssembler(
|
|
@@ -344,6 +371,7 @@ describe('ConversationNodeAssembler', () => {
|
|
|
: null,
|
|
: null,
|
|
|
start: (_context, match) => match.event.seq,
|
|
start: (_context, match) => match.event.seq,
|
|
|
update: context => context.state,
|
|
update: context => context.state,
|
|
|
|
|
+ target: 'chat',
|
|
|
buildViewNode: () => null,
|
|
buildViewNode: () => null,
|
|
|
}
|
|
}
|
|
|
const consumer: ConversationNodeDefinition<number> = {
|
|
const consumer: ConversationNodeDefinition<number> = {
|
|
@@ -353,6 +381,7 @@ describe('ConversationNodeAssembler', () => {
|
|
|
: null,
|
|
: null,
|
|
|
start: (_context, _match, reader) => reader.previous<number>('source')?.state ?? -1,
|
|
start: (_context, _match, reader) => reader.previous<number>('source')?.state ?? -1,
|
|
|
update: context => context.state,
|
|
update: context => context.state,
|
|
|
|
|
+ target: 'chat',
|
|
|
buildViewNode: context => node(context, context.state),
|
|
buildViewNode: context => node(context, context.state),
|
|
|
}
|
|
}
|
|
|
const assembler = new ConversationNodeAssembler(
|
|
const assembler = new ConversationNodeAssembler(
|
|
@@ -397,6 +426,7 @@ describe('ConversationNodeAssembler', () => {
|
|
|
: null,
|
|
: null,
|
|
|
start: consumerStart,
|
|
start: consumerStart,
|
|
|
update: context => context.state,
|
|
update: context => context.state,
|
|
|
|
|
+ target: 'chat',
|
|
|
buildViewNode: context => node(context, context.state),
|
|
buildViewNode: context => node(context, context.state),
|
|
|
}
|
|
}
|
|
|
const assembler = new ConversationNodeAssembler(
|
|
const assembler = new ConversationNodeAssembler(
|
|
@@ -425,6 +455,7 @@ describe('ConversationNodeAssembler', () => {
|
|
|
},
|
|
},
|
|
|
start: () => 1,
|
|
start: () => 1,
|
|
|
update: (_context, match) => (match.event.data as unknown as { value: number }).value,
|
|
update: (_context, match) => (match.event.data as unknown as { value: number }).value,
|
|
|
|
|
+ target: 'chat',
|
|
|
buildViewNode: () => null,
|
|
buildViewNode: () => null,
|
|
|
}
|
|
}
|
|
|
const consumerStart = vi.fn((
|
|
const consumerStart = vi.fn((
|
|
@@ -439,6 +470,7 @@ describe('ConversationNodeAssembler', () => {
|
|
|
: null,
|
|
: null,
|
|
|
start: consumerStart,
|
|
start: consumerStart,
|
|
|
update: context => context.state,
|
|
update: context => context.state,
|
|
|
|
|
+ target: 'chat',
|
|
|
buildViewNode: context => node(context, context.state),
|
|
buildViewNode: context => node(context, context.state),
|
|
|
}
|
|
}
|
|
|
const assembler = new ConversationNodeAssembler(
|
|
const assembler = new ConversationNodeAssembler(
|
|
@@ -468,6 +500,7 @@ describe('ConversationNodeAssembler', () => {
|
|
|
},
|
|
},
|
|
|
start: () => 1,
|
|
start: () => 1,
|
|
|
update: (_context, match) => (match.event.data as unknown as { value: number }).value,
|
|
update: (_context, match) => (match.event.data as unknown as { value: number }).value,
|
|
|
|
|
+ target: 'chat',
|
|
|
buildViewNode: () => null,
|
|
buildViewNode: () => null,
|
|
|
}
|
|
}
|
|
|
const sourceX: ConversationNodeDefinition<number> = {
|
|
const sourceX: ConversationNodeDefinition<number> = {
|
|
@@ -479,6 +512,7 @@ describe('ConversationNodeAssembler', () => {
|
|
|
},
|
|
},
|
|
|
start: () => 10,
|
|
start: () => 10,
|
|
|
update: (_context, match) => (match.event.data as unknown as { value: number }).value,
|
|
update: (_context, match) => (match.event.data as unknown as { value: number }).value,
|
|
|
|
|
+ target: 'chat',
|
|
|
buildViewNode: () => null,
|
|
buildViewNode: () => null,
|
|
|
}
|
|
}
|
|
|
const middle: ConversationNodeDefinition<number> = {
|
|
const middle: ConversationNodeDefinition<number> = {
|
|
@@ -491,6 +525,7 @@ describe('ConversationNodeAssembler', () => {
|
|
|
+ (reader.previous<number>('diamond-x')?.state ?? 0)
|
|
+ (reader.previous<number>('diamond-x')?.state ?? 0)
|
|
|
),
|
|
),
|
|
|
update: context => context.state,
|
|
update: context => context.state,
|
|
|
|
|
+ target: 'chat',
|
|
|
buildViewNode: context => node(context, context.state),
|
|
buildViewNode: context => node(context, context.state),
|
|
|
}
|
|
}
|
|
|
const consumer: ConversationNodeDefinition<number> = {
|
|
const consumer: ConversationNodeDefinition<number> = {
|
|
@@ -503,6 +538,7 @@ describe('ConversationNodeAssembler', () => {
|
|
|
+ (reader.previous<number>('diamond-b')?.state ?? 0)
|
|
+ (reader.previous<number>('diamond-b')?.state ?? 0)
|
|
|
),
|
|
),
|
|
|
update: context => context.state,
|
|
update: context => context.state,
|
|
|
|
|
+ target: 'chat',
|
|
|
buildViewNode: context => node(context, context.state),
|
|
buildViewNode: context => node(context, context.state),
|
|
|
}
|
|
}
|
|
|
const assembler = new ConversationNodeAssembler(
|
|
const assembler = new ConversationNodeAssembler(
|
|
@@ -538,6 +574,7 @@ describe('ConversationNodeAssembler', () => {
|
|
|
: null,
|
|
: null,
|
|
|
start: starts,
|
|
start: starts,
|
|
|
update: context => context.state,
|
|
update: context => context.state,
|
|
|
|
|
+ target: 'chat',
|
|
|
buildViewNode: context => node(context, context.state),
|
|
buildViewNode: context => node(context, context.state),
|
|
|
}
|
|
}
|
|
|
const assembler = new ConversationNodeAssembler(
|
|
const assembler = new ConversationNodeAssembler(
|
|
@@ -609,6 +646,7 @@ describe('ConversationNodeAssembler', () => {
|
|
|
value: { valueSeenFromStep: stepValue ?? -1 },
|
|
value: { valueSeenFromStep: stepValue ?? -1 },
|
|
|
}
|
|
}
|
|
|
},
|
|
},
|
|
|
|
|
+ target: 'chat',
|
|
|
buildViewNode: (context) => {
|
|
buildViewNode: (context) => {
|
|
|
const location = context.start?.location
|
|
const location = context.start?.location
|
|
|
if (location?.kind !== 'step') return null
|
|
if (location?.kind !== 'step') return null
|
|
@@ -646,6 +684,7 @@ describe('ConversationNodeAssembler', () => {
|
|
|
: null,
|
|
: null,
|
|
|
start: () => null,
|
|
start: () => null,
|
|
|
update: context => context.state,
|
|
update: context => context.state,
|
|
|
|
|
+ target: 'chat',
|
|
|
buildViewNode: context => node(context, context.start?.location.kind === 'turn'
|
|
buildViewNode: context => node(context, context.start?.location.kind === 'turn'
|
|
|
? context.start.location.turn.steps.length
|
|
? context.start.location.turn.steps.length
|
|
|
: -1),
|
|
: -1),
|
|
@@ -701,6 +740,7 @@ describe('ConversationNodeAssembler', () => {
|
|
|
},
|
|
},
|
|
|
start: () => null,
|
|
start: () => null,
|
|
|
update: context => context.state,
|
|
update: context => context.state,
|
|
|
|
|
+ target: 'chat',
|
|
|
buildViewNode: (context) => {
|
|
buildViewNode: (context) => {
|
|
|
const location = context.start?.location
|
|
const location = context.start?.location
|
|
|
const data = location?.kind === 'step'
|
|
const data = location?.kind === 'step'
|
|
@@ -734,6 +774,7 @@ describe('ConversationNodeAssembler', () => {
|
|
|
: null,
|
|
: null,
|
|
|
start: () => null,
|
|
start: () => null,
|
|
|
update: context => context.state,
|
|
update: context => context.state,
|
|
|
|
|
+ target: 'chat',
|
|
|
buildViewNode: context => node(context, context.start?.location.kind),
|
|
buildViewNode: context => node(context, context.start?.location.kind),
|
|
|
}
|
|
}
|
|
|
const assembler = new ConversationNodeAssembler(
|
|
const assembler = new ConversationNodeAssembler(
|
|
@@ -760,6 +801,7 @@ describe('ConversationNodeAssembler', () => {
|
|
|
: null,
|
|
: null,
|
|
|
start: () => null,
|
|
start: () => null,
|
|
|
update: context => context.state,
|
|
update: context => context.state,
|
|
|
|
|
+ target: 'chat',
|
|
|
buildViewNode: (context) => {
|
|
buildViewNode: (context) => {
|
|
|
const location = context.start?.location
|
|
const location = context.start?.location
|
|
|
return node(context, location?.kind === 'step'
|
|
return node(context, location?.kind === 'step'
|
|
@@ -792,6 +834,7 @@ describe('ConversationNodeAssembler', () => {
|
|
|
: null,
|
|
: null,
|
|
|
start: () => null,
|
|
start: () => null,
|
|
|
update: context => context.state,
|
|
update: context => context.state,
|
|
|
|
|
+ target: 'chat',
|
|
|
buildViewNode: (context) => {
|
|
buildViewNode: (context) => {
|
|
|
const location = context.start?.location
|
|
const location = context.start?.location
|
|
|
return node(context, location?.kind === 'step'
|
|
return node(context, location?.kind === 'step'
|
|
@@ -826,6 +869,7 @@ describe('ConversationNodeAssembler', () => {
|
|
|
: null,
|
|
: null,
|
|
|
start: seen,
|
|
start: seen,
|
|
|
update: context => context.state,
|
|
update: context => context.state,
|
|
|
|
|
+ target: 'chat',
|
|
|
buildViewNode: context => node(context, context.state),
|
|
buildViewNode: context => node(context, context.state),
|
|
|
}
|
|
}
|
|
|
const assembler = new ConversationNodeAssembler(
|
|
const assembler = new ConversationNodeAssembler(
|
|
@@ -841,24 +885,64 @@ describe('ConversationNodeAssembler', () => {
|
|
|
expect(seen).toHaveBeenCalledTimes(2)
|
|
expect(seen).toHaveBeenCalledTimes(2)
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
- it('does not invoke the fallback when an ordinary non-rendering Definition claims an event', () => {
|
|
|
|
|
|
|
+ it('invokes the fallback when only a State-only Definition claims an event', () => {
|
|
|
const fallbackStart = vi.fn(() => 'fallback')
|
|
const fallbackStart = vi.fn(() => 'fallback')
|
|
|
const claimed: ConversationNodeDefinition<null> = {
|
|
const claimed: ConversationNodeDefinition<null> = {
|
|
|
- kind: 'claimed',
|
|
|
|
|
- match: event => (event.type as string) === 'command/run' ? { id: 'claimed', role: 'start' } : null,
|
|
|
|
|
|
|
+ kind: 'claimed-state',
|
|
|
|
|
+ match: event => (event.type as string) === 'command/run'
|
|
|
|
|
+ ? { id: 'claimed', role: 'start' }
|
|
|
|
|
+ : null,
|
|
|
|
|
+ start: () => null,
|
|
|
|
|
+ update: context => context.state,
|
|
|
|
|
+ }
|
|
|
|
|
+ const assembler = new ConversationNodeAssembler(
|
|
|
|
|
+ new TestEventDefinitions([claimed], fallbackDefinition(fallbackStart)),
|
|
|
|
|
+ new TestViewDefinitions([testView()]),
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ assembler.replaceWindow([input(at(1, 'command/run', { commandId: 'one', name: 'x' }))], false)
|
|
|
|
|
+ assembler.flush()
|
|
|
|
|
+
|
|
|
|
|
+ expect(fallbackStart).toHaveBeenCalledOnce()
|
|
|
|
|
+ expect(chatSnapshot(assembler)?.order).toHaveLength(1)
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ it('invokes the fallback when only another target claims an event', () => {
|
|
|
|
|
+ const fallbackStart = vi.fn(() => 'fallback')
|
|
|
|
|
+ const claimed: ConversationNodeDefinition<null> = {
|
|
|
|
|
+ kind: 'claimed-trajectory',
|
|
|
|
|
+ target: 'trajectory',
|
|
|
|
|
+ match: event => (event.type as string) === 'command/run'
|
|
|
|
|
+ ? { id: 'claimed', role: 'start' }
|
|
|
|
|
+ : null,
|
|
|
start: () => null,
|
|
start: () => null,
|
|
|
update: context => context.state,
|
|
update: context => context.state,
|
|
|
buildViewNode: () => null,
|
|
buildViewNode: () => null,
|
|
|
}
|
|
}
|
|
|
- const fallback: ConversationNodeDefinition<string> = {
|
|
|
|
|
- kind: 'fallback',
|
|
|
|
|
- match: event => ({ id: String(event.seq), role: 'start' }),
|
|
|
|
|
- start: fallbackStart,
|
|
|
|
|
|
|
+ const assembler = new ConversationNodeAssembler(
|
|
|
|
|
+ new TestEventDefinitions([claimed], fallbackDefinition(fallbackStart)),
|
|
|
|
|
+ new TestViewDefinitions([testView()]),
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ assembler.replaceWindow([input(at(1, 'command/run', { commandId: 'one', name: 'x' }))], false)
|
|
|
|
|
+ assembler.flush()
|
|
|
|
|
+
|
|
|
|
|
+ expect(fallbackStart).toHaveBeenCalledOnce()
|
|
|
|
|
+ expect(chatSnapshot(assembler)?.order).toHaveLength(1)
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ it('suppresses the fallback when the same target claims an event', () => {
|
|
|
|
|
+ const fallbackStart = vi.fn(() => 'fallback')
|
|
|
|
|
+ const claimed: ConversationNodeDefinition<null> = {
|
|
|
|
|
+ kind: 'claimed',
|
|
|
|
|
+ target: 'chat',
|
|
|
|
|
+ match: event => (event.type as string) === 'command/run' ? { id: 'claimed', role: 'start' } : null,
|
|
|
|
|
+ start: () => null,
|
|
|
update: context => context.state,
|
|
update: context => context.state,
|
|
|
- buildViewNode: context => node(context, context.state),
|
|
|
|
|
|
|
+ buildViewNode: () => null,
|
|
|
}
|
|
}
|
|
|
const assembler = new ConversationNodeAssembler(
|
|
const assembler = new ConversationNodeAssembler(
|
|
|
- new TestEventDefinitions([claimed], fallback),
|
|
|
|
|
|
|
+ new TestEventDefinitions([claimed], fallbackDefinition(fallbackStart)),
|
|
|
new TestViewDefinitions([testView()]),
|
|
new TestViewDefinitions([testView()]),
|
|
|
)
|
|
)
|
|
|
assembler.replaceWindow([input(at(1, 'command/run', { commandId: 'one', name: 'x' }))], false)
|
|
assembler.replaceWindow([input(at(1, 'command/run', { commandId: 'one', name: 'x' }))], false)
|
|
@@ -878,6 +962,7 @@ describe('ConversationNodeAssembler', () => {
|
|
|
},
|
|
},
|
|
|
start: () => true,
|
|
start: () => true,
|
|
|
update: () => false,
|
|
update: () => false,
|
|
|
|
|
+ target: 'chat',
|
|
|
buildViewNode: context => context.state === true ? node(context, true) : null,
|
|
buildViewNode: context => context.state === true ? node(context, true) : null,
|
|
|
}
|
|
}
|
|
|
const assembler = new ConversationNodeAssembler(
|
|
const assembler = new ConversationNodeAssembler(
|
|
@@ -900,6 +985,7 @@ describe('ConversationNodeAssembler', () => {
|
|
|
match: event => (event.type as string) === 'command/run' ? { id: 'one', role: 'start' } : null,
|
|
match: event => (event.type as string) === 'command/run' ? { id: 'one', role: 'start' } : null,
|
|
|
start: () => undefined,
|
|
start: () => undefined,
|
|
|
update: context => context.state,
|
|
update: context => context.state,
|
|
|
|
|
+ target: 'chat',
|
|
|
buildViewNode: () => null,
|
|
buildViewNode: () => null,
|
|
|
}
|
|
}
|
|
|
const startAssembler = new ConversationNodeAssembler(
|
|
const startAssembler = new ConversationNodeAssembler(
|
|
@@ -919,6 +1005,7 @@ describe('ConversationNodeAssembler', () => {
|
|
|
},
|
|
},
|
|
|
start: () => true,
|
|
start: () => true,
|
|
|
update: () => undefined as never,
|
|
update: () => undefined as never,
|
|
|
|
|
+ target: 'chat',
|
|
|
buildViewNode: context => node(context, context.state),
|
|
buildViewNode: context => node(context, context.state),
|
|
|
}
|
|
}
|
|
|
const updateAssembler = new ConversationNodeAssembler(
|
|
const updateAssembler = new ConversationNodeAssembler(
|
|
@@ -939,6 +1026,7 @@ describe('ConversationNodeAssembler', () => {
|
|
|
match: event => (event.type as string) === 'command/run' ? { id: 'one', role: 'start' } : null,
|
|
match: event => (event.type as string) === 'command/run' ? { id: 'one', role: 'start' } : null,
|
|
|
start: (_context, match) => match.event.seq,
|
|
start: (_context, match) => match.event.seq,
|
|
|
update: context => context.state,
|
|
update: context => context.state,
|
|
|
|
|
+ target: 'chat',
|
|
|
buildViewNode: context => node(context, context.state),
|
|
buildViewNode: context => node(context, context.state),
|
|
|
}
|
|
}
|
|
|
const assembler = new ConversationNodeAssembler(
|
|
const assembler = new ConversationNodeAssembler(
|