Skip to content

Commit

Permalink
feat: allow to define service map
Browse files Browse the repository at this point in the history
Consumers of the diagram may bootstrap it with a service map
that is being used during type inference.
  • Loading branch information
nikku committed Feb 23, 2024
1 parent 6db5ad0 commit 0cc2a3f
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 33 deletions.
119 changes: 88 additions & 31 deletions lib/Diagram.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,16 @@ import CoreModule from './core';
* } & Record<string, any> } DiagramOptions
*/

/**
* @template T
* @typedef {import('didi').FactoryFunction<T>} FactoryFunction
*/

/**
* @template T
* @typedef {import('didi').ArrayFunc<T>} ArrayFunc
*/

/**
* Bootstrap an injector from a list of modules, instantiating a number of default components
*
Expand Down Expand Up @@ -59,6 +69,7 @@ function createInjector(options) {
*
* @class
* @constructor
* @template [ServiceMap=null]
*
* @example Creating a plug-in that logs whenever a shape is added to the canvas.
*
Expand Down Expand Up @@ -101,40 +112,10 @@ function createInjector(options) {
*/
export default function Diagram(options, injector) {

this._injector = injector = injector || createInjector(options);

// API

/**
* Resolves a diagram service.
*
* @template T
*
* @param {string} name The name of the service to get.
* @param {boolean} [strict=true] If false, resolve missing services to null.
*
* @return {T|null}
*/
this.get = injector.get;

/**
* Executes a function with its dependencies injected.
*
* @template T
*
* @param {Function} func function to be invoked
* @param {InjectionContext} [context] context of the invocation
* @param {LocalsMap} [locals] locals provided
*
* @return {T|null}
*/
this.invoke = injector.invoke;
this._injector = injector || createInjector(options);

// init

// indicate via event


/**
* An event indicating that all plug-ins are loaded.
*
Expand All @@ -157,6 +138,82 @@ export default function Diagram(options, injector) {
this.get('eventBus').fire('diagram.init');
}

/**
* @overlord
*
* Resolves a diagram service.
*
* @template T
*
* @param {string} name The name of the service to get.
*
* @return {T}
*/
/**
* @overlord
*
* Resolves a diagram service.
*
* @template T
*
* @param {string} name The name of the service to get.
* @param {true} strict If false, resolve missing services to null.
*
* @return {T}
*/
/**
* @overlord
*
* Resolves a diagram service.
*
* @template T
*
* @param {string} name The name of the service to get.
* @param {boolean} strict If false, resolve missing services to null.
*
* @return {T|null}
*/
/**
* Resolves a diagram service.
*
* @template {keyof ServiceMap} Name
*
* @param {Name} name The name of the service to get.
*
* @return {ServiceMap[Name]}
*/
Diagram.prototype.get = function(name, strict) {
return this._injector.get(name, strict);
};

/**
* @overlord
*
* Invoke the given function, injecting dependencies. Return the result.
*
* @template T
*
* @param {FactoryFunction<T>} func
* @param {InjectionContext} [context]
* @param {LocalsMap} [locals]
*
* @return {T}
*/
/**
* Invoke the given function, injecting dependencies provided in
* array notation. Return the result.
*
* @template T
*
* @param {ArrayFunc<T>} func function to be invoked
* @param {InjectionContext} [context] context of the invocation
* @param {LocalsMap} [locals] locals provided
*
* @return {T}
*/
Diagram.prototype.invoke = function(func, context, locals) {
return this._injector.invoke(func, context, locals);
};

/**
* Destroys the diagram
Expand Down
14 changes: 12 additions & 2 deletions lib/Diagram.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import Diagram from './Diagram';
import Diagram from './Diagram.js';

import CommandModule from './command';

Expand Down Expand Up @@ -33,4 +33,14 @@ const foo = diagram.invoke((modeling: Modeling, eventBus: EventBus) => {
};
});

foo.bar = false;
foo.bar = false;

type ServiceMap = {
'eventBus': EventBus
};

const typedDiagram = new Diagram<ServiceMap>();

const b = typedDiagram.get('eventBus');

b.on('a', (event: any) => console.log('a'));

0 comments on commit 0cc2a3f

Please sign in to comment.