@dxos/plugin-observability 0.8.4-main.21d9917 → 0.8.4-main.2244d791bb
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.
- package/dist/lib/browser/{app-graph-builder-6KDHLPUO.mjs → app-graph-builder-7PBOGFFG.mjs} +4 -3
- package/dist/lib/browser/app-graph-builder-7PBOGFFG.mjs.map +7 -0
- package/dist/lib/browser/{chunk-PYNLPSSZ.mjs → chunk-T3EKFAAB.mjs} +9 -4
- package/dist/lib/browser/chunk-T3EKFAAB.mjs.map +7 -0
- package/dist/lib/browser/{chunk-SN7DIHQG.mjs → chunk-UTYAG5Z3.mjs} +35 -14
- package/dist/lib/browser/chunk-UTYAG5Z3.mjs.map +7 -0
- package/dist/lib/browser/cli/index.mjs +5 -4
- package/dist/lib/browser/cli/index.mjs.map +3 -3
- package/dist/lib/browser/{client-ready-YWKHC5S2.mjs → client-ready-ZVLSHDH6.mjs} +18 -22
- package/dist/lib/browser/client-ready-ZVLSHDH6.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +24 -23
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/{operation-resolver-4ROZET3B.mjs → operation-resolver-GJYJZPY3.mjs} +21 -24
- package/dist/lib/browser/operation-resolver-GJYJZPY3.mjs.map +7 -0
- package/dist/lib/browser/{react-surface-SJTESQAF.mjs → react-surface-4RABGTCC.mjs} +10 -9
- package/dist/lib/browser/react-surface-4RABGTCC.mjs.map +7 -0
- package/dist/lib/browser/{settings-SQ4ICR7F.mjs → settings-QQBXDLBH.mjs} +6 -5
- package/dist/lib/browser/settings-QQBXDLBH.mjs.map +7 -0
- package/dist/lib/browser/{state-IKCFXHYV.mjs → state-SSUNAB2P.mjs} +6 -6
- package/dist/lib/browser/state-SSUNAB2P.mjs.map +7 -0
- package/dist/lib/browser/types/index.mjs +1 -1
- package/dist/lib/node-esm/{app-graph-builder-4YHKY4SP.mjs → app-graph-builder-D77CGMCQ.mjs} +4 -3
- package/dist/lib/node-esm/app-graph-builder-D77CGMCQ.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-HNMV7ZZZ.mjs → chunk-PE6CKAA6.mjs} +35 -14
- package/dist/lib/node-esm/chunk-PE6CKAA6.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-4T4N2NJZ.mjs → chunk-VC5HVE77.mjs} +9 -4
- package/dist/lib/node-esm/chunk-VC5HVE77.mjs.map +7 -0
- package/dist/lib/node-esm/cli/index.mjs +5 -4
- package/dist/lib/node-esm/cli/index.mjs.map +3 -3
- package/dist/lib/node-esm/{client-ready-YLYG6F6H.mjs → client-ready-JXG727PH.mjs} +18 -22
- package/dist/lib/node-esm/client-ready-JXG727PH.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +24 -23
- package/dist/lib/node-esm/index.mjs.map +3 -3
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/{operation-resolver-UI7ZINXR.mjs → operation-resolver-NB7XDO3M.mjs} +21 -24
- package/dist/lib/node-esm/operation-resolver-NB7XDO3M.mjs.map +7 -0
- package/dist/lib/node-esm/{react-surface-D53VLGHY.mjs → react-surface-ZHTRUHHM.mjs} +10 -9
- package/dist/lib/node-esm/react-surface-ZHTRUHHM.mjs.map +7 -0
- package/dist/lib/node-esm/{settings-WIRCHLWE.mjs → settings-IZ2DBP4E.mjs} +6 -5
- package/dist/lib/node-esm/settings-IZ2DBP4E.mjs.map +7 -0
- package/dist/lib/node-esm/{state-MQR4PNOT.mjs → state-3HUC5SJV.mjs} +6 -6
- package/dist/lib/node-esm/state-3HUC5SJV.mjs.map +7 -0
- package/dist/lib/node-esm/types/index.mjs +1 -1
- package/dist/types/src/ObservabilityPlugin.d.ts +1 -1
- package/dist/types/src/ObservabilityPlugin.d.ts.map +1 -1
- package/dist/types/src/capabilities/app-graph-builder/app-graph-builder.d.ts.map +1 -1
- package/dist/types/src/capabilities/client-ready/client-ready.d.ts +3 -3
- package/dist/types/src/capabilities/client-ready/client-ready.d.ts.map +1 -1
- package/dist/types/src/capabilities/client-ready/index.d.ts +2 -4
- package/dist/types/src/capabilities/client-ready/index.d.ts.map +1 -1
- package/dist/types/src/capabilities/operation-resolver/index.d.ts +1 -1
- package/dist/types/src/capabilities/operation-resolver/index.d.ts.map +1 -1
- package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts +2 -2
- package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts.map +1 -1
- package/dist/types/src/capabilities/react-surface/index.d.ts +1 -1
- package/dist/types/src/capabilities/react-surface/index.d.ts.map +1 -1
- package/dist/types/src/capabilities/react-surface/react-surface.d.ts +2 -2
- package/dist/types/src/capabilities/react-surface/react-surface.d.ts.map +1 -1
- package/dist/types/src/capabilities/settings/index.d.ts +1 -1
- package/dist/types/src/capabilities/settings/index.d.ts.map +1 -1
- package/dist/types/src/capabilities/settings/settings.d.ts +3 -2
- package/dist/types/src/capabilities/settings/settings.d.ts.map +1 -1
- package/dist/types/src/capabilities/state/state.d.ts.map +1 -1
- package/dist/types/src/cli/plugin.d.ts.map +1 -1
- package/dist/types/src/components/FeedbackForm.d.ts +3 -3
- package/dist/types/src/components/FeedbackForm.d.ts.map +1 -1
- package/dist/types/src/components/FeedbackForm.stories.d.ts +2 -1
- package/dist/types/src/components/FeedbackForm.stories.d.ts.map +1 -1
- package/dist/types/src/components/HelpContainer.d.ts +1 -0
- package/dist/types/src/components/HelpContainer.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +1 -0
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/types/capabilities.d.ts +1 -1
- package/dist/types/src/types/capabilities.d.ts.map +1 -1
- package/dist/types/src/types/events.d.ts.map +1 -1
- package/dist/types/src/types/schema.d.ts +2 -0
- package/dist/types/src/types/schema.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +31 -29
- package/src/ObservabilityPlugin.ts +11 -10
- package/src/capabilities/app-graph-builder/app-graph-builder.ts +3 -2
- package/src/capabilities/client-ready/client-ready.ts +17 -29
- package/src/capabilities/client-ready/index.ts +3 -1
- package/src/capabilities/operation-resolver/operation-resolver.ts +19 -24
- package/src/capabilities/react-surface/react-surface.tsx +8 -7
- package/src/capabilities/settings/settings.ts +3 -2
- package/src/capabilities/state/state.ts +4 -4
- package/src/cli/plugin.ts +4 -3
- package/src/components/FeedbackForm.stories.tsx +1 -1
- package/src/components/FeedbackForm.tsx +10 -5
- package/src/components/HelpContainer.tsx +27 -7
- package/src/components/ObservabilitySettings.tsx +10 -10
- package/src/translations.ts +1 -0
- package/src/types/capabilities.ts +1 -1
- package/src/types/events.ts +3 -2
- package/src/types/schema.ts +6 -0
- package/dist/lib/browser/app-graph-builder-6KDHLPUO.mjs.map +0 -7
- package/dist/lib/browser/chunk-PYNLPSSZ.mjs.map +0 -7
- package/dist/lib/browser/chunk-SN7DIHQG.mjs.map +0 -7
- package/dist/lib/browser/client-ready-YWKHC5S2.mjs.map +0 -7
- package/dist/lib/browser/operation-resolver-4ROZET3B.mjs.map +0 -7
- package/dist/lib/browser/react-surface-SJTESQAF.mjs.map +0 -7
- package/dist/lib/browser/settings-SQ4ICR7F.mjs.map +0 -7
- package/dist/lib/browser/state-IKCFXHYV.mjs.map +0 -7
- package/dist/lib/node-esm/app-graph-builder-4YHKY4SP.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-4T4N2NJZ.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-HNMV7ZZZ.mjs.map +0 -7
- package/dist/lib/node-esm/client-ready-YLYG6F6H.mjs.map +0 -7
- package/dist/lib/node-esm/operation-resolver-UI7ZINXR.mjs.map +0 -7
- package/dist/lib/node-esm/react-surface-D53VLGHY.mjs.map +0 -7
- package/dist/lib/node-esm/settings-WIRCHLWE.mjs.map +0 -7
- package/dist/lib/node-esm/state-MQR4PNOT.mjs.map +0 -7
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/plugin-observability",
|
|
3
|
-
"version": "0.8.4-main.
|
|
3
|
+
"version": "0.8.4-main.2244d791bb",
|
|
4
4
|
"description": "DXOS app framework plugin for hooking up app observability",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
@@ -45,44 +45,46 @@
|
|
|
45
45
|
"src"
|
|
46
46
|
],
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@effect-atom/atom": "^0.
|
|
49
|
-
"@effect-atom/atom-react": "^0.
|
|
50
|
-
"effect": "3.19.
|
|
48
|
+
"@effect-atom/atom": "^0.5.1",
|
|
49
|
+
"@effect-atom/atom-react": "^0.5.0",
|
|
50
|
+
"effect": "3.19.16",
|
|
51
51
|
"localforage": "^1.10.0",
|
|
52
|
-
"@dxos/app-framework": "0.8.4-main.
|
|
53
|
-
"@dxos/
|
|
54
|
-
"@dxos/
|
|
55
|
-
"@dxos/
|
|
56
|
-
"@dxos/
|
|
57
|
-
"@dxos/
|
|
58
|
-
"@dxos/
|
|
59
|
-
"@dxos/log": "0.8.4-main.
|
|
60
|
-
"@dxos/operation": "0.8.4-main.
|
|
61
|
-
"@dxos/
|
|
62
|
-
"@dxos/
|
|
63
|
-
"@dxos/
|
|
64
|
-
"@dxos/react-
|
|
65
|
-
"@dxos/
|
|
66
|
-
"@dxos/react-
|
|
52
|
+
"@dxos/app-framework": "0.8.4-main.2244d791bb",
|
|
53
|
+
"@dxos/app-toolkit": "0.8.4-main.2244d791bb",
|
|
54
|
+
"@dxos/async": "0.8.4-main.2244d791bb",
|
|
55
|
+
"@dxos/context": "0.8.4-main.2244d791bb",
|
|
56
|
+
"@dxos/invariant": "0.8.4-main.2244d791bb",
|
|
57
|
+
"@dxos/echo": "0.8.4-main.2244d791bb",
|
|
58
|
+
"@dxos/effect": "0.8.4-main.2244d791bb",
|
|
59
|
+
"@dxos/log": "0.8.4-main.2244d791bb",
|
|
60
|
+
"@dxos/operation": "0.8.4-main.2244d791bb",
|
|
61
|
+
"@dxos/observability": "0.8.4-main.2244d791bb",
|
|
62
|
+
"@dxos/plugin-graph": "0.8.4-main.2244d791bb",
|
|
63
|
+
"@dxos/protocols": "0.8.4-main.2244d791bb",
|
|
64
|
+
"@dxos/react-client": "0.8.4-main.2244d791bb",
|
|
65
|
+
"@dxos/react-hooks": "0.8.4-main.2244d791bb",
|
|
66
|
+
"@dxos/react-ui-form": "0.8.4-main.2244d791bb",
|
|
67
|
+
"@dxos/react-ui-stack": "0.8.4-main.2244d791bb",
|
|
68
|
+
"@dxos/util": "0.8.4-main.2244d791bb"
|
|
67
69
|
},
|
|
68
70
|
"devDependencies": {
|
|
69
|
-
"@effect-atom/atom-react": "^0.
|
|
70
|
-
"@effect/platform": "0.
|
|
71
|
+
"@effect-atom/atom-react": "^0.5.0",
|
|
72
|
+
"@effect/platform": "0.94.4",
|
|
71
73
|
"@types/react": "~19.2.7",
|
|
72
74
|
"react": "~19.2.3",
|
|
73
75
|
"vite": "7.1.9",
|
|
74
|
-
"@dxos/react-ui": "0.8.4-main.
|
|
75
|
-
"@dxos/
|
|
76
|
-
"@dxos/
|
|
76
|
+
"@dxos/react-ui": "0.8.4-main.2244d791bb",
|
|
77
|
+
"@dxos/storybook-utils": "0.8.4-main.2244d791bb",
|
|
78
|
+
"@dxos/ui-theme": "0.8.4-main.2244d791bb"
|
|
77
79
|
},
|
|
78
80
|
"peerDependencies": {
|
|
79
|
-
"@effect-atom/atom-react": "^0.
|
|
80
|
-
"@effect/platform": "0.
|
|
81
|
-
"effect": "3.19.
|
|
81
|
+
"@effect-atom/atom-react": "^0.5.0",
|
|
82
|
+
"@effect/platform": "0.94.4",
|
|
83
|
+
"effect": "3.19.16",
|
|
82
84
|
"react": "~19.2.3",
|
|
83
85
|
"react-dom": "~19.2.3",
|
|
84
|
-
"@dxos/react-ui": "0.8.4-main.
|
|
85
|
-
"@dxos/ui-theme": "0.8.4-main.
|
|
86
|
+
"@dxos/react-ui": "0.8.4-main.2244d791bb",
|
|
87
|
+
"@dxos/ui-theme": "0.8.4-main.2244d791bb"
|
|
86
88
|
},
|
|
87
89
|
"publishConfig": {
|
|
88
90
|
"access": "public"
|
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
import * as Effect from 'effect/Effect';
|
|
6
6
|
|
|
7
|
-
import { ActivationEvent,
|
|
7
|
+
import { ActivationEvent, ActivationEvents, Capability, Plugin } from '@dxos/app-framework';
|
|
8
|
+
import { AppActivationEvents, AppPlugin } from '@dxos/app-toolkit';
|
|
8
9
|
import { type Observability } from '@dxos/observability';
|
|
9
10
|
|
|
10
11
|
import {
|
|
@@ -22,13 +23,16 @@ import { ObservabilityCapabilities } from './types';
|
|
|
22
23
|
|
|
23
24
|
export type ObservabilityPluginOptions = {
|
|
24
25
|
namespace: string;
|
|
25
|
-
observability: () => Promise<Observability>;
|
|
26
|
+
observability: () => Promise<Observability.Observability>;
|
|
26
27
|
};
|
|
27
28
|
|
|
28
29
|
export const ObservabilityPlugin = Plugin.define<ObservabilityPluginOptions>(meta).pipe(
|
|
30
|
+
AppPlugin.addAppGraphModule({ activate: AppGraphBuilder }),
|
|
31
|
+
AppPlugin.addSurfaceModule({ activate: ReactSurface }),
|
|
32
|
+
AppPlugin.addTranslationsModule({ translations }),
|
|
29
33
|
Plugin.addModule(({ namespace, observability }) => ({
|
|
30
34
|
id: 'observability',
|
|
31
|
-
activatesOn:
|
|
35
|
+
activatesOn: ActivationEvents.Startup,
|
|
32
36
|
activate: () =>
|
|
33
37
|
Effect.gen(function* () {
|
|
34
38
|
const obs = yield* Effect.tryPromise(() => observability());
|
|
@@ -36,27 +40,24 @@ export const ObservabilityPlugin = Plugin.define<ObservabilityPluginOptions>(met
|
|
|
36
40
|
}),
|
|
37
41
|
})),
|
|
38
42
|
Plugin.addModule({
|
|
39
|
-
activatesOn:
|
|
43
|
+
activatesOn: AppActivationEvents.SetupSettings,
|
|
40
44
|
activate: ObservabilitySettings,
|
|
41
45
|
}),
|
|
42
46
|
Plugin.addModule(({ namespace }) => ({
|
|
43
47
|
id: Capability.getModuleTag(ObservabilityState),
|
|
44
|
-
activatesOn:
|
|
48
|
+
activatesOn: ActivationEvents.Startup,
|
|
45
49
|
activatesAfter: [ObservabilityEvents.StateReady],
|
|
46
50
|
activate: () => ObservabilityState({ namespace }),
|
|
47
51
|
})),
|
|
48
|
-
Common.Plugin.addTranslationsModule({ translations }),
|
|
49
52
|
Plugin.addModule(({ namespace }) => ({
|
|
50
53
|
id: Capability.getModuleTag(OperationResolver),
|
|
51
|
-
activatesOn:
|
|
54
|
+
activatesOn: ActivationEvents.SetupOperationResolver,
|
|
52
55
|
activate: () => OperationResolver({ namespace }),
|
|
53
56
|
})),
|
|
54
|
-
Common.Plugin.addSurfaceModule({ activate: ReactSurface }),
|
|
55
|
-
Common.Plugin.addAppGraphModule({ activate: AppGraphBuilder }),
|
|
56
57
|
Plugin.addModule(({ namespace, observability }) => ({
|
|
57
58
|
id: Capability.getModuleTag(ClientReady),
|
|
58
59
|
activatesOn: ActivationEvent.allOf(
|
|
59
|
-
|
|
60
|
+
ActivationEvents.OperationInvokerReady,
|
|
60
61
|
ObservabilityEvents.StateReady,
|
|
61
62
|
ClientReadyEvent,
|
|
62
63
|
),
|
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
import * as Effect from 'effect/Effect';
|
|
6
6
|
|
|
7
|
-
import { Capability
|
|
7
|
+
import { Capability } from '@dxos/app-framework';
|
|
8
|
+
import { AppCapabilities } from '@dxos/app-toolkit';
|
|
8
9
|
import { GraphBuilder, NodeMatcher } from '@dxos/plugin-graph';
|
|
9
10
|
|
|
10
11
|
import { meta } from '../../meta';
|
|
@@ -37,6 +38,6 @@ export default Capability.makeModule(
|
|
|
37
38
|
}),
|
|
38
39
|
]);
|
|
39
40
|
|
|
40
|
-
return Capability.contributes(
|
|
41
|
+
return Capability.contributes(AppCapabilities.AppGraphBuilder, extensions);
|
|
41
42
|
}),
|
|
42
43
|
);
|
|
@@ -4,23 +4,24 @@
|
|
|
4
4
|
|
|
5
5
|
import * as Effect from 'effect/Effect';
|
|
6
6
|
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
7
|
+
import { Capabilities, Capability } from '@dxos/app-framework';
|
|
8
|
+
import { LayoutOperation, SettingsOperation } from '@dxos/app-toolkit';
|
|
9
|
+
import { type Observability, ObservabilityProvider } from '@dxos/observability';
|
|
9
10
|
|
|
10
11
|
import { meta } from '../../meta';
|
|
11
12
|
import { ClientCapability, ObservabilityCapabilities, ObservabilityOperation } from '../../types';
|
|
12
13
|
|
|
13
|
-
type ClientReadyOptions = {
|
|
14
|
+
export type ClientReadyOptions = {
|
|
14
15
|
namespace: string;
|
|
15
|
-
observability: Observability;
|
|
16
|
+
observability: Observability.Observability;
|
|
16
17
|
};
|
|
17
18
|
|
|
18
19
|
export default Capability.makeModule(
|
|
19
20
|
Effect.fnUntraced(function* (props?: ClientReadyOptions) {
|
|
20
|
-
const {
|
|
21
|
-
const manager = yield* Capability.get(
|
|
22
|
-
const { invokePromise } = yield* Capability.get(
|
|
23
|
-
const registry = yield* Capability.get(
|
|
21
|
+
const { observability } = props!;
|
|
22
|
+
const manager = yield* Capability.get(Capabilities.PluginManager);
|
|
23
|
+
const { invokePromise } = yield* Capability.get(Capabilities.OperationInvoker);
|
|
24
|
+
const registry = yield* Capability.get(Capabilities.AtomRegistry);
|
|
24
25
|
const stateAtom = yield* Capability.get(ObservabilityCapabilities.State);
|
|
25
26
|
const client = yield* Capability.get(ClientCapability);
|
|
26
27
|
|
|
@@ -30,7 +31,7 @@ export default Capability.makeModule(
|
|
|
30
31
|
environment && environment !== 'ci' && !environment.endsWith('.local') && !environment.endsWith('.lan');
|
|
31
32
|
const state = registry.get(stateAtom);
|
|
32
33
|
if (!state.notified && notify) {
|
|
33
|
-
await invokePromise(
|
|
34
|
+
await invokePromise(LayoutOperation.AddToast, {
|
|
34
35
|
id: `${meta.id}/notice`,
|
|
35
36
|
title: ['observability toast label', { ns: meta.id }],
|
|
36
37
|
description: ['observability toast description', { ns: meta.id }],
|
|
@@ -49,7 +50,7 @@ export default Capability.makeModule(
|
|
|
49
50
|
// Ensure errors are tagged with enabled plugins to help with reproductions.
|
|
50
51
|
const enabledPlugins = manager.getEnabled();
|
|
51
52
|
for (const plugin of enabledPlugins) {
|
|
52
|
-
observability
|
|
53
|
+
observability.setTags({ [`pluginEnabled-${plugin}`]: 'true' }, 'errors');
|
|
53
54
|
}
|
|
54
55
|
|
|
55
56
|
yield* Effect.tryPromise(() =>
|
|
@@ -62,18 +63,11 @@ export default Capability.makeModule(
|
|
|
62
63
|
}),
|
|
63
64
|
);
|
|
64
65
|
|
|
65
|
-
//
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
yield*
|
|
70
|
-
Promise.all([
|
|
71
|
-
observability.setIdentityTags(client.services.services),
|
|
72
|
-
observability.startRuntimeMetrics(client),
|
|
73
|
-
observability.startNetworkMetrics(client.services.services),
|
|
74
|
-
observability.startSpacesMetrics(client, namespace),
|
|
75
|
-
]),
|
|
76
|
-
);
|
|
66
|
+
// Add client data providers.
|
|
67
|
+
yield* observability.addDataProvider(ObservabilityProvider.Client.identityProvider(client.services.services));
|
|
68
|
+
yield* observability.addDataProvider(ObservabilityProvider.Client.networkMetricsProvider(client.services.services));
|
|
69
|
+
yield* observability.addDataProvider(ObservabilityProvider.Client.runtimeMetricsProvider(client.services.services));
|
|
70
|
+
yield* observability.addDataProvider(ObservabilityProvider.Client.spacesMetricsProvider(client));
|
|
77
71
|
|
|
78
72
|
if (client.halo.identity.get()) {
|
|
79
73
|
yield* Effect.tryPromise(() => sendPrivacyNotice());
|
|
@@ -81,17 +75,11 @@ export default Capability.makeModule(
|
|
|
81
75
|
const subscription = client.halo.identity.subscribe(async (identity) => {
|
|
82
76
|
if (identity && observability) {
|
|
83
77
|
await sendPrivacyNotice();
|
|
84
|
-
await observability.setIdentityTags(client.services.services);
|
|
85
78
|
subscription.unsubscribe();
|
|
86
79
|
}
|
|
87
80
|
});
|
|
88
81
|
}
|
|
89
82
|
|
|
90
|
-
return Capability.contributes(ObservabilityCapabilities.Observability, observability, () =>
|
|
91
|
-
Effect.tryPromise(async () => {
|
|
92
|
-
cleanup();
|
|
93
|
-
await observability.close();
|
|
94
|
-
}),
|
|
95
|
-
);
|
|
83
|
+
return Capability.contributes(ObservabilityCapabilities.Observability, observability, () => observability.close());
|
|
96
84
|
}),
|
|
97
85
|
);
|
|
@@ -4,4 +4,6 @@
|
|
|
4
4
|
|
|
5
5
|
import { Capability } from '@dxos/app-framework';
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
import { type ClientReadyOptions } from './client-ready';
|
|
8
|
+
|
|
9
|
+
export const ClientReady = Capability.lazy<ClientReadyOptions>('ClientReady', () => import('./client-ready'));
|
|
@@ -4,46 +4,47 @@
|
|
|
4
4
|
|
|
5
5
|
import * as Effect from 'effect/Effect';
|
|
6
6
|
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
7
|
+
import { Capabilities, Capability } from '@dxos/app-framework';
|
|
8
|
+
import { AppCapabilities } from '@dxos/app-toolkit';
|
|
9
|
+
import { Observability } from '@dxos/observability';
|
|
9
10
|
import { OperationResolver } from '@dxos/operation';
|
|
10
11
|
|
|
11
12
|
import { type ObservabilitySettingsProps } from '../../components';
|
|
12
13
|
import { meta } from '../../meta';
|
|
13
|
-
import {
|
|
14
|
+
import { ObservabilityCapabilities, ObservabilityOperation } from '../../types';
|
|
14
15
|
|
|
15
16
|
export default Capability.makeModule(
|
|
16
17
|
Effect.fnUntraced(function* (props?: { namespace: string }) {
|
|
17
18
|
const { namespace } = props!;
|
|
18
19
|
const capabilities = yield* Capability.Service;
|
|
19
20
|
|
|
20
|
-
return Capability.contributes(
|
|
21
|
+
return Capability.contributes(Capabilities.OperationResolver, [
|
|
21
22
|
//
|
|
22
23
|
// Toggle
|
|
23
24
|
//
|
|
24
25
|
OperationResolver.make({
|
|
25
26
|
operation: ObservabilityOperation.Toggle,
|
|
26
27
|
handler: Effect.fnUntraced(function* (input) {
|
|
27
|
-
const client = yield* Capability.get(ClientCapability);
|
|
28
28
|
const observability = yield* Capability.get(ObservabilityCapabilities.Observability);
|
|
29
|
-
const registry = capabilities.get(
|
|
30
|
-
const allSettings = capabilities.getAll(
|
|
31
|
-
const settingsObj = allSettings.find((s:
|
|
29
|
+
const registry = capabilities.get(Capabilities.AtomRegistry);
|
|
30
|
+
const allSettings = capabilities.getAll(AppCapabilities.Settings);
|
|
31
|
+
const settingsObj = allSettings.find((s: AppCapabilities.Settings) => s.prefix === meta.id);
|
|
32
32
|
if (!settingsObj) {
|
|
33
33
|
return false;
|
|
34
34
|
}
|
|
35
35
|
const settings = registry.get(settingsObj.atom) as ObservabilitySettingsProps;
|
|
36
36
|
const newEnabled = input.state ?? !settings.enabled;
|
|
37
37
|
registry.set(settingsObj.atom, { ...settings, enabled: newEnabled });
|
|
38
|
-
observability.
|
|
39
|
-
|
|
40
|
-
action: 'observability.toggle',
|
|
41
|
-
properties: {
|
|
42
|
-
enabled: newEnabled,
|
|
43
|
-
},
|
|
38
|
+
observability.events.captureEvent('observability.toggle', {
|
|
39
|
+
enabled: newEnabled,
|
|
44
40
|
});
|
|
45
|
-
|
|
46
|
-
|
|
41
|
+
|
|
42
|
+
if (newEnabled) {
|
|
43
|
+
yield* observability.enable();
|
|
44
|
+
} else {
|
|
45
|
+
yield* observability.disable();
|
|
46
|
+
}
|
|
47
|
+
yield* Effect.promise(() => Observability.storeObservabilityDisabled(namespace, !newEnabled));
|
|
47
48
|
return newEnabled;
|
|
48
49
|
}),
|
|
49
50
|
}),
|
|
@@ -56,14 +57,8 @@ export default Capability.makeModule(
|
|
|
56
57
|
handler: Effect.fnUntraced(function* (input) {
|
|
57
58
|
// NOTE: This is to ensure that events fired before observability is ready are still sent.
|
|
58
59
|
const observability = yield* Capability.waitFor(ObservabilityCapabilities.Observability);
|
|
59
|
-
const client = yield* Capability.get(ClientCapability);
|
|
60
60
|
const properties = input.properties ?? {};
|
|
61
|
-
|
|
62
|
-
observability.track({
|
|
63
|
-
...getTelemetryIdentity(client),
|
|
64
|
-
action: input.name,
|
|
65
|
-
properties,
|
|
66
|
-
});
|
|
61
|
+
observability.events.captureEvent(input.name, properties);
|
|
67
62
|
}),
|
|
68
63
|
}),
|
|
69
64
|
|
|
@@ -74,7 +69,7 @@ export default Capability.makeModule(
|
|
|
74
69
|
operation: ObservabilityOperation.CaptureUserFeedback,
|
|
75
70
|
handler: Effect.fnUntraced(function* (input) {
|
|
76
71
|
const observability = yield* Capability.get(ObservabilityCapabilities.Observability);
|
|
77
|
-
observability.captureUserFeedback(input.message);
|
|
72
|
+
observability.feedback.captureUserFeedback({ message: input.message, includeLogs: input.includeLogs });
|
|
78
73
|
}),
|
|
79
74
|
}),
|
|
80
75
|
]);
|
|
@@ -5,26 +5,27 @@
|
|
|
5
5
|
import * as Effect from 'effect/Effect';
|
|
6
6
|
import React from 'react';
|
|
7
7
|
|
|
8
|
-
import {
|
|
9
|
-
import { useSettingsState } from '@dxos/app-framework/
|
|
8
|
+
import { Capabilities, Capability } from '@dxos/app-framework';
|
|
9
|
+
import { Surface, useSettingsState } from '@dxos/app-framework/ui';
|
|
10
|
+
import { AppCapabilities } from '@dxos/app-toolkit';
|
|
10
11
|
|
|
11
12
|
import { HelpContainer, ObservabilitySettings, type ObservabilitySettingsProps } from '../../components';
|
|
12
13
|
import { meta } from '../../meta';
|
|
13
14
|
|
|
14
15
|
export default Capability.makeModule(() =>
|
|
15
16
|
Effect.succeed(
|
|
16
|
-
Capability.contributes(
|
|
17
|
-
|
|
17
|
+
Capability.contributes(Capabilities.ReactSurface, [
|
|
18
|
+
Surface.create({
|
|
18
19
|
id: meta.id,
|
|
19
20
|
role: 'article',
|
|
20
|
-
filter: (data): data is { subject:
|
|
21
|
-
|
|
21
|
+
filter: (data): data is { subject: AppCapabilities.Settings } =>
|
|
22
|
+
AppCapabilities.isSettings(data.subject) && data.subject.prefix === meta.id,
|
|
22
23
|
component: ({ data: { subject } }) => {
|
|
23
24
|
const { settings, updateSettings } = useSettingsState<ObservabilitySettingsProps>(subject.atom);
|
|
24
25
|
return <ObservabilitySettings settings={settings} onSettingsChange={updateSettings} />;
|
|
25
26
|
},
|
|
26
27
|
}),
|
|
27
|
-
|
|
28
|
+
Surface.create({
|
|
28
29
|
id: `${meta.id}/help`,
|
|
29
30
|
role: 'deck-companion--help',
|
|
30
31
|
component: () => <HelpContainer />,
|
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
import * as Effect from 'effect/Effect';
|
|
6
6
|
|
|
7
|
-
import { Capability
|
|
7
|
+
import { Capability } from '@dxos/app-framework';
|
|
8
|
+
import { AppCapabilities } from '@dxos/app-toolkit';
|
|
8
9
|
import { createKvsStore } from '@dxos/effect';
|
|
9
10
|
|
|
10
11
|
import { ObservabilitySettingsSchema } from '../../components';
|
|
@@ -23,7 +24,7 @@ export default Capability.makeModule(() =>
|
|
|
23
24
|
|
|
24
25
|
return [
|
|
25
26
|
Capability.contributes(ObservabilityCapabilities.Settings, settingsAtom),
|
|
26
|
-
Capability.contributes(
|
|
27
|
+
Capability.contributes(AppCapabilities.Settings, {
|
|
27
28
|
prefix: meta.id,
|
|
28
29
|
schema: ObservabilitySettingsSchema,
|
|
29
30
|
atom: settingsAtom,
|
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
|
|
5
5
|
import * as Effect from 'effect/Effect';
|
|
6
6
|
|
|
7
|
-
import {
|
|
7
|
+
import { Capabilities, Capability } from '@dxos/app-framework';
|
|
8
8
|
import { createKvsStore } from '@dxos/effect';
|
|
9
|
-
import {
|
|
9
|
+
import { Observability } from '@dxos/observability';
|
|
10
10
|
|
|
11
11
|
import { meta } from '../../meta';
|
|
12
12
|
import { ObservabilityCapabilities } from '../../types';
|
|
@@ -21,8 +21,8 @@ export default Capability.makeModule(
|
|
|
21
21
|
});
|
|
22
22
|
|
|
23
23
|
// NOTE: Group is set at runtime, not persisted.
|
|
24
|
-
const group = yield* Effect.tryPromise(() => getObservabilityGroup(namespace));
|
|
25
|
-
const registry = yield* Capability.get(
|
|
24
|
+
const group = yield* Effect.tryPromise(() => Observability.getObservabilityGroup(namespace));
|
|
25
|
+
const registry = yield* Capability.get(Capabilities.AtomRegistry);
|
|
26
26
|
registry.set(stateAtom, { ...registry.get(stateAtom), group });
|
|
27
27
|
|
|
28
28
|
return Capability.contributes(ObservabilityCapabilities.State, stateAtom);
|
package/src/cli/plugin.ts
CHANGED
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
import * as Effect from 'effect/Effect';
|
|
6
6
|
|
|
7
|
-
import {
|
|
7
|
+
import { Capabilities, Capability, Plugin } from '@dxos/app-framework';
|
|
8
|
+
import { AppPlugin } from '@dxos/app-toolkit';
|
|
8
9
|
import { OperationResolver } from '@dxos/operation';
|
|
9
10
|
|
|
10
11
|
import { meta } from '../meta';
|
|
@@ -12,10 +13,10 @@ import { ObservabilityOperation } from '../types';
|
|
|
12
13
|
|
|
13
14
|
// TODO(wittjosiah): Hook up.
|
|
14
15
|
export const ObservabilityPlugin = Plugin.define(meta).pipe(
|
|
15
|
-
|
|
16
|
+
AppPlugin.addOperationResolverModule({
|
|
16
17
|
activate: () =>
|
|
17
18
|
Effect.succeed(
|
|
18
|
-
Capability.contributes(
|
|
19
|
+
Capability.contributes(Capabilities.OperationResolver, [
|
|
19
20
|
OperationResolver.make({
|
|
20
21
|
operation: ObservabilityOperation.SendEvent,
|
|
21
22
|
handler: () => Effect.void,
|
|
@@ -13,7 +13,7 @@ import { FeedbackForm } from './FeedbackForm';
|
|
|
13
13
|
const meta = {
|
|
14
14
|
title: 'plugins/plugin-observability/FeedbackForm',
|
|
15
15
|
component: FeedbackForm,
|
|
16
|
-
decorators: [withTheme, withLayout({ layout: 'column' })],
|
|
16
|
+
decorators: [withTheme(), withLayout({ layout: 'column' })],
|
|
17
17
|
parameters: {
|
|
18
18
|
layout: 'fullscreen',
|
|
19
19
|
translations,
|
|
@@ -5,21 +5,26 @@
|
|
|
5
5
|
import React from 'react';
|
|
6
6
|
|
|
7
7
|
import { useTranslation } from '@dxos/react-ui';
|
|
8
|
-
import { Form, type FormRootProps } from '@dxos/react-ui-form';
|
|
8
|
+
import { Form, type FormRootProps, type FormSubmitProps } from '@dxos/react-ui-form';
|
|
9
9
|
|
|
10
10
|
import { meta } from '../meta';
|
|
11
11
|
import { UserFeedback } from '../types';
|
|
12
12
|
|
|
13
|
-
export type FeedbackFormProps = Pick<FormRootProps<UserFeedback>, 'onSave'>;
|
|
13
|
+
export type FeedbackFormProps = Pick<FormRootProps<UserFeedback>, 'onSave'> & Pick<FormSubmitProps, 'disabled'>;
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
const defaultValues: UserFeedback = {
|
|
16
|
+
message: '',
|
|
17
|
+
includeLogs: true,
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export const FeedbackForm = ({ onSave, disabled }: FeedbackFormProps) => {
|
|
16
21
|
const { t } = useTranslation(meta.id);
|
|
17
22
|
|
|
18
23
|
return (
|
|
19
|
-
<Form.Root schema={UserFeedback} onSave={onSave}>
|
|
24
|
+
<Form.Root schema={UserFeedback} defaultValues={defaultValues} onSave={onSave}>
|
|
20
25
|
<Form.Content>
|
|
21
26
|
<Form.FieldSet />
|
|
22
|
-
<Form.Submit icon='ph--paper-plane-tilt--regular' label={t('send feedback label')} />
|
|
27
|
+
<Form.Submit icon='ph--paper-plane-tilt--regular' label={t('send feedback label')} disabled={disabled} />
|
|
23
28
|
</Form.Content>
|
|
24
29
|
</Form.Root>
|
|
25
30
|
);
|
|
@@ -2,25 +2,45 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import
|
|
5
|
+
import * as Effect from 'effect/Effect';
|
|
6
|
+
import React, { useCallback, useState } from 'react';
|
|
6
7
|
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
8
|
+
import { useCapability, useOperationInvoker } from '@dxos/app-framework/ui';
|
|
9
|
+
import { LayoutOperation } from '@dxos/app-toolkit';
|
|
10
|
+
import { runAndForwardErrors } from '@dxos/effect';
|
|
11
|
+
import { useAsyncEffect } from '@dxos/react-hooks';
|
|
9
12
|
import { osTranslations } from '@dxos/ui-theme';
|
|
10
13
|
|
|
11
14
|
import { meta } from '../meta';
|
|
12
|
-
import { ObservabilityOperation, type UserFeedback } from '../types';
|
|
15
|
+
import { ObservabilityCapabilities, ObservabilityOperation, type UserFeedback } from '../types';
|
|
13
16
|
|
|
14
17
|
import { FeedbackForm } from './FeedbackForm';
|
|
15
18
|
|
|
19
|
+
/** Renders the feedback form, disabling it when the feedback survey is unavailable. */
|
|
16
20
|
export const HelpContainer = () => {
|
|
17
21
|
const { invokePromise } = useOperationInvoker();
|
|
22
|
+
const observability = useCapability(ObservabilityCapabilities.Observability);
|
|
23
|
+
const [feedbackAvailable, setFeedbackAvailable] = useState(false);
|
|
24
|
+
|
|
25
|
+
useAsyncEffect(
|
|
26
|
+
async (controller) => {
|
|
27
|
+
const available = await observability.isAvailable('feedback').pipe(
|
|
28
|
+
Effect.catchAll(() => Effect.succeed(false)),
|
|
29
|
+
Effect.catchAllDefect(() => Effect.succeed(false)),
|
|
30
|
+
runAndForwardErrors,
|
|
31
|
+
);
|
|
32
|
+
if (!controller.signal.aborted) {
|
|
33
|
+
setFeedbackAvailable(available);
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
[observability],
|
|
37
|
+
);
|
|
18
38
|
|
|
19
39
|
const handleSave = useCallback(
|
|
20
40
|
async (values: UserFeedback) => {
|
|
21
41
|
await invokePromise(ObservabilityOperation.CaptureUserFeedback, values);
|
|
22
|
-
await invokePromise(
|
|
23
|
-
await invokePromise(
|
|
42
|
+
await invokePromise(LayoutOperation.UpdateComplementary, { state: 'collapsed' });
|
|
43
|
+
await invokePromise(LayoutOperation.AddToast, {
|
|
24
44
|
id: `${meta.id}/feedback-success`,
|
|
25
45
|
icon: 'ph--paper-plane-tilt--regular',
|
|
26
46
|
duration: 3000,
|
|
@@ -32,5 +52,5 @@ export const HelpContainer = () => {
|
|
|
32
52
|
[invokePromise],
|
|
33
53
|
);
|
|
34
54
|
|
|
35
|
-
return <FeedbackForm onSave={handleSave} />;
|
|
55
|
+
return <FeedbackForm onSave={handleSave} disabled={!feedbackAvailable} />;
|
|
36
56
|
};
|
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
import * as Schema from 'effect/Schema';
|
|
6
6
|
import React from 'react';
|
|
7
7
|
|
|
8
|
-
import { useOperationInvoker } from '@dxos/app-framework/
|
|
8
|
+
import { useOperationInvoker } from '@dxos/app-framework/ui';
|
|
9
9
|
import { Input, Message, useTranslation } from '@dxos/react-ui';
|
|
10
|
-
import {
|
|
10
|
+
import { Settings } from '@dxos/react-ui-form';
|
|
11
11
|
|
|
12
12
|
import { meta } from '../meta';
|
|
13
13
|
import { ObservabilityOperation } from '../types';
|
|
@@ -34,20 +34,20 @@ export const ObservabilitySettings = ({ settings }: ObservabilitySettingsCompone
|
|
|
34
34
|
const { invokePromise } = useOperationInvoker();
|
|
35
35
|
|
|
36
36
|
return (
|
|
37
|
-
<
|
|
38
|
-
<
|
|
37
|
+
<Settings.Root>
|
|
38
|
+
<Settings.Section title={t('settings title', { ns: meta.id })}>
|
|
39
39
|
<Message.Root valence='info' classNames='container-max-width mbe-cardSpacingBlock'>
|
|
40
40
|
<Message.Content>{t('observability description')}</Message.Content>
|
|
41
41
|
</Message.Root>
|
|
42
|
-
<
|
|
43
|
-
<
|
|
42
|
+
<Settings.Group>
|
|
43
|
+
<Settings.ItemInput title={t('observability enabled label')}>
|
|
44
44
|
<Input.Switch
|
|
45
45
|
checked={settings.enabled}
|
|
46
46
|
onCheckedChange={(checked) => invokePromise(ObservabilityOperation.Toggle, { state: !!checked })}
|
|
47
47
|
/>
|
|
48
|
-
</
|
|
49
|
-
</
|
|
50
|
-
</
|
|
51
|
-
</
|
|
48
|
+
</Settings.ItemInput>
|
|
49
|
+
</Settings.Group>
|
|
50
|
+
</Settings.Section>
|
|
51
|
+
</Settings.Root>
|
|
52
52
|
);
|
|
53
53
|
};
|
package/src/translations.ts
CHANGED
|
@@ -26,6 +26,7 @@ export const translations = [
|
|
|
26
26
|
'help label': 'Feedback & Support',
|
|
27
27
|
'feedback textarea label': 'Feedback',
|
|
28
28
|
'feedback textarea placeholder': 'Please enter your feedback, technical issue, or feature request.',
|
|
29
|
+
'include debug logs label': 'Include debug logs',
|
|
29
30
|
'send feedback label': 'Send Feedback',
|
|
30
31
|
'feedback toast label': 'Thank you for your feedback!',
|
|
31
32
|
'feedback toast description': 'We will review your feedback and get back to you as soon as possible.',
|
|
@@ -26,7 +26,7 @@ export namespace ObservabilityCapabilities {
|
|
|
26
26
|
|
|
27
27
|
export const State = Capability.make<Atom.Writable<State>>(`${meta.id}/capability/state`);
|
|
28
28
|
|
|
29
|
-
export const Observability = Capability.make<Observability>(`${meta.id}/capability/observability`);
|
|
29
|
+
export const Observability = Capability.make<Observability.Observability>(`${meta.id}/capability/observability`);
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
// NOTE: This is cloned from the client plugin to avoid circular dependencies.
|
package/src/types/events.ts
CHANGED
|
@@ -2,12 +2,13 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { ActivationEvent
|
|
5
|
+
import { ActivationEvent } from '@dxos/app-framework';
|
|
6
|
+
import { AppActivationEvents } from '@dxos/app-toolkit';
|
|
6
7
|
|
|
7
8
|
import { meta } from '../meta';
|
|
8
9
|
|
|
9
10
|
export namespace ObservabilityEvents {
|
|
10
|
-
export const StateReady: ActivationEvent.ActivationEvent =
|
|
11
|
+
export const StateReady: ActivationEvent.ActivationEvent = AppActivationEvents.createStateEvent(meta.id);
|
|
11
12
|
}
|
|
12
13
|
|
|
13
14
|
// NOTE: This is cloned from the client plugin to avoid circular dependencies.
|