@perses-dev/plugin-system 0.54.0 → 0.55.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/dist/cjs/components/PanelSpecEditor/PanelAnnotationsEditor.js +246 -0
  2. package/dist/cjs/components/PanelSpecEditor/PanelSpecEditor.js +16 -1
  3. package/dist/cjs/components/PluginRegistry/PluginRegistry.js +4 -0
  4. package/dist/cjs/components/TimeRangeControls/TimeRangeControls.js +5 -2
  5. package/dist/cjs/remote/PluginRuntime.js +12 -12
  6. package/dist/cjs/remote/remotePluginLoader.js +3 -1
  7. package/dist/cjs/runtime/UsageMetricsProvider.js +4 -2
  8. package/dist/cjs/runtime/item-actions.js +9 -10
  9. package/dist/components/PanelSpecEditor/PanelAnnotationsEditor.d.ts +15 -0
  10. package/dist/components/PanelSpecEditor/PanelAnnotationsEditor.d.ts.map +1 -0
  11. package/dist/components/PanelSpecEditor/PanelAnnotationsEditor.js +238 -0
  12. package/dist/components/PanelSpecEditor/PanelAnnotationsEditor.js.map +1 -0
  13. package/dist/components/PanelSpecEditor/PanelSpecEditor.d.ts.map +1 -1
  14. package/dist/components/PanelSpecEditor/PanelSpecEditor.js +16 -1
  15. package/dist/components/PanelSpecEditor/PanelSpecEditor.js.map +1 -1
  16. package/dist/components/PluginRegistry/PluginRegistry.d.ts.map +1 -1
  17. package/dist/components/PluginRegistry/PluginRegistry.js +4 -0
  18. package/dist/components/PluginRegistry/PluginRegistry.js.map +1 -1
  19. package/dist/components/TimeRangeControls/TimeRangeControls.d.ts.map +1 -1
  20. package/dist/components/TimeRangeControls/TimeRangeControls.js +5 -2
  21. package/dist/components/TimeRangeControls/TimeRangeControls.js.map +1 -1
  22. package/dist/model/panels.d.ts +6 -0
  23. package/dist/model/panels.d.ts.map +1 -1
  24. package/dist/model/panels.js.map +1 -1
  25. package/dist/remote/PluginRuntime.js +12 -12
  26. package/dist/remote/PluginRuntime.js.map +1 -1
  27. package/dist/remote/remotePluginLoader.d.ts +5 -0
  28. package/dist/remote/remotePluginLoader.d.ts.map +1 -1
  29. package/dist/remote/remotePluginLoader.js +3 -1
  30. package/dist/remote/remotePluginLoader.js.map +1 -1
  31. package/dist/runtime/UsageMetricsProvider.d.ts +2 -0
  32. package/dist/runtime/UsageMetricsProvider.d.ts.map +1 -1
  33. package/dist/runtime/UsageMetricsProvider.js +5 -3
  34. package/dist/runtime/UsageMetricsProvider.js.map +1 -1
  35. package/dist/runtime/item-actions.d.ts +3 -0
  36. package/dist/runtime/item-actions.d.ts.map +1 -1
  37. package/dist/runtime/item-actions.js +9 -10
  38. package/dist/runtime/item-actions.js.map +1 -1
  39. package/package.json +4 -4
@@ -84,11 +84,11 @@ const getPluginRuntime = ()=>{
84
84
  }
85
85
  },
86
86
  '@perses-dev/spec': {
87
- version: '0.2.0-rc.0',
87
+ version: '0.3.0-beta.1',
88
88
  lib: ()=>require('@perses-dev/spec'),
89
89
  shareConfig: {
90
90
  singleton: true,
91
- requiredVersion: '^0.2.0-rc.0'
91
+ requiredVersion: '^0.3.0-beta.1'
92
92
  }
93
93
  },
94
94
  '@perses-dev/core': {
@@ -100,43 +100,43 @@ const getPluginRuntime = ()=>{
100
100
  }
101
101
  },
102
102
  '@perses-dev/client': {
103
- version: '0.54.0-rc.1',
103
+ version: '0.55.0-beta.1',
104
104
  lib: ()=>require('@perses-dev/client'),
105
105
  shareConfig: {
106
106
  singleton: true,
107
- requiredVersion: '^0.54.0-rc.1'
107
+ requiredVersion: '^0.55.0-beta.1'
108
108
  }
109
109
  },
110
110
  '@perses-dev/components': {
111
- version: '0.54.0-rc.1',
111
+ version: '0.55.0-beta.1',
112
112
  lib: ()=>require('@perses-dev/components'),
113
113
  shareConfig: {
114
114
  singleton: true,
115
- requiredVersion: '^0.54.0-rc.1'
115
+ requiredVersion: '^0.55.0-beta.1'
116
116
  }
117
117
  },
118
118
  '@perses-dev/plugin-system': {
119
- version: '0.54.0-rc.1',
119
+ version: '0.55.0-beta.1',
120
120
  lib: ()=>require('@perses-dev/plugin-system'),
121
121
  shareConfig: {
122
122
  singleton: true,
123
- requiredVersion: '^0.54.0-rc.1'
123
+ requiredVersion: '^0.55.0-beta.1'
124
124
  }
125
125
  },
126
126
  '@perses-dev/explore': {
127
- version: '0.54.0-rc.1',
127
+ version: '0.55.0-beta.1',
128
128
  lib: ()=>require('@perses-dev/explore'),
129
129
  shareConfig: {
130
130
  singleton: true,
131
- requiredVersion: '^0.54.0-rc.1'
131
+ requiredVersion: '^0.55.0-beta.1'
132
132
  }
133
133
  },
134
134
  '@perses-dev/dashboards': {
135
- version: '0.54.0-rc.1',
135
+ version: '0.55.0-beta.1',
136
136
  lib: ()=>require('@perses-dev/dashboards'),
137
137
  shareConfig: {
138
138
  singleton: true,
139
- requiredVersion: '^0.54.0-rc.1'
139
+ requiredVersion: '^0.55.0-beta.1'
140
140
  }
141
141
  },
