Skip to content

Commit

Permalink
Use pluginId explicitly
Browse files Browse the repository at this point in the history
  • Loading branch information
joshdover committed Jul 23, 2019
1 parent 131a75b commit 7bb0177
Show file tree
Hide file tree
Showing 21 changed files with 254 additions and 384 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,19 @@ Create a new handler function pre-wired to context for the plugin.
<b>Signature:</b>

```typescript
createHandler(handler: Handler<TContext, THandlerReturn, THandlerParameters>): (...rest: THandlerParameters) => Promisify<THandlerReturn>;
createHandler(plugin: string | CoreId, handler: Handler<TContext, THandlerReturn, THandlerParameters>): (...rest: THandlerParameters) => Promisify<THandlerReturn>;
```

## Parameters

| Parameter | Type | Description |
| --- | --- | --- |
| plugin | <code>string &#124; CoreId</code> | The plugin ID for the plugin that registers this context. |
| handler | <code>Handler&lt;TContext, THandlerReturn, THandlerParameters&gt;</code> | |

<b>Returns:</b>

`(...rest: THandlerParameters) => Promisify<THandlerReturn>`

## Remarks

This must be called when the handler is registered by the consuming plugin. If this is called later in the lifecycle it will throw an exception.
A function that takes `THandlerParameters`<!-- -->, calls `handler` with a new context, and returns a Promise of the `handler` return value.

Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

## ContextContainer interface

An object that handles registration of context providers and building of new context objects.
An object that handles registration of context providers and configuring handlers with context.

<b>Signature:</b>

Expand All @@ -16,16 +16,18 @@ export interface ContextContainer<TContext extends {}, THandlerReturn, THandlerP

| Method | Description |
| --- | --- |
| [createHandler(handler)](./kibana-plugin-public.contextcontainer.createhandler.md) | Create a new handler function pre-wired to context for the plugin. |
| [registerContext(contextName, provider)](./kibana-plugin-public.contextcontainer.registercontext.md) | Register a new context provider. Throws an exception if more than one provider is registered for the same context key. |
| [createHandler(plugin, handler)](./kibana-plugin-public.contextcontainer.createhandler.md) | Create a new handler function pre-wired to context for the plugin. |
| [registerContext(plugin, contextName, provider)](./kibana-plugin-public.contextcontainer.registercontext.md) | Register a new context provider. Throws an exception if more than one provider is registered for the same <code>contextName</code>. |

## Remarks

A [ContextContainer](./kibana-plugin-public.contextcontainer.md) can be used by any Core service or plugin (known as the "service owner") which wishes to expose APIs in a handler function. The container object will manage registering context providers and building a context object for a handler with all of the contexts that should be exposed to the handler's plugin. This is dependent on the dependencies that the handler's plugin declares.
A [ContextContainer](./kibana-plugin-public.contextcontainer.md) can be used by any Core service or plugin (known as the "service owner") which wishes to expose APIs in a handler function. The container object will manage registering context providers and configuring a handler with all of the contexts that should be exposed to the handler's plugin. This is dependent on the dependencies that the handler's plugin declares.

Contexts providers are executed in the order they were registered. Each provider gets access to context values provided by any plugins that it depends on.

In order to configure a handler with context, you must call the [ContextContainer.createHandler()](./kibana-plugin-public.contextcontainer.createhandler.md) function. This function must be called \_while the calling plugin's lifecycle method is still running\_ or else you risk configuring the handler for the wrong plugin, or not plugin at all (the latter will throw an error).
In order to configure a handler with context, you must call the [ContextContainer.createHandler()](./kibana-plugin-public.contextcontainer.createhandler.md) function and use the returned handler which will automatically build a context object when called.

When registering context or creating handlers, the \_calling plugin's id\_ must be provided. Note this should NOT be the context service owner, but the plugin that is actually registering the context or handler.

