@dxos/plugin-debug 0.11.1 → 0.12.0-next-bbabc02363f18d7643ea4160e3a7a7809870fd0d
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/Debug.mjs +22 -0
- package/dist/lib/Debug.mjs.map +1 -0
- package/dist/lib/DebugEvents.mjs +15 -0
- package/dist/lib/DebugEvents.mjs.map +1 -0
- package/dist/lib/DebugNodes.mjs +19 -0
- package/dist/lib/DebugNodes.mjs.map +1 -0
- package/dist/lib/DebugPlugin.mjs +4 -16
- package/dist/lib/DebugPlugin.mjs.map +1 -1
- package/dist/lib/DebugPlugin.node.mjs +2 -3
- package/dist/lib/DebugPlugin.node.mjs.map +1 -1
- package/dist/lib/DebugPlugin.workerd.mjs +1 -1
- package/dist/lib/DebugPlugin.workerd.mjs.map +1 -1
- package/dist/lib/DebugSurface.mjs +15 -0
- package/dist/lib/DebugSurface.mjs.map +1 -0
- package/dist/lib/Settings.mjs +12 -0
- package/dist/lib/Settings.mjs.map +1 -0
- package/dist/lib/capabilities.mjs +38 -6
- package/dist/lib/capabilities.mjs.map +1 -1
- package/dist/lib/chunk-DebugObjectPanel.mjs +1 -1
- package/dist/lib/chunk-DebugSettings.mjs +95 -15
- package/dist/lib/chunk-DebugSettings.mjs.map +1 -1
- package/dist/lib/chunk-DebugSpaceObjectsPanel.mjs +1 -1
- package/dist/lib/chunk-SpaceGenerator.mjs +52 -10
- package/dist/lib/chunk-SpaceGenerator.mjs.map +1 -1
- package/dist/lib/chunk-StatsPanel.mjs +2 -2
- package/dist/lib/chunk-StatsPanel.mjs.map +1 -1
- package/dist/lib/chunk-Wireframe.mjs +1 -1
- package/dist/lib/chunk-app-graph-builder.mjs +13 -10
- package/dist/lib/chunk-app-graph-builder.mjs.map +1 -1
- package/dist/lib/chunk-log-recording.mjs +3 -2
- package/dist/lib/chunk-log-recording.mjs.map +1 -1
- package/dist/lib/chunk-meta.mjs +1 -1
- package/dist/lib/chunk-meta.mjs.map +1 -1
- package/dist/lib/chunk-react-surface.mjs +20 -14
- package/dist/lib/chunk-react-surface.mjs.map +1 -1
- package/dist/lib/chunk-rolldown-runtime.mjs +13 -0
- package/dist/lib/chunk-settings.mjs +7 -6
- package/dist/lib/chunk-settings.mjs.map +1 -1
- package/dist/lib/chunk-stats-panel.mjs +5 -4
- package/dist/lib/chunk-stats-panel.mjs.map +1 -1
- package/dist/lib/components.mjs +41 -35
- package/dist/lib/components.mjs.map +1 -1
- package/dist/lib/index.mjs +6 -2
- package/dist/lib/plugin.mjs +1 -1
- package/dist/lib/plugin.mjs.map +1 -1
- package/dist/lib/translations.mjs +10 -1
- package/dist/lib/translations.mjs.map +1 -1
- package/dist/types/src/DebugPlugin.d.ts +3 -3
- package/dist/types/src/DebugPlugin.d.ts.map +1 -1
- package/dist/types/src/DebugPlugin.node.d.ts +3 -3
- package/dist/types/src/DebugPlugin.node.d.ts.map +1 -1
- package/dist/types/src/DebugPlugin.workerd.d.ts +3 -3
- package/dist/types/src/DebugPlugin.workerd.d.ts.map +1 -1
- package/dist/types/src/capabilities/DebugSurfaces.d.ts +1 -1
- package/dist/types/src/capabilities/DebugSurfaces.d.ts.map +1 -1
- package/dist/types/src/capabilities/app-graph-builder.d.ts +2 -2
- package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -1
- package/dist/types/src/capabilities/index.d.ts +7 -10
- package/dist/types/src/capabilities/index.d.ts.map +1 -1
- package/dist/types/src/capabilities/log-recording.d.ts +1 -2
- package/dist/types/src/capabilities/log-recording.d.ts.map +1 -1
- package/dist/types/src/capabilities/react-surface.d.ts +2 -2
- package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
- package/dist/types/src/capabilities/settings.d.ts +2 -2
- package/dist/types/src/capabilities/settings.d.ts.map +1 -1
- package/dist/types/src/capabilities/stats-panel.d.ts +2 -2
- package/dist/types/src/capabilities/stats-panel.d.ts.map +1 -1
- package/dist/types/src/components/SchemaTable/SchemaTable.d.ts.map +1 -1
- package/dist/types/src/components/SpaceGenerator/presets.d.ts.map +1 -1
- package/dist/types/src/containers/DebugPortSettings/DebugPortSettings.d.ts +13 -0
- package/dist/types/src/containers/DebugPortSettings/DebugPortSettings.d.ts.map +1 -0
- package/dist/types/src/containers/DebugPortSettings/DebugPortSettings.stories.d.ts +93 -0
- package/dist/types/src/containers/DebugPortSettings/DebugPortSettings.stories.d.ts.map +1 -0
- package/dist/types/src/containers/DebugPortSettings/index.d.ts +2 -0
- package/dist/types/src/containers/DebugPortSettings/index.d.ts.map +1 -0
- package/dist/types/src/containers/DebugSettings/DebugSettings.d.ts +2 -2
- package/dist/types/src/containers/DebugSettings/DebugSettings.d.ts.map +1 -1
- package/dist/types/src/containers/DebugSettings/DebugSettings.stories.d.ts +10 -1
- package/dist/types/src/containers/DebugSettings/DebugSettings.stories.d.ts.map +1 -1
- package/dist/types/src/containers/SpaceGenerator/SpaceGenerator.d.ts.map +1 -1
- package/dist/types/src/containers/SpaceGenerator/SpaceGenerator.stories.d.ts +87 -0
- package/dist/types/src/containers/SpaceGenerator/SpaceGenerator.stories.d.ts.map +1 -0
- package/dist/types/src/index.d.ts +5 -1
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/plugin.d.ts +3 -3
- package/dist/types/src/plugin.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +9 -0
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/types/{debug.d.ts → Debug.d.ts} +3 -3
- package/dist/types/src/types/Debug.d.ts.map +1 -0
- package/dist/types/src/types/DebugEvents.d.ts +8 -0
- package/dist/types/src/types/DebugEvents.d.ts.map +1 -0
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +93 -54
- package/src/DebugPlugin.node.ts +6 -6
- package/src/DebugPlugin.tsx +18 -25
- package/src/DebugPlugin.workerd.ts +4 -3
- package/src/capabilities/DebugSurfaces.tsx +9 -4
- package/src/capabilities/app-graph-builder.ts +8 -4
- package/src/capabilities/index.ts +40 -6
- package/src/capabilities/log-recording.ts +3 -2
- package/src/capabilities/react-surface.ts +10 -8
- package/src/capabilities/settings.ts +7 -5
- package/src/capabilities/stats-panel.ts +5 -4
- package/src/components/SchemaTable/SchemaTable.tsx +19 -13
- package/src/components/SpaceGenerator/ObjectGenerator.tsx +5 -5
- package/src/components/SpaceGenerator/presets.ts +6 -4
- package/src/containers/DebugPortSettings/DebugPortSettings.stories.tsx +144 -0
- package/src/containers/DebugPortSettings/DebugPortSettings.tsx +112 -0
- package/src/containers/DebugPortSettings/index.ts +5 -0
- package/src/containers/DebugSettings/DebugSettings.tsx +11 -6
- package/src/containers/SpaceGenerator/SpaceGenerator.stories.tsx +93 -0
- package/src/containers/SpaceGenerator/SpaceGenerator.tsx +44 -6
- package/src/containers/StatsPanel/StatsPanel.tsx +2 -2
- package/src/index.ts +5 -1
- package/src/meta.ts +1 -1
- package/src/plugin.ts +2 -2
- package/src/translations.ts +13 -0
- package/src/types/{debug.ts → Debug.ts} +4 -2
- package/src/types/DebugEvents.ts +16 -0
- package/dist/lib/chunk-types.mjs +0 -60
- package/dist/lib/chunk-types.mjs.map +0 -1
- package/dist/lib/types.mjs +0 -2
- package/dist/types/src/components/SpaceGenerator/draw-util.d.ts +0 -8
- package/dist/types/src/components/SpaceGenerator/draw-util.d.ts.map +0 -1
- package/dist/types/src/types/debug.d.ts.map +0 -1
- package/dist/types/src/types/index.d.ts +0 -5
- package/dist/types/src/types/index.d.ts.map +0 -1
- package/src/components/SpaceGenerator/draw-util.ts +0 -191
- package/src/types/index.ts +0 -8
|
@@ -1,21 +1,24 @@
|
|
|
1
|
-
import { sortKeys } from "@dxos/util";
|
|
2
1
|
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
3
2
|
import { meta } from "#meta";
|
|
4
|
-
import {
|
|
5
|
-
import
|
|
3
|
+
import { sortKeys } from "@dxos/util";
|
|
4
|
+
import * as AppCapabilities from "@dxos/app-toolkit/AppCapabilities";
|
|
5
|
+
import { Filter, Obj, Type } from "@dxos/echo";
|
|
6
|
+
import { DropdownMenu, IconButton, Input, Panel, ScrollArea, Toolbar, composable, composableProps, useAsyncEffect } from "@dxos/react-ui";
|
|
6
7
|
import { mx } from "@dxos/ui-theme";
|
|
7
8
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
9
|
import { ComputeGraph } from "@dxos/conductor";
|
|
9
|
-
import
|
|
10
|
-
import { Markdown } from "@dxos/plugin-markdown";
|
|
10
|
+
import * as Markdown from "@dxos/plugin-markdown/Markdown";
|
|
11
11
|
import { Organization, Person, Task } from "@dxos/types";
|
|
12
|
-
import
|
|
13
|
-
import
|
|
12
|
+
import * as Drawing from "@dxos/plugin-illustrator/Drawing";
|
|
13
|
+
import * as Sheet from "@dxos/plugin-sheet/Sheet";
|
|
14
|
+
import { SpaceOperation } from "@dxos/plugin-space";
|
|
14
15
|
import { useOperationInvoker, useOptionalCapability } from "@dxos/app-framework/ui";
|
|
15
16
|
import { useProgress } from "@dxos/app-toolkit/ui";
|
|
16
17
|
import { useClient } from "@dxos/react-client";
|
|
18
|
+
import { log } from "@dxos/log";
|
|
17
19
|
import { SchemaTable, createGenerator, generator, staticGenerators } from "#components";
|
|
18
20
|
//#region src/containers/SpaceGenerator/SpaceGenerator.tsx
|
|
21
|
+
var __dxlog_file = "/__w/dxos/dxos/packages/plugins/plugin-debug/src/containers/SpaceGenerator/SpaceGenerator.tsx";
|
|
19
22
|
var staticTypes = [
|
|
20
23
|
Markdown.Document,
|
|
21
24
|
Drawing.Drawing,
|
|
@@ -70,6 +73,29 @@ var SpaceGenerator = composable(({ space, onCreateObjects, children, ...props },
|
|
|
70
73
|
});
|
|
71
74
|
}, [space]);
|
|
72
75
|
useAsyncEffect(updateInfo, [updateInfo]);
|
|
76
|
+
const handleReset = useCallback(async () => {
|
|
77
|
+
try {
|
|
78
|
+
const { error } = await invokePromise(SpaceOperation.RemoveAllObjects, void 0, { spaceId: space.id });
|
|
79
|
+
if (error) log.catch(error, void 0, {
|
|
80
|
+
"~LogMeta": "~LogMeta",
|
|
81
|
+
F: __dxlog_file,
|
|
82
|
+
L: 102,
|
|
83
|
+
S: void 0
|
|
84
|
+
});
|
|
85
|
+
await updateInfo();
|
|
86
|
+
} catch (error) {
|
|
87
|
+
log.catch(error, void 0, {
|
|
88
|
+
"~LogMeta": "~LogMeta",
|
|
89
|
+
F: __dxlog_file,
|
|
90
|
+
L: 106,
|
|
91
|
+
S: void 0
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
}, [
|
|
95
|
+
space,
|
|
96
|
+
invokePromise,
|
|
97
|
+
updateInfo
|
|
98
|
+
]);
|
|
73
99
|
const handleCreateData = useCallback(async (typename) => {
|
|
74
100
|
const constructor = typeMap.get(typename);
|
|
75
101
|
if (constructor) {
|
|
@@ -77,11 +103,11 @@ var SpaceGenerator = composable(({ space, onCreateObjects, children, ...props },
|
|
|
77
103
|
await updateInfo();
|
|
78
104
|
}
|
|
79
105
|
}, [
|
|
106
|
+
space,
|
|
80
107
|
typeMap,
|
|
81
108
|
count,
|
|
82
|
-
|
|
83
|
-
onCreateObjects
|
|
84
|
-
updateInfo
|
|
109
|
+
updateInfo,
|
|
110
|
+
onCreateObjects
|
|
85
111
|
]);
|
|
86
112
|
return /* @__PURE__ */ jsxs(Panel.Root, {
|
|
87
113
|
...composableProps(props),
|
|
@@ -95,6 +121,22 @@ var SpaceGenerator = composable(({ space, onCreateObjects, children, ...props },
|
|
|
95
121
|
label: "Refresh",
|
|
96
122
|
onClick: updateInfo
|
|
97
123
|
}),
|
|
124
|
+
/* @__PURE__ */ jsxs(DropdownMenu.Root, { children: [/* @__PURE__ */ jsx(DropdownMenu.Trigger, {
|
|
125
|
+
asChild: true,
|
|
126
|
+
children: /* @__PURE__ */ jsx(IconButton, {
|
|
127
|
+
icon: "ph--trash--regular",
|
|
128
|
+
iconOnly: true,
|
|
129
|
+
label: "Reset space",
|
|
130
|
+
"data-testid": "spaceGenerator.reset"
|
|
131
|
+
})
|
|
132
|
+
}), /* @__PURE__ */ jsx(DropdownMenu.Portal, { children: /* @__PURE__ */ jsxs(DropdownMenu.Content, {
|
|
133
|
+
side: "bottom",
|
|
134
|
+
children: [/* @__PURE__ */ jsx(DropdownMenu.Viewport, { children: /* @__PURE__ */ jsx(DropdownMenu.Item, {
|
|
135
|
+
"data-testid": "spaceGenerator.confirmReset",
|
|
136
|
+
onClick: handleReset,
|
|
137
|
+
children: "Confirm to remove all objects from the space."
|
|
138
|
+
}) }), /* @__PURE__ */ jsx(DropdownMenu.Arrow, {})]
|
|
139
|
+
}) })] }),
|
|
98
140
|
/* @__PURE__ */ jsx(Toolbar.Separator, {}),
|
|
99
141
|
/* @__PURE__ */ jsx(Input.Root, { children: /* @__PURE__ */ jsx(Input.TextInput, {
|
|
100
142
|
type: "number",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chunk-SpaceGenerator.mjs","names":[],"sources":["../../src/containers/SpaceGenerator/SpaceGenerator.tsx"],"sourcesContent":["//\n// Copyright 2024 DXOS.org\n//\n\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\n\nimport { useOperationInvoker, useOptionalCapability } from '@dxos/app-framework/ui';\nimport { AppCapabilities } from '@dxos/app-toolkit';\nimport { useProgress } from '@dxos/app-toolkit/ui';\nimport { ComputeGraph } from '@dxos/conductor';\nimport { Filter, Obj, Type } from '@dxos/echo';\nimport { Drawing } from '@dxos/plugin-illustrator';\nimport { Markdown } from '@dxos/plugin-markdown';\nimport { Sheet } from '@dxos/plugin-sheet';\nimport { useClient } from '@dxos/react-client';\nimport { type Space } from '@dxos/react-client/echo';\nimport { IconButton, Input, Panel, ScrollArea, ThemedClassName, Toolbar, useAsyncEffect } from '@dxos/react-ui';\nimport { composable, composableProps } from '@dxos/react-ui';\nimport { Organization, Person, Task } from '@dxos/types';\nimport { mx } from '@dxos/ui-theme';\nimport { sortKeys } from '@dxos/util';\n\nimport { type ObjectGenerator, SchemaTable, createGenerator, generator, staticGenerators } from '#components';\nimport { meta } from '#meta';\n\n// TODO(burdon): Make extensible.\nconst staticTypes = [Markdown.Document, Drawing.Drawing, Sheet.Sheet, ComputeGraph];\nconst recordTypes: Type.AnyObj[] = [Organization.Organization, Person.Person, Task.Task];\n\nexport type SpaceGeneratorProps = {\n space: Space;\n onCreateObjects?: (objects: Obj.Unknown[]) => void;\n};\n\nexport const SpaceGenerator = composable<HTMLDivElement, SpaceGeneratorProps>(\n ({ space, onCreateObjects, children, ...props }, forwardedRef) => {\n const { invokePromise } = useOperationInvoker();\n const client = useClient();\n const [count, setCount] = useState(1);\n const [info, setInfo] = useState<any>({});\n const presets = useMemo(() => generator(), []);\n\n // Register types.\n useAsyncEffect(async () => {\n await client.addTypes([...staticTypes, ...recordTypes, ...presets.schemas]);\n }, [client, presets]);\n\n // Create type generators.\n const typeMap = useMemo(() => {\n const recordGenerators = new Map<string, ObjectGenerator<any>>(\n recordTypes.map((type) => [Type.getTypename(type), createGenerator(client, invokePromise, type)]),\n );\n\n return new Map([...staticGenerators, ...presets.items, ...recordGenerators]);\n }, [client, invokePromise, presets]);\n\n // Query space to get info.\n const updateInfo = useCallback(async () => {\n const allSchema = [...space.db.graph.registry.list().filter(Type.isType)];\n const echoSchema = allSchema.filter((t) => Type.isTypeKind(t));\n const staticSchema = allSchema.filter((t) => !Type.isTypeKind(t));\n\n const objects = await space.db.query(Filter.everything()).run();\n const objectMap = sortKeys(\n objects.reduce<Record<string, number>>((map, obj) => {\n const type = Obj.getTypename(obj);\n if (type) {\n const count = map[type] ?? 0;\n map[type] = count + 1;\n }\n\n return map;\n }, {}),\n );\n\n setInfo({\n schema: {\n static: staticSchema.length,\n mutable: echoSchema.length,\n },\n objects: objectMap,\n });\n }, [space]);\n\n useAsyncEffect(updateInfo, [updateInfo]);\n\n const handleCreateData = useCallback(\n async (typename: string) => {\n const constructor = typeMap.get(typename);\n if (constructor) {\n // TODO(burdon): Input to specify number of objects.\n await constructor(space, count, onCreateObjects);\n await updateInfo();\n }\n },\n [typeMap, count, space, onCreateObjects, updateInfo],\n );\n\n return (\n <Panel.Root {...composableProps(props)} ref={forwardedRef}>\n <Panel.Toolbar>\n <Toolbar.Root classNames='dx-document'>\n <IconButton icon='ph--arrow-clockwise--regular' iconOnly label='Refresh' onClick={updateInfo} />\n <Toolbar.Separator />\n <Input.Root>\n <Input.TextInput\n type='number'\n placeholder='Count'\n classNames='w-[4rem] text-right'\n min={1}\n max={100}\n size={8}\n value={count}\n onChange={(event) => setCount(parseInt(event.target.value))}\n />\n </Input.Root>\n </Toolbar.Root>\n </Panel.Toolbar>\n <Panel.Content asChild>\n <ScrollArea.Root thin orientation='vertical'>\n <ScrollArea.Viewport classNames='dx-document gap-4 divide-y divide-subdued-separator'>\n <SchemaTable\n classNames='py-1'\n types={staticTypes}\n objects={info.objects}\n label='Static Types'\n onClick={handleCreateData}\n />\n <SchemaTable\n classNames='py-1'\n types={recordTypes}\n objects={info.objects}\n label='Record Types'\n onClick={handleCreateData}\n />\n <SchemaTable\n classNames='py-1'\n types={presets.types}\n objects={info.objects}\n label='Presets'\n onClick={handleCreateData}\n />\n <ProgressGenerator classNames='py-1' />\n </ScrollArea.Viewport>\n </ScrollArea.Root>\n </Panel.Content>\n </Panel.Root>\n );\n },\n);\n\nSpaceGenerator.displayName = 'SpaceGenerator';\n\n// Stable key for the test progress monitor within the shared registry.\nconst TEST_PROGRESS_NAME = `${meta.profile.key}.test-progress`;\n\ntype ProgressGeneratorProps = ThemedClassName;\n\n// Drives a synthetic progress monitor (10s over 10 steps) so the R0 rail meter can be exercised.\nconst ProgressGenerator = ({ classNames }: ProgressGeneratorProps) => {\n const registry = useOptionalCapability(AppCapabilities.ProgressRegistry);\n const monitor = useProgress(TEST_PROGRESS_NAME);\n const running = monitor?.status === 'running';\n const intervalRef = useRef<ReturnType<typeof setInterval> | undefined>(undefined);\n\n const clearTimer = useCallback(() => {\n if (intervalRef.current) {\n clearInterval(intervalRef.current);\n intervalRef.current = undefined;\n }\n }, []);\n\n const handleStart = useCallback(() => {\n // Guard on the timer ref too: `running` (derived from the registry) can lag a fast second click.\n if (!registry || running || intervalRef.current) {\n return;\n }\n\n const steps = 10;\n let current = 0;\n const handle = registry.register(TEST_PROGRESS_NAME, {\n label: 'Test Progress',\n total: steps,\n // Invoked by the meter's cancel control (R0 rail) or the local button.\n onCancel: () => {\n clearTimer();\n handle.remove();\n },\n });\n\n intervalRef.current = setInterval(() => {\n current += 1;\n handle.set(current);\n if (current >= steps) {\n clearTimer();\n handle.done();\n handle.remove();\n }\n }, 1_000);\n }, [registry, running, clearTimer]);\n\n // Tear down the timer and the registry entry if unmounted mid-run.\n useEffect(\n () => () => {\n clearTimer();\n registry?.cancel(TEST_PROGRESS_NAME);\n },\n [clearTimer, registry],\n );\n\n return (\n <div className={mx('flex items-center gap-2 py-1', classNames)}>\n <span className='grow'>Progress Monitor</span>\n {running ? (\n <IconButton\n icon='ph--x--regular'\n label='Cancel test progress'\n onClick={() => registry?.cancel(TEST_PROGRESS_NAME)}\n />\n ) : (\n <IconButton icon='ph--play--regular' label='Start test progress' disabled={!registry} onClick={handleStart} />\n )}\n </div>\n );\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"chunk-SpaceGenerator.mjs","names":[],"sources":["../../src/containers/SpaceGenerator/SpaceGenerator.tsx"],"sourcesContent":["//\n// Copyright 2024 DXOS.org\n//\n\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\n\nimport { useOperationInvoker, useOptionalCapability } from '@dxos/app-framework/ui';\nimport * as AppCapabilities from '@dxos/app-toolkit/AppCapabilities';\nimport { useProgress } from '@dxos/app-toolkit/ui';\nimport { ComputeGraph } from '@dxos/conductor';\nimport { Filter, Obj, Type } from '@dxos/echo';\nimport { log } from '@dxos/log';\nimport * as Drawing from '@dxos/plugin-illustrator/Drawing';\nimport * as Markdown from '@dxos/plugin-markdown/Markdown';\nimport * as Sheet from '@dxos/plugin-sheet/Sheet';\nimport { SpaceOperation } from '@dxos/plugin-space';\nimport { useClient } from '@dxos/react-client';\nimport { type Space } from '@dxos/react-client/echo';\nimport {\n DropdownMenu,\n IconButton,\n Input,\n Panel,\n ScrollArea,\n ThemedClassName,\n Toolbar,\n useAsyncEffect,\n} from '@dxos/react-ui';\nimport { composable, composableProps } from '@dxos/react-ui';\nimport { Organization, Person, Task } from '@dxos/types';\nimport { mx } from '@dxos/ui-theme';\nimport { sortKeys } from '@dxos/util';\n\nimport { type ObjectGenerator, SchemaTable, createGenerator, generator, staticGenerators } from '#components';\nimport { meta } from '#meta';\n\n// TODO(burdon): Make extensible.\nconst staticTypes = [Markdown.Document, Drawing.Drawing, Sheet.Sheet, ComputeGraph];\nconst recordTypes: Type.AnyObj[] = [Organization.Organization, Person.Person, Task.Task];\n\nexport type SpaceGeneratorProps = {\n space: Space;\n onCreateObjects?: (objects: Obj.Unknown[]) => void;\n};\n\nexport const SpaceGenerator = composable<HTMLDivElement, SpaceGeneratorProps>(\n ({ space, onCreateObjects, children, ...props }, forwardedRef) => {\n const { invokePromise } = useOperationInvoker();\n const client = useClient();\n const [count, setCount] = useState(1);\n const [info, setInfo] = useState<any>({});\n const presets = useMemo(() => generator(), []);\n\n // Register types.\n useAsyncEffect(async () => {\n await client.addTypes([...staticTypes, ...recordTypes, ...presets.schemas]);\n }, [client, presets]);\n\n // Create type generators.\n const typeMap = useMemo(() => {\n const recordGenerators = new Map<string, ObjectGenerator<any>>(\n recordTypes.map((type) => [Type.getTypename(type), createGenerator(client, invokePromise, type)]),\n );\n\n return new Map([...staticGenerators, ...presets.items, ...recordGenerators]);\n }, [client, invokePromise, presets]);\n\n // Query space to get info.\n const updateInfo = useCallback(async () => {\n const allSchema = [...space.db.graph.registry.list().filter(Type.isType)];\n const echoSchema = allSchema.filter((t) => Type.isTypeKind(t));\n const staticSchema = allSchema.filter((t) => !Type.isTypeKind(t));\n\n const objects = await space.db.query(Filter.everything()).run();\n const objectMap = sortKeys(\n objects.reduce<Record<string, number>>((map, obj) => {\n const type = Obj.getTypename(obj);\n if (type) {\n const count = map[type] ?? 0;\n map[type] = count + 1;\n }\n\n return map;\n }, {}),\n );\n\n setInfo({\n schema: {\n static: staticSchema.length,\n mutable: echoSchema.length,\n },\n objects: objectMap,\n });\n }, [space]);\n\n useAsyncEffect(updateInfo, [updateInfo]);\n\n const handleReset = useCallback(async () => {\n try {\n const { error } = await invokePromise(SpaceOperation.RemoveAllObjects, undefined, { spaceId: space.id });\n if (error) {\n log.catch(error);\n }\n await updateInfo();\n } catch (error) {\n log.catch(error);\n }\n }, [space, invokePromise, updateInfo]);\n\n const handleCreateData = useCallback(\n async (typename: string) => {\n const constructor = typeMap.get(typename);\n if (constructor) {\n // TODO(burdon): Input to specify number of objects.\n await constructor(space, count, onCreateObjects);\n await updateInfo();\n }\n },\n [space, typeMap, count, updateInfo, onCreateObjects],\n );\n\n return (\n <Panel.Root {...composableProps(props)} ref={forwardedRef}>\n <Panel.Toolbar>\n <Toolbar.Root classNames='dx-document'>\n <IconButton icon='ph--arrow-clockwise--regular' iconOnly label='Refresh' onClick={updateInfo} />\n <DropdownMenu.Root>\n <DropdownMenu.Trigger asChild>\n <IconButton icon='ph--trash--regular' iconOnly label='Reset space' data-testid='spaceGenerator.reset' />\n </DropdownMenu.Trigger>\n <DropdownMenu.Portal>\n <DropdownMenu.Content side='bottom'>\n <DropdownMenu.Viewport>\n <DropdownMenu.Item data-testid='spaceGenerator.confirmReset' onClick={handleReset}>\n Confirm to remove all objects from the space.\n </DropdownMenu.Item>\n </DropdownMenu.Viewport>\n <DropdownMenu.Arrow />\n </DropdownMenu.Content>\n </DropdownMenu.Portal>\n </DropdownMenu.Root>\n <Toolbar.Separator />\n <Input.Root>\n <Input.TextInput\n type='number'\n placeholder='Count'\n classNames='w-[4rem] text-right'\n min={1}\n max={100}\n size={8}\n value={count}\n onChange={(event) => setCount(parseInt(event.target.value))}\n />\n </Input.Root>\n </Toolbar.Root>\n </Panel.Toolbar>\n <Panel.Content asChild>\n <ScrollArea.Root thin orientation='vertical'>\n <ScrollArea.Viewport classNames='dx-document gap-4 divide-y divide-subdued-separator'>\n <SchemaTable\n classNames='py-1'\n types={staticTypes}\n objects={info.objects}\n label='Static Types'\n onClick={handleCreateData}\n />\n <SchemaTable\n classNames='py-1'\n types={recordTypes}\n objects={info.objects}\n label='Record Types'\n onClick={handleCreateData}\n />\n <SchemaTable\n classNames='py-1'\n types={presets.types}\n objects={info.objects}\n label='Presets'\n onClick={handleCreateData}\n />\n <ProgressGenerator classNames='py-1' />\n </ScrollArea.Viewport>\n </ScrollArea.Root>\n </Panel.Content>\n </Panel.Root>\n );\n },\n);\n\nSpaceGenerator.displayName = 'SpaceGenerator';\n\n// Stable key for the test progress monitor within the shared registry.\nconst TEST_PROGRESS_NAME = `${meta.profile.key}.test-progress`;\n\ntype ProgressGeneratorProps = ThemedClassName;\n\n// Drives a synthetic progress monitor (10s over 10 steps) so the R0 rail meter can be exercised.\nconst ProgressGenerator = ({ classNames }: ProgressGeneratorProps) => {\n const registry = useOptionalCapability(AppCapabilities.ProgressRegistry);\n const monitor = useProgress(TEST_PROGRESS_NAME);\n const running = monitor?.status === 'running';\n const intervalRef = useRef<ReturnType<typeof setInterval> | undefined>(undefined);\n\n const clearTimer = useCallback(() => {\n if (intervalRef.current) {\n clearInterval(intervalRef.current);\n intervalRef.current = undefined;\n }\n }, []);\n\n const handleStart = useCallback(() => {\n // Guard on the timer ref too: `running` (derived from the registry) can lag a fast second click.\n if (!registry || running || intervalRef.current) {\n return;\n }\n\n const steps = 10;\n let current = 0;\n const handle = registry.register(TEST_PROGRESS_NAME, {\n label: 'Test Progress',\n total: steps,\n // Invoked by the meter's cancel control (R0 rail) or the local button.\n onCancel: () => {\n clearTimer();\n handle.remove();\n },\n });\n\n intervalRef.current = setInterval(() => {\n current += 1;\n handle.set(current);\n if (current >= steps) {\n clearTimer();\n handle.done();\n handle.remove();\n }\n }, 1_000);\n }, [registry, running, clearTimer]);\n\n // Tear down the timer and the registry entry if unmounted mid-run.\n useEffect(\n () => () => {\n clearTimer();\n registry?.cancel(TEST_PROGRESS_NAME);\n },\n [clearTimer, registry],\n );\n\n return (\n <div className={mx('flex items-center gap-2 py-1', classNames)}>\n <span className='grow'>Progress Monitor</span>\n {running ? (\n <IconButton\n icon='ph--x--regular'\n label='Cancel test progress'\n onClick={() => registry?.cancel(TEST_PROGRESS_NAME)}\n />\n ) : (\n <IconButton icon='ph--play--regular' label='Start test progress' disabled={!registry} onClick={handleStart} />\n )}\n </div>\n );\n};\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Fragment } from "react";
|
|
2
|
-
import
|
|
2
|
+
import * as AppCapabilities from "@dxos/app-toolkit/AppCapabilities";
|
|
3
3
|
import { ScrollArea } from "@dxos/react-ui";
|
|
4
4
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
5
|
import { useOptionalCapability } from "@dxos/app-framework/ui";
|
|
@@ -41,7 +41,7 @@ var StatsPanel = () => {
|
|
|
41
41
|
}), /* @__PURE__ */ jsx("dl", {
|
|
42
42
|
className: "grid grid-cols-[auto_minmax(0,1fr)] w-full",
|
|
43
43
|
children: flatten(value).map(([key, cell]) => /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("dt", {
|
|
44
|
-
className: "border-be border-separator pbe-1 pbs-1
|
|
44
|
+
className: "border-be border-separator pbe-1 pbs-1 pe-2 text-description self-start",
|
|
45
45
|
children: key
|
|
46
46
|
}), /* @__PURE__ */ jsx("dd", {
|
|
47
47
|
className: "border-be border-separator pbe-1 pbs-1 truncate font-mono text-end",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chunk-StatsPanel.mjs","names":[],"sources":["../../src/containers/StatsPanel/StatsPanel.tsx"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\nimport { Atom, useAtomValue } from '@effect-atom/atom-react';\nimport React, { Fragment } from 'react';\n\nimport { useOptionalCapability } from '@dxos/app-framework/ui';\nimport
|
|
1
|
+
{"version":3,"file":"chunk-StatsPanel.mjs","names":[],"sources":["../../src/containers/StatsPanel/StatsPanel.tsx"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\nimport { Atom, useAtomValue } from '@effect-atom/atom-react';\nimport React, { Fragment } from 'react';\n\nimport { useOptionalCapability } from '@dxos/app-framework/ui';\nimport * as AppCapabilities from '@dxos/app-toolkit/AppCapabilities';\nimport { ScrollArea } from '@dxos/react-ui';\n\n// Fallback so the atom hook is called unconditionally when no store is contributed (host plugin not\n// loaded); the panel then renders its empty state.\nconst EMPTY = Atom.make<Record<string, unknown>>({});\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value);\n\n/** Renders a leaf value; numbers are monospace so columns of counts align. */\nconst formatValue = (value: unknown): string => (typeof value === 'number' ? value.toLocaleString() : String(value));\n\n/**\n * Flattens a compartment into `key → value` rows, one level deep: nested objects (e.g. `coverage`)\n * become dotted keys (`coverage.plain`) so everything renders in a single flat table.\n */\nconst flatten = (stats: unknown): [string, unknown][] => {\n if (!isRecord(stats)) {\n return [['value', stats]];\n }\n\n return Object.entries(stats).flatMap(([key, value]) =>\n isRecord(value)\n ? Object.entries(value).map(([subKey, subValue]): [string, unknown] => [`${key}.${subKey}`, subValue])\n : [[key, value] as [string, unknown]],\n );\n};\n\n/**\n * Presentational panel for the {@link AppCapabilities.StatsPanel} store: renders every plugin\n * compartment as a flat key × value table, live (re-renders on each write). Purely generic — it\n * displays whatever each plugin stores, so it works for sync telemetry or any other stats.\n */\nexport const StatsPanel = () => {\n const store = useOptionalCapability(AppCapabilities.StatsPanel);\n const stats = useAtomValue(store?.statsAtom ?? EMPTY);\n const compartments = Object.entries(stats);\n if (compartments.length === 0) {\n return <div className='p-2 text-sm text-description'>No stats yet.</div>;\n }\n\n return (\n <ScrollArea.Root thin centered padding>\n <ScrollArea.Viewport>\n {compartments.map(([pluginKey, value]) => (\n <section key={pluginKey} className='w-full'>\n <h3 className='text-start font-mono text-xs text-description pbe-1'>{pluginKey}</h3>\n <dl className='grid grid-cols-[auto_minmax(0,1fr)] w-full'>\n {flatten(value).map(([key, cell]) => (\n <Fragment key={key}>\n <dt className='border-be border-separator pbe-1 pbs-1 pe-2 text-description self-start'>{key}</dt>\n <dd className='border-be border-separator pbe-1 pbs-1 truncate font-mono text-end'>\n {formatValue(cell)}\n </dd>\n </Fragment>\n ))}\n </dl>\n </section>\n ))}\n </ScrollArea.Viewport>\n </ScrollArea.Root>\n );\n};\n\nStatsPanel.displayName = 'StatsPanel';\n"],"mappings":";;;;;;;AAaA,IAAM,QAAQ,KAAK,KAA8B,CAAC,CAAC;AAEnD,IAAM,YAAY,UAChB,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;;AAGrE,IAAM,eAAe,UAA4B,OAAO,UAAU,WAAW,MAAM,eAAe,IAAI,OAAO,KAAK;;;;;AAMlH,IAAM,WAAW,UAAwC;CACvD,IAAI,CAAC,SAAS,KAAK,GACjB,OAAO,CAAC,CAAC,SAAS,KAAK,CAAC;CAG1B,OAAO,OAAO,QAAQ,KAAK,CAAC,CAAC,SAAS,CAAC,KAAK,WAC1C,SAAS,KAAK,IACV,OAAO,QAAQ,KAAK,CAAC,CAAC,KAAK,CAAC,QAAQ,cAAiC,CAAC,GAAG,IAAI,GAAG,UAAU,QAAQ,CAAC,IACnG,CAAC,CAAC,KAAK,KAAK,CAAsB,CACxC;AACF;;;;;;AAOA,IAAa,mBAAmB;CAE9B,MAAM,QAAQ,aADA,sBAAsB,gBAAgB,UACzB,CAAA,EAAO,aAAa,KAAK;CACpD,MAAM,eAAe,OAAO,QAAQ,KAAK;CACzC,IAAI,aAAa,WAAW,GAC1B,OAAO,oBAAC,OAAD;EAAK,WAAU;YAA+B;CAAkB,CAAA;CAGzE,OACE,oBAAC,WAAW,MAAZ;EAAiB,MAAA;EAAK,UAAA;EAAS,SAAA;YAC7B,oBAAC,WAAW,UAAZ,EAAA,UACG,aAAa,KAAK,CAAC,WAAW,WAC7B,qBAAC,WAAD;GAAyB,WAAU;aAAnC,CACE,oBAAC,MAAD;IAAI,WAAU;cAAuD;GAAc,CAAA,GACnF,oBAAC,MAAD;IAAI,WAAU;cACX,QAAQ,KAAK,CAAC,CAAC,KAAK,CAAC,KAAK,UACzB,qBAAC,UAAD,EAAA,UAAA,CACE,oBAAC,MAAD;KAAI,WAAU;eAA2E;IAAQ,CAAA,GACjG,oBAAC,MAAD;KAAI,WAAU;eACX,YAAY,IAAI;IACf,CAAA,CACI,EAAA,GALK,GAKL,CACX;GACC,CAAA,CACG;KAZK,SAYL,CACV,EACkB,CAAA;CACN,CAAA;AAErB;AAEA,WAAW,cAAc"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import "react";
|
|
2
|
+
import { Obj } from "@dxos/echo";
|
|
2
3
|
import { mx } from "@dxos/ui-theme";
|
|
3
4
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4
|
-
import { Obj } from "@dxos/echo";
|
|
5
5
|
import { JsonHighlighter } from "@dxos/react-ui-syntax-highlighter";
|
|
6
6
|
import { useResizeDetector } from "react-resize-detector";
|
|
7
7
|
import { useAttentionAttributes } from "@dxos/react-ui-attention";
|
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
1
|
+
import { SpaceType, id, nodeId } from "./DebugNodes.mjs";
|
|
2
|
+
import * as Capability from "@dxos/app-framework/Capability";
|
|
3
3
|
import { meta } from "#meta";
|
|
4
|
-
import {
|
|
4
|
+
import { Position } from "@dxos/util";
|
|
5
|
+
import * as AppCapabilities from "@dxos/app-toolkit/AppCapabilities";
|
|
5
6
|
import * as Effect from "effect/Effect";
|
|
7
|
+
import * as AppNode from "@dxos/app-toolkit/AppNode";
|
|
8
|
+
import * as AppNodeMatcher from "@dxos/app-toolkit/AppNodeMatcher";
|
|
9
|
+
import * as GraphPath from "@dxos/app-toolkit/GraphPath";
|
|
6
10
|
import { GraphBuilder, Node, NodeMatcher } from "@dxos/plugin-graph";
|
|
7
|
-
import { DebugNodes } from "#types";
|
|
8
11
|
//#region src/capabilities/app-graph-builder.ts
|
|
9
12
|
var app_graph_builder_default = Capability.makeModule(Effect.fnUntraced(function* () {
|
|
10
13
|
const extensions = yield* Effect.all([
|
|
@@ -12,20 +15,20 @@ var app_graph_builder_default = Capability.makeModule(Effect.fnUntraced(function
|
|
|
12
15
|
id: "debug",
|
|
13
16
|
match: AppNodeMatcher.whenNavTreeGroup(GraphPath.GroupTypes.system),
|
|
14
17
|
connector: (space) => Effect.succeed([Node.make({
|
|
15
|
-
id:
|
|
18
|
+
id: nodeId(id),
|
|
16
19
|
data: null,
|
|
17
|
-
type:
|
|
20
|
+
type: id,
|
|
18
21
|
properties: {
|
|
19
22
|
label: ["debug.label", { ns: meta.profile.key }],
|
|
20
23
|
icon: "ph--bug--regular",
|
|
21
24
|
position: Position.last
|
|
22
25
|
},
|
|
23
26
|
nodes: [Node.make({
|
|
24
|
-
id:
|
|
25
|
-
type:
|
|
27
|
+
id: nodeId(SpaceType),
|
|
28
|
+
type: SpaceType,
|
|
26
29
|
data: {
|
|
27
30
|
space,
|
|
28
|
-
type:
|
|
31
|
+
type: SpaceType
|
|
29
32
|
},
|
|
30
33
|
properties: {
|
|
31
34
|
label: ["generate-objects.label", { ns: meta.profile.key }],
|
|
@@ -68,7 +71,7 @@ var app_graph_builder_default = Capability.makeModule(Effect.fnUntraced(function
|
|
|
68
71
|
})])
|
|
69
72
|
})
|
|
70
73
|
]);
|
|
71
|
-
return Capability.
|
|
74
|
+
return Capability.contribute(AppCapabilities.AppGraphBuilder, extensions);
|
|
72
75
|
}));
|
|
73
76
|
//#endregion
|
|
74
77
|
export { app_graph_builder_default as default };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chunk-app-graph-builder.mjs","names":[],"sources":["../../src/capabilities/app-graph-builder.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\n\nimport
|
|
1
|
+
{"version":3,"file":"chunk-app-graph-builder.mjs","names":[],"sources":["../../src/capabilities/app-graph-builder.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\n\nimport * as Capability from '@dxos/app-framework/Capability';\nimport * as AppCapabilities from '@dxos/app-toolkit/AppCapabilities';\nimport * as AppNode from '@dxos/app-toolkit/AppNode';\nimport * as AppNodeMatcher from '@dxos/app-toolkit/AppNodeMatcher';\nimport * as GraphPath from '@dxos/app-toolkit/GraphPath';\nimport { GraphBuilder, Node, NodeMatcher } from '@dxos/plugin-graph';\nimport { type Space } from '@dxos/react-client/echo';\nimport { Position } from '@dxos/util';\n\nimport { meta } from '#meta';\n\nimport * as DebugNodes from '../types/DebugNodes';\n\nexport default Capability.makeModule(\n Effect.fnUntraced(function* () {\n const extensions = yield* Effect.all([\n // Top-level Debug node (sibling of DevTools under SYSTEM); only present when a space is active.\n GraphBuilder.createExtension({\n id: 'debug',\n match: AppNodeMatcher.whenNavTreeGroup(GraphPath.GroupTypes.system),\n connector: (space: Space) =>\n Effect.succeed([\n Node.make({\n id: DebugNodes.nodeId(DebugNodes.id),\n data: null,\n type: DebugNodes.id,\n properties: {\n label: ['debug.label', { ns: meta.profile.key }],\n icon: 'ph--bug--regular',\n position: Position.last,\n },\n nodes: [\n Node.make({\n id: DebugNodes.nodeId(DebugNodes.SpaceType),\n type: DebugNodes.SpaceType,\n data: { space, type: DebugNodes.SpaceType },\n properties: {\n label: ['generate-objects.label', { ns: meta.profile.key }],\n icon: 'ph--dice-five--regular',\n },\n }),\n ],\n }),\n ]),\n }),\n\n // Debug object companion.\n GraphBuilder.createExtension({\n id: 'debugObject',\n match: NodeMatcher.whenEchoObject,\n connector: () =>\n Effect.succeed([\n AppNode.makeCompanion({\n variant: 'debug',\n label: ['debug.label', { ns: meta.profile.key }],\n icon: 'ph--bug--regular',\n data: 'debug',\n position: Position.last,\n }),\n ]),\n }),\n\n // Object explorer deck companion.\n GraphBuilder.createExtension({\n id: 'spaceObjects',\n match: NodeMatcher.whenRoot,\n connector: () =>\n Effect.succeed([\n AppNode.makeDeckCompanion({\n id: 'spaceObjects',\n label: ['space-objects.label', { ns: meta.profile.key }],\n icon: 'ph--cube--regular',\n data: 'space-objects' as const,\n position: Position.last,\n }),\n ]),\n }),\n\n // Log panel deck companion.\n GraphBuilder.createExtension({\n id: 'logs',\n match: NodeMatcher.whenRoot,\n connector: () =>\n Effect.succeed([\n AppNode.makeDeckCompanion({\n id: 'logs',\n label: ['logs.label', { ns: meta.profile.key }],\n icon: 'ph--list-magnifying-glass--regular',\n data: 'logs' as const,\n position: Position.last,\n }),\n ]),\n }),\n ]);\n\n return Capability.contribute(AppCapabilities.AppGraphBuilder, extensions);\n }),\n);\n"],"mappings":";;;;;;;;;;;AAmBA,IAAA,4BAAe,WAAW,WACxB,OAAO,WAAW,aAAa;CAC7B,MAAM,aAAa,OAAO,OAAO,IAAI;EAEnC,aAAa,gBAAgB;GAC3B,IAAI;GACJ,OAAO,eAAe,iBAAiB,UAAU,WAAW,MAAM;GAClE,YAAY,UACV,OAAO,QAAQ,CACb,KAAK,KAAK;IACR,IAAI,OAAkB,EAAa;IACnC,MAAM;IACN,MAAM;IACN,YAAY;KACV,OAAO,CAAC,eAAe,EAAE,IAAI,KAAK,QAAQ,IAAI,CAAC;KAC/C,MAAM;KACN,UAAU,SAAS;IACrB;IACA,OAAO,CACL,KAAK,KAAK;KACR,IAAI,OAAkB,SAAoB;KAC1C,MAAM;KACN,MAAM;MAAE;MAAO,MAAM;KAAqB;KAC1C,YAAY;MACV,OAAO,CAAC,0BAA0B,EAAE,IAAI,KAAK,QAAQ,IAAI,CAAC;MAC1D,MAAM;KACR;IACF,CAAC,CACH;GACF,CAAC,CACH,CAAC;EACL,CAAC;EAGD,aAAa,gBAAgB;GAC3B,IAAI;GACJ,OAAO,YAAY;GACnB,iBACE,OAAO,QAAQ,CACb,QAAQ,cAAc;IACpB,SAAS;IACT,OAAO,CAAC,eAAe,EAAE,IAAI,KAAK,QAAQ,IAAI,CAAC;IAC/C,MAAM;IACN,MAAM;IACN,UAAU,SAAS;GACrB,CAAC,CACH,CAAC;EACL,CAAC;EAGD,aAAa,gBAAgB;GAC3B,IAAI;GACJ,OAAO,YAAY;GACnB,iBACE,OAAO,QAAQ,CACb,QAAQ,kBAAkB;IACxB,IAAI;IACJ,OAAO,CAAC,uBAAuB,EAAE,IAAI,KAAK,QAAQ,IAAI,CAAC;IACvD,MAAM;IACN,MAAM;IACN,UAAU,SAAS;GACrB,CAAC,CACH,CAAC;EACL,CAAC;EAGD,aAAa,gBAAgB;GAC3B,IAAI;GACJ,OAAO,YAAY;GACnB,iBACE,OAAO,QAAQ,CACb,QAAQ,kBAAkB;IACxB,IAAI;IACJ,OAAO,CAAC,cAAc,EAAE,IAAI,KAAK,QAAQ,IAAI,CAAC;IAC9C,MAAM;IACN,MAAM;IACN,UAAU,SAAS;GACrB,CAAC,CACH,CAAC;EACL,CAAC;CACH,CAAC;CAED,OAAO,WAAW,WAAW,gBAAgB,iBAAiB,UAAU;AAC1E,CAAC,CACH"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as Capability from "@dxos/app-framework/Capability";
|
|
2
2
|
import * as Effect from "effect/Effect";
|
|
3
3
|
import { logBuffer } from "@dxos/react-ui-debug";
|
|
4
4
|
//#region src/capabilities/log-recording.ts
|
|
@@ -9,7 +9,8 @@ import { logBuffer } from "@dxos/react-ui-debug";
|
|
|
9
9
|
*/
|
|
10
10
|
var log_recording_default = Capability.makeModule(Effect.fnUntraced(function* () {
|
|
11
11
|
logBuffer.start();
|
|
12
|
-
|
|
12
|
+
yield* Effect.addFinalizer(() => Effect.sync(() => logBuffer.stop()));
|
|
13
|
+
return [];
|
|
13
14
|
}));
|
|
14
15
|
//#endregion
|
|
15
16
|
export { log_recording_default as default };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chunk-log-recording.mjs","names":[],"sources":["../../src/capabilities/log-recording.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\n\nimport
|
|
1
|
+
{"version":3,"file":"chunk-log-recording.mjs","names":[],"sources":["../../src/capabilities/log-recording.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\n\nimport * as Capability from '@dxos/app-framework/Capability';\nimport { logBuffer } from '@dxos/react-ui-debug';\n\n/**\n * Start recording into the process-wide log buffer at startup, so the log companion shows what\n * happened before it was opened. Recording deliberately does not follow the panel's mount: the\n * entries worth reading are usually the ones from before you went looking.\n */\nexport default Capability.makeModule(\n Effect.fnUntraced(function* () {\n logBuffer.start();\n yield* Effect.addFinalizer(() => Effect.sync(() => logBuffer.stop()));\n return [];\n }),\n);\n"],"mappings":";;;;;;;;;AAcA,IAAA,wBAAe,WAAW,WACxB,OAAO,WAAW,aAAa;CAC7B,UAAU,MAAM;CAChB,OAAO,OAAO,mBAAmB,OAAO,WAAW,UAAU,KAAK,CAAC,CAAC;CACpE,OAAO,CAAC;AACV,CAAC,CACH"}
|
package/dist/lib/chunk-meta.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chunk-meta.mjs","names":[],"sources":["../../dx.config.ts","../../src/meta.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\nimport { Config2 } from '@dxos/app-framework/config';\nimport { trim } from '@dxos/util';\n\nexport default Config2.make({\n plugin: {\n key: 'org.dxos.plugin.debug',\n name: 'Debug',\n author: 'DXOS',\n description: trim`\n DebugPlugin bundles developer debugging utilities for DXOS Composer under a Debug node in the\n SYSTEM navigation group (a sibling of the Devtools inspector).\n\n Test-data generation is available via a SpaceGenerator article surface: developers can\n create configurable batches of synthetic ECHO objects into any space collection, with a\n status indicator showing when generation is running.\n\n The plugin contributes a Debug companion tab to every ECHO object in the deck so developers\n can inspect raw field values and DXNs inline, and a Space Objects companion panel that lists\n all objects in the active space with live reactive updates.\n\n Additional utilities include a wireframe overlay mode that draws labelled borders around\n every article and section surface, a log-capture and download facility backed by an\n IdbLogStore, and a transient-stats panel for live telemetry.\n `,\n source: 'https://github.com/dxos/dxos/tree/main/packages/plugins/plugin-debug',\n icon: { key: 'ph--bug--regular' },\n spec: 'PLUGIN.mdl',\n tags: ['labs'],\n },\n});\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport
|
|
1
|
+
{"version":3,"file":"chunk-meta.mjs","names":[],"sources":["../../dx.config.ts","../../src/meta.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\nimport { Config2 } from '@dxos/app-framework/config';\nimport { trim } from '@dxos/util';\n\nexport default Config2.make({\n plugin: {\n key: 'org.dxos.plugin.debug',\n name: 'Debug',\n author: 'DXOS',\n description: trim`\n DebugPlugin bundles developer debugging utilities for DXOS Composer under a Debug node in the\n SYSTEM navigation group (a sibling of the Devtools inspector).\n\n Test-data generation is available via a SpaceGenerator article surface: developers can\n create configurable batches of synthetic ECHO objects into any space collection, with a\n status indicator showing when generation is running.\n\n The plugin contributes a Debug companion tab to every ECHO object in the deck so developers\n can inspect raw field values and DXNs inline, and a Space Objects companion panel that lists\n all objects in the active space with live reactive updates.\n\n Additional utilities include a wireframe overlay mode that draws labelled borders around\n every article and section surface, a log-capture and download facility backed by an\n IdbLogStore, and a transient-stats panel for live telemetry.\n `,\n source: 'https://github.com/dxos/dxos/tree/main/packages/plugins/plugin-debug',\n icon: { key: 'ph--bug--regular' },\n spec: 'PLUGIN.mdl',\n tags: ['labs'],\n },\n});\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport * as Plugin from '@dxos/app-framework/Plugin';\n\nimport config from '../dx.config';\n\nexport const meta = Plugin.getMetaFromConfig(config);\n"],"mappings":";;;;AAOA,IAAA,oBAAe,QAAQ,KAAK,EAC1B,QAAQ;CACN,KAAK;CACL,MAAM;CACN,QAAQ;CACR,aAAa,IAAI;;;;;;;;;;;;;;;;CAgBjB,QAAQ;CACR,MAAM,EAAE,KAAK,mBAAmB;CAChC,MAAM;CACN,MAAM,CAAC,MAAM;AACf,EACF,CAAC;;;ACzBD,IAAa,OAAO,OAAO,kBAAkB,iBAAM"}
|
|
@@ -1,14 +1,18 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { DebugCapabilities } from "./Debug.mjs";
|
|
2
|
+
import { SpaceType } from "./DebugNodes.mjs";
|
|
3
|
+
import { Stats } from "./DebugSurface.mjs";
|
|
3
4
|
import { useCallback, useMemo } from "react";
|
|
5
|
+
import * as Capability from "@dxos/app-framework/Capability";
|
|
4
6
|
import { meta } from "#meta";
|
|
5
|
-
import {
|
|
7
|
+
import { Position } from "@dxos/util";
|
|
8
|
+
import * as Capabilities from "@dxos/app-framework/Capabilities";
|
|
9
|
+
import * as AppCapabilities from "@dxos/app-toolkit/AppCapabilities";
|
|
10
|
+
import { Annotation, Collection, Entity, Filter, Obj, Type } from "@dxos/echo";
|
|
6
11
|
import { Panel } from "@dxos/react-ui";
|
|
7
12
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
|
-
import {
|
|
9
|
-
import { SpaceCapabilities, SpaceOperation } from "@dxos/plugin-space";
|
|
13
|
+
import { SpaceOperation } from "@dxos/plugin-space";
|
|
10
14
|
import * as Effect from "effect/Effect";
|
|
11
|
-
import
|
|
15
|
+
import * as GraphPath from "@dxos/app-toolkit/GraphPath";
|
|
12
16
|
import { Logger } from "@dxos/react-ui-debug";
|
|
13
17
|
import { Surface, useAtomCapability, useOperationInvoker, useSettingsState } from "@dxos/app-framework/ui";
|
|
14
18
|
import { AppSurface, useActiveSpace } from "@dxos/app-toolkit/ui";
|
|
@@ -16,13 +20,16 @@ import { SpaceState, isSpace } from "@dxos/react-client/echo";
|
|
|
16
20
|
import { DebugObjectPanel, DebugSettings, DebugSpaceObjectsPanel, DebugStatus, LogStatus, SpaceGenerator, StatsPanel, Wireframe } from "#containers";
|
|
17
21
|
import { useAtomValue } from "@effect-atom/atom-react";
|
|
18
22
|
import * as Option from "effect/Option";
|
|
23
|
+
import * as AppAnnotation from "@dxos/app-toolkit/AppAnnotation";
|
|
24
|
+
import * as LayoutOperation from "@dxos/app-toolkit/LayoutOperation";
|
|
19
25
|
import { HiddenAnnotation } from "@dxos/echo/Annotation";
|
|
26
|
+
import * as SpaceCapabilities from "@dxos/plugin-space/SpaceCapabilities";
|
|
20
27
|
import { useClient } from "@dxos/react-client";
|
|
21
28
|
//#region src/capabilities/DebugSurfaces.tsx
|
|
22
29
|
/** Returns `onOpen` and `canOpen` for the ObjectsTree "Open" action. */
|
|
23
30
|
var useObjectOpenAction = (invokePromise) => {
|
|
24
31
|
const client = useClient();
|
|
25
|
-
const showHidden = useAtomCapability(SpaceCapabilities.
|
|
32
|
+
const showHidden = useAtomCapability(SpaceCapabilities.SettingsAtom)?.showHidden ?? false;
|
|
26
33
|
const allTypes = useAtomValue(useMemo(() => client.graph.registry.query(Filter.type(Type.Type)).atom, [client]));
|
|
27
34
|
const hiddenTypenames = useMemo(() => {
|
|
28
35
|
const result = /* @__PURE__ */ new Set();
|
|
@@ -107,13 +114,12 @@ var LoggerSurface = () => /* @__PURE__ */ jsx(Logger.Root, { children: /* @__PUR
|
|
|
107
114
|
] }) });
|
|
108
115
|
//#endregion
|
|
109
116
|
//#region src/capabilities/react-surface.ts
|
|
110
|
-
var isSpaceDebug = (data) => typeof data === "object" && data !== null && "type" in data && data.type ===
|
|
117
|
+
var isSpaceDebug = (data) => typeof data === "object" && data !== null && "type" in data && data.type === SpaceType && "space" in data && isSpace(data.space);
|
|
111
118
|
var react_surface_default = Capability.makeModule(Effect.fnUntraced(function* ({ logStore }) {
|
|
112
|
-
const
|
|
113
|
-
const
|
|
114
|
-
const
|
|
115
|
-
|
|
116
|
-
return Capability.contributes(Capabilities.ReactSurface, [
|
|
119
|
+
const registry = yield* Capabilities.AtomRegistry;
|
|
120
|
+
const settingsAtom = yield* DebugCapabilities.Settings;
|
|
121
|
+
const fileUploader = (yield* Capability.getAll(AppCapabilities.FileUploader))[0];
|
|
122
|
+
return Capability.contribute(Capabilities.ReactSurface, [
|
|
117
123
|
Surface.create({
|
|
118
124
|
id: "pluginSettings",
|
|
119
125
|
filter: AppSurface.settings(AppSurface.Article, meta.profile.key),
|
|
@@ -182,7 +188,7 @@ var react_surface_default = Capability.makeModule(Effect.fnUntraced(function* ({
|
|
|
182
188
|
}),
|
|
183
189
|
Surface.create({
|
|
184
190
|
id: "statsPanel",
|
|
185
|
-
filter: Surface.makeFilter(
|
|
191
|
+
filter: Surface.makeFilter(Stats),
|
|
186
192
|
component: StatsPanel
|
|
187
193
|
})
|
|
188
194
|
]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chunk-react-surface.mjs","names":[],"sources":["../../src/capabilities/DebugSurfaces.tsx","../../src/capabilities/react-surface.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\n// Surface components that cannot be expressed as a `props` mapper, because they call hooks or compose.\n\nimport { useAtomValue } from '@effect-atom/atom-react';\nimport * as Option from 'effect/Option';\nimport React, { useCallback, useMemo } from 'react';\n\nimport { useAtomCapability, useOperationInvoker, useSettingsState } from '@dxos/app-framework/ui';\nimport { AppAnnotation, type AppCapabilities, GraphPath, LayoutOperation } from '@dxos/app-toolkit';\nimport { useActiveSpace } from '@dxos/app-toolkit/ui';\nimport { Annotation, Collection, Entity, Filter, Obj, Type } from '@dxos/echo';\nimport { HiddenAnnotation } from '@dxos/echo/Annotation';\nimport { type IdbLogStore } from '@dxos/log-store-idb';\nimport { SpaceCapabilities, SpaceOperation } from '@dxos/plugin-space';\nimport { useClient } from '@dxos/react-client';\nimport { type Space, SpaceState } from '@dxos/react-client/echo';\nimport { Panel } from '@dxos/react-ui';\nimport { Logger } from '@dxos/react-ui-debug';\n\nimport { DebugObjectPanel, DebugSettings, DebugSpaceObjectsPanel, SpaceGenerator } from '#containers';\nimport { type Settings } from '#types';\n\n/** Returns `onOpen` and `canOpen` for the ObjectsTree \"Open\" action. */\nconst useObjectOpenAction = (invokePromise: ReturnType<typeof useOperationInvoker>['invokePromise']) => {\n const client = useClient();\n const spaceSettings = useAtomCapability(SpaceCapabilities.Settings);\n const showHidden = spaceSettings?.showHidden ?? false;\n\n const allTypes = useAtomValue(useMemo(() => client.graph.registry.query(Filter.type(Type.Type)).atom, [client]));\n\n const hiddenTypenames = useMemo(() => {\n const result = new Set<string>();\n for (const typeEntity of allTypes) {\n const schema = Type.getSchema(typeEntity);\n if (HiddenAnnotation.get(schema).pipe(Option.getOrElse(() => false))) {\n result.add(Type.getTypename(typeEntity));\n }\n }\n return result;\n }, [allTypes]);\n\n const onOpen = useCallback(\n (object: Obj.Unknown) => {\n void invokePromise(LayoutOperation.Open, { subject: [GraphPath.getObjectPathFromObject(object)] });\n },\n [invokePromise],\n );\n\n const canOpen = useCallback(\n (entity: Entity.Snapshot) => {\n if (showHidden) {\n return true;\n }\n const typename = Entity.getTypename(entity);\n return !hiddenTypenames.has(typename ?? '');\n },\n [showHidden, hiddenTypenames],\n );\n\n return { onOpen, canOpen };\n};\n\nexport type DebugSettingsSurfaceProps = {\n subject: AppCapabilities.Settings;\n logStore?: IdbLogStore;\n onUpload?: AppCapabilities.FileUploader;\n};\n\nexport const DebugSettingsSurface = ({ subject, logStore, onUpload }: DebugSettingsSurfaceProps) => {\n const { settings, updateSettings } = useSettingsState<Settings.Settings>(subject.atom);\n\n return (\n <DebugSettings settings={settings} onSettingsChange={updateSettings} logStore={logStore} onUpload={onUpload} />\n );\n};\n\nexport type SpaceGeneratorSurfaceProps = {\n role: string;\n space: Space;\n};\n\n/** Generated objects are added to the space's root collection, resolved at invocation time. */\nexport const SpaceGeneratorSurface = ({ role, space }: SpaceGeneratorSurfaceProps) => {\n const { invokePromise } = useOperationInvoker();\n const handleCreateObjects = useCallback(\n (objects: Obj.Unknown[]) => {\n const collection =\n space.state.get() === SpaceState.SPACE_READY &&\n Annotation.get(space.properties, AppAnnotation.RootCollectionAnnotation).pipe(Option.getOrUndefined)?.target;\n if (!Obj.instanceOf(Collection.Collection, collection)) {\n return;\n }\n\n objects.forEach((object) => {\n void invokePromise(SpaceOperation.AddObject, { target: collection, object });\n });\n },\n [space, invokePromise],\n );\n\n return <SpaceGenerator role={role} space={space} onCreateObjects={handleCreateObjects} />;\n};\n\nexport type ObjectDebugSurfaceProps = {\n role: string;\n companionTo: Obj.Unknown;\n};\n\nexport const ObjectDebugSurface = ({ role, companionTo }: ObjectDebugSurfaceProps) => {\n const { invokePromise } = useOperationInvoker();\n const { onOpen, canOpen } = useObjectOpenAction(invokePromise);\n\n return <DebugObjectPanel role={role} companionTo={companionTo} onOpen={onOpen} canOpen={canOpen} />;\n};\n\nexport const SpaceObjectsSurface = () => {\n const space = useActiveSpace();\n const { invokePromise } = useOperationInvoker();\n const { onOpen, canOpen } = useObjectOpenAction(invokePromise);\n if (!space) {\n return null;\n }\n\n return <DebugSpaceObjectsPanel space={space} onOpen={onOpen} canOpen={canOpen} />;\n};\n\nexport const LoggerSurface = () => (\n <Logger.Root>\n <Panel.Root>\n <Panel.Toolbar asChild>\n <Logger.Toolbar />\n </Panel.Toolbar>\n <Panel.Content asChild>\n <Logger.Content>\n <Logger.List />\n </Logger.Content>\n </Panel.Content>\n <Panel.Statusbar asChild>\n <Logger.Filter />\n </Panel.Statusbar>\n </Panel.Root>\n </Logger.Root>\n);\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\n\nimport { Capabilities, Capability } from '@dxos/app-framework';\nimport { Surface } from '@dxos/app-framework/ui';\nimport { AppCapabilities } from '@dxos/app-toolkit';\nimport { AppSurface } from '@dxos/app-toolkit/ui';\nimport { Obj } from '@dxos/echo';\nimport { type IdbLogStore } from '@dxos/log-store-idb';\nimport { type Space, isSpace } from '@dxos/react-client/echo';\nimport { Position } from '@dxos/util';\n\nimport { DebugStatus, LogStatus, StatsPanel, Wireframe } from '#containers';\nimport { meta } from '#meta';\nimport { DebugCapabilities, DebugNodes, DebugSurface } from '#types';\n\nimport {\n DebugSettingsSurface,\n LoggerSurface,\n ObjectDebugSurface,\n SpaceGeneratorSurface,\n SpaceObjectsSurface,\n} from './DebugSurfaces';\n\ntype SpaceDebug = {\n type: string;\n space: Space;\n};\n\nconst isSpaceDebug = (data: unknown): data is SpaceDebug =>\n typeof data === 'object' &&\n data !== null &&\n 'type' in data &&\n data.type === DebugNodes.SpaceType &&\n 'space' in data &&\n isSpace(data.space);\n\ntype ReactSurfaceOptions = {\n logStore?: IdbLogStore;\n};\n\nexport default Capability.makeModule(\n Effect.fnUntraced(function* ({ logStore }: ReactSurfaceOptions) {\n const capabilities = yield* Capability.Service;\n const registry = capabilities.get(Capabilities.AtomRegistry);\n const settingsAtom = capabilities.get(DebugCapabilities.Settings);\n const fileUploader = capabilities.getAll(AppCapabilities.FileUploader)[0];\n\n return Capability.contributes(Capabilities.ReactSurface, [\n Surface.create({\n id: 'pluginSettings',\n filter: AppSurface.settings(AppSurface.Article, meta.profile.key),\n component: DebugSettingsSurface,\n props: ({ data: { subject } }) => ({ subject, logStore, onUpload: fileUploader }),\n }),\n Surface.create({\n id: 'space',\n filter: AppSurface.subject(AppSurface.Article, isSpaceDebug),\n component: SpaceGeneratorSurface,\n props: ({ role, data: { subject } }) => ({ role, space: subject.space }),\n }),\n Surface.create({\n id: 'wireframe',\n // TODO(wittjosiah): Split into multiple surfaces if this filter proves too strict for non-article roles.\n filter: AppSurface.oneOf(\n AppSurface.subject(AppSurface.Article, (value): value is Obj.Unknown => {\n const settings = registry.get(settingsAtom);\n return Obj.isObject(value) && !!settings.wireframe;\n }),\n AppSurface.subject(AppSurface.Section, (value): value is Obj.Unknown => {\n const settings = registry.get(settingsAtom);\n return Obj.isObject(value) && !!settings.wireframe;\n }),\n ),\n position: Position.first,\n component: Wireframe,\n props: ({ role, name, data: { subject } }) => ({\n label: `${role}:${name}`,\n object: subject,\n classNames: 'row-span-2 overflow-hidden',\n }),\n }),\n Surface.create({\n id: 'objectDebug',\n filter: AppSurface.allOf(\n AppSurface.literal(AppSurface.Article, 'debug'),\n AppSurface.companion(AppSurface.Article),\n ),\n component: ObjectDebugSurface,\n props: ({ role, data: { companionTo } }) => ({ role, companionTo }),\n }),\n Surface.create({\n id: 'spaceObjects',\n filter: Surface.makeFilter(AppSurface.deckCompanion('spaceObjects')),\n component: SpaceObjectsSurface,\n }),\n Surface.create({\n id: 'debugStatus',\n filter: Surface.makeFilter(AppSurface.StatusIndicator),\n position: Position.first,\n component: DebugStatus,\n }),\n Surface.create({\n id: 'logs',\n filter: Surface.makeFilter(AppSurface.deckCompanion('logs')),\n component: LoggerSurface,\n }),\n Surface.create({\n id: 'logStatus',\n filter: Surface.makeFilter(AppSurface.StatusIndicator),\n component: LogStatus,\n }),\n Surface.create({\n id: 'statsPanel',\n filter: Surface.makeFilter(DebugSurface.Stats),\n component: StatsPanel,\n }),\n ]);\n }),\n);\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AA0BA,IAAM,uBAAuB,kBAA2E;CACtG,MAAM,SAAS,UAAU;CAEzB,MAAM,aADgB,kBAAkB,kBAAkB,QACvC,CAAA,EAAe,cAAc;CAEhD,MAAM,WAAW,aAAa,cAAc,OAAO,MAAM,SAAS,MAAM,OAAO,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;CAE/G,MAAM,kBAAkB,cAAc;EACpC,MAAM,yBAAS,IAAI,IAAY;EAC/B,KAAK,MAAM,cAAc,UAAU;GACjC,MAAM,SAAS,KAAK,UAAU,UAAU;GACxC,IAAI,iBAAiB,IAAI,MAAM,CAAC,CAAC,KAAK,OAAO,gBAAgB,KAAK,CAAC,GACjE,OAAO,IAAI,KAAK,YAAY,UAAU,CAAC;EAE3C;EACA,OAAO;CACT,GAAG,CAAC,QAAQ,CAAC;CAoBb,OAAO;EAAE,QAlBM,aACZ,WAAwB;GACvB,cAAmB,gBAAgB,MAAM,EAAE,SAAS,CAAC,UAAU,wBAAwB,MAAM,CAAC,EAAE,CAAC;EACnG,GACA,CAAC,aAAa,CAcP;EAAQ,SAXD,aACb,WAA4B;GAC3B,IAAI,YACF,OAAO;GAET,MAAM,WAAW,OAAO,YAAY,MAAM;GAC1C,OAAO,CAAC,gBAAgB,IAAI,YAAY,EAAE;EAC5C,GACA,CAAC,YAAY,eAAe,CAGb;CAAQ;AAC3B;AAQA,IAAa,wBAAwB,EAAE,SAAS,UAAU,eAA0C;CAClG,MAAM,EAAE,UAAU,mBAAmB,iBAAoC,QAAQ,IAAI;CAErF,OACE,oBAAC,eAAD;EAAyB;EAAU,kBAAkB;EAA0B;EAAoB;CAAW,CAAA;AAElH;;AAQA,IAAa,yBAAyB,EAAE,MAAM,YAAwC;CACpF,MAAM,EAAE,kBAAkB,oBAAoB;CAiB9C,OAAO,oBAAC,gBAAD;EAAsB;EAAa;EAAO,iBAhBrB,aACzB,YAA2B;GAC1B,MAAM,aACJ,MAAM,MAAM,IAAI,MAAM,WAAW,eACjC,WAAW,IAAI,MAAM,YAAY,cAAc,wBAAwB,CAAC,CAAC,KAAK,OAAO,cAAc,CAAC,EAAE;GACxG,IAAI,CAAC,IAAI,WAAW,WAAW,YAAY,UAAU,GACnD;GAGF,QAAQ,SAAS,WAAW;IAC1B,cAAmB,eAAe,WAAW;KAAE,QAAQ;KAAY;IAAO,CAAC;GAC7E,CAAC;EACH,GACA,CAAC,OAAO,aAAa,CAG2C;CAAsB,CAAA;AAC1F;AAOA,IAAa,sBAAsB,EAAE,MAAM,kBAA2C;CACpF,MAAM,EAAE,kBAAkB,oBAAoB;CAC9C,MAAM,EAAE,QAAQ,YAAY,oBAAoB,aAAa;CAE7D,OAAO,oBAAC,kBAAD;EAAwB;EAAmB;EAAqB;EAAiB;CAAU,CAAA;AACpG;AAEA,IAAa,4BAA4B;CACvC,MAAM,QAAQ,eAAe;CAC7B,MAAM,EAAE,kBAAkB,oBAAoB;CAC9C,MAAM,EAAE,QAAQ,YAAY,oBAAoB,aAAa;CAC7D,IAAI,CAAC,OACH,OAAO;CAGT,OAAO,oBAAC,wBAAD;EAA+B;EAAe;EAAiB;CAAU,CAAA;AAClF;AAEA,IAAa,sBACX,oBAAC,OAAO,MAAR,EAAA,UACE,qBAAC,MAAM,MAAP,EAAA,UAAA;CACE,oBAAC,MAAM,SAAP;EAAe,SAAA;YACb,oBAAC,OAAO,SAAR,CAAiB,CAAA;CACJ,CAAA;CACf,oBAAC,MAAM,SAAP;EAAe,SAAA;YACb,oBAAC,OAAO,SAAR,EAAA,UACE,oBAAC,OAAO,MAAR,CAAc,CAAA,EACA,CAAA;CACH,CAAA;CACf,oBAAC,MAAM,WAAP;EAAiB,SAAA;YACf,oBAAC,OAAO,QAAR,CAAgB,CAAA;CACD,CAAA;AACP,EAAA,CAAA,EACD,CAAA;;;AChHf,IAAM,gBAAgB,SACpB,OAAO,SAAS,YAChB,SAAS,QACT,UAAU,QACV,KAAK,SAAS,WAAW,aACzB,WAAW,QACX,QAAQ,KAAK,KAAK;AAMpB,IAAA,wBAAe,WAAW,WACxB,OAAO,WAAW,WAAW,EAAE,YAAiC;CAC9D,MAAM,eAAe,OAAO,WAAW;CACvC,MAAM,WAAW,aAAa,IAAI,aAAa,YAAY;CAC3D,MAAM,eAAe,aAAa,IAAI,kBAAkB,QAAQ;CAChE,MAAM,eAAe,aAAa,OAAO,gBAAgB,YAAY,CAAC,CAAC;CAEvE,OAAO,WAAW,YAAY,aAAa,cAAc;EACvD,QAAQ,OAAO;GACb,IAAI;GACJ,QAAQ,WAAW,SAAS,WAAW,SAAS,KAAK,QAAQ,GAAG;GAChE,WAAW;GACX,QAAQ,EAAE,MAAM,EAAE,iBAAiB;IAAE;IAAS;IAAU,UAAU;GAAa;EACjF,CAAC;EACD,QAAQ,OAAO;GACb,IAAI;GACJ,QAAQ,WAAW,QAAQ,WAAW,SAAS,YAAY;GAC3D,WAAW;GACX,QAAQ,EAAE,MAAM,MAAM,EAAE,iBAAiB;IAAE;IAAM,OAAO,QAAQ;GAAM;EACxE,CAAC;EACD,QAAQ,OAAO;GACb,IAAI;GAEJ,QAAQ,WAAW,MACjB,WAAW,QAAQ,WAAW,UAAU,UAAgC;IACtE,MAAM,WAAW,SAAS,IAAI,YAAY;IAC1C,OAAO,IAAI,SAAS,KAAK,KAAK,CAAC,CAAC,SAAS;GAC3C,CAAC,GACD,WAAW,QAAQ,WAAW,UAAU,UAAgC;IACtE,MAAM,WAAW,SAAS,IAAI,YAAY;IAC1C,OAAO,IAAI,SAAS,KAAK,KAAK,CAAC,CAAC,SAAS;GAC3C,CAAC,CACH;GACA,UAAU,SAAS;GACnB,WAAW;GACX,QAAQ,EAAE,MAAM,MAAM,MAAM,EAAE,iBAAiB;IAC7C,OAAO,GAAG,KAAK,GAAG;IAClB,QAAQ;IACR,YAAY;GACd;EACF,CAAC;EACD,QAAQ,OAAO;GACb,IAAI;GACJ,QAAQ,WAAW,MACjB,WAAW,QAAQ,WAAW,SAAS,OAAO,GAC9C,WAAW,UAAU,WAAW,OAAO,CACzC;GACA,WAAW;GACX,QAAQ,EAAE,MAAM,MAAM,EAAE,qBAAqB;IAAE;IAAM;GAAY;EACnE,CAAC;EACD,QAAQ,OAAO;GACb,IAAI;GACJ,QAAQ,QAAQ,WAAW,WAAW,cAAc,cAAc,CAAC;GACnE,WAAW;EACb,CAAC;EACD,QAAQ,OAAO;GACb,IAAI;GACJ,QAAQ,QAAQ,WAAW,WAAW,eAAe;GACrD,UAAU,SAAS;GACnB,WAAW;EACb,CAAC;EACD,QAAQ,OAAO;GACb,IAAI;GACJ,QAAQ,QAAQ,WAAW,WAAW,cAAc,MAAM,CAAC;GAC3D,WAAW;EACb,CAAC;EACD,QAAQ,OAAO;GACb,IAAI;GACJ,QAAQ,QAAQ,WAAW,WAAW,eAAe;GACrD,WAAW;EACb,CAAC;EACD,QAAQ,OAAO;GACb,IAAI;GACJ,QAAQ,QAAQ,WAAW,aAAa,KAAK;GAC7C,WAAW;EACb,CAAC;CACH,CAAC;AACH,CAAC,CACH"}
|
|
1
|
+
{"version":3,"file":"chunk-react-surface.mjs","names":[],"sources":["../../src/capabilities/DebugSurfaces.tsx","../../src/capabilities/react-surface.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\n// Surface components that cannot be expressed as a `props` mapper, because they call hooks or compose.\n\nimport { useAtomValue } from '@effect-atom/atom-react';\nimport * as Option from 'effect/Option';\nimport React, { useCallback, useMemo } from 'react';\n\nimport { useAtomCapability, useOperationInvoker, useSettingsState } from '@dxos/app-framework/ui';\nimport * as AppAnnotation from '@dxos/app-toolkit/AppAnnotation';\nimport type * as AppCapabilities from '@dxos/app-toolkit/AppCapabilities';\nimport * as GraphPath from '@dxos/app-toolkit/GraphPath';\nimport * as LayoutOperation from '@dxos/app-toolkit/LayoutOperation';\nimport { useActiveSpace } from '@dxos/app-toolkit/ui';\nimport { Annotation, Collection, Entity, Filter, Obj, Type } from '@dxos/echo';\nimport { HiddenAnnotation } from '@dxos/echo/Annotation';\nimport { type IdbLogStore } from '@dxos/log-store-idb';\nimport { SpaceOperation } from '@dxos/plugin-space';\nimport * as SpaceCapabilities from '@dxos/plugin-space/SpaceCapabilities';\nimport { useClient } from '@dxos/react-client';\nimport { type Space, SpaceState } from '@dxos/react-client/echo';\nimport { Panel } from '@dxos/react-ui';\nimport { Logger } from '@dxos/react-ui-debug';\n\nimport { DebugObjectPanel, DebugSettings, DebugSpaceObjectsPanel, SpaceGenerator } from '#containers';\n\nimport * as Settings from '../types/Settings';\n\n/** Returns `onOpen` and `canOpen` for the ObjectsTree \"Open\" action. */\nconst useObjectOpenAction = (invokePromise: ReturnType<typeof useOperationInvoker>['invokePromise']) => {\n const client = useClient();\n const spaceSettings = useAtomCapability(SpaceCapabilities.SettingsAtom);\n const showHidden = spaceSettings?.showHidden ?? false;\n\n const allTypes = useAtomValue(useMemo(() => client.graph.registry.query(Filter.type(Type.Type)).atom, [client]));\n\n const hiddenTypenames = useMemo(() => {\n const result = new Set<string>();\n for (const typeEntity of allTypes) {\n const schema = Type.getSchema(typeEntity);\n if (HiddenAnnotation.get(schema).pipe(Option.getOrElse(() => false))) {\n result.add(Type.getTypename(typeEntity));\n }\n }\n return result;\n }, [allTypes]);\n\n const onOpen = useCallback(\n (object: Obj.Unknown) => {\n void invokePromise(LayoutOperation.Open, { subject: [GraphPath.getObjectPathFromObject(object)] });\n },\n [invokePromise],\n );\n\n const canOpen = useCallback(\n (entity: Entity.Snapshot) => {\n if (showHidden) {\n return true;\n }\n const typename = Entity.getTypename(entity);\n return !hiddenTypenames.has(typename ?? '');\n },\n [showHidden, hiddenTypenames],\n );\n\n return { onOpen, canOpen };\n};\n\nexport type DebugSettingsSurfaceProps = {\n subject: AppCapabilities.Settings;\n logStore?: IdbLogStore;\n onUpload?: AppCapabilities.FileUploader;\n};\n\nexport const DebugSettingsSurface = ({ subject, logStore, onUpload }: DebugSettingsSurfaceProps) => {\n const { settings, updateSettings } = useSettingsState<Settings.Settings>(subject.atom);\n\n return (\n <DebugSettings settings={settings} onSettingsChange={updateSettings} logStore={logStore} onUpload={onUpload} />\n );\n};\n\nexport type SpaceGeneratorSurfaceProps = {\n role: string;\n space: Space;\n};\n\n/** Generated objects are added to the space's root collection, resolved at invocation time. */\nexport const SpaceGeneratorSurface = ({ role, space }: SpaceGeneratorSurfaceProps) => {\n const { invokePromise } = useOperationInvoker();\n const handleCreateObjects = useCallback(\n (objects: Obj.Unknown[]) => {\n const collection =\n space.state.get() === SpaceState.SPACE_READY &&\n Annotation.get(space.properties, AppAnnotation.RootCollectionAnnotation).pipe(Option.getOrUndefined)?.target;\n if (!Obj.instanceOf(Collection.Collection, collection)) {\n return;\n }\n\n objects.forEach((object) => {\n void invokePromise(SpaceOperation.AddObject, { target: collection, object });\n });\n },\n [space, invokePromise],\n );\n\n return <SpaceGenerator role={role} space={space} onCreateObjects={handleCreateObjects} />;\n};\n\nexport type ObjectDebugSurfaceProps = {\n role: string;\n companionTo: Obj.Unknown;\n};\n\nexport const ObjectDebugSurface = ({ role, companionTo }: ObjectDebugSurfaceProps) => {\n const { invokePromise } = useOperationInvoker();\n const { onOpen, canOpen } = useObjectOpenAction(invokePromise);\n\n return <DebugObjectPanel role={role} companionTo={companionTo} onOpen={onOpen} canOpen={canOpen} />;\n};\n\nexport const SpaceObjectsSurface = () => {\n const space = useActiveSpace();\n const { invokePromise } = useOperationInvoker();\n const { onOpen, canOpen } = useObjectOpenAction(invokePromise);\n if (!space) {\n return null;\n }\n\n return <DebugSpaceObjectsPanel space={space} onOpen={onOpen} canOpen={canOpen} />;\n};\n\nexport const LoggerSurface = () => (\n <Logger.Root>\n <Panel.Root>\n <Panel.Toolbar asChild>\n <Logger.Toolbar />\n </Panel.Toolbar>\n <Panel.Content asChild>\n <Logger.Content>\n <Logger.List />\n </Logger.Content>\n </Panel.Content>\n <Panel.Statusbar asChild>\n <Logger.Filter />\n </Panel.Statusbar>\n </Panel.Root>\n </Logger.Root>\n);\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\n\nimport * as Capabilities from '@dxos/app-framework/Capabilities';\nimport * as Capability from '@dxos/app-framework/Capability';\nimport { Surface } from '@dxos/app-framework/ui';\nimport * as AppCapabilities from '@dxos/app-toolkit/AppCapabilities';\nimport { AppSurface } from '@dxos/app-toolkit/ui';\nimport { Obj } from '@dxos/echo';\nimport { type IdbLogStore } from '@dxos/log-store-idb';\nimport { type Space, isSpace } from '@dxos/react-client/echo';\nimport { Position } from '@dxos/util';\n\nimport { DebugStatus, LogStatus, StatsPanel, Wireframe } from '#containers';\nimport { meta } from '#meta';\n\nimport { DebugCapabilities } from '../types/Debug';\nimport * as DebugNodes from '../types/DebugNodes';\nimport * as DebugSurface from '../types/DebugSurface';\nimport {\n DebugSettingsSurface,\n LoggerSurface,\n ObjectDebugSurface,\n SpaceGeneratorSurface,\n SpaceObjectsSurface,\n} from './DebugSurfaces';\n\ntype SpaceDebug = {\n type: string;\n space: Space;\n};\n\nconst isSpaceDebug = (data: unknown): data is SpaceDebug =>\n typeof data === 'object' &&\n data !== null &&\n 'type' in data &&\n data.type === DebugNodes.SpaceType &&\n 'space' in data &&\n isSpace(data.space);\n\ntype ReactSurfaceOptions = {\n logStore?: IdbLogStore;\n};\n\nexport default Capability.makeModule(\n Effect.fnUntraced(function* ({ logStore }: ReactSurfaceOptions) {\n const registry = yield* Capabilities.AtomRegistry;\n const settingsAtom = yield* DebugCapabilities.Settings;\n const fileUploader = (yield* Capability.getAll(AppCapabilities.FileUploader))[0];\n\n return Capability.contribute(Capabilities.ReactSurface, [\n Surface.create({\n id: 'pluginSettings',\n filter: AppSurface.settings(AppSurface.Article, meta.profile.key),\n component: DebugSettingsSurface,\n props: ({ data: { subject } }) => ({ subject, logStore, onUpload: fileUploader }),\n }),\n Surface.create({\n id: 'space',\n filter: AppSurface.subject(AppSurface.Article, isSpaceDebug),\n component: SpaceGeneratorSurface,\n props: ({ role, data: { subject } }) => ({ role, space: subject.space }),\n }),\n Surface.create({\n id: 'wireframe',\n // TODO(wittjosiah): Split into multiple surfaces if this filter proves too strict for non-article roles.\n filter: AppSurface.oneOf(\n AppSurface.subject(AppSurface.Article, (value): value is Obj.Unknown => {\n const settings = registry.get(settingsAtom);\n return Obj.isObject(value) && !!settings.wireframe;\n }),\n AppSurface.subject(AppSurface.Section, (value): value is Obj.Unknown => {\n const settings = registry.get(settingsAtom);\n return Obj.isObject(value) && !!settings.wireframe;\n }),\n ),\n position: Position.first,\n component: Wireframe,\n props: ({ role, name, data: { subject } }) => ({\n label: `${role}:${name}`,\n object: subject,\n classNames: 'row-span-2 overflow-hidden',\n }),\n }),\n Surface.create({\n id: 'objectDebug',\n filter: AppSurface.allOf(\n AppSurface.literal(AppSurface.Article, 'debug'),\n AppSurface.companion(AppSurface.Article),\n ),\n component: ObjectDebugSurface,\n props: ({ role, data: { companionTo } }) => ({ role, companionTo }),\n }),\n Surface.create({\n id: 'spaceObjects',\n filter: Surface.makeFilter(AppSurface.deckCompanion('spaceObjects')),\n component: SpaceObjectsSurface,\n }),\n Surface.create({\n id: 'debugStatus',\n filter: Surface.makeFilter(AppSurface.StatusIndicator),\n position: Position.first,\n component: DebugStatus,\n }),\n Surface.create({\n id: 'logs',\n filter: Surface.makeFilter(AppSurface.deckCompanion('logs')),\n component: LoggerSurface,\n }),\n Surface.create({\n id: 'logStatus',\n filter: Surface.makeFilter(AppSurface.StatusIndicator),\n component: LogStatus,\n }),\n Surface.create({\n id: 'statsPanel',\n filter: Surface.makeFilter(DebugSurface.Stats),\n component: StatsPanel,\n }),\n ]);\n }),\n);\n"],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
//#region \0rolldown/runtime.js
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __exportAll = (all, no_symbols) => {
|
|
4
|
+
let target = {};
|
|
5
|
+
for (var name in all) __defProp(target, name, {
|
|
6
|
+
get: all[name],
|
|
7
|
+
enumerable: true
|
|
8
|
+
});
|
|
9
|
+
if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
|
|
10
|
+
return target;
|
|
11
|
+
};
|
|
12
|
+
//#endregion
|
|
13
|
+
export { __exportAll as t };
|
|
@@ -1,19 +1,20 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { DebugCapabilities } from "./Debug.mjs";
|
|
2
|
+
import { Settings } from "./Settings.mjs";
|
|
3
|
+
import * as Capability from "@dxos/app-framework/Capability";
|
|
2
4
|
import { meta } from "#meta";
|
|
3
|
-
import
|
|
5
|
+
import * as AppCapabilities from "@dxos/app-toolkit/AppCapabilities";
|
|
4
6
|
import * as Effect from "effect/Effect";
|
|
5
|
-
import { DebugCapabilities, Settings } from "#types";
|
|
6
7
|
import { createKvsStore } from "@dxos/effect";
|
|
7
8
|
//#region src/capabilities/settings.ts
|
|
8
9
|
var settings_default = Capability.makeModule(() => Effect.sync(() => {
|
|
9
10
|
const settingsAtom = createKvsStore({
|
|
10
11
|
key: meta.profile.key,
|
|
11
|
-
schema: Settings
|
|
12
|
+
schema: Settings,
|
|
12
13
|
defaultValue: () => ({})
|
|
13
14
|
});
|
|
14
|
-
return [Capability.
|
|
15
|
+
return [Capability.contribute(DebugCapabilities.Settings, settingsAtom), Capability.contribute(AppCapabilities.Settings, {
|
|
15
16
|
prefix: meta.profile.key,
|
|
16
|
-
schema: Settings
|
|
17
|
+
schema: Settings,
|
|
17
18
|
atom: settingsAtom
|
|
18
19
|
})];
|
|
19
20
|
}));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chunk-settings.mjs","names":[],"sources":["../../src/capabilities/settings.ts"],"sourcesContent":["//\n// Copyright 2025 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\n\nimport
|
|
1
|
+
{"version":3,"file":"chunk-settings.mjs","names":[],"sources":["../../src/capabilities/settings.ts"],"sourcesContent":["//\n// Copyright 2025 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\n\nimport * as Capability from '@dxos/app-framework/Capability';\nimport * as AppCapabilities from '@dxos/app-toolkit/AppCapabilities';\nimport { createKvsStore } from '@dxos/effect';\n\nimport { meta } from '#meta';\n\nimport * as Debug from '../types/Debug';\nimport * as Settings from '../types/Settings';\n\nexport default Capability.makeModule(() =>\n Effect.sync(() => {\n const settingsAtom = createKvsStore({\n key: meta.profile.key,\n schema: Settings.Settings,\n defaultValue: () => ({}),\n });\n\n return [\n Capability.contribute(Debug.DebugCapabilities.Settings, settingsAtom),\n Capability.contribute(AppCapabilities.Settings, {\n prefix: meta.profile.key,\n schema: Settings.Settings,\n atom: settingsAtom,\n }),\n ];\n }),\n);\n"],"mappings":";;;;;;;;AAeA,IAAA,mBAAe,WAAW,iBACxB,OAAO,WAAW;CAChB,MAAM,eAAe,eAAe;EAClC,KAAK,KAAK,QAAQ;EAClB,QAAQ;EACR,qBAAqB,CAAC;CACxB,CAAC;CAED,OAAO,CACL,WAAW,WAAA,kBAAmC,UAAU,YAAY,GACpE,WAAW,WAAW,gBAAgB,UAAU;EAC9C,QAAQ,KAAK,QAAQ;EACrB,QAAQ;EACR,MAAM;CACR,CAAC,CACH;AACF,CAAC,CACH"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as Capability from "@dxos/app-framework/Capability";
|
|
2
2
|
import { meta } from "#meta";
|
|
3
|
-
import
|
|
3
|
+
import * as Capabilities from "@dxos/app-framework/Capabilities";
|
|
4
|
+
import * as AppCapabilities from "@dxos/app-toolkit/AppCapabilities";
|
|
4
5
|
import * as Effect from "effect/Effect";
|
|
5
6
|
import { Atom } from "@effect-atom/atom";
|
|
6
7
|
//#region src/capabilities/stats-panel.ts
|
|
@@ -13,7 +14,7 @@ var STORAGE_KEY = `${meta.profile.key}.statsPanel`;
|
|
|
13
14
|
* the store hydrates from and saves to localStorage so stats survive a reload.
|
|
14
15
|
*/
|
|
15
16
|
var stats_panel_default = Capability.makeModule(Effect.fnUntraced(function* ({ persist = true } = {}) {
|
|
16
|
-
const registry = yield*
|
|
17
|
+
const registry = yield* Capabilities.AtomRegistry;
|
|
17
18
|
const canPersist = persist && typeof localStorage !== "undefined";
|
|
18
19
|
const hydrate = () => {
|
|
19
20
|
if (!canPersist) return {};
|
|
@@ -31,7 +32,7 @@ var stats_panel_default = Capability.makeModule(Effect.fnUntraced(function* ({ p
|
|
|
31
32
|
localStorage.setItem(STORAGE_KEY, JSON.stringify(registry.get(statsAtom)));
|
|
32
33
|
} catch {}
|
|
33
34
|
};
|
|
34
|
-
return Capability.
|
|
35
|
+
return Capability.contribute(AppCapabilities.StatsPanel, {
|
|
35
36
|
statsAtom,
|
|
36
37
|
get: (pluginKey) => registry.get(statsAtom)[pluginKey],
|
|
37
38
|
compartment: (pluginKey) => ({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chunk-stats-panel.mjs","names":[],"sources":["../../src/capabilities/stats-panel.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\nimport { Atom } from '@effect-atom/atom';\nimport * as Effect from 'effect/Effect';\n\nimport
|
|
1
|
+
{"version":3,"file":"chunk-stats-panel.mjs","names":[],"sources":["../../src/capabilities/stats-panel.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\nimport { Atom } from '@effect-atom/atom';\nimport * as Effect from 'effect/Effect';\n\nimport * as Capabilities from '@dxos/app-framework/Capabilities';\nimport * as Capability from '@dxos/app-framework/Capability';\nimport * as AppCapabilities from '@dxos/app-toolkit/AppCapabilities';\n\nimport { meta } from '#meta';\n\ntype StatsPanelOptions = {\n /** Persist the store to localStorage (hydrate on load, save on write). */\n persist?: boolean;\n};\n\nconst STORAGE_KEY = `${meta.profile.key}.statsPanel`;\n\n/**\n * Contributes the {@link AppCapabilities.StatsPanel} store: a single reactive atom holding one\n * compartment per plugin, keyed by plugin key. Read access spans the whole store; writes are scoped\n * to a compartment via `compartment(pluginKey)`. Kept alive with `Atom.keepAlive` so a background\n * writer (e.g. a sync operation) can populate it before any surface subscribes. When `persist` is set\n * the store hydrates from and saves to localStorage so stats survive a reload.\n */\nexport default Capability.makeModule(\n Effect.fnUntraced(function* ({ persist = true }: StatsPanelOptions = {}) {\n const registry = yield* Capabilities.AtomRegistry;\n const canPersist = persist && typeof localStorage !== 'undefined';\n\n const hydrate = (): Record<string, unknown> => {\n if (!canPersist) {\n return {};\n }\n try {\n const raw = localStorage.getItem(STORAGE_KEY);\n return raw ? JSON.parse(raw) : {};\n } catch {\n // Best-effort: a malformed/unavailable value just starts empty.\n return {};\n }\n };\n\n const statsAtom = Atom.make<Record<string, unknown>>(hydrate()).pipe(Atom.keepAlive);\n\n const save = () => {\n if (!canPersist) {\n return;\n }\n try {\n localStorage.setItem(STORAGE_KEY, JSON.stringify(registry.get(statsAtom)));\n } catch {\n // Best-effort: localStorage may be disabled or over quota; the in-memory atom is authoritative.\n }\n };\n\n return Capability.contribute(AppCapabilities.StatsPanel, {\n statsAtom,\n get: (pluginKey) => registry.get(statsAtom)[pluginKey],\n compartment: (pluginKey) => ({\n set: (stats) => {\n registry.set(statsAtom, { ...registry.get(statsAtom), [pluginKey]: stats });\n save();\n },\n clear: () => {\n const { [pluginKey]: _removed, ...rest } = registry.get(statsAtom);\n registry.set(statsAtom, rest);\n save();\n },\n }),\n });\n }),\n);\n"],"mappings":";;;;;;;AAkBA,IAAM,cAAc,GAAG,KAAK,QAAQ,IAAI;;;;;;;;AASxC,IAAA,sBAAe,WAAW,WACxB,OAAO,WAAW,WAAW,EAAE,UAAU,SAA4B,CAAC,GAAG;CACvE,MAAM,WAAW,OAAO,aAAa;CACrC,MAAM,aAAa,WAAW,OAAO,iBAAiB;CAEtD,MAAM,gBAAyC;EAC7C,IAAI,CAAC,YACH,OAAO,CAAC;EAEV,IAAI;GACF,MAAM,MAAM,aAAa,QAAQ,WAAW;GAC5C,OAAO,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;EAClC,QAAQ;GAEN,OAAO,CAAC;EACV;CACF;CAEA,MAAM,YAAY,KAAK,KAA8B,QAAQ,CAAC,CAAC,CAAC,KAAK,KAAK,SAAS;CAEnF,MAAM,aAAa;EACjB,IAAI,CAAC,YACH;EAEF,IAAI;GACF,aAAa,QAAQ,aAAa,KAAK,UAAU,SAAS,IAAI,SAAS,CAAC,CAAC;EAC3E,QAAQ,CAER;CACF;CAEA,OAAO,WAAW,WAAW,gBAAgB,YAAY;EACvD;EACA,MAAM,cAAc,SAAS,IAAI,SAAS,CAAC,CAAC;EAC5C,cAAc,eAAe;GAC3B,MAAM,UAAU;IACd,SAAS,IAAI,WAAW;KAAE,GAAG,SAAS,IAAI,SAAS;MAAI,YAAY;IAAM,CAAC;IAC1E,KAAK;GACP;GACA,aAAa;IACX,MAAM,GAAG,YAAY,UAAU,GAAG,SAAS,SAAS,IAAI,SAAS;IACjE,SAAS,IAAI,WAAW,IAAI;IAC5B,KAAK;GACP;EACF;CACF,CAAC;AACH,CAAC,CACH"}
|