142
142
  // Below are the shared modules that are used by the plugins, this can be part of the SDK
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/remote/PluginRuntime.tsx"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \\\"AS IS\\\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n/* eslint-disable @typescript-eslint/no-require-imports */\n// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { createInstance, ModuleFederation } from '@module-federation/enhanced/runtime';\n\nimport * as ReactQuery from '@tanstack/react-query';\nimport React from 'react';\nimport ReactDOM from 'react-dom';\nimport * as ReactHookForm from 'react-hook-form';\nimport * as ReactRouterDOM from 'react-router-dom';\nimport { PersesPlugin, RemotePluginModule } from './PersesPlugin.types';\n\nlet instance: ModuleFederation | null = null;\n\nconst getPluginRuntime = (): ModuleFederation => {\n if (instance === null) {\n const pluginRuntime = createInstance({\n name: '@perses/perses-ui-host',\n remotes: [], // all remotes are loaded dynamically\n shared: {\n react: {\n version: React.version,\n lib: () => React,\n shareConfig: {\n singleton: true,\n requiredVersion: `^${React.version}`,\n },\n },\n 'react-dom': {\n version: '18.3.1',\n lib: () => ReactDOM,\n shareConfig: {\n singleton: true,\n requiredVersion: `^18.3.1`,\n },\n },\n 'react-router-dom': {\n version: '6.26.0',\n lib: () => ReactRouterDOM,\n shareConfig: {\n singleton: true,\n requiredVersion: '^6.26.0',\n },\n },\n '@tanstack/react-query': {\n version: '4.39.1',\n lib: () => ReactQuery,\n shareConfig: {\n singleton: true,\n requiredVersion: '^4.39.1',\n },\n },\n 'react-hook-form': {\n version: '7.52.2',\n lib: () => ReactHookForm,\n shareConfig: {\n singleton: true,\n requiredVersion: '^7.52.2',\n },\n },\n echarts: {\n version: '5.5.0',\n lib: () => require('echarts'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^5.5.0',\n },\n },\n '@perses-dev/spec': {\n version: '0.2.0-rc.0',\n lib: () => require('@perses-dev/spec'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^0.2.0-rc.0',\n },\n },\n '@perses-dev/core': {\n version: '0.53.1',\n lib: () => require('@perses-dev/core'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^0.53.1',\n },\n },\n '@perses-dev/client': {\n version: '0.54.0-rc.1',\n lib: () => require('@perses-dev/client'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^0.54.0-rc.1',\n },\n },\n '@perses-dev/components': {\n version: '0.54.0-rc.1',\n lib: () => require('@perses-dev/components'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^0.54.0-rc.1',\n },\n },\n '@perses-dev/plugin-system': {\n version: '0.54.0-rc.1',\n lib: () => require('@perses-dev/plugin-system'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^0.54.0-rc.1',\n },\n },\n '@perses-dev/explore': {\n version: '0.54.0-rc.1',\n lib: () => require('@perses-dev/explore'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^0.54.0-rc.1',\n },\n },\n '@perses-dev/dashboards': {\n version: '0.54.0-rc.1',\n lib: () => require('@perses-dev/dashboards'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^0.54.0-rc.1',\n },\n },\n // Below are the shared modules that are used by the plugins, this can be part of the SDK\n 'date-fns': {\n version: '4.1.0',\n lib: () => require('date-fns'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^4.1.0',\n },\n },\n 'date-fns-tz': {\n version: '3.2.0',\n lib: () => require('date-fns-tz'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^3.2.0',\n },\n },\n lodash: {\n version: '4.17.21',\n lib: () => require('lodash'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^4.17.21',\n },\n },\n '@emotion/react': {\n version: '11.11.3',\n lib: () => require('@emotion/react'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^11.11.3',\n },\n },\n '@emotion/styled': {\n version: '11.11.0',\n lib: () => require('@emotion/styled'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^11.11.0',\n },\n },\n '@hookform/resolvers/zod': {\n version: '3.3.4',\n lib: () => require('@hookform/resolvers/zod'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^3.3.4',\n },\n },\n 'use-resize-observer': {\n version: '9.1.0',\n lib: () => require('use-resize-observer'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^9.1.0',\n },\n },\n 'mdi-material-ui': {\n version: '7.4.0',\n lib: () => require('mdi-material-ui'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^7.4.0',\n },\n },\n immer: {\n version: '10.1.1',\n lib: () => require('immer'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^10.1.1',\n },\n },\n },\n });\n\n instance = pluginRuntime;\n\n return instance;\n }\n return instance;\n};\n\nfunction getModuleFederationRemoteName(name: string, registry?: string, version?: string): string {\n return `${name}:${registry ?? ''}:${version ?? ''}`;\n}\n\nconst registerRemote = (name: string, registry?: string, version?: string, baseURL?: string): void => {\n const pluginRuntime = getPluginRuntime();\n const registryName = getModuleFederationRemoteName(name, registry, version);\n\n const existingRemote = pluginRuntime.options.remotes.find((remote) => remote.name === registryName);\n if (!existingRemote) {\n const nameVersionRegistry = [name, version, registry].filter(Boolean).join('~');\n const prefix = baseURL || '/plugins';\n const remoteEntryURL = `${prefix}/${nameVersionRegistry}/mf-manifest.json`;\n\n pluginRuntime.registerRemotes([\n {\n name: registryName,\n entry: remoteEntryURL,\n alias: registryName,\n },\n ]);\n }\n};\n\nexport const loadPlugin = async (target: {\n moduleName: string;\n pluginName: string;\n registry?: string;\n version?: string;\n baseURL?: string;\n}): Promise<RemotePluginModule | null> => {\n const { moduleName, pluginName, registry, version, baseURL } = target;\n registerRemote(moduleName, registry, version, baseURL);\n\n const pluginRuntime = getPluginRuntime();\n const registryName = getModuleFederationRemoteName(moduleName, registry, version);\n return pluginRuntime.loadRemote<RemotePluginModule>(`${registryName}/${pluginName}`);\n};\n\nexport function usePluginRuntime({ plugin }: { plugin: PersesPlugin }): {\n pluginRuntime: ModuleFederation;\n loadPlugin: () => Promise<RemotePluginModule | null>;\n} {\n return {\n pluginRuntime: getPluginRuntime(),\n loadPlugin: (): Promise<RemotePluginModule | null> => {\n const { moduleName, name: pluginName, registry, version, baseURL } = plugin;\n return loadPlugin({ moduleName, pluginName, registry, version, baseURL });\n },\n };\n}\n"],"names":["createInstance","ReactQuery","React","ReactDOM","ReactHookForm","ReactRouterDOM","instance","getPluginRuntime","pluginRuntime","name","remotes","shared","react","version","lib","shareConfig","singleton","requiredVersion","echarts","require","lodash","immer","getModuleFederationRemoteName","registry","registerRemote","baseURL","registryName","existingRemote","options","find","remote","nameVersionRegistry","filter","Boolean","join","prefix","remoteEntryURL","registerRemotes","entry","alias","loadPlugin","target","moduleName","pluginName","loadRemote","usePluginRuntime","plugin"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/remote/PluginRuntime.tsx"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \\\"AS IS\\\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n/* eslint-disable @typescript-eslint/no-require-imports */\n// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { createInstance, ModuleFederation } from '@module-federation/enhanced/runtime';\n\nimport * as ReactQuery from '@tanstack/react-query';\nimport React from 'react';\nimport ReactDOM from 'react-dom';\nimport * as ReactHookForm from 'react-hook-form';\nimport * as ReactRouterDOM from 'react-router-dom';\nimport { PersesPlugin, RemotePluginModule } from './PersesPlugin.types';\n\nlet instance: ModuleFederation | null = null;\n\nconst getPluginRuntime = (): ModuleFederation => {\n if (instance === null) {\n const pluginRuntime = createInstance({\n name: '@perses/perses-ui-host',\n remotes: [], // all remotes are loaded dynamically\n shared: {\n react: {\n version: React.version,\n lib: () => React,\n shareConfig: {\n singleton: true,\n requiredVersion: `^${React.version}`,\n },\n },\n 'react-dom': {\n version: '18.3.1',\n lib: () => ReactDOM,\n shareConfig: {\n singleton: true,\n requiredVersion: `^18.3.1`,\n },\n },\n 'react-router-dom': {\n version: '6.26.0',\n lib: () => ReactRouterDOM,\n shareConfig: {\n singleton: true,\n requiredVersion: '^6.26.0',\n },\n },\n '@tanstack/react-query': {\n version: '4.39.1',\n lib: () => ReactQuery,\n shareConfig: {\n singleton: true,\n requiredVersion: '^4.39.1',\n },\n },\n 'react-hook-form': {\n version: '7.52.2',\n lib: () => ReactHookForm,\n shareConfig: {\n singleton: true,\n requiredVersion: '^7.52.2',\n },\n },\n echarts: {\n version: '5.5.0',\n lib: () => require('echarts'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^5.5.0',\n },\n },\n '@perses-dev/spec': {\n version: '0.3.0-beta.1',\n lib: () => require('@perses-dev/spec'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^0.3.0-beta.1',\n },\n },\n '@perses-dev/core': {\n version: '0.53.1',\n lib: () => require('@perses-dev/core'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^0.53.1',\n },\n },\n '@perses-dev/client': {\n version: '0.55.0-beta.1',\n lib: () => require('@perses-dev/client'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^0.55.0-beta.1',\n },\n },\n '@perses-dev/components': {\n version: '0.55.0-beta.1',\n lib: () => require('@perses-dev/components'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^0.55.0-beta.1',\n },\n },\n '@perses-dev/plugin-system': {\n version: '0.55.0-beta.1',\n lib: () => require('@perses-dev/plugin-system'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^0.55.0-beta.1',\n },\n },\n '@perses-dev/explore': {\n version: '0.55.0-beta.1',\n lib: () => require('@perses-dev/explore'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^0.55.0-beta.1',\n },\n },\n '@perses-dev/dashboards': {\n version: '0.55.0-beta.1',\n lib: () => require('@perses-dev/dashboards'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^0.55.0-beta.1',\n },\n },\n // Below are the shared modules that are used by the plugins, this can be part of the SDK\n 'date-fns': {\n version: '4.1.0',\n lib: () => require('date-fns'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^4.1.0',\n },\n },\n 'date-fns-tz': {\n version: '3.2.0',\n lib: () => require('date-fns-tz'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^3.2.0',\n },\n },\n lodash: {\n version: '4.17.21',\n lib: () => require('lodash'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^4.17.21',\n },\n },\n '@emotion/react': {\n version: '11.11.3',\n lib: () => require('@emotion/react'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^11.11.3',\n },\n },\n '@emotion/styled': {\n version: '11.11.0',\n lib: () => require('@emotion/styled'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^11.11.0',\n },\n },\n '@hookform/resolvers/zod': {\n version: '3.3.4',\n lib: () => require('@hookform/resolvers/zod'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^3.3.4',\n },\n },\n 'use-resize-observer': {\n version: '9.1.0',\n lib: () => require('use-resize-observer'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^9.1.0',\n },\n },\n 'mdi-material-ui': {\n version: '7.4.0',\n lib: () => require('mdi-material-ui'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^7.4.0',\n },\n },\n immer: {\n version: '10.1.1',\n lib: () => require('immer'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^10.1.1',\n },\n },\n },\n });\n\n instance = pluginRuntime;\n\n return instance;\n }\n return instance;\n};\n\nfunction getModuleFederationRemoteName(name: string, registry?: string, version?: string): string {\n return `${name}:${registry ?? ''}:${version ?? ''}`;\n}\n\nconst registerRemote = (name: string, registry?: string, version?: string, baseURL?: string): void => {\n const pluginRuntime = getPluginRuntime();\n const registryName = getModuleFederationRemoteName(name, registry, version);\n\n const existingRemote = pluginRuntime.options.remotes.find((remote) => remote.name === registryName);\n if (!existingRemote) {\n const nameVersionRegistry = [name, version, registry].filter(Boolean).join('~');\n const prefix = baseURL || '/plugins';\n const remoteEntryURL = `${prefix}/${nameVersionRegistry}/mf-manifest.json`;\n\n pluginRuntime.registerRemotes([\n {\n name: registryName,\n entry: remoteEntryURL,\n alias: registryName,\n },\n ]);\n }\n};\n\nexport const loadPlugin = async (target: {\n moduleName: string;\n pluginName: string;\n registry?: string;\n version?: string;\n baseURL?: string;\n}): Promise<RemotePluginModule | null> => {\n const { moduleName, pluginName, registry, version, baseURL } = target;\n registerRemote(moduleName, registry, version, baseURL);\n\n const pluginRuntime = getPluginRuntime();\n const registryName = getModuleFederationRemoteName(moduleName, registry, version);\n return pluginRuntime.loadRemote<RemotePluginModule>(`${registryName}/${pluginName}`);\n};\n\nexport function usePluginRuntime({ plugin }: { plugin: PersesPlugin }): {\n pluginRuntime: ModuleFederation;\n loadPlugin: () => Promise<RemotePluginModule | null>;\n} {\n return {\n pluginRuntime: getPluginRuntime(),\n loadPlugin: (): Promise<RemotePluginModule | null> => {\n const { moduleName, name: pluginName, registry, version, baseURL } = plugin;\n return loadPlugin({ moduleName, pluginName, registry, version, baseURL });\n },\n };\n}\n"],"names":["createInstance","ReactQuery","React","ReactDOM","ReactHookForm","ReactRouterDOM","instance","getPluginRuntime","pluginRuntime","name","remotes","shared","react","version","lib","shareConfig","singleton","requiredVersion","echarts","require","lodash","immer","getModuleFederationRemoteName","registry","registerRemote","baseURL","registryName","existingRemote","options","find","remote","nameVersionRegistry","filter","Boolean","join","prefix","remoteEntryURL","registerRemotes","entry","alias","loadPlugin","target","moduleName","pluginName","loadRemote","usePluginRuntime","plugin"],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import { PluginLoader } from '@perses-dev/plugin-system';
2
+ import { type FetchFn } from '@perses-dev/client';
2
3
  type RemotePluginLoaderOptions = {
3
4
  /**
4
5
  * The API path for fetching available Perses plugins. Used to construct the full URL to the `/api/v1/plugins` endpoint.
@@ -10,6 +11,10 @@ type RemotePluginLoaderOptions = {
10
11
  * @default ''
11
12
  **/
12
13
  baseURL?: string;
14
+ /**
15
+ * Optional custom fetch function to use for network requests. If not provided, the default fetch implementation will be used.
16
+ */
17
+ fetchFn?: FetchFn;
13
18
  };