```ts
// GOOD
Expand All @@ -35,10 +37,13 @@ class MyPlugin {
setup(core) {
this.contextContainer = core.context.createContextContainer();
return {
registerRoute(path, handler) {
registerContext(plugin, contextName, provider) {
this.contextContainer.registerContext(plugin, contextName, provider);
},
registerRoute(plugin, path, handler) {
this.handlers.set(
path,
this.contextContainer.createHandler(handler)
this.contextContainer.createHandler(plugin, handler)
);
}
}
Expand All @@ -52,32 +57,15 @@ class MyPlugin {
setup(core) {
this.contextContainer = core.context.createContextContainer();
return {
// When the promise isn't returned, it's possible `createHandler` won't be called until after the lifecycle
// hook is completed.
registerRoute(path, handler) {
doAsyncThing().then(() => this.handlers.set(
path,
this.contextContainer.createHandler(handler)
));
}
}
}
}

// ALSO GOOD
class MyPlugin {
private readonly handlers = new Map();

setup(core) {
this.contextContainer = core.context.createContextContainer();
return {
// Returning a Promise also works, but only if calling plugins wait for it to resolve before returning from
// their lifecycle hooks.
async registerRoute(path, handler) {
await doAsyncThing();
registerContext(plugin, contextName, provider) {
// This would leak this context to all handlers rather tha only plugins that depend on the calling plugin.
this.contextContainer.registerContext('my_plugin', contextName, provider);
},
registerRoute(plugin, path, handler) {
this.handlers.set(
path,
this.contextContainer.createHandler(handler)
// the handler will not receive any contexts provided by other dependencies of the calling plugin.
this.contextContainer.createHandler('my_plugin', handler)
);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,19 @@

## ContextContainer.registerContext() method

Register a new context provider. Throws an exception if more than one provider is registered for the same context key.
Register a new context provider. Throws an exception if more than one provider is registered for the same `contextName`<!-- -->.

<b>Signature:</b>

```typescript
registerContext<TContextName extends keyof TContext>(contextName: TContextName, provider: ContextProvider<TContext, TContextName, THandlerParameters>): this;
registerContext<TContextName extends keyof TContext>(plugin: string | CoreId, contextName: TContextName, provider: ContextProvider<TContext, TContextName, THandlerParameters>): this;
```
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| plugin | <code>string &#124; CoreId</code> | The plugin ID for the plugin that registers this context. |
| contextName | <code>TContextName</code> | The key of the <code>TContext</code> object this provider supplies the value for. |
| provider | <code>ContextProvider&lt;TContext, TContextName, THandlerParameters&gt;</code> | A [ContextProvider](./kibana-plugin-public.contextprovider.md) to be called each time a new context is created. |
Expand Down
62 changes: 25 additions & 37 deletions docs/development/core/public/kibana-plugin-public.contextsetup.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

## ContextSetup interface

An object that handles registration of context providers and building of new context objects.
An object that handles registration of context providers and configuring handlers with context.

<b>Signature:</b>

Expand All @@ -20,11 +20,13 @@ export interface ContextSetup

## Remarks

A [ContextContainer](./kibana-plugin-public.contextcontainer.md) can be used by any Core service or plugin (known as the "service owner") which wishes to expose APIs in a handler function. The container object will manage registering context providers and building a context object for a handler with all of the contexts that should be exposed to the handler's plugin. This is dependent on the dependencies that the handler's plugin declares.
A [ContextContainer](./kibana-plugin-public.contextcontainer.md) can be used by any Core service or plugin (known as the "service owner") which wishes to expose APIs in a handler function. The container object will manage registering context providers and configuring a handler with all of the contexts that should be exposed to the handler's plugin. This is dependent on the dependencies that the handler's plugin declares.

Contexts providers are executed in the order they were registered. Each provider gets access to context values provided by any plugins that it depends on.

In order to configure a handler with context, you must call the [ContextContainer.createHandler()](./kibana-plugin-public.contextcontainer.createhandler.md) function. This function must be called \_while the calling plugin's lifecycle method is still running\_ or else you risk configuring the handler for the wrong plugin, or not plugin at all (the latter will throw an error).
In order to configure a handler with context, you must call the [ContextContainer.createHandler()](./kibana-plugin-public.contextcontainer.createhandler.md) function and use the returned handler which will automatically build a context object when called.

When registering context or creating handlers, the \_calling plugin's id\_ must be provided. Note this should NOT be the context service owner, but the plugin that is actually registering the context or handler.

```ts
// GOOD
Expand All @@ -34,10 +36,13 @@ class MyPlugin {
setup(core) {
this.contextContainer = core.context.createContextContainer();
return {
registerRoute(path, handler) {
registerContext(plugin, contextName, provider) {
this.contextContainer.registerContext(plugin, contextName, provider);
},
registerRoute(plugin, path, handler) {
this.handlers.set(
path,
this.contextContainer.createHandler(handler)
this.contextContainer.createHandler(plugin, handler)
);
}
}
Expand All @@ -51,32 +56,15 @@ class MyPlugin {
setup(core) {
this.contextContainer = core.context.createContextContainer();
return {
// When the promise isn't returned, it's possible `createHandler` won't be called until after the lifecycle
// hook is completed.
registerRoute(path, handler) {
doAsyncThing().then(() => this.handlers.set(
path,
this.contextContainer.createHandler(handler)
));
}
}
}
}

// ALSO GOOD
class MyPlugin {
private readonly handlers = new Map();

setup(core) {
this.contextContainer = core.context.createContextContainer();
return {
// Returning a Promise also works, but only if calling plugins wait for it to resolve before returning from
// their lifecycle hooks.
async registerRoute(path, handler) {
await doAsyncThing();
registerContext(plugin, contextName, provider) {
// This would leak this context to all handlers rather tha only plugins that depend on the calling plugin.
this.contextContainer.registerContext('my_plugin', contextName, provider);
},
registerRoute(plugin, path, handler) {
this.handlers.set(
path,
this.contextContainer.createHandler(handler)
// the handler will not receive any contexts provided by other dependencies of the calling plugin.
this.contextContainer.createHandler('my_plugin', handler)
);
}
}
Expand Down Expand Up @@ -111,27 +99,27 @@ class VizRenderingPlugin {
>();

return {
registerContext: this.contextContainer.register,
registerVizRenderer: (renderMethod: string, renderer: VizTypeRenderer) =>
// `createHandler` must be called immediately during the calling plugin's lifecycle method.
this.vizRenderers.set(renderMethod, this.contextContainer.createHandler(renderer)),
registerContext: this.contextContainer.registerContext,
registerVizRenderer: (plugin: string, renderMethod: string, renderer: VizTypeRenderer) =>
this.vizRenderers.set(renderMethod, this.contextContainer.createHandler(plugin, renderer)),
};
}

start(core) {
// Register the core context available to all renderers
this.contextContainer.register('core', () => ({
// Register the core context available to all renderers. Use the VizRendererContext's pluginId as the first arg.
this.contextContainer.registerContext('viz_rendering', 'core', () => ({
i18n: core.i18n,
uiSettings: core.uiSettings
}));

return {
registerContext: this.contextContainer.register,
registerContext: this.contextContainer.registerContext,

// The handler can now be called directly with only an `HTMLElement` and will automaticallly
// have the `context` argument supplied.
renderVizualization: (renderMethod: string, domElement: HTMLElement) => {
if (!this.vizRenderer.has(renderMethod)) {
throw new Error(`Render method ${renderMethod} has not be registered`);
throw new Error(`Render method '${renderMethod}' has not been registered`);
}

return this.vizRenderers.get(renderMethod)(domElement);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@
<b>Signature:</b>

```typescript
context: Pick<ContextSetup, 'createContextContainer'>;
context: ContextSetup;
```
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export interface CoreSetup

| Property | Type | Description |
| --- | --- | --- |
| [context](./kibana-plugin-public.coresetup.context.md) | <code>Pick&lt;ContextSetup, 'createContextContainer'&gt;</code> | [ContextSetup](./kibana-plugin-public.contextsetup.md) |
| [context](./kibana-plugin-public.coresetup.context.md) | <code>ContextSetup</code> | [ContextSetup](./kibana-plugin-public.contextsetup.md) |
| [fatalErrors](./kibana-plugin-public.coresetup.fatalerrors.md) | <code>FatalErrorsSetup</code> | [FatalErrorsSetup](./kibana-plugin-public.fatalerrorssetup.md) |
| [http](./kibana-plugin-public.coresetup.http.md) | <code>HttpSetup</code> | [HttpSetup](./kibana-plugin-public.httpsetup.md) |
| [notifications](./kibana-plugin-public.coresetup.notifications.md) | <code>NotificationsSetup</code> | [NotificationsSetup](./kibana-plugin-public.notificationssetup.md) |
Expand Down
4 changes: 2 additions & 2 deletions docs/development/core/public/kibana-plugin-public.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ The plugin integrates with the core system via lifecycle events: `setup`<!-- -->
| [ChromeRecentlyAccessed](./kibana-plugin-public.chromerecentlyaccessed.md) | [APIs](./kibana-plugin-public.chromerecentlyaccessed.md) for recently accessed history. |
| [ChromeRecentlyAccessedHistoryItem](./kibana-plugin-public.chromerecentlyaccessedhistoryitem.md) | |
| [ChromeStart](./kibana-plugin-public.chromestart.md) | ChromeStart allows plugins to customize the global chrome header UI and enrich the UX with additional information about the current location of the browser. |
| [ContextContainer](./kibana-plugin-public.contextcontainer.md) | An object that handles registration of context providers and building of new context objects. |
| [ContextSetup](./kibana-plugin-public.contextsetup.md) | An object that handles registration of context providers and building of new context objects. |
| [ContextContainer](./kibana-plugin-public.contextcontainer.md) | An object that handles registration of context providers and configuring handlers with context. |
| [ContextSetup](./kibana-plugin-public.contextsetup.md) | An object that handles registration of context providers and configuring handlers with context. |
| [CoreSetup](./kibana-plugin-public.coresetup.md) | Core services exposed to the <code>Plugin</code> setup lifecycle |
| [CoreStart](./kibana-plugin-public.corestart.md) | Core services exposed to the <code>Plugin</code> start lifecycle |
| [DocLinksStart](./kibana-plugin-public.doclinksstart.md) | |
Expand Down
1 change: 0 additions & 1 deletion src/core/public/context/context.mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ const createContextMock = () => {
const contextMock: ContextContainerMock = {
registerContext: jest.fn(),
createHandler: jest.fn(),
setCurrentPlugin: jest.fn(),
};
return contextMock;
};
Expand Down
Loading

0 comments on commit 7bb0177

Please sign in to comment.