Skip to content

Commit 195dc08

Browse files
committed
breaking: migrate to new Scope typing
1 parent be17683 commit 195dc08

12 files changed

Lines changed: 100 additions & 94 deletions

File tree

src/core.ts

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import { Injector } from '@angular/core';
2-
import { BaseSchemes, Scope } from 'rete'
3-
import { Area2DInherited, RenderData } from 'rete-area-plugin'
2+
import { BaseSchemes, CanAssignSignal, Scope } from 'rete'
43
import { createCustomElement } from '@angular/elements';
54

6-
import { ExtraRender, NgElement, NodeProps, Position, RenderPreset } from './types'
5+
import { NgElement, NodeProps, Position, RenderSignal } from './types'
6+
import { RenderPreset } from './presets/types';
77

88
type Item = { key: string, ngElement: NgElement }
99

@@ -55,9 +55,14 @@ function getRenderer(): Renderer {
5555
}
5656

5757
type Produces<Schemes extends BaseSchemes> =
58-
| { type: 'connectionpath', data: { payload: Schemes['Connection'], path?: string, points: Position[] } }
58+
| { type: 'connectionpath', data: { payload: Schemes['Connection'], path?: string, points: Position[] } }
5959

60-
export class AngularRenderPlugin<Schemes extends BaseSchemes, T extends ExtraRender = never> extends Scope<Produces<Schemes>, Area2DInherited<Schemes, T>> {
60+
type Requires<Schemes extends BaseSchemes> =
61+
| RenderSignal<'node', { payload: Schemes['Node'] }>
62+
| RenderSignal<'connection', { payload: Schemes['Connection'], start?: Position, end?: Position }>
63+
| { type: 'unmount', data: { element: HTMLElement } }
64+
65+
export class AngularRenderPlugin<Schemes extends BaseSchemes, T = Requires<Schemes>> extends Scope<Produces<Schemes>, [Requires<Schemes> | T]> {
6166
presets: RenderPreset<Schemes, T>[] = []
6267
renderer: Renderer
6368
owners = new WeakMap<HTMLElement, RenderPreset<Schemes, T>>()
@@ -67,49 +72,58 @@ export class AngularRenderPlugin<Schemes extends BaseSchemes, T extends ExtraRen
6772
this.renderer = getRenderer()
6873

6974
this.addPipe(context => {
70-
if (!('type' in context)) return
75+
if (!context || typeof context !== 'object' || !('type' in context)) return context
7176
if (context.type === 'unmount') {
7277
this.unmount(context.data.element)
7378
} else if (context.type === 'render') {
7479
if ('filled' in context.data && context.data.filled) {
7580
return context
7681
}
77-
if (this.mount(context.data.element, context as T)) {
82+
if (this.mount(context.data.element, context)) {
7883
return {
7984
...context,
8085
data: {
8186
...context.data,
8287
filled: true
8388
}
84-
}
89+
} as typeof context
8590
}
8691
}
8792
return context
8893
})
8994
}
9095

96+
setParent(scope: Scope<Requires<Schemes> | T>): void {
97+
super.setParent(scope)
98+
99+
this.presets.forEach(preset => {
100+
if (preset.attach) preset.attach(this)
101+
})
102+
}
103+
104+
91105
private unmount(element: HTMLElement) {
92106
this.owners.delete(element)
93107
this.renderer.unmount(element)
94108
}
95109

96-
private mount(element: HTMLElement, context: T) {
110+
private mount(element: HTMLElement, context: Requires<Schemes>) {
97111
const existing = this.renderer.get(element)
98112

99113
if (existing) {
100114
this.presets.forEach(preset => {
101115
if (this.owners.get(element) !== preset) return
102-
const result = preset.update(context as Extract<T, { type: 'render' }>, this)
116+
const result = preset.update(context as unknown as Extract<T, { type: 'render' }>, this)
103117

104118
if (result) {
105119
this.renderer.update(existing, result)
106120
}
107121
})
108-
return true // TODO ??
122+
return true
109123
}
110124

111125
for (const preset of this.presets) {
112-
const result = preset.mount(context as Extract<T, { type: 'render' }>, this)
126+
const result = preset.mount(context as unknown as Extract<T, { type: 'render' }>, this)
113127

114128
if (!result) continue
115129

@@ -123,7 +137,10 @@ export class AngularRenderPlugin<Schemes extends BaseSchemes, T extends ExtraRen
123137
return
124138
}
125139

126-
public addPreset<K>(preset: RenderPreset<Schemes, K extends T ? K : T>) {
127-
this.presets.push(preset as RenderPreset<Schemes, T>)
140+
public addPreset<K>(preset: RenderPreset<Schemes, CanAssignSignal<T, K> extends true ? K : 'Cannot apply preset. Provided signals are not compatible'>) {
141+
const local = preset as unknown as RenderPreset<Schemes, T>
142+
143+
if (local.attach) local.attach(this)
144+
this.presets.push(local)
128145
}
129146
}

src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ export * as Presets from './presets'
22

33
export { AngularArea2D } from './presets/classic/types'
44
export { ReteModule } from './module'
5-
export { RenderPreset } from './types'
5+
export { RenderPreset } from './presets/types'
66
export { ReteContextMenuModule } from './presets/context-menu/module'
77
export { ReteMinimapModule } from './presets/minimap/module'
88
export { ReteRerouteModule } from './presets/reroute/module'

src/presets/classic/index.ts

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
import { Type } from '@angular/core';
2-
import { CanAssignSignal, ClassicPreset, getUID } from 'rete';
2+
import { ClassicPreset, getUID } from 'rete';
33
import { AreaPlugin } from 'rete-area-plugin';
4-
import { classicConnectionPath, loopConnectionPath, SocketPositionWatcher, useDOMSocketPosition } from 'rete-render-utils';
5-
import { AngularArea2D, ClassicScheme, RenderPayload, ExtractPayload } from './types';
4+
import { classicConnectionPath, loopConnectionPath, SocketPositionWatcher, getDOMSocketPosition } from 'rete-render-utils';
5+
import { AngularArea2D, ClassicScheme, ExtractPayload } from './types';
66
import { NodeComponent } from './components/node/node.component';
77
import { SocketComponent } from './components/socket/socket.component';
88
import { ControlComponent } from './components/control/control.component';
99
import { ConnectionComponent } from './components/connection/connection.component';
1010
import { ConnectionWrapperComponent } from './components/connection/connection-wrapper.component';
11-
import { ExtraRender, Position, RenderPreset } from '../../types';
11+
import { Position } from '../../types';
12+
import { RenderPreset } from '../types'
1213

1314
type AngularComponent = Type<any>
1415
type CustomizationProps <Schemes extends ClassicScheme>= {
@@ -18,26 +19,24 @@ type CustomizationProps <Schemes extends ClassicScheme>= {
1819
control?: (data: ExtractPayload<Schemes, 'control'>) => AngularComponent | null
1920
}
2021

21-
type IsCompatible<K> = Extract<K, { type: 'render' | 'rendered' }> extends { type: 'render' | 'rendered', data: infer P } ? CanAssignSignal<P, RenderPayload<ClassicScheme>> : false
22-
type Substitute<K, Schemes extends ClassicScheme> = IsCompatible<K> extends true ? K : AngularArea2D<Schemes>
23-
24-
type ClasssicProps<Schemes extends ClassicScheme, K extends ExtraRender> = (
25-
| { socketPositionWatcher: SocketPositionWatcher }
26-
| { area: AreaPlugin<Schemes, Substitute<K, Schemes>> }
27-
) & {
22+
type ClassicProps<Schemes extends ClassicScheme, K> = {
23+
socketPositionWatcher?: SocketPositionWatcher<AreaPlugin<Schemes, K>>
2824
customize?: CustomizationProps<Schemes>
2925
}
3026

31-
export function setup<Schemes extends ClassicScheme, K extends ExtraRender>(
32-
props: ClasssicProps<Schemes, K>
33-
): RenderPreset<Schemes, AngularArea2D<Schemes> | K> {
34-
const positionWatcher = 'socketPositionWatcher' in props
35-
? props.socketPositionWatcher
36-
: useDOMSocketPosition(props.area as AreaPlugin<Schemes, AngularArea2D<Schemes>>)
37-
const { node, connection, socket, control } = props.customize || {}
27+
export function setup<Schemes extends ClassicScheme, K extends AngularArea2D<Schemes>>(
28+
props?: ClassicProps<Schemes, K>
29+
): RenderPreset<Schemes, K> {
30+
const positionWatcher = typeof props?.socketPositionWatcher === 'undefined'
31+
? getDOMSocketPosition<Schemes, any>() // fix Type instantiation is excessively deep and possibly infinite.
32+
: props?.socketPositionWatcher
33+
const { node, connection, socket, control } = props?.customize || {}
3834

3935

4036
return {
37+
attach(plugin) {
38+
positionWatcher.attach(plugin.parentScope<AreaPlugin<Schemes, any>>(AreaPlugin))
39+
},
4140
update(context) {
4241
const data = context.data.payload
4342

@@ -84,8 +83,8 @@ export function setup<Schemes extends ClassicScheme, K extends ExtraRender>(
8483
props: {
8584
connectionComponent: component,
8685
data: payload,
87-
start: start || ((change: any) => positionWatcher(source, 'output', sourceOutput, change)),
88-
end: end || ((change: any) => positionWatcher(target, 'input', targetInput, change)),
86+
start: start || ((change: any) => positionWatcher.listen(source, 'output', sourceOutput, change)),
87+
end: end || ((change: any) => positionWatcher.listen(target, 'input', targetInput, change)),
8988
path: async (start, end) => {
9089
const response = await plugin.emit({ type: 'connectionpath', data: { payload, points: [start, end] } })
9190
const { path, points } = response.data

src/presets/classic/types.ts

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { NodeId, ClassicPreset as Classic, GetSchemes } from 'rete'
2-
import { RenderData } from 'rete-area-plugin'
2+
import { Position, RenderSignal } from '../../types'
33

44
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends ((k: infer I) => void)
55
? I
@@ -15,7 +15,6 @@ type GetSockets<
1515
> = Union extends { socket: any } ? Union['socket'] : Classic.Socket
1616

1717

18-
1918
export type Side = 'input' | 'output'
2019
export type AngularRenderData<T extends ClassicScheme> =
2120
| {
@@ -32,11 +31,19 @@ export type AngularRenderData<T extends ClassicScheme> =
3231
payload: GetControls<T['Node']>
3332
}
3433

35-
export type RenderPayload<T extends ClassicScheme> = RenderData<T> | AngularRenderData<T>
36-
export type ExtractPayload<T extends ClassicScheme, K extends string> = Extract<RenderPayload<T>, { type: K }>
34+
export type ExtractPayload<T extends ClassicScheme, K extends string> = Extract<AngularArea2D<T>, { type: 'render', data: { type: K } }>['data']
3735
export type AngularArea2D<T extends ClassicScheme> =
38-
| { type: 'render', data: RenderPayload<T> }
39-
| { type: 'rendered', data: RenderPayload<T> }
36+
| RenderSignal<'node', { payload: T['Node'] }>
37+
| RenderSignal<'connection', { payload: T['Connection'], start?: Position, end?: Position }>
38+
| RenderSignal<'socket', {
39+
payload: GetSockets<T['Node']>
40+
nodeId: NodeId
41+
side: Side
42+
key: string
43+
}>
44+
| RenderSignal<'control', {
45+
payload: GetControls<T['Node']>
46+
}>
4047
| { type: 'unmount', data: { element: HTMLElement } }
4148

4249
export type ClassicScheme = GetSchemes<Classic.Node, Classic.Connection<Classic.Node, Classic.Node> & { isLoop?: boolean }>

src/presets/context-menu/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ import { BaseSchemes } from 'rete';
22

33
import { ContextMenuRender } from './types';
44
import { ContextMenuComponent } from './components/menu/menu.component';
5-
import { RenderPreset } from '../../types';
5+
import { RenderPreset } from '../types';
66

7-
export function setup<Schemes extends BaseSchemes, K extends ContextMenuRender<Schemes>>(props?: { delay?: number }): RenderPreset<Schemes, K> {
7+
export function setup<Schemes extends BaseSchemes, K extends ContextMenuRender>(props?: { delay?: number }): RenderPreset<Schemes, K> {
88
const delay = typeof props?.delay === 'undefined' ? 1000 : props.delay
99

1010
return {

src/presets/context-menu/types.ts

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
import { BaseSchemes } from 'rete'
2-
import { RenderData } from 'rete-area-plugin'
1+
import { RenderSignal } from '../../types'
32

43
export type Item = {
54
label: string
@@ -8,14 +7,5 @@ export type Item = {
87
subitems?: Item[]
98
}
109

11-
export type ContextMenuData = {
12-
type: 'contextmenu'
13-
element: HTMLElement
14-
items: Item[]
15-
onHide(): void
16-
searchBar?: boolean
17-
}
18-
export type ContextMenuRender<Schemes extends BaseSchemes> =
19-
| { type: 'unmount', data: { element: HTMLElement } }
20-
| { type: 'render', data: RenderData<Schemes> | ContextMenuData }
21-
| { type: 'rendered', data: RenderData<Schemes> | ContextMenuData }
10+
export type ContextMenuRender =
11+
| RenderSignal<'contextmenu', { items: Item[], onHide(): void, searchBar?: boolean }>

src/presets/minimap/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import { BaseSchemes } from 'rete';
22

3-
import { RenderPreset } from '../../types';
3+
import { RenderPreset } from '../types';
44
import { MinimapRender } from './types';
55
import { MinimapComponent } from './components/minimap/minimap.component';
66

7-
export function setup<Schemes extends BaseSchemes, K extends MinimapRender<Schemes>>(props?: { size?: number }): RenderPreset<Schemes, K> {
7+
export function setup<Schemes extends BaseSchemes, K extends MinimapRender>(props?: { size?: number }): RenderPreset<Schemes, K> {
88
return {
99
update(context) {
1010
if (context.data.type === 'minimap') {

src/presets/minimap/types.ts

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
import { BaseSchemes } from 'rete'
2-
import { RenderData } from 'rete-area-plugin'
1+
import { RenderSignal } from '../../types'
32

43
export type Rect = {
54
width: number
@@ -13,17 +12,15 @@ export type Transform = {
1312
k: number
1413
}
1514
export type Translate = (dx: number, dy: number) => void
15+
1616
export type MinimapData = {
17-
type: 'minimap'
18-
element: HTMLElement
19-
ratio: number
20-
nodes: Rect[]
21-
viewport: Rect
22-
translate: Translate
23-
point(x: number, y: number): void
24-
}
17+
ratio: number
18+
nodes: Rect[]
19+
viewport: Rect
20+
start(): Transform
21+
translate: Translate
22+
point(x: number, y: number): void
23+
}
2524

26-
export type MinimapRender<Schemes extends BaseSchemes> =
27-
| { type: 'unmount', data: { element: HTMLElement } }
28-
| { type: 'render', data: RenderData<Schemes> | MinimapData }
29-
| { type: 'rendered', data: RenderData<Schemes> | MinimapData }
25+
export type MinimapRender =
26+
| RenderSignal<'minimap', MinimapData>

src/presets/reroute/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { BaseSchemes } from 'rete';
22

3-
import { RenderPreset } from '../../types'
3+
import { RenderPreset } from '../types'
44
import { PinsRender } from './types';
55
import { PinsComponent } from './components/pins/pins.component';
66

@@ -10,7 +10,7 @@ type Props = {
1010
pointerdown?: (id: string) => void
1111
}
1212

13-
export function setup<Schemes extends BaseSchemes, K extends PinsRender<Schemes>>(props?: Props): RenderPreset<Schemes, K> {
13+
export function setup<Schemes extends BaseSchemes, K extends PinsRender>(props?: Props): RenderPreset<Schemes, K> {
1414
const getProps = () => ({
1515
menu: props?.contextMenu || (() => null),
1616
translate: props?.translate || (() => null),

src/presets/reroute/types.ts

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { BaseSchemes, ConnectionId } from 'rete'
2-
import { RenderData } from 'rete-area-plugin'
1+
import { ConnectionId } from 'rete'
2+
import { RenderSignal } from '../../types'
33

44
export type Position = {
55
x: number
@@ -15,12 +15,5 @@ export type PinData = {
1515
pins: Pin[]
1616
}
1717

18-
export type PinsData = {
19-
element: HTMLElement
20-
type: 'reroute-pins'
21-
data: PinData
22-
}
23-
24-
export type PinsRender<Schemes extends BaseSchemes> =
25-
| { type: 'render', data: RenderData<Schemes> | PinsData }
26-
| { type: 'rendered', data: RenderData<Schemes> | PinsData }
18+
export type PinsRender =
19+
| RenderSignal<'reroute-pins', { data: PinData }>

0 commit comments

Comments
 (0)