14
19
  /**
15
20
  * Get a PluginLoader that fetches the list of installed plugins from a remote server and loads them as needed.
@@ -1 +1 @@
1
- {"version":3,"file":"remotePluginLoader.d.ts","sourceRoot":"","sources":["../../src/remote/remotePluginLoader.ts"],"names":[],"mappings":"AAaA,OAAO,EACL,YAAY,EAKb,MAAM,2BAA2B,CAAC;AA8BnC,KAAK,yBAAyB,GAAG;IAC/B;;;QAGI;IACJ,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;QAGI;IACJ,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAwBF;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,CAAC,EAAE,yBAAyB,GAAG,YAAY,CAyDpF"}
1
+ {"version":3,"file":"remotePluginLoader.d.ts","sourceRoot":"","sources":["../../src/remote/remotePluginLoader.ts"],"names":[],"mappings":"AAaA,OAAO,EACL,YAAY,EAKb,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAyB,KAAK,OAAO,EAAE,MAAM,oBAAoB,CAAC;AA8BzE,KAAK,yBAAyB,GAAG;IAC/B;;;QAGI;IACJ,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;QAGI;IACJ,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;OAEG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC;AAwBF;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,CAAC,EAAE,yBAAyB,GAAG,YAAY,CA0DpF"}
@@ -11,6 +11,7 @@
11
11
  // See the License for the specific language governing permissions and
12
12
  // limitations under the License.
13
13
  import { getPluginModuleCompoundKey } from '@perses-dev/plugin-system';
14
+ import { fetch as defaultFetch } from '@perses-dev/client';
14
15
  import { loadPlugin } from './PluginRuntime';
15
16
  const isPluginMetadata = (plugin)=>{
16
17
  return typeof plugin === 'object' && plugin !== null && 'kind' in plugin && 'spec' in plugin && typeof plugin.spec === 'object' && plugin.spec !== null && 'name' in plugin.spec;
@@ -37,9 +38,10 @@ const paramToOptions = (options)=>{
37
38
  * @param options - Optional configuration options for the remote plugin loader.
38
39
  */ export function remotePluginLoader(options) {
39
40
  const { pluginsApiPath, pluginsAssetsPath } = paramToOptions(options);
41
+ const fetchFn = options?.fetchFn ?? defaultFetch;
40
42
  return {
41
43
  getInstalledPlugins: async ()=>{
42
- const pluginsResponse = await fetch(pluginsApiPath);
44
+ const pluginsResponse = await fetchFn(pluginsApiPath);
43
45
  const plugins = await pluginsResponse.json();
44
46
  let pluginModules = [];
45
47
  if (Array.isArray(plugins)) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/remote/remotePluginLoader.ts"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport {\n PluginLoader,\n PluginMetadata,\n PluginModuleResource,\n PluginType,\n getPluginModuleCompoundKey,\n} from '@perses-dev/plugin-system';\nimport { RemotePluginModule } from './PersesPlugin.types';\nimport { loadPlugin } from './PluginRuntime';\n\nconst isPluginMetadata = (plugin: unknown): plugin is PluginMetadata => {\n return (\n typeof plugin === 'object' &&\n plugin !== null &&\n 'kind' in plugin &&\n 'spec' in plugin &&\n typeof plugin.spec === 'object' &&\n plugin.spec !== null &&\n 'name' in plugin.spec\n );\n};\n\nconst isPluginModuleResource = (pluginModule: unknown): pluginModule is PluginModuleResource => {\n return (\n typeof pluginModule === 'object' &&\n pluginModule !== null &&\n 'metadata' in pluginModule &&\n 'spec' in pluginModule &&\n typeof pluginModule.spec === 'object' &&\n pluginModule.spec !== null &&\n 'plugins' in pluginModule.spec &&\n Array.isArray(pluginModule.spec.plugins) &&\n pluginModule.spec.plugins.every(isPluginMetadata)\n );\n};\n\ntype RemotePluginLoaderOptions = {\n /**\n * The API path for fetching available Perses plugins. Used to construct the full URL to the `/api/v1/plugins` endpoint.\n * @default ''\n **/\n apiPrefix?: string;\n /**\n * The base URL for loading plugin assets (e.g., JavaScript files). Used to construct the full URL to the `/plugins` directory\n * @default ''\n **/\n baseURL?: string;\n};\n\ntype ParsedPluginOptions = {\n pluginsApiPath: string;\n pluginsAssetsPath: string;\n};\n\nconst DEFAULT_PLUGINS_API_PATH = '/api/v1/plugins';\nconst DEFAULT_PLUGINS_ASSETS_PATH = '/plugins';\n\nconst paramToOptions = (options?: RemotePluginLoaderOptions): ParsedPluginOptions => {\n if (options === undefined) {\n return {\n pluginsApiPath: DEFAULT_PLUGINS_API_PATH,\n pluginsAssetsPath: DEFAULT_PLUGINS_ASSETS_PATH,\n };\n }\n\n return {\n pluginsApiPath: `${options?.apiPrefix ?? ''}${DEFAULT_PLUGINS_API_PATH}`,\n pluginsAssetsPath: `${options?.baseURL ?? ''}${DEFAULT_PLUGINS_ASSETS_PATH}`,\n };\n};\n\n/**\n * Get a PluginLoader that fetches the list of installed plugins from a remote server and loads them as needed.\n * @param options - Optional configuration options for the remote plugin loader.\n */\nexport function remotePluginLoader(options?: RemotePluginLoaderOptions): PluginLoader {\n const { pluginsApiPath, pluginsAssetsPath } = paramToOptions(options);\n\n return {\n getInstalledPlugins: async (): Promise<PluginModuleResource[]> => {\n const pluginsResponse = await fetch(pluginsApiPath);\n\n const plugins = await pluginsResponse.json();\n let pluginModules: PluginModuleResource[] = [];\n\n if (Array.isArray(plugins)) {\n pluginModules = plugins.filter(isPluginModuleResource);\n } else {\n console.error('RemotePluginLoader: Error loading plugins, response is not an array');\n }\n\n if (!pluginModules.length) {\n console.error('RemotePluginLoader: No valid plugins found');\n }\n\n return pluginModules;\n },\n importPluginModule: async (resource): Promise<RemotePluginModule> => {\n const { name: pluginModuleName, version, registry } = resource.metadata;\n\n const pluginModule: RemotePluginModule = {};\n\n const loadPromises = resource.spec.plugins.map(async (plugin) => {\n const remotePluginModule = await loadPlugin({\n moduleName: pluginModuleName,\n pluginName: plugin.spec.name,\n registry,\n version,\n baseURL: pluginsAssetsPath,\n });\n\n const remotePlugin = remotePluginModule?.[plugin.spec.name];\n if (remotePlugin) {\n return { kind: plugin.kind as PluginType, name: plugin.spec.name, remotePlugin };\n } else {\n console.error(`RemotePluginLoader: Error loading plugin ${plugin.spec.name}`);\n return null;\n }\n });\n\n const loadedPlugins = await Promise.all(loadPromises);\n\n loadedPlugins.forEach((item) => {\n if (item?.remotePlugin) {\n pluginModule[getPluginModuleCompoundKey({ kind: item.kind, name: item.name, registry, version })] =\n item.remotePlugin;\n }\n });\n\n return pluginModule;\n },\n };\n}\n"],"names":["getPluginModuleCompoundKey","loadPlugin","isPluginMetadata","plugin","spec","isPluginModuleResource","pluginModule","Array","isArray","plugins","every","DEFAULT_PLUGINS_API_PATH","DEFAULT_PLUGINS_ASSETS_PATH","paramToOptions","options","undefined","pluginsApiPath","pluginsAssetsPath","apiPrefix","baseURL","remotePluginLoader","getInstalledPlugins","pluginsResponse","fetch","json","pluginModules","filter","console","error","length","importPluginModule","resource","name","pluginModuleName","version","registry","metadata","loadPromises","map","remotePluginModule","moduleName","pluginName","remotePlugin","kind","loadedPlugins","Promise","all","forEach","item"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/remote/remotePluginLoader.ts"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport {\n PluginLoader,\n PluginMetadata,\n PluginModuleResource,\n PluginType,\n getPluginModuleCompoundKey,\n} from '@perses-dev/plugin-system';\nimport { fetch as defaultFetch, type FetchFn } from '@perses-dev/client';\nimport { RemotePluginModule } from './PersesPlugin.types';\nimport { loadPlugin } from './PluginRuntime';\n\nconst isPluginMetadata = (plugin: unknown): plugin is PluginMetadata => {\n return (\n typeof plugin === 'object' &&\n plugin !== null &&\n 'kind' in plugin &&\n 'spec' in plugin &&\n typeof plugin.spec === 'object' &&\n plugin.spec !== null &&\n 'name' in plugin.spec\n );\n};\n\nconst isPluginModuleResource = (pluginModule: unknown): pluginModule is PluginModuleResource => {\n return (\n typeof pluginModule === 'object' &&\n pluginModule !== null &&\n 'metadata' in pluginModule &&\n 'spec' in pluginModule &&\n typeof pluginModule.spec === 'object' &&\n pluginModule.spec !== null &&\n 'plugins' in pluginModule.spec &&\n Array.isArray(pluginModule.spec.plugins) &&\n pluginModule.spec.plugins.every(isPluginMetadata)\n );\n};\n\ntype RemotePluginLoaderOptions = {\n /**\n * The API path for fetching available Perses plugins. Used to construct the full URL to the `/api/v1/plugins` endpoint.\n * @default ''\n **/\n apiPrefix?: string;\n /**\n * The base URL for loading plugin assets (e.g., JavaScript files). Used to construct the full URL to the `/plugins` directory\n * @default ''\n **/\n baseURL?: string;\n /**\n * Optional custom fetch function to use for network requests. If not provided, the default fetch implementation will be used.\n */\n fetchFn?: FetchFn;\n};\n\ntype ParsedPluginOptions = {\n pluginsApiPath: string;\n pluginsAssetsPath: string;\n};\n\nconst DEFAULT_PLUGINS_API_PATH = '/api/v1/plugins';\nconst DEFAULT_PLUGINS_ASSETS_PATH = '/plugins';\n\nconst paramToOptions = (options?: RemotePluginLoaderOptions): ParsedPluginOptions => {\n if (options === undefined) {\n return {\n pluginsApiPath: DEFAULT_PLUGINS_API_PATH,\n pluginsAssetsPath: DEFAULT_PLUGINS_ASSETS_PATH,\n };\n }\n\n return {\n pluginsApiPath: `${options?.apiPrefix ?? ''}${DEFAULT_PLUGINS_API_PATH}`,\n pluginsAssetsPath: `${options?.baseURL ?? ''}${DEFAULT_PLUGINS_ASSETS_PATH}`,\n };\n};\n\n/**\n * Get a PluginLoader that fetches the list of installed plugins from a remote server and loads them as needed.\n * @param options - Optional configuration options for the remote plugin loader.\n */\nexport function remotePluginLoader(options?: RemotePluginLoaderOptions): PluginLoader {\n const { pluginsApiPath, pluginsAssetsPath } = paramToOptions(options);\n const fetchFn = options?.fetchFn ?? defaultFetch;\n\n return {\n getInstalledPlugins: async (): Promise<PluginModuleResource[]> => {\n const pluginsResponse = await fetchFn(pluginsApiPath);\n\n const plugins = await pluginsResponse.json();\n let pluginModules: PluginModuleResource[] = [];\n\n if (Array.isArray(plugins)) {\n pluginModules = plugins.filter(isPluginModuleResource);\n } else {\n console.error('RemotePluginLoader: Error loading plugins, response is not an array');\n }\n\n if (!pluginModules.length) {\n console.error('RemotePluginLoader: No valid plugins found');\n }\n\n return pluginModules;\n },\n importPluginModule: async (resource): Promise<RemotePluginModule> => {\n const { name: pluginModuleName, version, registry } = resource.metadata;\n\n const pluginModule: RemotePluginModule = {};\n\n const loadPromises = resource.spec.plugins.map(async (plugin) => {\n const remotePluginModule = await loadPlugin({\n moduleName: pluginModuleName,\n pluginName: plugin.spec.name,\n registry,\n version,\n baseURL: pluginsAssetsPath,\n });\n\n const remotePlugin = remotePluginModule?.[plugin.spec.name];\n if (remotePlugin) {\n return { kind: plugin.kind as PluginType, name: plugin.spec.name, remotePlugin };\n } else {\n console.error(`RemotePluginLoader: Error loading plugin ${plugin.spec.name}`);\n return null;\n }\n });\n\n const loadedPlugins = await Promise.all(loadPromises);\n\n loadedPlugins.forEach((item) => {\n if (item?.remotePlugin) {\n pluginModule[getPluginModuleCompoundKey({ kind: item.kind, name: item.name, registry, version })] =\n item.remotePlugin;\n }\n });\n\n return pluginModule;\n },\n };\n}\n"],"names":["getPluginModuleCompoundKey","fetch","defaultFetch","loadPlugin","isPluginMetadata","plugin","spec","isPluginModuleResource","pluginModule","Array","isArray","plugins","every","DEFAULT_PLUGINS_API_PATH","DEFAULT_PLUGINS_ASSETS_PATH","paramToOptions","options","undefined","pluginsApiPath","pluginsAssetsPath","apiPrefix","baseURL","remotePluginLoader","fetchFn","getInstalledPlugins","pluginsResponse","json","pluginModules","filter","console","error","length","importPluginModule","resource","name","pluginModuleName","version","registry","metadata","loadPromises","map","remotePluginModule","moduleName","pluginName","remotePlugin","kind","loadedPlugins","Promise","all","forEach","item"],"mappings":"AAAA,+BAA+B;AAC/B,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAEjC,SAKEA,0BAA0B,QACrB,4BAA4B;AACnC,SAASC,SAASC,YAAY,QAAsB,qBAAqB;AAEzE,SAASC,UAAU,QAAQ,kBAAkB;AAE7C,MAAMC,mBAAmB,CAACC;IACxB,OACE,OAAOA,WAAW,YAClBA,WAAW,QACX,UAAUA,UACV,UAAUA,UACV,OAAOA,OAAOC,IAAI,KAAK,YACvBD,OAAOC,IAAI,KAAK,QAChB,UAAUD,OAAOC,IAAI;AAEzB;AAEA,MAAMC,yBAAyB,CAACC;IAC9B,OACE,OAAOA,iBAAiB,YACxBA,iBAAiB,QACjB,cAAcA,gBACd,UAAUA,gBACV,OAAOA,aAAaF,IAAI,KAAK,YAC7BE,aAAaF,IAAI,KAAK,QACtB,aAAaE,aAAaF,IAAI,IAC9BG,MAAMC,OAAO,CAACF,aAAaF,IAAI,CAACK,OAAO,KACvCH,aAAaF,IAAI,CAACK,OAAO,CAACC,KAAK,CAACR;AAEpC;AAwBA,MAAMS,2BAA2B;AACjC,MAAMC,8BAA8B;AAEpC,MAAMC,iBAAiB,CAACC;IACtB,IAAIA,YAAYC,WAAW;QACzB,OAAO;YACLC,gBAAgBL;YAChBM,mBAAmBL;QACrB;IACF;IAEA,OAAO;QACLI,gBAAgB,GAAGF,SAASI,aAAa,KAAKP,0BAA0B;QACxEM,mBAAmB,GAAGH,SAASK,WAAW,KAAKP,6BAA6B;IAC9E;AACF;AAEA;;;CAGC,GACD,OAAO,SAASQ,mBAAmBN,OAAmC;IACpE,MAAM,EAAEE,cAAc,EAAEC,iBAAiB,EAAE,GAAGJ,eAAeC;IAC7D,MAAMO,UAAUP,SAASO,WAAWrB;IAEpC,OAAO;QACLsB,qBAAqB;YACnB,MAAMC,kBAAkB,MAAMF,QAAQL;YAEtC,MAAMP,UAAU,MAAMc,gBAAgBC,IAAI;YAC1C,IAAIC,gBAAwC,EAAE;YAE9C,IAAIlB,MAAMC,OAAO,CAACC,UAAU;gBAC1BgB,gBAAgBhB,QAAQiB,MAAM,CAACrB;YACjC,OAAO;gBACLsB,QAAQC,KAAK,CAAC;YAChB;YAEA,IAAI,CAACH,cAAcI,MAAM,EAAE;gBACzBF,QAAQC,KAAK,CAAC;YAChB;YAEA,OAAOH;QACT;QACAK,oBAAoB,OAAOC;YACzB,MAAM,EAAEC,MAAMC,gBAAgB,EAAEC,OAAO,EAAEC,QAAQ,EAAE,GAAGJ,SAASK,QAAQ;YAEvE,MAAM9B,eAAmC,CAAC;YAE1C,MAAM+B,eAAeN,SAAS3B,IAAI,CAACK,OAAO,CAAC6B,GAAG,CAAC,OAAOnC;gBACpD,MAAMoC,qBAAqB,MAAMtC,WAAW;oBAC1CuC,YAAYP;oBACZQ,YAAYtC,OAAOC,IAAI,CAAC4B,IAAI;oBAC5BG;oBACAD;oBACAf,SAASF;gBACX;gBAEA,MAAMyB,eAAeH,oBAAoB,CAACpC,OAAOC,IAAI,CAAC4B,IAAI,CAAC;gBAC3D,IAAIU,cAAc;oBAChB,OAAO;wBAAEC,MAAMxC,OAAOwC,IAAI;wBAAgBX,MAAM7B,OAAOC,IAAI,CAAC4B,IAAI;wBAAEU;oBAAa;gBACjF,OAAO;oBACLf,QAAQC,KAAK,CAAC,CAAC,yCAAyC,EAAEzB,OAAOC,IAAI,CAAC4B,IAAI,EAAE;oBAC5E,OAAO;gBACT;YACF;YAEA,MAAMY,gBAAgB,MAAMC,QAAQC,GAAG,CAACT;YAExCO,cAAcG,OAAO,CAAC,CAACC;gBACrB,IAAIA,MAAMN,cAAc;oBACtBpC,YAAY,CAACR,2BAA2B;wBAAE6C,MAAMK,KAAKL,IAAI;wBAAEX,MAAMgB,KAAKhB,IAAI;wBAAEG;wBAAUD;oBAAQ,GAAG,GAC/Fc,KAAKN,YAAY;gBACrB;YACF;YAEA,OAAOpC;QACT;IACF;AACF"}
@@ -1,3 +1,4 @@
1
+ import { FetchFn } from '@perses-dev/client';
1
2
  import { QueryDefinition } from '@perses-dev/spec';
2
3
  import { ReactElement, ReactNode } from 'react';
3
4
  type QueryState = 'pending' | 'success' | 'error';
@@ -9,6 +10,7 @@ interface UsageMetrics {
9
10
  renderErrorCount: number;
10
11
  pendingQueries: Map<string, QueryState>;
11
12
  apiPrefix?: string;
13
+ fetchFn: FetchFn;
12
14
  }
13
15
  interface UsageMetricsProps {
14
16
  project: string;
@@ -1 +1 @@
1
- {"version":3,"file":"UsageMetricsProvider.d.ts","sourceRoot":"","sources":["../../src/runtime/UsageMetricsProvider.tsx"],"names":[],"mappings":"AAcA,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAiB,YAAY,EAAE,SAAS,EAAc,MAAM,OAAO,CAAC;AAE3E,KAAK,UAAU,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;AAElD,UAAU,YAAY;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,MAAM,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC;IACzB,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,UAAU,iBAAiB;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,UAAU,sBAAsB;IAC9B,SAAS,EAAE,CAAC,UAAU,EAAE,eAAe,EAAE,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;CACrE;AAED,eAAO,MAAM,mBAAmB,mDAAqD,CAAC;AAEtF,eAAO,MAAM,sBAAsB,QAAO,YAAY,GAAG,SAExD,CAAC;AAEF,eAAO,MAAM,eAAe,QAAO,sBA6BlC,CAAC;AAiBF,eAAO,MAAM,oBAAoB,gDAAiD,iBAAiB,KAAG,YAYrG,CAAC"}
1
+ {"version":3,"file":"UsageMetricsProvider.d.ts","sourceRoot":"","sources":["../../src/runtime/UsageMetricsProvider.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAE,OAAO,EAAY,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAiB,YAAY,EAAE,SAAS,EAAc,MAAM,OAAO,CAAC;AAE3E,KAAK,UAAU,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;AAElD,UAAU,YAAY;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,MAAM,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC;IACzB,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,UAAU,iBAAiB;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,UAAU,sBAAsB;IAC9B,SAAS,EAAE,CAAC,UAAU,EAAE,eAAe,EAAE,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;CACrE;AAED,eAAO,MAAM,mBAAmB,mDAAqD,CAAC;AAEtF,eAAO,MAAM,sBAAsB,QAAO,YAAY,GAAG,SAExD,CAAC;AAEF,eAAO,MAAM,eAAe,QAAO,sBA6BlC,CAAC;AAiBF,eAAO,MAAM,oBAAoB,gDAAiD,iBAAiB,KAAG,YAerG,CAAC"}
@@ -11,7 +11,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
11
11
  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
12
  // See the License for the specific language governing permissions and
13
13
  // limitations under the License.
14
- import { fetch } from '@perses-dev/client';
14
+ import { useFetch } from '@perses-dev/client';
15
15
  import { createContext, useContext } from 'react';
16
16
  export const UsageMetricsContext = /*#__PURE__*/ createContext(undefined);
17
17
  export const useUsageMetricsContext = ()=>{
@@ -46,7 +46,7 @@ export const useUsageMetrics = ()=>{
46
46
  };
47
47
  };
48
48
  const submitMetrics = async (stats)=>{
49
- await fetch(`${stats.apiPrefix ?? ''}/api/v1/view`, {
49
+ await stats.fetchFn(`${stats.apiPrefix ?? ''}/api/v1/view`, {
50
50
  method: 'POST',
51
51
  headers: {
52
52
  'Content-Type': 'application/json'
@@ -60,6 +60,7 @@ const submitMetrics = async (stats)=>{
60
60
  });
61
61
  };
62
62
  export const UsageMetricsProvider = ({ apiPrefix, project, dashboard, children })=>{
63
+ const { fetch } = useFetch();
63
64
  const ctx = {
64
65
  project: project,
65
66
  dashboard: dashboard,
@@ -67,7 +68,8 @@ export const UsageMetricsProvider = ({ apiPrefix, project, dashboard, children }
67
68
  startRenderTime: Date.now(),
68
69
  renderDurationMs: 0,
69
70
  pendingQueries: new Map(),
70
- apiPrefix
71
+ apiPrefix,
72
+ fetchFn: fetch
71
73
  };
72
74
  return /*#__PURE__*/ _jsx(UsageMetricsContext.Provider, {
73
75
  value: ctx,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/runtime/UsageMetricsProvider.tsx"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { fetch } from '@perses-dev/client';\nimport { QueryDefinition } from '@perses-dev/spec';\nimport { createContext, ReactElement, ReactNode, useContext } from 'react';\n\ntype QueryState = 'pending' | 'success' | 'error';\n\ninterface UsageMetrics {\n project: string;\n dashboard: string;\n startRenderTime: number;\n renderDurationMs: number;\n renderErrorCount: number;\n pendingQueries: Map<string, QueryState>;\n apiPrefix?: string;\n}\n\ninterface UsageMetricsProps {\n project: string;\n dashboard: string;\n apiPrefix?: string;\n children: ReactNode;\n}\n\ninterface UseUsageMetricsResults {\n markQuery: (definition: QueryDefinition, state: QueryState) => void;\n}\n\nexport const UsageMetricsContext = createContext<UsageMetrics | undefined>(undefined);\n\nexport const useUsageMetricsContext = (): UsageMetrics | undefined => {\n return useContext(UsageMetricsContext);\n};\n\nexport const useUsageMetrics = (): UseUsageMetricsResults => {\n const ctx = useUsageMetricsContext();\n\n return {\n markQuery: (definition: QueryDefinition, newState: QueryState): void => {\n if (ctx === undefined) {\n return;\n }\n\n const definitionKey = JSON.stringify(definition);\n if (ctx.pendingQueries.has(definitionKey) && newState === 'pending') {\n // Never allow transitions back to pending, to avoid re-sending stats on a re-render.\n return;\n }\n\n if (ctx.pendingQueries.get(definitionKey) !== newState) {\n ctx.pendingQueries.set(definitionKey, newState);\n if (newState === 'error') {\n ctx.renderErrorCount += 1;\n }\n\n const allDone = [...ctx.pendingQueries.values()].every((p) => p !== 'pending');\n if (ctx.renderDurationMs === 0 && allDone) {\n ctx.renderDurationMs = Date.now() - ctx.startRenderTime;\n submitMetrics(ctx);\n }\n }\n },\n };\n};\n\nconst submitMetrics = async (stats: UsageMetrics): Promise<void> => {\n await fetch(`${stats.apiPrefix ?? ''}/api/v1/view`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n project: stats.project,\n dashboard: stats.dashboard,\n render_time: stats.renderDurationMs / 1000,\n render_errors: stats.renderErrorCount,\n }),\n });\n};\n\nexport const UsageMetricsProvider = ({ apiPrefix, project, dashboard, children }: UsageMetricsProps): ReactElement => {\n const ctx: UsageMetrics = {\n project: project,\n dashboard: dashboard,\n renderErrorCount: 0,\n startRenderTime: Date.now(),\n renderDurationMs: 0,\n pendingQueries: new Map(),\n apiPrefix,\n };\n\n return <UsageMetricsContext.Provider value={ctx}>{children}</UsageMetricsContext.Provider>;\n};\n"],"names":["fetch","createContext","useContext","UsageMetricsContext","undefined","useUsageMetricsContext","useUsageMetrics","ctx","markQuery","definition","newState","definitionKey","JSON","stringify","pendingQueries","has","get","set","renderErrorCount","allDone","values","every","p","renderDurationMs","Date","now","startRenderTime","submitMetrics","stats","apiPrefix","method","headers","body","project","dashboard","render_time","render_errors","UsageMetricsProvider","children","Map","Provider","value"],"mappings":";AAAA,+BAA+B;AAC/B,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAEjC,SAASA,KAAK,QAAQ,qBAAqB;AAE3C,SAASC,aAAa,EAA2BC,UAAU,QAAQ,QAAQ;AAyB3E,OAAO,MAAMC,oCAAsBF,cAAwCG,WAAW;AAEtF,OAAO,MAAMC,yBAAyB;IACpC,OAAOH,WAAWC;AACpB,EAAE;AAEF,OAAO,MAAMG,kBAAkB;IAC7B,MAAMC,MAAMF;IAEZ,OAAO;QACLG,WAAW,CAACC,YAA6BC;YACvC,IAAIH,QAAQH,WAAW;gBACrB;YACF;YAEA,MAAMO,gBAAgBC,KAAKC,SAAS,CAACJ;YACrC,IAAIF,IAAIO,cAAc,CAACC,GAAG,CAACJ,kBAAkBD,aAAa,WAAW;gBACnE,qFAAqF;gBACrF;YACF;YAEA,IAAIH,IAAIO,cAAc,CAACE,GAAG,CAACL,mBAAmBD,UAAU;gBACtDH,IAAIO,cAAc,CAACG,GAAG,CAACN,eAAeD;gBACtC,IAAIA,aAAa,SAAS;oBACxBH,IAAIW,gBAAgB,IAAI;gBAC1B;gBAEA,MAAMC,UAAU;uBAAIZ,IAAIO,cAAc,CAACM,MAAM;iBAAG,CAACC,KAAK,CAAC,CAACC,IAAMA,MAAM;gBACpE,IAAIf,IAAIgB,gBAAgB,KAAK,KAAKJ,SAAS;oBACzCZ,IAAIgB,gBAAgB,GAAGC,KAAKC,GAAG,KAAKlB,IAAImB,eAAe;oBACvDC,cAAcpB;gBAChB;YACF;QACF;IACF;AACF,EAAE;AAEF,MAAMoB,gBAAgB,OAAOC;IAC3B,MAAM5B,MAAM,GAAG4B,MAAMC,SAAS,IAAI,GAAG,YAAY,CAAC,EAAE;QAClDC,QAAQ;QACRC,SAAS;YACP,gBAAgB;QAClB;QACAC,MAAMpB,KAAKC,SAAS,CAAC;YACnBoB,SAASL,MAAMK,OAAO;YACtBC,WAAWN,MAAMM,SAAS;YAC1BC,aAAaP,MAAML,gBAAgB,GAAG;YACtCa,eAAeR,MAAMV,gBAAgB;QACvC;IACF;AACF;AAEA,OAAO,MAAMmB,uBAAuB,CAAC,EAAER,SAAS,EAAEI,OAAO,EAAEC,SAAS,EAAEI,QAAQ,EAAqB;IACjG,MAAM/B,MAAoB;QACxB0B,SAASA;QACTC,WAAWA;QACXhB,kBAAkB;QAClBQ,iBAAiBF,KAAKC,GAAG;QACzBF,kBAAkB;QAClBT,gBAAgB,IAAIyB;QACpBV;IACF;IAEA,qBAAO,KAAC1B,oBAAoBqC,QAAQ;QAACC,OAAOlC;kBAAM+B;;AACpD,EAAE"}
1
+ {"version":3,"sources":["../../src/runtime/UsageMetricsProvider.tsx"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { FetchFn, useFetch } from '@perses-dev/client';\nimport { QueryDefinition } from '@perses-dev/spec';\nimport { createContext, ReactElement, ReactNode, useContext } from 'react';\n\ntype QueryState = 'pending' | 'success' | 'error';\n\ninterface UsageMetrics {\n project: string;\n dashboard: string;\n startRenderTime: number;\n renderDurationMs: number;\n renderErrorCount: number;\n pendingQueries: Map<string, QueryState>;\n apiPrefix?: string;\n fetchFn: FetchFn;\n}\n\ninterface UsageMetricsProps {\n project: string;\n dashboard: string;\n apiPrefix?: string;\n children: ReactNode;\n}\n\ninterface UseUsageMetricsResults {\n markQuery: (definition: QueryDefinition, state: QueryState) => void;\n}\n\nexport const UsageMetricsContext = createContext<UsageMetrics | undefined>(undefined);\n\nexport const useUsageMetricsContext = (): UsageMetrics | undefined => {\n return useContext(UsageMetricsContext);\n};\n\nexport const useUsageMetrics = (): UseUsageMetricsResults => {\n const ctx = useUsageMetricsContext();\n\n return {\n markQuery: (definition: QueryDefinition, newState: QueryState): void => {\n if (ctx === undefined) {\n return;\n }\n\n const definitionKey = JSON.stringify(definition);\n if (ctx.pendingQueries.has(definitionKey) && newState === 'pending') {\n // Never allow transitions back to pending, to avoid re-sending stats on a re-render.\n return;\n }\n\n if (ctx.pendingQueries.get(definitionKey) !== newState) {\n ctx.pendingQueries.set(definitionKey, newState);\n if (newState === 'error') {\n ctx.renderErrorCount += 1;\n }\n\n const allDone = [...ctx.pendingQueries.values()].every((p) => p !== 'pending');\n if (ctx.renderDurationMs === 0 && allDone) {\n ctx.renderDurationMs = Date.now() - ctx.startRenderTime;\n submitMetrics(ctx);\n }\n }\n },\n };\n};\n\nconst submitMetrics = async (stats: UsageMetrics): Promise<void> => {\n await stats.fetchFn(`${stats.apiPrefix ?? ''}/api/v1/view`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n project: stats.project,\n dashboard: stats.dashboard,\n render_time: stats.renderDurationMs / 1000,\n render_errors: stats.renderErrorCount,\n }),\n });\n};\n\nexport const UsageMetricsProvider = ({ apiPrefix, project, dashboard, children }: UsageMetricsProps): ReactElement => {\n const { fetch } = useFetch();\n\n const ctx: UsageMetrics = {\n project: project,\n dashboard: dashboard,\n renderErrorCount: 0,\n startRenderTime: Date.now(),\n renderDurationMs: 0,\n pendingQueries: new Map(),\n apiPrefix,\n fetchFn: fetch,\n };\n\n return <UsageMetricsContext.Provider value={ctx}>{children}</UsageMetricsContext.Provider>;\n};\n"],"names":["useFetch","createContext","useContext","UsageMetricsContext","undefined","useUsageMetricsContext","useUsageMetrics","ctx","markQuery","definition","newState","definitionKey","JSON","stringify","pendingQueries","has","get","set","renderErrorCount","allDone","values","every","p","renderDurationMs","Date","now","startRenderTime","submitMetrics","stats","fetchFn","apiPrefix","method","headers","body","project","dashboard","render_time","render_errors","UsageMetricsProvider","children","fetch","Map","Provider","value"],"mappings":";AAAA,+BAA+B;AAC/B,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAEjC,SAAkBA,QAAQ,QAAQ,qBAAqB;AAEvD,SAASC,aAAa,EAA2BC,UAAU,QAAQ,QAAQ;AA0B3E,OAAO,MAAMC,oCAAsBF,cAAwCG,WAAW;AAEtF,OAAO,MAAMC,yBAAyB;IACpC,OAAOH,WAAWC;AACpB,EAAE;AAEF,OAAO,MAAMG,kBAAkB;IAC7B,MAAMC,MAAMF;IAEZ,OAAO;QACLG,WAAW,CAACC,YAA6BC;YACvC,IAAIH,QAAQH,WAAW;gBACrB;YACF;YAEA,MAAMO,gBAAgBC,KAAKC,SAAS,CAACJ;YACrC,IAAIF,IAAIO,cAAc,CAACC,GAAG,CAACJ,kBAAkBD,aAAa,WAAW;gBACnE,qFAAqF;gBACrF;YACF;YAEA,IAAIH,IAAIO,cAAc,CAACE,GAAG,CAACL,mBAAmBD,UAAU;gBACtDH,IAAIO,cAAc,CAACG,GAAG,CAACN,eAAeD;gBACtC,IAAIA,aAAa,SAAS;oBACxBH,IAAIW,gBAAgB,IAAI;gBAC1B;gBAEA,MAAMC,UAAU;uBAAIZ,IAAIO,cAAc,CAACM,MAAM;iBAAG,CAACC,KAAK,CAAC,CAACC,IAAMA,MAAM;gBACpE,IAAIf,IAAIgB,gBAAgB,KAAK,KAAKJ,SAAS;oBACzCZ,IAAIgB,gBAAgB,GAAGC,KAAKC,GAAG,KAAKlB,IAAImB,eAAe;oBACvDC,cAAcpB;gBAChB;YACF;QACF;IACF;AACF,EAAE;AAEF,MAAMoB,gBAAgB,OAAOC;IAC3B,MAAMA,MAAMC,OAAO,CAAC,GAAGD,MAAME,SAAS,IAAI,GAAG,YAAY,CAAC,EAAE;QAC1DC,QAAQ;QACRC,SAAS;YACP,gBAAgB;QAClB;QACAC,MAAMrB,KAAKC,SAAS,CAAC;YACnBqB,SAASN,MAAMM,OAAO;YACtBC,WAAWP,MAAMO,SAAS;YAC1BC,aAAaR,MAAML,gBAAgB,GAAG;YACtCc,eAAeT,MAAMV,gBAAgB;QACvC;IACF;AACF;AAEA,OAAO,MAAMoB,uBAAuB,CAAC,EAAER,SAAS,EAAEI,OAAO,EAAEC,SAAS,EAAEI,QAAQ,EAAqB;IACjG,MAAM,EAAEC,KAAK,EAAE,GAAGxC;IAElB,MAAMO,MAAoB;QACxB2B,SAASA;QACTC,WAAWA;QACXjB,kBAAkB;QAClBQ,iBAAiBF,KAAKC,GAAG;QACzBF,kBAAkB;QAClBT,gBAAgB,IAAI2B;QACpBX;QACAD,SAASW;IACX;IAEA,qBAAO,KAACrC,oBAAoBuC,QAAQ;QAACC,OAAOpC;kBAAMgC;;AACpD,EAAE"}
@@ -1,4 +1,5 @@
1
1
  import { ActionStatus, SelectionItem, VariableStateMap } from '@perses-dev/components';
2
+ import { type FetchFn } from '@perses-dev/client';
2
3
  import { ItemAction } from '../components/ItemSelectionActionsOptionsEditor';
3
4
  /**
4
5
  * Parameters for executing a selection action
@@ -12,6 +13,8 @@ export interface ExecuteActionParams<Id = unknown> {
12
13
  variableState?: VariableStateMap;
13
14
  /** Callback to update action status */
14
15
  setActionStatus: (actionName: string, status: Partial<ActionStatus>, itemId?: Id) => void;
16
+ /** Fetch function from FetchProvider context */
17
+ fetchFn: FetchFn;
15
18
  }
16
19
  /**
17
20
  * Result of action execution
@@ -1 +1 @@
1
- {"version":3,"file":"item-actions.d.ts","sourceRoot":"","sources":["../../src/runtime/item-actions.ts"],"names":[],"mappings":"AAaA,OAAO,EACL,YAAY,EAGZ,aAAa,EACb,gBAAgB,EACjB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,UAAU,EAA8B,MAAM,iDAAiD,CAAC;AAkBzG;;GAEG;AACH,MAAM,WAAW,mBAAmB,CAAC,EAAE,GAAG,OAAO;IAC/C,4BAA4B;IAC5B,MAAM,EAAE,UAAU,CAAC;IACnB,yCAAyC;IACzC,YAAY,EAAE,GAAG,CAAC,EAAE,EAAE,aAAa,CAAC,CAAC;IACrC,0DAA0D;IAC1D,aAAa,CAAC,EAAE,gBAAgB,CAAC;IACjC,uCAAuC;IACvC,eAAe,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC,EAAE,EAAE,KAAK,IAAI,CAAC;CAC3F;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,kDAAkD;IAClD,WAAW,CAAC,EAAE,GAAG,CAAC,OAAO,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,KAAK,CAAA;KAAE,CAAC,CAAC;CACjE;AAyPD;;;;;GAKG;AACH,wBAAsB,aAAa,CAAC,EAAE,GAAG,OAAO,EAAE,MAAM,EAAE,mBAAmB,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAcjH"}
1
+ {"version":3,"file":"item-actions.d.ts","sourceRoot":"","sources":["../../src/runtime/item-actions.ts"],"names":[],"mappings":"AAaA,OAAO,EACL,YAAY,EAGZ,aAAa,EACb,gBAAgB,EACjB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,UAAU,EAA8B,MAAM,iDAAiD,CAAC;AAkBzG;;GAEG;AACH,MAAM,WAAW,mBAAmB,CAAC,EAAE,GAAG,OAAO;IAC/C,4BAA4B;IAC5B,MAAM,EAAE,UAAU,CAAC;IACnB,yCAAyC;IACzC,YAAY,EAAE,GAAG,CAAC,EAAE,EAAE,aAAa,CAAC,CAAC;IACrC,0DAA0D;IAC1D,aAAa,CAAC,EAAE,gBAAgB,CAAC;IACjC,uCAAuC;IACvC,eAAe,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC,EAAE,EAAE,KAAK,IAAI,CAAC;IAC1F,gDAAgD;IAChD,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,kDAAkD;IAClD,WAAW,CAAC,EAAE,GAAG,CAAC,OAAO,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,KAAK,CAAA;KAAE,CAAC,CAAC;CACjE;AA4PD;;;;;GAKG;AACH,wBAAsB,aAAa,CAAC,EAAE,GAAG,OAAO,EAAE,MAAM,EAAE,mBAAmB,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAcjH"}
@@ -11,7 +11,6 @@
11
11
  // See the License for the specific language governing permissions and
12
12
  // limitations under the License.
13
13
  import { interpolateSelectionBatch, interpolateSelectionIndividual } from '@perses-dev/components';
14
- import { fetch } from '@perses-dev/client';
15
14
  const BODY_METHODS = new Set([
16
15
  'POST',
17
16
  'PUT',
@@ -137,7 +136,7 @@ function buildWebhookHeaders(action) {
137
136
  }
138
137
  /**
139
138
  * Execute a webhook action in individual mode (one request per selection)
140
- */ async function executeWebhookIndividual(action, selectionMap, variableState, setActionStatus) {
139
+ */ async function executeWebhookIndividual(action, selectionMap, variableState, setActionStatus, fetchFn) {
141
140
  const entries = Array.from(selectionMap.entries());
142
141
  const count = entries.length;
143
142
  const itemResults = new Map();
@@ -164,7 +163,7 @@ function buildWebhookHeaders(action) {
164
163
  body = bodyResult.text;
165
164
  }
166
165
  // Make the request
167
- const response = await fetch(urlResult.text, {
166
+ const response = await fetchFn(urlResult.text, {
168
167
  method: action.method,
169
168
  headers: buildWebhookHeaders(action),
170
169
  body: body
@@ -212,7 +211,7 @@ function buildWebhookHeaders(action) {
212
211
  }
213
212
  /**
214
213
  * Execute a webhook action in batch mode (single request with all selections)
215
- */ async function executeWebhookBatch(action, selectionMap, variableState, setActionStatus) {
214
+ */ async function executeWebhookBatch(action, selectionMap, variableState, setActionStatus, fetchFn) {
216
215
  const items = Array.from(selectionMap.values());
217
216
  setActionStatus(action.name, {
218
217
  loading: true
@@ -229,7 +228,7 @@ function buildWebhookHeaders(action) {
229
228
  body = bodyResult.text;
230
229
  }
231
230
  // Make the request
232
- const response = await fetch(urlResult.text, {
231
+ const response = await fetchFn(urlResult.text, {
233
232
  method: action.method,
234
233
  headers: buildWebhookHeaders(action),
235
234
  body: body
@@ -258,11 +257,11 @@ function buildWebhookHeaders(action) {
258
257
  }
259
258
  /**
260
259
  * Execute a webhook action
261
- */ async function executeWebhookAction(action, selectionMap, variableState, setActionStatus) {
260
+ */ async function executeWebhookAction(action, selectionMap, variableState, setActionStatus, fetchFn) {
262
261
  if (action.batchMode === 'batch') {
263
- return executeWebhookBatch(action, selectionMap, variableState, setActionStatus);
262
+ return executeWebhookBatch(action, selectionMap, variableState, setActionStatus, fetchFn);
264
263
  } else {
265
- return executeWebhookIndividual(action, selectionMap, variableState, setActionStatus);
264
+ return executeWebhookIndividual(action, selectionMap, variableState, setActionStatus, fetchFn);
266
265
  }
267
266
  }
268
267
  /**
@@ -280,7 +279,7 @@ function buildWebhookHeaders(action) {
280
279
  * @param params - Execution parameters including action, selections, and callbacks
281
280
  * @returns Promise resolving to the execution result
282
281
  */ export async function executeAction(params) {
283
- const { action, selectionMap, variableState, setActionStatus } = params;
282
+ const { action, selectionMap, variableState, setActionStatus, fetchFn } = params;
284
283
  if (selectionMap.size === 0) {
285
284
  return {
286
285
  success: true
@@ -289,7 +288,7 @@ function buildWebhookHeaders(action) {
289
288
  if (action.type === 'event') {
290
289
  return executeEventAction(action, selectionMap, variableState, setActionStatus);
291
290
  } else if (action.type === 'webhook') {
292
- return executeWebhookAction(action, selectionMap, variableState, setActionStatus);
291
+ return executeWebhookAction(action, selectionMap, variableState, setActionStatus, fetchFn);
293
292
  }
294
293
  return {
295
294
  success: false,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/runtime/item-actions.ts"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport {\n ActionStatus,\n interpolateSelectionBatch,\n interpolateSelectionIndividual,\n SelectionItem,\n VariableStateMap,\n} from '@perses-dev/components';\nimport { fetch } from '@perses-dev/client';\nimport { ItemAction, EventAction, WebhookAction } from '../components/ItemSelectionActionsOptionsEditor';\n\nconst BODY_METHODS = new Set(['POST', 'PUT', 'PATCH']);\n\nfunction buildWebhookHeaders(action: WebhookAction): Record<string, string> {\n const headers: Record<string, string> = { ...(action.headers ?? {}) };\n const contentType = action.contentType ?? 'none';\n const supportsBody = BODY_METHODS.has(action.method);\n\n if (supportsBody && contentType === 'json') {\n headers['Content-Type'] = 'application/json';\n } else if (supportsBody && contentType === 'text') {\n headers['Content-Type'] = 'text/plain; charset=utf-8';\n }\n\n return headers;\n}\n\n/**\n * Parameters for executing a selection action\n */\nexport interface ExecuteActionParams<Id = unknown> {\n /** The action to execute */\n action: ItemAction;\n /** Map of selection IDs to their data */\n selectionMap: Map<Id, SelectionItem>;\n /** Optional dashboard variable state for interpolation */\n variableState?: VariableStateMap;\n /** Callback to update action status */\n setActionStatus: (actionName: string, status: Partial<ActionStatus>, itemId?: Id) => void;\n}\n\n/**\n * Result of action execution\n */\nexport interface ActionExecutionResult {\n success: boolean;\n error?: Error;\n /** For individual batch mode, results per item */\n itemResults?: Map<unknown, { success: boolean; error?: Error }>;\n}\n\n/**\n * Execute an event action by dispatching a single CustomEvent with batch data\n */\nfunction executeEventBatch<Id>(\n action: EventAction,\n selectionMap: Map<Id, SelectionItem>,\n variableState: VariableStateMap | undefined,\n setActionStatus: ExecuteActionParams<Id>['setActionStatus']\n): ActionExecutionResult {\n try {\n setActionStatus(action.name, { loading: true });\n\n const items = Array.from(selectionMap.values());\n\n // Interpolate body template if provided\n let body: string | undefined;\n if (action.bodyTemplate) {\n const bodyResult = interpolateSelectionBatch(action.bodyTemplate, items, variableState);\n body = bodyResult.text;\n } else {\n body = JSON.stringify({ items });\n }\n\n const event = new CustomEvent(action.eventName, {\n detail: body,\n bubbles: true,\n cancelable: true,\n });\n\n window.dispatchEvent(event);\n\n setActionStatus(action.name, { loading: false, success: true });\n return { success: true };\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n setActionStatus(action.name, { loading: false, error: err });\n return { success: false, error: err };\n }\n}\n\n/**\n * Execute events actions by dispatching one CustomEvent per selection\n */\nfunction executeEventIndividual<Id>(\n action: EventAction,\n selectionMap: Map<Id, SelectionItem>,\n variableState: VariableStateMap | undefined,\n setActionStatus: ExecuteActionParams<Id>['setActionStatus']\n): ActionExecutionResult {\n const entries = Array.from(selectionMap.entries());\n const count = entries.length;\n const itemResults = new Map<Id, { success: boolean; error?: Error }>();\n\n // Initialize all items as loading\n setActionStatus(action.name, { loading: true, itemStatuses: new Map() });\n\n for (let index = 0; index < entries.length; index++) {\n const [id, item] = entries[index]!;\n\n setActionStatus(action.name, { loading: true }, id);\n\n try {\n // Interpolate body template if provided\n let body: string | undefined;\n if (action.bodyTemplate) {\n const bodyResult = interpolateSelectionIndividual(action.bodyTemplate, item, index, count, variableState);\n body = bodyResult.text;\n } else {\n body = JSON.stringify({ id, data: item });\n }\n\n const event = new CustomEvent(action.eventName, {\n detail: body,\n bubbles: true,\n cancelable: true,\n });\n\n window.dispatchEvent(event);\n itemResults.set(id, { success: true });\n setActionStatus(action.name, { loading: false, success: true }, id);\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n setActionStatus(action.name, { loading: false, error: err }, id);\n itemResults.set(id, { success: false, error: err });\n }\n }\n\n setActionStatus(action.name, { loading: false, success: true });\n\n return {\n success: true,\n itemResults,\n };\n}\n\n/**\n * Execute a webhook action in individual mode (one request per selection)\n */\nasync function executeWebhookIndividual<Id>(\n action: WebhookAction,\n selectionMap: Map<Id, SelectionItem>,\n variableState: VariableStateMap | undefined,\n setActionStatus: ExecuteActionParams<Id>['setActionStatus']\n): Promise<ActionExecutionResult> {\n const entries = Array.from(selectionMap.entries());\n const count = entries.length;\n const itemResults = new Map<Id, { success: boolean; error?: Error }>();\n\n // Initialize all items as loading\n setActionStatus(action.name, { loading: true, itemStatuses: new Map() });\n\n // Execute requests sequentially to avoid overwhelming the server\n for (let index = 0; index < entries.length; index++) {\n const [id, item] = entries[index]!;\n\n setActionStatus(action.name, { loading: true }, id);\n\n try {\n // Interpolate URL\n const urlResult = interpolateSelectionIndividual(action.url, item, index, count, variableState);\n\n // Interpolate body template if provided\n const contentType = action.contentType ?? 'none';\n const supportsBody = BODY_METHODS.has(action.method) && contentType !== 'none';\n let body: string | undefined;\n if (supportsBody && action.bodyTemplate) {\n const bodyResult = interpolateSelectionIndividual(action.bodyTemplate, item, index, count, variableState);\n body = bodyResult.text;\n }\n\n // Make the request\n const response = await fetch(urlResult.text, {\n method: action.method,\n headers: buildWebhookHeaders(action),\n body: body,\n });\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n\n setActionStatus(action.name, { loading: false, success: true }, id);\n itemResults.set(id, { success: true });\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n setActionStatus(action.name, { loading: false, error: err }, id);\n itemResults.set(id, { success: false, error: err });\n }\n }\n\n // Update overall action status\n const allSucceeded = Array.from(itemResults.values()).every((r) => r.success);\n const anyFailed = Array.from(itemResults.values()).some((r) => !r.success);\n\n if (allSucceeded) {\n setActionStatus(action.name, { loading: false, success: true });\n } else if (anyFailed) {\n setActionStatus(action.name, {\n loading: false,\n error: new Error('Some requests failed'),\n });\n }\n\n return {\n success: allSucceeded,\n itemResults,\n };\n}\n\n/**\n * Execute a webhook action in batch mode (single request with all selections)\n */\nasync function executeWebhookBatch<Id>(\n action: WebhookAction,\n selectionMap: Map<Id, SelectionItem>,\n variableState: VariableStateMap | undefined,\n setActionStatus: ExecuteActionParams<Id>['setActionStatus']\n): Promise<ActionExecutionResult> {\n const items = Array.from(selectionMap.values());\n\n setActionStatus(action.name, { loading: true });\n\n try {\n // Interpolate URL\n const urlResult = interpolateSelectionBatch(action.url, items, variableState);\n\n // Interpolate body template if provided\n const contentType = action.contentType ?? 'none';\n const supportsBody = BODY_METHODS.has(action.method) && contentType !== 'none';\n let body: string | undefined;\n if (supportsBody && action.bodyTemplate) {\n const bodyResult = interpolateSelectionBatch(action.bodyTemplate, items, variableState);\n body = bodyResult.text;\n }\n\n // Make the request\n const response = await fetch(urlResult.text, {\n method: action.method,\n headers: buildWebhookHeaders(action),\n body: body,\n });\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n\n setActionStatus(action.name, { loading: false, success: true });\n return { success: true };\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n setActionStatus(action.name, { loading: false, error: err });\n return { success: false, error: err };\n }\n}\n\n/**\n * Execute a webhook action\n */\nasync function executeWebhookAction<Id>(\n action: WebhookAction,\n selectionMap: Map<Id, SelectionItem>,\n variableState: VariableStateMap | undefined,\n setActionStatus: ExecuteActionParams<Id>['setActionStatus']\n): Promise<ActionExecutionResult> {\n if (action.batchMode === 'batch') {\n return executeWebhookBatch(action, selectionMap, variableState, setActionStatus);\n } else {\n return executeWebhookIndividual(action, selectionMap, variableState, setActionStatus);\n }\n}\n\n/**\n * Execute an event action\n */\nasync function executeEventAction<Id>(\n action: EventAction,\n selectionMap: Map<Id, SelectionItem>,\n variableState: VariableStateMap | undefined,\n setActionStatus: ExecuteActionParams<Id>['setActionStatus']\n): Promise<ActionExecutionResult> {\n if (action.batchMode === 'batch') {\n return executeEventBatch(action, selectionMap, variableState, setActionStatus);\n } else {\n return executeEventIndividual(action, selectionMap, variableState, setActionStatus);\n }\n}\n\n/**\n * Execute a selection action (event or webhook)\n *\n * @param params - Execution parameters including action, selections, and callbacks\n * @returns Promise resolving to the execution result\n */\nexport async function executeAction<Id = unknown>(params: ExecuteActionParams<Id>): Promise<ActionExecutionResult> {\n const { action, selectionMap, variableState, setActionStatus } = params;\n\n if (selectionMap.size === 0) {\n return { success: true };\n }\n\n if (action.type === 'event') {\n return executeEventAction(action, selectionMap, variableState, setActionStatus);\n } else if (action.type === 'webhook') {\n return executeWebhookAction(action, selectionMap, variableState, setActionStatus);\n }\n\n return { success: false, error: new Error(`Unknown action type`) };\n}\n"],"names":["interpolateSelectionBatch","interpolateSelectionIndividual","fetch","BODY_METHODS","Set","buildWebhookHeaders","action","headers","contentType","supportsBody","has","method","executeEventBatch","selectionMap","variableState","setActionStatus","name","loading","items","Array","from","values","body","bodyTemplate","bodyResult","text","JSON","stringify","event","CustomEvent","eventName","detail","bubbles","cancelable","window","dispatchEvent","success","error","err","Error","String","executeEventIndividual","entries","count","length","itemResults","Map","itemStatuses","index","id","item","data","set","executeWebhookIndividual","urlResult","url","response","ok","status","statusText","allSucceeded","every","r","anyFailed","some","executeWebhookBatch","executeWebhookAction","batchMode","executeEventAction","executeAction","params","size","type"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/runtime/item-actions.ts"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport {\n ActionStatus,\n interpolateSelectionBatch,\n interpolateSelectionIndividual,\n SelectionItem,\n VariableStateMap,\n} from '@perses-dev/components';\nimport { type FetchFn } from '@perses-dev/client';\nimport { ItemAction, EventAction, WebhookAction } from '../components/ItemSelectionActionsOptionsEditor';\n\nconst BODY_METHODS = new Set(['POST', 'PUT', 'PATCH']);\n\nfunction buildWebhookHeaders(action: WebhookAction): Record<string, string> {\n const headers: Record<string, string> = { ...(action.headers ?? {}) };\n const contentType = action.contentType ?? 'none';\n const supportsBody = BODY_METHODS.has(action.method);\n\n if (supportsBody && contentType === 'json') {\n headers['Content-Type'] = 'application/json';\n } else if (supportsBody && contentType === 'text') {\n headers['Content-Type'] = 'text/plain; charset=utf-8';\n }\n\n return headers;\n}\n\n/**\n * Parameters for executing a selection action\n */\nexport interface ExecuteActionParams<Id = unknown> {\n /** The action to execute */\n action: ItemAction;\n /** Map of selection IDs to their data */\n selectionMap: Map<Id, SelectionItem>;\n /** Optional dashboard variable state for interpolation */\n variableState?: VariableStateMap;\n /** Callback to update action status */\n setActionStatus: (actionName: string, status: Partial<ActionStatus>, itemId?: Id) => void;\n /** Fetch function from FetchProvider context */\n fetchFn: FetchFn;\n}\n\n/**\n * Result of action execution\n */\nexport interface ActionExecutionResult {\n success: boolean;\n error?: Error;\n /** For individual batch mode, results per item */\n itemResults?: Map<unknown, { success: boolean; error?: Error }>;\n}\n\n/**\n * Execute an event action by dispatching a single CustomEvent with batch data\n */\nfunction executeEventBatch<Id>(\n action: EventAction,\n selectionMap: Map<Id, SelectionItem>,\n variableState: VariableStateMap | undefined,\n setActionStatus: ExecuteActionParams<Id>['setActionStatus']\n): ActionExecutionResult {\n try {\n setActionStatus(action.name, { loading: true });\n\n const items = Array.from(selectionMap.values());\n\n // Interpolate body template if provided\n let body: string | undefined;\n if (action.bodyTemplate) {\n const bodyResult = interpolateSelectionBatch(action.bodyTemplate, items, variableState);\n body = bodyResult.text;\n } else {\n body = JSON.stringify({ items });\n }\n\n const event = new CustomEvent(action.eventName, {\n detail: body,\n bubbles: true,\n cancelable: true,\n });\n\n window.dispatchEvent(event);\n\n setActionStatus(action.name, { loading: false, success: true });\n return { success: true };\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n setActionStatus(action.name, { loading: false, error: err });\n return { success: false, error: err };\n }\n}\n\n/**\n * Execute events actions by dispatching one CustomEvent per selection\n */\nfunction executeEventIndividual<Id>(\n action: EventAction,\n selectionMap: Map<Id, SelectionItem>,\n variableState: VariableStateMap | undefined,\n setActionStatus: ExecuteActionParams<Id>['setActionStatus']\n): ActionExecutionResult {\n const entries = Array.from(selectionMap.entries());\n const count = entries.length;\n const itemResults = new Map<Id, { success: boolean; error?: Error }>();\n\n // Initialize all items as loading\n setActionStatus(action.name, { loading: true, itemStatuses: new Map() });\n\n for (let index = 0; index < entries.length; index++) {\n const [id, item] = entries[index]!;\n\n setActionStatus(action.name, { loading: true }, id);\n\n try {\n // Interpolate body template if provided\n let body: string | undefined;\n if (action.bodyTemplate) {\n const bodyResult = interpolateSelectionIndividual(action.bodyTemplate, item, index, count, variableState);\n body = bodyResult.text;\n } else {\n body = JSON.stringify({ id, data: item });\n }\n\n const event = new CustomEvent(action.eventName, {\n detail: body,\n bubbles: true,\n cancelable: true,\n });\n\n window.dispatchEvent(event);\n itemResults.set(id, { success: true });\n setActionStatus(action.name, { loading: false, success: true }, id);\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n setActionStatus(action.name, { loading: false, error: err }, id);\n itemResults.set(id, { success: false, error: err });\n }\n }\n\n setActionStatus(action.name, { loading: false, success: true });\n\n return {\n success: true,\n itemResults,\n };\n}\n\n/**\n * Execute a webhook action in individual mode (one request per selection)\n */\nasync function executeWebhookIndividual<Id>(\n action: WebhookAction,\n selectionMap: Map<Id, SelectionItem>,\n variableState: VariableStateMap | undefined,\n setActionStatus: ExecuteActionParams<Id>['setActionStatus'],\n fetchFn: FetchFn\n): Promise<ActionExecutionResult> {\n const entries = Array.from(selectionMap.entries());\n const count = entries.length;\n const itemResults = new Map<Id, { success: boolean; error?: Error }>();\n\n // Initialize all items as loading\n setActionStatus(action.name, { loading: true, itemStatuses: new Map() });\n\n // Execute requests sequentially to avoid overwhelming the server\n for (let index = 0; index < entries.length; index++) {\n const [id, item] = entries[index]!;\n\n setActionStatus(action.name, { loading: true }, id);\n\n try {\n // Interpolate URL\n const urlResult = interpolateSelectionIndividual(action.url, item, index, count, variableState);\n\n // Interpolate body template if provided\n const contentType = action.contentType ?? 'none';\n const supportsBody = BODY_METHODS.has(action.method) && contentType !== 'none';\n let body: string | undefined;\n if (supportsBody && action.bodyTemplate) {\n const bodyResult = interpolateSelectionIndividual(action.bodyTemplate, item, index, count, variableState);\n body = bodyResult.text;\n }\n\n // Make the request\n const response = await fetchFn(urlResult.text, {\n method: action.method,\n headers: buildWebhookHeaders(action),\n body: body,\n });\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n\n setActionStatus(action.name, { loading: false, success: true }, id);\n itemResults.set(id, { success: true });\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n setActionStatus(action.name, { loading: false, error: err }, id);\n itemResults.set(id, { success: false, error: err });\n }\n }\n\n // Update overall action status\n const allSucceeded = Array.from(itemResults.values()).every((r) => r.success);\n const anyFailed = Array.from(itemResults.values()).some((r) => !r.success);\n\n if (allSucceeded) {\n setActionStatus(action.name, { loading: false, success: true });\n } else if (anyFailed) {\n setActionStatus(action.name, {\n loading: false,\n error: new Error('Some requests failed'),\n });\n }\n\n return {\n success: allSucceeded,\n itemResults,\n };\n}\n\n/**\n * Execute a webhook action in batch mode (single request with all selections)\n */\nasync function executeWebhookBatch<Id>(\n action: WebhookAction,\n selectionMap: Map<Id, SelectionItem>,\n variableState: VariableStateMap | undefined,\n setActionStatus: ExecuteActionParams<Id>['setActionStatus'],\n fetchFn: FetchFn\n): Promise<ActionExecutionResult> {\n const items = Array.from(selectionMap.values());\n\n setActionStatus(action.name, { loading: true });\n\n try {\n // Interpolate URL\n const urlResult = interpolateSelectionBatch(action.url, items, variableState);\n\n // Interpolate body template if provided\n const contentType = action.contentType ?? 'none';\n const supportsBody = BODY_METHODS.has(action.method) && contentType !== 'none';\n let body: string | undefined;\n if (supportsBody && action.bodyTemplate) {\n const bodyResult = interpolateSelectionBatch(action.bodyTemplate, items, variableState);\n body = bodyResult.text;\n }\n\n // Make the request\n const response = await fetchFn(urlResult.text, {\n method: action.method,\n headers: buildWebhookHeaders(action),\n body: body,\n });\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n\n setActionStatus(action.name, { loading: false, success: true });\n return { success: true };\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n setActionStatus(action.name, { loading: false, error: err });\n return { success: false, error: err };\n }\n}\n\n/**\n * Execute a webhook action\n */\nasync function executeWebhookAction<Id>(\n action: WebhookAction,\n selectionMap: Map<Id, SelectionItem>,\n variableState: VariableStateMap | undefined,\n setActionStatus: ExecuteActionParams<Id>['setActionStatus'],\n fetchFn: FetchFn\n): Promise<ActionExecutionResult> {\n if (action.batchMode === 'batch') {\n return executeWebhookBatch(action, selectionMap, variableState, setActionStatus, fetchFn);\n } else {\n return executeWebhookIndividual(action, selectionMap, variableState, setActionStatus, fetchFn);\n }\n}\n\n/**\n * Execute an event action\n */\nasync function executeEventAction<Id>(\n action: EventAction,\n selectionMap: Map<Id, SelectionItem>,\n variableState: VariableStateMap | undefined,\n setActionStatus: ExecuteActionParams<Id>['setActionStatus']\n): Promise<ActionExecutionResult> {\n if (action.batchMode === 'batch') {\n return executeEventBatch(action, selectionMap, variableState, setActionStatus);\n } else {\n return executeEventIndividual(action, selectionMap, variableState, setActionStatus);\n }\n}\n\n/**\n * Execute a selection action (event or webhook)\n *\n * @param params - Execution parameters including action, selections, and callbacks\n * @returns Promise resolving to the execution result\n */\nexport async function executeAction<Id = unknown>(params: ExecuteActionParams<Id>): Promise<ActionExecutionResult> {\n const { action, selectionMap, variableState, setActionStatus, fetchFn } = params;\n\n if (selectionMap.size === 0) {\n return { success: true };\n }\n\n if (action.type === 'event') {\n return executeEventAction(action, selectionMap, variableState, setActionStatus);\n } else if (action.type === 'webhook') {\n return executeWebhookAction(action, selectionMap, variableState, setActionStatus, fetchFn);\n }\n\n return { success: false, error: new Error(`Unknown action type`) };\n}\n"],"names":["interpolateSelectionBatch","interpolateSelectionIndividual","BODY_METHODS","Set","buildWebhookHeaders","action","headers","contentType","supportsBody","has","method","executeEventBatch","selectionMap","variableState","setActionStatus","name","loading","items","Array","from","values","body","bodyTemplate","bodyResult","text","JSON","stringify","event","CustomEvent","eventName","detail","bubbles","cancelable","window","dispatchEvent","success","error","err","Error","String","executeEventIndividual","entries","count","length","itemResults","Map","itemStatuses","index","id","item","data","set","executeWebhookIndividual","fetchFn","urlResult","url","response","ok","status","statusText","allSucceeded","every","r","anyFailed","some","executeWebhookBatch","executeWebhookAction","batchMode","executeEventAction","executeAction","params","size","type"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@perses-dev/plugin-system",
3
- "version": "0.54.0",
3
+ "version": "0.55.0-beta.1",
4
4
  "description": "The plugin feature in Pereses",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://github.com/perses/perses/blob/main/README.md",
@@ -29,10 +29,10 @@
29
29
  },
30
30
  "dependencies": {
31
31
  "@module-federation/enhanced": "^2.8.0",
32
- "@perses-dev/client": "0.54.0",
33
- "@perses-dev/components": "0.54.0",
32
+ "@perses-dev/client": "0.55.0-beta.1",
33
+ "@perses-dev/components": "0.55.0-beta.1",
34
34
  "@perses-dev/core": "0.53.0",
35
- "@perses-dev/spec": "0.2.0",
35
+ "@perses-dev/spec": "0.3.0-beta.1",
36
36
  "date-fns": "^4.1.0",
37
37
  "date-fns-tz": "^3.2.0",
38
38
  "immer": "^10.1.1",