mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
moving state out of kbn-interpreter (#27317)
This commit is contained in:
parent
dc10e48761
commit
90fbaf11c2
35 changed files with 256 additions and 252 deletions
|
@ -17,8 +17,8 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
export { functionsRegistry } from './lib/functions_registry';
|
||||
export { typesRegistry } from './lib/types_registry';
|
||||
export { FunctionsRegistry } from './lib/functions_registry';
|
||||
export { TypesRegistry } from './lib/types_registry';
|
||||
export { createError } from './interpreter/create_error';
|
||||
export { interpretProvider } from './interpreter/interpret';
|
||||
export { serializeProvider } from './lib/serialize';
|
||||
|
|
|
@ -22,7 +22,6 @@ import { each, keys, last, mapValues, reduce, zipObject } from 'lodash';
|
|||
import { getType } from '../lib/get_type';
|
||||
import { fromExpression } from '../lib/ast';
|
||||
import { getByAlias } from '../lib/get_by_alias';
|
||||
import { typesRegistry } from '../lib/types_registry';
|
||||
import { castProvider } from './cast';
|
||||
import { createError } from './create_error';
|
||||
|
||||
|
@ -103,7 +102,7 @@ export function interpretProvider(config) {
|
|||
}
|
||||
|
||||
// Validate the function output against the type definition's validate function
|
||||
const type = typesRegistry.get(fnDef.type);
|
||||
const type = handlers.types[fnDef.type];
|
||||
if (type && type.validate) {
|
||||
try {
|
||||
type.validate(fnOutput);
|
||||
|
|
|
@ -20,10 +20,8 @@
|
|||
import { Registry } from './registry';
|
||||
import { Fn } from './fn';
|
||||
|
||||
class FunctionsRegistry extends Registry {
|
||||
export class FunctionsRegistry extends Registry {
|
||||
wrapper(obj) {
|
||||
return new Fn(obj);
|
||||
}
|
||||
}
|
||||
|
||||
export const functionsRegistry = new FunctionsRegistry();
|
||||
|
|
|
@ -20,10 +20,8 @@
|
|||
import { Registry } from './registry';
|
||||
import { Type } from './type';
|
||||
|
||||
class TypesRegistry extends Registry {
|
||||
export class TypesRegistry extends Registry {
|
||||
wrapper(obj) {
|
||||
return new Type(obj);
|
||||
}
|
||||
}
|
||||
|
||||
export const typesRegistry = new TypesRegistry();
|
||||
|
|
|
@ -20,18 +20,7 @@
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import $script from 'scriptjs';
|
||||
|
||||
let resolvePromise = null;
|
||||
let called = false;
|
||||
|
||||
let populatePromise = new Promise(_resolve => {
|
||||
resolvePromise = _resolve;
|
||||
});
|
||||
|
||||
export const getBrowserRegistries = () => {
|
||||
return populatePromise;
|
||||
};
|
||||
|
||||
const loadBrowserRegistries = (registries, basePath) => {
|
||||
export const loadBrowserRegistries = (registries, basePath) => {
|
||||
const remainingTypes = Object.keys(registries);
|
||||
const populatedTypes = {};
|
||||
|
||||
|
@ -58,27 +47,3 @@ const loadBrowserRegistries = (registries, basePath) => {
|
|||
loadType();
|
||||
});
|
||||
};
|
||||
|
||||
export const populateBrowserRegistries = (registries, basePath) => {
|
||||
if (called) {
|
||||
const oldPromise = populatePromise;
|
||||
let newResolve;
|
||||
populatePromise = new Promise(_resolve => {
|
||||
newResolve = _resolve;
|
||||
});
|
||||
oldPromise.then(oldTypes => {
|
||||
loadBrowserRegistries(registries, basePath).then(newTypes => {
|
||||
newResolve({
|
||||
...oldTypes,
|
||||
...newTypes,
|
||||
});
|
||||
});
|
||||
});
|
||||
return populatePromise;
|
||||
}
|
||||
called = true;
|
||||
loadBrowserRegistries(registries, basePath).then(registries => {
|
||||
resolvePromise(registries);
|
||||
});
|
||||
return populatePromise;
|
||||
};
|
||||
|
|
|
@ -17,6 +17,6 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
export { populateBrowserRegistries, getBrowserRegistries } from './browser_registries';
|
||||
export { loadBrowserRegistries } from './browser_registries';
|
||||
export { createSocket } from './socket';
|
||||
export { initializeInterpreter, interpretAst, getInitializedFunctions } from './interpreter';
|
||||
export { initializeInterpreter } from './interpreter';
|
||||
|
|
|
@ -19,18 +19,28 @@
|
|||
|
||||
import { socketInterpreterProvider } from '../common/interpreter/socket_interpret';
|
||||
import { serializeProvider } from '../common/lib/serialize';
|
||||
import { getSocket } from './socket';
|
||||
import { typesRegistry } from '../common/lib/types_registry';
|
||||
import { createHandlers } from './create_handlers';
|
||||
import { functionsRegistry } from '../common/lib/functions_registry';
|
||||
import { getBrowserRegistries } from './browser_registries';
|
||||
|
||||
let socket;
|
||||
let resolve;
|
||||
const functionList = new Promise(_resolve => (resolve = _resolve));
|
||||
export async function initializeInterpreter(socket, typesRegistry, functionsRegistry) {
|
||||
let resolve;
|
||||
const functionList = new Promise(_resolve => (resolve = _resolve));
|
||||
|
||||
export async function initializeInterpreter() {
|
||||
socket = getSocket();
|
||||
const getInitializedFunctions = async () => {
|
||||
return functionList;
|
||||
};
|
||||
|
||||
const interpretAst = async (ast, context, handlers) => {
|
||||
// Load plugins before attempting to get functions, otherwise this gets racey
|
||||
const serverFunctionList = await functionList;
|
||||
const interpretFn = await socketInterpreterProvider({
|
||||
types: typesRegistry.toJS(),
|
||||
handlers: { ...handlers, ...createHandlers(socket) },
|
||||
functions: functionsRegistry.toJS(),
|
||||
referableFunctions: serverFunctionList,
|
||||
socket: socket,
|
||||
});
|
||||
return interpretFn(ast, context);
|
||||
};
|
||||
|
||||
// Listen for interpreter runs
|
||||
socket.on('run', ({ ast, context, id }) => {
|
||||
|
@ -42,27 +52,20 @@ export async function initializeInterpreter() {
|
|||
});
|
||||
|
||||
// Create the function list
|
||||
socket.emit('getFunctionList');
|
||||
socket.once('functionList', resolve);
|
||||
return functionList;
|
||||
let gotFunctionList = false;
|
||||
socket.once('functionList', (fl) => {
|
||||
gotFunctionList = true;
|
||||
resolve(fl);
|
||||
});
|
||||
|
||||
const interval = setInterval(() => {
|
||||
if (gotFunctionList) {
|
||||
clearInterval(interval);
|
||||
return;
|
||||
}
|
||||
socket.emit('getFunctionList');
|
||||
}, 1000);
|
||||
|
||||
return { getInitializedFunctions, interpretAst };
|
||||
}
|
||||
|
||||
export async function getInitializedFunctions() {
|
||||
return functionList;
|
||||
}
|
||||
|
||||
// Use the above promise to seed the interpreter with the functions it can defer to
|
||||
export async function interpretAst(ast, context, handlers) {
|
||||
// Load plugins before attempting to get functions, otherwise this gets racey
|
||||
return Promise.all([functionList, getBrowserRegistries()])
|
||||
.then(([serverFunctionList]) => {
|
||||
return socketInterpreterProvider({
|
||||
types: typesRegistry.toJS(),
|
||||
handlers: { ...handlers, ...createHandlers(socket) },
|
||||
functions: functionsRegistry.toJS(),
|
||||
referableFunctions: serverFunctionList,
|
||||
socket: socket,
|
||||
});
|
||||
})
|
||||
.then(interpretFn => interpretFn(ast, context));
|
||||
}
|
||||
|
|
|
@ -18,22 +18,13 @@
|
|||
*/
|
||||
|
||||
import io from 'socket.io-client';
|
||||
import { functionsRegistry } from '../common/lib/functions_registry';
|
||||
import { getBrowserRegistries } from './browser_registries';
|
||||
|
||||
const SOCKET_CONNECTION_TIMEOUT = 5000; // timeout in ms
|
||||
let socket;
|
||||
|
||||
export async function createSocket(basePath) {
|
||||
if (socket != null) return socket;
|
||||
export async function createSocket(basePath, functionsRegistry) {
|
||||
|
||||
return new Promise((resolve, rej) => {
|
||||
const reject = p => {
|
||||
socket = null; // reset the socket on errors
|
||||
rej(p);
|
||||
};
|
||||
|
||||
socket = io({
|
||||
return new Promise((resolve, reject) => {
|
||||
const socket = io({
|
||||
path: `${basePath}/socket.io`,
|
||||
transports: ['polling', 'websocket'],
|
||||
transportOptions: {
|
||||
|
@ -49,12 +40,11 @@ export async function createSocket(basePath) {
|
|||
});
|
||||
|
||||
socket.on('getFunctionList', () => {
|
||||
const pluginsLoaded = getBrowserRegistries();
|
||||
pluginsLoaded.then(() => socket.emit('functionList', functionsRegistry.toJS()));
|
||||
socket.emit('functionList', functionsRegistry.toJS());
|
||||
});
|
||||
|
||||
socket.on('connect', () => {
|
||||
resolve();
|
||||
resolve(socket);
|
||||
socket.off('connectionFailed', errorHandler);
|
||||
socket.off('connect_error', errorHandler);
|
||||
socket.off('connect_timeout', errorHandler);
|
||||
|
@ -71,8 +61,3 @@ export async function createSocket(basePath) {
|
|||
socket.on('connect_timeout', errorHandler);
|
||||
});
|
||||
}
|
||||
|
||||
export function getSocket() {
|
||||
if (!socket) throw new Error('getSocket failed, socket has not been created');
|
||||
return socket;
|
||||
}
|
||||
|
|
|
@ -17,6 +17,6 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
export { populateServerRegistries, getServerRegistries } from './server_registries';
|
||||
export { populateServerRegistries } from './server_registries';
|
||||
export { getPluginPaths } from './get_plugin_paths';
|
||||
export { pluginPaths } from './plugin_paths';
|
||||
|
|
|
@ -18,56 +18,39 @@
|
|||
*/
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { typesRegistry } from '../common/lib/types_registry';
|
||||
import { functionsRegistry as serverFunctions } from '../common/lib/functions_registry';
|
||||
import { getPluginPaths } from './get_plugin_paths';
|
||||
|
||||
const registries = {
|
||||
serverFunctions: serverFunctions,
|
||||
commonFunctions: serverFunctions,
|
||||
types: typesRegistry,
|
||||
};
|
||||
|
||||
let resolve = null;
|
||||
let called = false;
|
||||
export const populateServerRegistries = registries => {
|
||||
if (!registries) throw new Error('registries are required');
|
||||
|
||||
const populatePromise = new Promise(_resolve => {
|
||||
resolve = _resolve;
|
||||
});
|
||||
return new Promise(resolve => {
|
||||
const remainingTypes = Object.keys(registries);
|
||||
const populatedTypes = {};
|
||||
|
||||
export const getServerRegistries = () => {
|
||||
return populatePromise;
|
||||
};
|
||||
const loadType = () => {
|
||||
const type = remainingTypes.pop();
|
||||
getPluginPaths(type).then(paths => {
|
||||
global.canvas = global.canvas || {};
|
||||
global.canvas.register = d => registries[type].register(d);
|
||||
global.canvas.i18n = i18n;
|
||||
|
||||
export const populateServerRegistries = types => {
|
||||
if (called) {
|
||||
return populatePromise;
|
||||
}
|
||||
called = true;
|
||||
if (!types || !types.length) throw new Error('types is required');
|
||||
paths.forEach(path => {
|
||||
require(path); // eslint-disable-line import/no-dynamic-require
|
||||
});
|
||||
|
||||
const remainingTypes = types;
|
||||
const populatedTypes = {};
|
||||
delete global.canvas;
|
||||
|
||||
const loadType = () => {
|
||||
const type = remainingTypes.pop();
|
||||
getPluginPaths(type).then(paths => {
|
||||
global.canvas = global.canvas || {};
|
||||
global.canvas.register = d => registries[type].register(d);
|
||||
global.canvas.i18n = i18n;
|
||||
|
||||
paths.forEach(path => {
|
||||
require(path); // eslint-disable-line import/no-dynamic-require
|
||||
populatedTypes[type] = registries[type];
|
||||
if (remainingTypes.length) {
|
||||
loadType();
|
||||
}
|
||||
else {
|
||||
resolve(populatedTypes);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
delete global.canvas;
|
||||
|
||||
populatedTypes[type] = registries[type];
|
||||
if (remainingTypes.length) loadType();
|
||||
else resolve(populatedTypes);
|
||||
});
|
||||
};
|
||||
|
||||
if (remainingTypes.length) loadType();
|
||||
return populatePromise;
|
||||
if (remainingTypes.length) loadType();
|
||||
});
|
||||
};
|
||||
|
|
|
@ -36,6 +36,7 @@ module.exports = function ({ sourceMaps }, { watch }) {
|
|||
entry: {
|
||||
'types/all': resolve(PLUGIN_SOURCE_DIR, 'types/register.js'),
|
||||
'functions/browser/all': resolve(PLUGIN_SOURCE_DIR, 'functions/browser/register.js'),
|
||||
'functions/browser/common': resolve(PLUGIN_SOURCE_DIR, 'functions/common/register.js'),
|
||||
},
|
||||
|
||||
// there were problems with the node and web targets since this code is actually
|
||||
|
|
|
@ -25,11 +25,6 @@ export default function (kibana) {
|
|||
id: 'interpreter',
|
||||
require: ['kibana', 'elasticsearch'],
|
||||
publicDir: resolve(__dirname, 'public'),
|
||||
uiExports: {
|
||||
hacks: [
|
||||
'plugins/interpreter/load_browser_plugins.js',
|
||||
],
|
||||
},
|
||||
init,
|
||||
});
|
||||
}
|
||||
|
|
|
@ -18,10 +18,16 @@
|
|||
*/
|
||||
|
||||
import { routes } from './server/routes';
|
||||
import { functionsRegistry } from '@kbn/interpreter/common';
|
||||
import { FunctionsRegistry, TypesRegistry } from '@kbn/interpreter/common';
|
||||
import { populateServerRegistries } from '@kbn/interpreter/server';
|
||||
|
||||
export default async function (server /*options*/) {
|
||||
|
||||
const registries = {
|
||||
serverFunctions: new FunctionsRegistry(),
|
||||
types: new TypesRegistry()
|
||||
};
|
||||
|
||||
server.injectUiAppVars('canvas', () => {
|
||||
const config = server.config();
|
||||
const basePath = config.get('server.basePath');
|
||||
|
@ -35,12 +41,14 @@ export default async function (server /*options*/) {
|
|||
kbnIndex: config.get('kibana.index'),
|
||||
esShardTimeout: config.get('elasticsearch.shardTimeout'),
|
||||
esApiVersion: config.get('elasticsearch.apiVersion'),
|
||||
serverFunctions: functionsRegistry.toArray(),
|
||||
serverFunctions: registries.serverFunctions.toArray(),
|
||||
basePath,
|
||||
reportingBrowserType,
|
||||
};
|
||||
});
|
||||
|
||||
await populateServerRegistries(['serverFunctions', 'types']);
|
||||
await populateServerRegistries(registries);
|
||||
|
||||
server.expose(registries);
|
||||
routes(server);
|
||||
}
|
||||
|
|
|
@ -17,25 +17,7 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import chrome from 'ui/chrome';
|
||||
import { populateBrowserRegistries, createSocket, initializeInterpreter } from '@kbn/interpreter/public';
|
||||
import { typesRegistry, functionsRegistry } from '@kbn/interpreter/common';
|
||||
import { functions } from './functions';
|
||||
|
||||
const basePath = chrome.getBasePath();
|
||||
import { FunctionsRegistry } from '@kbn/interpreter/common';
|
||||
|
||||
const types = {
|
||||
browserFunctions: functionsRegistry,
|
||||
types: typesRegistry
|
||||
};
|
||||
|
||||
function addFunction(fnDef) {
|
||||
functionsRegistry.register(fnDef);
|
||||
}
|
||||
|
||||
functions.forEach(addFunction);
|
||||
|
||||
createSocket(basePath).then(async () => {
|
||||
await populateBrowserRegistries(types, basePath);
|
||||
await initializeInterpreter();
|
||||
});
|
||||
export const functionsRegistry = new FunctionsRegistry();
|
67
src/legacy/core_plugins/interpreter/public/interpreter.js
Normal file
67
src/legacy/core_plugins/interpreter/public/interpreter.js
Normal file
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
|
||||
import { initializeInterpreter, loadBrowserRegistries, createSocket } from '@kbn/interpreter/public';
|
||||
import chrome from 'ui/chrome';
|
||||
import { functions } from './functions';
|
||||
import { functionsRegistry } from './functions_registry';
|
||||
import { typesRegistry } from './types_registry';
|
||||
|
||||
const basePath = chrome.getBasePath();
|
||||
|
||||
const types = {
|
||||
browserFunctions: functionsRegistry,
|
||||
types: typesRegistry
|
||||
};
|
||||
|
||||
function addFunction(fnDef) {
|
||||
functionsRegistry.register(fnDef);
|
||||
}
|
||||
|
||||
functions.forEach(addFunction);
|
||||
|
||||
let _resolve;
|
||||
let _interpreterPromise;
|
||||
|
||||
const initialize = async () => {
|
||||
await loadBrowserRegistries(types, basePath);
|
||||
const socket = await createSocket(basePath, functionsRegistry);
|
||||
initializeInterpreter(socket, typesRegistry, functionsRegistry).then(interpreter => {
|
||||
_resolve({ interpreter, socket });
|
||||
});
|
||||
};
|
||||
|
||||
export const getInterpreter = async () => {
|
||||
if (!_interpreterPromise) {
|
||||
_interpreterPromise = new Promise(resolve => _resolve = resolve);
|
||||
initialize();
|
||||
}
|
||||
return await _interpreterPromise;
|
||||
};
|
||||
|
||||
export const interpretAst = async (...params) => {
|
||||
const { interpreter } = await getInterpreter();
|
||||
return await interpreter.interpretAst(...params);
|
||||
};
|
||||
|
||||
export const updateInterpreterFunctions = async () => {
|
||||
const { socket } = await getInterpreter();
|
||||
socket.emit('updateFunctionList');
|
||||
};
|
23
src/legacy/core_plugins/interpreter/public/types_registry.js
Normal file
23
src/legacy/core_plugins/interpreter/public/types_registry.js
Normal file
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
|
||||
import { TypesRegistry } from '@kbn/interpreter/common';
|
||||
|
||||
export const typesRegistry = new TypesRegistry();
|
|
@ -22,36 +22,46 @@ import uuid from 'uuid/v4';
|
|||
export const browser = ({ socket, serialize, deserialize }) => {
|
||||
// Note that we need to be careful about how many times routeExpressionProvider is called, because of the socket.once below.
|
||||
// It's too bad we can't get a list of browser plugins on the server
|
||||
const getClientFunctions = new Promise(resolve => {
|
||||
socket.emit('getFunctionList');
|
||||
socket.once('functionList', resolve);
|
||||
|
||||
let getFunctionsPromise;
|
||||
socket.on('updateFunctionList', () => {
|
||||
getFunctionsPromise = undefined;
|
||||
});
|
||||
|
||||
return getClientFunctions.then(functions => {
|
||||
return {
|
||||
interpret: (ast, context) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const id = uuid();
|
||||
const listener = resp => {
|
||||
if (resp.type === 'msgError') {
|
||||
const { value } = resp;
|
||||
// cast error strings back into error instances
|
||||
const err = value instanceof Error ? value : new Error(value);
|
||||
if (value.stack) err.stack = value.stack;
|
||||
// Reject's with a legit error. Check! Environments should always reject with an error when something bad happens
|
||||
reject(err);
|
||||
} else {
|
||||
resolve(deserialize(resp.value));
|
||||
}
|
||||
};
|
||||
const getFunctions = async () => {
|
||||
if (!getFunctionsPromise) {
|
||||
getFunctionsPromise = new Promise(resolve => {
|
||||
socket.once('functionList', resolve);
|
||||
socket.emit('getFunctionList');
|
||||
});
|
||||
}
|
||||
|
||||
// {type: msgSuccess or msgError, value: foo}. Doesn't matter if it's success or error, we do the same thing for now
|
||||
socket.once(`resp:${id}`, listener);
|
||||
return Object.keys(await getFunctionsPromise);
|
||||
};
|
||||
|
||||
socket.emit('run', { ast, context: serialize(context), id });
|
||||
});
|
||||
},
|
||||
getFunctions: () => Object.keys(functions),
|
||||
};
|
||||
});
|
||||
return {
|
||||
interpret: (ast, context) => {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
await getFunctions();
|
||||
const id = uuid();
|
||||
const listener = resp => {
|
||||
if (resp.type === 'msgError') {
|
||||
const { value } = resp;
|
||||
// cast error strings back into error instances
|
||||
const err = value instanceof Error ? value : new Error(value);
|
||||
if (value.stack) err.stack = value.stack;
|
||||
// Reject's with a legit error. Check! Environments should always reject with an error when something bad happens
|
||||
reject(err);
|
||||
} else {
|
||||
resolve(deserialize(resp.value));
|
||||
}
|
||||
};
|
||||
|
||||
// {type: msgSuccess or msgError, value: foo}. Doesn't matter if it's success or error, we do the same thing for now
|
||||
socket.once(`resp:${id}`, listener);
|
||||
|
||||
socket.emit('run', { ast, context: serialize(context), id });
|
||||
});
|
||||
}, getFunctions
|
||||
};
|
||||
};
|
||||
|
|
|
@ -23,8 +23,8 @@ export const routeExpressionProvider = environments => {
|
|||
async function routeExpression(ast, context = null) {
|
||||
// List of environments in order of preference
|
||||
|
||||
return Promise.all(environments).then(environments => {
|
||||
const environmentFunctions = environments.map(env => env.getFunctions());
|
||||
return Promise.all(environments).then(async environments => {
|
||||
const environmentFunctions = await Promise.all(environments.map(env => env.getFunctions()));
|
||||
|
||||
// Grab name of the first function in the chain
|
||||
const fnName = ast.chain[0].function.toLowerCase();
|
||||
|
|
|
@ -17,12 +17,11 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { getServerRegistries } from '@kbn/interpreter/server';
|
||||
import { interpretProvider } from '@kbn/interpreter/common';
|
||||
import { createHandlers } from '../create_handlers';
|
||||
|
||||
export const server = async ({ onFunctionNotFound, server, request }) => {
|
||||
const { serverFunctions, types } = await getServerRegistries(['serverFunctions', 'types']);
|
||||
const { serverFunctions, types } = server.plugins.interpreter;
|
||||
|
||||
return {
|
||||
interpret: (ast, context) => {
|
||||
|
|
|
@ -19,10 +19,15 @@
|
|||
|
||||
import uuid from 'uuid/v4';
|
||||
import { populateServerRegistries } from '@kbn/interpreter/server';
|
||||
import { interpretProvider, serializeProvider } from '@kbn/interpreter/common';
|
||||
import { interpretProvider, serializeProvider, FunctionsRegistry, TypesRegistry } from '@kbn/interpreter/common';
|
||||
|
||||
// We actually DO need populateServerRegistries here since this is a different node process
|
||||
const pluginsReady = populateServerRegistries(['commonFunctions', 'types']);
|
||||
const registries = {
|
||||
commonFunctions: new FunctionsRegistry(),
|
||||
types: new TypesRegistry(),
|
||||
};
|
||||
|
||||
const pluginsReady = populateServerRegistries(registries);
|
||||
const heap = {};
|
||||
|
||||
process.on('message', msg => {
|
||||
|
|
|
@ -18,8 +18,7 @@
|
|||
*/
|
||||
|
||||
import socket from 'socket.io';
|
||||
import { serializeProvider, typesRegistry } from '@kbn/interpreter/common';
|
||||
import { getServerRegistries } from '@kbn/interpreter/server';
|
||||
import { serializeProvider } from '@kbn/interpreter/common';
|
||||
import { routeExpressionProvider } from '../lib/route_expression/index';
|
||||
import { browser } from '../lib/route_expression/browser';
|
||||
import { thread } from '../lib/route_expression/thread/index';
|
||||
|
@ -54,7 +53,7 @@ export function socketApi(server) {
|
|||
const request = await getModifiedRequest(server, socket);
|
||||
if (!request) return; // do nothing without the request object
|
||||
|
||||
const types = typesRegistry.toJS();
|
||||
const types = server.plugins.interpreter.types.toJS();
|
||||
const { serialize, deserialize } = serializeProvider(types);
|
||||
|
||||
// I'd love to find a way to generalize all of these, but they each need a different set of things
|
||||
|
@ -70,9 +69,7 @@ export function socketApi(server) {
|
|||
}
|
||||
|
||||
socket.on('getFunctionList', () => {
|
||||
getServerRegistries().then(({ serverFunctions }) =>
|
||||
socket.emit('functionList', serverFunctions.toJS())
|
||||
);
|
||||
socket.emit('functionList', server.plugins.interpreter.serverFunctions.toJS());
|
||||
});
|
||||
|
||||
socket.on('run', async ({ ast, context, id }) => {
|
||||
|
|
|
@ -20,10 +20,11 @@
|
|||
// @ts-ignore
|
||||
import { fromExpression } from '@kbn/interpreter/common';
|
||||
// @ts-ignore
|
||||
import { interpretAst } from '@kbn/interpreter/public';
|
||||
import { getInterpreter } from 'plugins/interpreter/interpreter';
|
||||
|
||||
export const runPipeline = async (expression: string, context: any, handlers: any) => {
|
||||
const ast = fromExpression(expression);
|
||||
const pipelineResponse = await interpretAst(ast, context, handlers);
|
||||
const { interpreter } = await getInterpreter();
|
||||
const pipelineResponse = await interpreter.interpretAst(ast, context, handlers);
|
||||
return pipelineResponse;
|
||||
};
|
||||
|
|
|
@ -14,7 +14,7 @@ export function canvas(kibana) {
|
|||
return new kibana.Plugin({
|
||||
id: CANVAS_APP,
|
||||
configPrefix: 'xpack.canvas',
|
||||
require: ['kibana', 'elasticsearch', 'xpack_main'],
|
||||
require: ['kibana', 'elasticsearch', 'xpack_main', 'interpreter'],
|
||||
publicDir: resolve(__dirname, 'public'),
|
||||
uiExports: {
|
||||
app: {
|
||||
|
|
|
@ -4,14 +4,14 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { functionsRegistry } from '@kbn/interpreter/common';
|
||||
import { populateServerRegistries } from '@kbn/interpreter/server';
|
||||
import { routes } from './server/routes';
|
||||
import { commonFunctions } from './common/functions';
|
||||
import { registerCanvasUsageCollector } from './server/usage';
|
||||
import { loadSampleData } from './server/sample_data';
|
||||
|
||||
export default async function(server /*options*/) {
|
||||
const functionsRegistry = server.plugins.interpreter.serverFunctions;
|
||||
|
||||
server.injectUiAppVars('canvas', async () => {
|
||||
const config = server.config();
|
||||
const basePath = config.get('server.basePath');
|
||||
|
@ -40,8 +40,5 @@ export default async function(server /*options*/) {
|
|||
|
||||
registerCanvasUsageCollector(server);
|
||||
loadSampleData(server);
|
||||
|
||||
// Do not initialize the app until the registries are populated
|
||||
await populateServerRegistries(['serverFunctions', 'types']);
|
||||
routes(server);
|
||||
}
|
||||
|
|
|
@ -4,7 +4,9 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { populateBrowserRegistries, getInitializedFunctions } from '@kbn/interpreter/public';
|
||||
import { functionsRegistry } from 'plugins/interpreter/functions_registry';
|
||||
import { getInterpreter, updateInterpreterFunctions } from 'plugins/interpreter/interpreter';
|
||||
import { loadBrowserRegistries } from '@kbn/interpreter/public';
|
||||
import { connect } from 'react-redux';
|
||||
import { compose, withProps } from 'recompose';
|
||||
import { getAppReady, getBasePath } from '../../state/selectors/app';
|
||||
|
@ -50,10 +52,12 @@ const mapDispatchToProps = dispatch => ({
|
|||
// TODO: the correct socket path should come from upstream, using the constant here is not ideal
|
||||
setAppReady: basePath => async () => {
|
||||
try {
|
||||
// wait for core interpreter to load
|
||||
await getInterpreter();
|
||||
// initialize the socket and interpreter
|
||||
loadPrivateBrowserFunctions();
|
||||
await populateBrowserRegistries(types, basePath);
|
||||
await getInitializedFunctions();
|
||||
loadPrivateBrowserFunctions(functionsRegistry);
|
||||
await updateInterpreterFunctions();
|
||||
await loadBrowserRegistries(types, basePath);
|
||||
|
||||
// set app state to ready
|
||||
dispatch(appReady());
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { interpretAst } from '@kbn/interpreter/public';
|
||||
import { interpretAst } from 'plugins/interpreter/interpreter';
|
||||
import { pure, compose, lifecycle, withState, branch, renderComponent } from 'recompose';
|
||||
import { PropTypes } from 'prop-types';
|
||||
import { Loading } from '../../loading';
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { interpretAst } from '@kbn/interpreter/public';
|
||||
import { interpretAst } from 'plugins/interpreter/interpreter';
|
||||
import { compose, withProps } from 'recompose';
|
||||
import { get } from 'lodash';
|
||||
import { toExpression } from '@kbn/interpreter/common';
|
||||
|
|
|
@ -4,8 +4,9 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { interpretAst } from '@kbn/interpreter/public';
|
||||
import { fromExpression, typesRegistry } from '@kbn/interpreter/common';
|
||||
import { interpretAst } from 'plugins/interpreter/interpreter';
|
||||
import { typesRegistry } from 'plugins/interpreter/types_registry';
|
||||
import { fromExpression } from '@kbn/interpreter/common';
|
||||
import { getState } from '../state/store';
|
||||
import { getGlobalFilterExpression } from '../state/selectors/workpad';
|
||||
|
||||
|
|
|
@ -4,12 +4,11 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { functionsRegistry } from 'plugins/interpreter/functions_registry';
|
||||
import uniqBy from 'lodash.uniqby';
|
||||
import { getBrowserRegistries } from '@kbn/interpreter/public';
|
||||
import { getServerFunctions } from '../state/selectors/app';
|
||||
|
||||
export async function getFunctionDefinitions(state) {
|
||||
const { browserFunctions } = await getBrowserRegistries();
|
||||
const serverFunctions = getServerFunctions(state);
|
||||
return uniqBy(serverFunctions.concat(browserFunctions.toArray()), 'name');
|
||||
return uniqBy(serverFunctions.concat(functionsRegistry.toArray()), 'name');
|
||||
}
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
// export the common registry here, so it's available in plugin public code
|
||||
export { functionsRegistry } from '@kbn/interpreter/common';
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
import { commonFunctions } from '../../common/functions';
|
||||
import { clientFunctions } from '../functions';
|
||||
import { functionsRegistry } from './functions_registry';
|
||||
|
||||
/*
|
||||
Functions loaded here use PRIVATE APIs
|
||||
|
@ -15,11 +14,11 @@ import { functionsRegistry } from './functions_registry';
|
|||
few of these things as we can't thread them.
|
||||
*/
|
||||
|
||||
function addFunction(fnDef) {
|
||||
functionsRegistry.register(fnDef);
|
||||
}
|
||||
export const loadPrivateBrowserFunctions = functionsRegistry => {
|
||||
function addFunction(fnDef) {
|
||||
functionsRegistry.register(fnDef);
|
||||
}
|
||||
|
||||
export const loadPrivateBrowserFunctions = () => {
|
||||
clientFunctions.forEach(addFunction);
|
||||
commonFunctions.forEach(addFunction);
|
||||
};
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { interpretAst } from '@kbn/interpreter/public';
|
||||
import { interpretAst } from 'plugins/interpreter/interpreter';
|
||||
import { fromExpression, getType } from '@kbn/interpreter/common';
|
||||
import { notify } from './notify';
|
||||
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
// export the common registry here, so it's available in plugin public code
|
||||
export { typesRegistry } from '@kbn/interpreter/common';
|
|
@ -4,7 +4,7 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { interpretAst } from '@kbn/interpreter/public';
|
||||
import { interpretAst } from 'plugins/interpreter/interpreter';
|
||||
import { createAction } from 'redux-actions';
|
||||
import { createThunk } from 'redux-thunks';
|
||||
import { set, del } from 'object-path-immutable';
|
||||
|
|
|
@ -28,6 +28,7 @@ export function getWebpackConfig({ devtool, watch, production } = {}) {
|
|||
'uis/datasources/all': path.join(sourceDir, 'uis/datasources/register.js'),
|
||||
'uis/arguments/all': path.join(sourceDir, 'uis/arguments/register.js'),
|
||||
'functions/browser/all': path.join(sourceDir, 'functions/browser/register.js'),
|
||||
'functions/browser/common': path.join(sourceDir, 'functions/common/register.js'),
|
||||
'templates/all': path.join(sourceDir, 'templates/register.js'),
|
||||
'uis/tags/all': path.join(sourceDir, 'uis/tags/register.js'),
|
||||
},
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue