Плагіни пропонують можливість додавати нові функції переважно через одну точку входу. Вони спілкуються один з одним за допомогою сигналів, які поширюються від батьківських плагінів до дочірніх. Оскільки плагіни можуть мати кілька дочірніх плагінів, ці сигнали передаються в тому порядку, в якому вони підключені (це може бути важливо під час включення плагінів, таких як rete-readonly-plugin
)
Наступний приклад коду демонструє створення двох скоупів: батьківського та дочірнього. Обидва скоупи логують сигнали.
tsimport { Scope } from 'rete'; const parentScope = new Scope<number>('parent'); // number це продукуємий тип const childScope = new Scope<string, [number]>('child'); // [number] це очікуваний тип батьківського ланцюга parentScope.addPipe((context) => { // додати пайп до батьківської області console.log('parent', context); // number return context; }); childScope.addPipe((context) => { // додати пайп до дочірньої області console.log('child', context); // string | number return context; }); parentScope.use(childScope); // forward all signals to child scope const returnedNumber = await parentScope.emit(1); // can emit number const returnedString = await childScope.emit('a'); // can emit string
Майте на увазі, що порядок use
і addPipe
впливає на порядок виклику батьківського та дочірнього обробників.
Логи:
logparent 1 child 1 child a
У деяких випадках сигнали можна змінювати або блокувати.
tsparentScope.addPipe((context) => { return context * 2; }); childScope.addPipe((context) => { if (context === 'b') return // запобігання поширення 'b' return context; }); const doubledNumber = await parentScope.emit(1); // 2 const expectedString = await childScope.emit('a'); // 'a' const expectedUndefined = await childScope.emit('b'); // undefined
Статична типізація використовується для гарантії того, що очікувані сигнали використовуваних плагінів сумісні з сигналами, створеними батьківським плагіном.
tsimport { Scope } from 'rete'; const parentScope = new Scope<number>('parent'); const childScope = new Scope<string, [number | boolean]>('child'); parentScope.use(childScope); // Type 'boolean' is not assignable to type 'string | number'.ts(2345)
Дочірні плагіни можуть отримати доступ до екземпляра батьківського плагіна як для прямого доступу до його інтерфейсів, так і для продукування сигналів від імені батьківського плагіна
tsimport { Scope } from 'rete'; class Root extends Scope<number> { isRoot = true } class Root2 extends Scope<number> { isRoot2 = true } const parentScope = new Root('parent'); const childScope = new Scope<string, [number]>('child'); parentScope.use(childScope); const parent = childScope.parentScope(); // екземпляр Root, але Scope з точки зору TS const root = childScope.parentScope<Root>(Root); // екземпляр Root const wrongInstance = childScope.parentScope<Root2>(Root2); // викидає виняток