@dxos/plugin-search 0.8.4-main.9735255 → 0.8.4-main.9be5663bfe
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/README.md +0 -1
- package/dist/lib/browser/index.mjs +306 -52
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/types/src/SearchPlugin.d.ts.map +1 -1
- package/dist/types/src/capabilities/app-graph-builder.d.ts +6 -0
- package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -0
- package/dist/types/src/capabilities/index.d.ts +5 -3
- package/dist/types/src/capabilities/index.d.ts.map +1 -1
- package/dist/types/src/capabilities/operation-handler.d.ts +6 -0
- package/dist/types/src/capabilities/operation-handler.d.ts.map +1 -0
- package/dist/types/src/capabilities/react-surface.d.ts +5 -0
- package/dist/types/src/capabilities/react-surface.d.ts.map +1 -0
- package/dist/types/src/components/SearchResultStack/SearchResultStack.d.ts +9 -0
- package/dist/types/src/components/SearchResultStack/SearchResultStack.d.ts.map +1 -0
- package/dist/types/src/components/SearchResultStack/index.d.ts +2 -0
- package/dist/types/src/components/SearchResultStack/index.d.ts.map +1 -0
- package/dist/types/src/components/index.d.ts +1 -3
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/constants.d.ts +2 -0
- package/dist/types/src/constants.d.ts.map +1 -0
- package/dist/types/src/containers/SearchArticle/SearchArticle.d.ts +7 -0
- package/dist/types/src/containers/SearchArticle/SearchArticle.d.ts.map +1 -0
- package/dist/types/src/containers/SearchArticle/SearchArticle.stories.d.ts +15 -0
- package/dist/types/src/containers/SearchArticle/SearchArticle.stories.d.ts.map +1 -0
- package/dist/types/src/containers/SearchArticle/index.d.ts +2 -0
- package/dist/types/src/containers/SearchArticle/index.d.ts.map +1 -0
- package/dist/types/src/containers/SearchDialog/SearchDialog.d.ts +8 -0
- package/dist/types/src/containers/SearchDialog/SearchDialog.d.ts.map +1 -0
- package/dist/types/src/containers/SearchDialog/SearchDialog.stories.d.ts +17 -0
- package/dist/types/src/containers/SearchDialog/SearchDialog.stories.d.ts.map +1 -0
- package/dist/types/src/containers/SearchDialog/index.d.ts +3 -0
- package/dist/types/src/containers/SearchDialog/index.d.ts.map +1 -0
- package/dist/types/src/containers/index.d.ts +5 -0
- package/dist/types/src/containers/index.d.ts.map +1 -0
- package/dist/types/src/hooks/sync.d.ts +1 -1
- package/dist/types/src/hooks/sync.d.ts.map +1 -1
- package/dist/types/src/hooks/useGlobalSearch.d.ts +2 -2
- package/dist/types/src/hooks/useGlobalSearch.d.ts.map +1 -1
- package/dist/types/src/hooks/useWebSearch.d.ts +1 -1
- package/dist/types/src/hooks/useWebSearch.d.ts.map +1 -1
- package/dist/types/src/operations/definitions.d.ts +3 -0
- package/dist/types/src/operations/definitions.d.ts.map +1 -0
- package/dist/types/src/operations/index.d.ts +4 -0
- package/dist/types/src/operations/index.d.ts.map +1 -0
- package/dist/types/src/operations/open-search.d.ts +5 -0
- package/dist/types/src/operations/open-search.d.ts.map +1 -0
- package/dist/types/src/translations.d.ts +15 -9
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/types/index.d.ts +0 -1
- package/dist/types/src/types/index.d.ts.map +1 -1
- package/dist/types/src/types/search.d.ts +1 -16
- package/dist/types/src/types/search.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +53 -41
- package/src/SearchPlugin.tsx +11 -9
- package/src/capabilities/{app-graph-builder/app-graph-builder.ts → app-graph-builder.ts} +17 -21
- package/src/capabilities/index.ts +9 -3
- package/src/capabilities/operation-handler.ts +16 -0
- package/src/capabilities/react-surface.tsx +63 -0
- package/src/components/SearchResultStack/SearchResultStack.tsx +118 -0
- package/src/components/SearchResultStack/index.ts +5 -0
- package/src/components/index.ts +1 -3
- package/src/constants.ts +7 -0
- package/src/containers/SearchArticle/SearchArticle.stories.tsx +80 -0
- package/src/containers/SearchArticle/SearchArticle.tsx +63 -0
- package/src/containers/SearchArticle/index.ts +5 -0
- package/src/containers/SearchDialog/SearchDialog.stories.tsx +109 -0
- package/src/containers/SearchDialog/SearchDialog.tsx +100 -0
- package/src/containers/SearchDialog/index.ts +6 -0
- package/src/containers/index.ts +10 -0
- package/src/hooks/sync.test.ts +4 -4
- package/src/hooks/sync.ts +1 -1
- package/src/hooks/useGlobalSearch.tsx +3 -3
- package/src/hooks/useWebSearch.ts +2 -2
- package/src/meta.ts +2 -2
- package/src/operations/definitions.ts +17 -0
- package/src/operations/index.ts +9 -0
- package/src/operations/open-search.ts +24 -0
- package/src/search/exa.ts +2 -2
- package/src/translations.ts +10 -9
- package/src/types/index.ts +0 -1
- package/src/types/search.ts +1 -19
- package/dist/lib/browser/app-graph-builder-KZ3V2E5U.mjs +0 -81
- package/dist/lib/browser/app-graph-builder-KZ3V2E5U.mjs.map +0 -7
- package/dist/lib/browser/chunk-HRIWTRJV.mjs +0 -22
- package/dist/lib/browser/chunk-HRIWTRJV.mjs.map +0 -7
- package/dist/lib/browser/chunk-I7YWQSUZ.mjs +0 -26
- package/dist/lib/browser/chunk-I7YWQSUZ.mjs.map +0 -7
- package/dist/lib/browser/chunk-ZRJJXRGF.mjs +0 -282
- package/dist/lib/browser/chunk-ZRJJXRGF.mjs.map +0 -7
- package/dist/lib/browser/operation-resolver-6MBOKZQH.mjs +0 -25
- package/dist/lib/browser/operation-resolver-6MBOKZQH.mjs.map +0 -7
- package/dist/lib/browser/react-surface-RVLK6KJ5.mjs +0 -368
- package/dist/lib/browser/react-surface-RVLK6KJ5.mjs.map +0 -7
- package/dist/types/src/capabilities/app-graph-builder/app-graph-builder.d.ts +0 -6
- package/dist/types/src/capabilities/app-graph-builder/app-graph-builder.d.ts.map +0 -1
- package/dist/types/src/capabilities/app-graph-builder/index.d.ts +0 -3
- package/dist/types/src/capabilities/app-graph-builder/index.d.ts.map +0 -1
- package/dist/types/src/capabilities/operation-resolver/index.d.ts +0 -3
- package/dist/types/src/capabilities/operation-resolver/index.d.ts.map +0 -1
- package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts +0 -5
- package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts.map +0 -1
- package/dist/types/src/capabilities/react-surface/index.d.ts +0 -3
- package/dist/types/src/capabilities/react-surface/index.d.ts.map +0 -1
- package/dist/types/src/capabilities/react-surface/react-surface.d.ts +0 -5
- package/dist/types/src/capabilities/react-surface/react-surface.d.ts.map +0 -1
- package/dist/types/src/components/SearchDialog.d.ts +0 -7
- package/dist/types/src/components/SearchDialog.d.ts.map +0 -1
- package/dist/types/src/components/SearchMain.d.ts +0 -6
- package/dist/types/src/components/SearchMain.d.ts.map +0 -1
- package/dist/types/src/components/SearchMain.stories.d.ts +0 -31
- package/dist/types/src/components/SearchMain.stories.d.ts.map +0 -1
- package/dist/types/src/components/SpaceMain.d.ts +0 -9
- package/dist/types/src/components/SpaceMain.d.ts.map +0 -1
- package/dist/types/src/types/action.d.ts +0 -16
- package/dist/types/src/types/action.d.ts.map +0 -1
- package/src/capabilities/app-graph-builder/index.ts +0 -7
- package/src/capabilities/operation-resolver/index.ts +0 -7
- package/src/capabilities/operation-resolver/operation-resolver.ts +0 -23
- package/src/capabilities/react-surface/index.ts +0 -7
- package/src/capabilities/react-surface/react-surface.tsx +0 -70
- package/src/components/SearchDialog.tsx +0 -130
- package/src/components/SearchMain.stories.tsx +0 -90
- package/src/components/SearchMain.tsx +0 -83
- package/src/components/SpaceMain.tsx +0 -169
- package/src/types/action.tsx +0 -18
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
6
|
+
import * as Effect from 'effect/Effect';
|
|
7
|
+
import React from 'react';
|
|
8
|
+
import { expect, userEvent, waitFor, within } from 'storybook/test';
|
|
9
|
+
|
|
10
|
+
import { Capability } from '@dxos/app-framework';
|
|
11
|
+
import { withPluginManager } from '@dxos/app-framework/testing';
|
|
12
|
+
import { AppCapabilities } from '@dxos/app-toolkit';
|
|
13
|
+
import { ClientPlugin } from '@dxos/plugin-client';
|
|
14
|
+
import { initializeIdentity } from '@dxos/plugin-client/testing';
|
|
15
|
+
import { corePlugins, StorybookPlugin } from '@dxos/plugin-testing';
|
|
16
|
+
import { random } from '@dxos/random';
|
|
17
|
+
import { useSpaces } from '@dxos/react-client/echo';
|
|
18
|
+
import { Dialog } from '@dxos/react-ui';
|
|
19
|
+
import { Loading, withLayout } from '@dxos/react-ui/testing';
|
|
20
|
+
import { createObjectFactory } from '@dxos/schema/testing';
|
|
21
|
+
import { Organization, Person } from '@dxos/types';
|
|
22
|
+
|
|
23
|
+
import { SearchContextProvider } from '#hooks';
|
|
24
|
+
|
|
25
|
+
import { translations } from '../../translations';
|
|
26
|
+
import { SearchDialog } from './SearchDialog';
|
|
27
|
+
|
|
28
|
+
random.seed(0);
|
|
29
|
+
|
|
30
|
+
const DefaultStory = () => {
|
|
31
|
+
const spaces = useSpaces();
|
|
32
|
+
const space = spaces[spaces.length - 1];
|
|
33
|
+
if (!space) {
|
|
34
|
+
return <Loading />;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return (
|
|
38
|
+
<SearchContextProvider>
|
|
39
|
+
<Dialog.Root defaultOpen>
|
|
40
|
+
<Dialog.Overlay>
|
|
41
|
+
<SearchDialog pivotId='storybook' space={space} />
|
|
42
|
+
</Dialog.Overlay>
|
|
43
|
+
</Dialog.Root>
|
|
44
|
+
</SearchContextProvider>
|
|
45
|
+
);
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
const meta = {
|
|
49
|
+
title: 'plugins/plugin-search/containers/SearchDialog',
|
|
50
|
+
component: SearchDialog,
|
|
51
|
+
render: DefaultStory,
|
|
52
|
+
decorators: [
|
|
53
|
+
withLayout({ layout: 'fullscreen' }),
|
|
54
|
+
withPluginManager({
|
|
55
|
+
capabilities: [Capability.contributes(AppCapabilities.Translations, translations)],
|
|
56
|
+
plugins: [
|
|
57
|
+
...corePlugins(),
|
|
58
|
+
StorybookPlugin({}),
|
|
59
|
+
ClientPlugin({
|
|
60
|
+
types: [Organization.Organization, Person.Person],
|
|
61
|
+
onClientInitialized: ({ client }) =>
|
|
62
|
+
Effect.gen(function* () {
|
|
63
|
+
const { personalSpace } = yield* initializeIdentity(client);
|
|
64
|
+
|
|
65
|
+
const factory = createObjectFactory(personalSpace.db, random as any);
|
|
66
|
+
yield* Effect.promise(() =>
|
|
67
|
+
factory([
|
|
68
|
+
{ type: Organization.Organization, count: 10 },
|
|
69
|
+
{ type: Person.Person, count: 50 },
|
|
70
|
+
]),
|
|
71
|
+
);
|
|
72
|
+
}),
|
|
73
|
+
}),
|
|
74
|
+
],
|
|
75
|
+
}),
|
|
76
|
+
],
|
|
77
|
+
tags: ['test'],
|
|
78
|
+
parameters: {
|
|
79
|
+
layout: 'fullscreen',
|
|
80
|
+
},
|
|
81
|
+
} satisfies Meta<typeof SearchDialog>;
|
|
82
|
+
|
|
83
|
+
export default meta;
|
|
84
|
+
|
|
85
|
+
type Story = StoryObj<typeof meta>;
|
|
86
|
+
|
|
87
|
+
export const Default: Story = {};
|
|
88
|
+
|
|
89
|
+
export const Test: Story = {
|
|
90
|
+
play: async () => {
|
|
91
|
+
const body = within(document.body);
|
|
92
|
+
|
|
93
|
+
// Wait for the dialog to render and the search input to appear.
|
|
94
|
+
const searchInput = await body.findByRole('textbox', undefined, { timeout: 10_000 });
|
|
95
|
+
await expect(searchInput).toBeInTheDocument();
|
|
96
|
+
|
|
97
|
+
// Type a search term that should match generated Person/Organization names.
|
|
98
|
+
await userEvent.type(searchInput, 'a');
|
|
99
|
+
|
|
100
|
+
// Wait for search results to appear as options in the listbox.
|
|
101
|
+
await waitFor(
|
|
102
|
+
async () => {
|
|
103
|
+
const options = body.queryAllByRole('option');
|
|
104
|
+
await expect(options.length).toBeGreaterThan(0);
|
|
105
|
+
},
|
|
106
|
+
{ timeout: 10_000 },
|
|
107
|
+
);
|
|
108
|
+
},
|
|
109
|
+
};
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2024 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import React, { useCallback, useMemo, useState } from 'react';
|
|
6
|
+
|
|
7
|
+
import { useOperationInvoker } from '@dxos/app-framework/ui';
|
|
8
|
+
import { getObjectPathFromObject, LayoutOperation } from '@dxos/app-toolkit';
|
|
9
|
+
import { useLayout } from '@dxos/app-toolkit/ui';
|
|
10
|
+
import { useActiveSpace } from '@dxos/app-toolkit/ui';
|
|
11
|
+
import { Entity, Obj, Query } from '@dxos/echo';
|
|
12
|
+
import { Filter, type Space, useQuery } from '@dxos/react-client/echo';
|
|
13
|
+
import { Dialog, useTranslation } from '@dxos/react-ui';
|
|
14
|
+
import { SearchList } from '@dxos/react-ui-search';
|
|
15
|
+
import { Text } from '@dxos/schema';
|
|
16
|
+
|
|
17
|
+
import { useGlobalSearch, useGlobalSearchResults } from '#hooks';
|
|
18
|
+
import { meta } from '#meta';
|
|
19
|
+
import { type SearchResult } from '#types';
|
|
20
|
+
|
|
21
|
+
export type SearchDialogProps = {
|
|
22
|
+
pivotId?: string;
|
|
23
|
+
space?: Space;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export const SearchDialog = ({ pivotId: pivotIdProp, space: spaceProp }: SearchDialogProps) => {
|
|
27
|
+
const { t } = useTranslation(meta.id);
|
|
28
|
+
const layout = useLayout();
|
|
29
|
+
const pivotId = pivotIdProp ?? layout.active[layout.active.length - 1];
|
|
30
|
+
const { invokePromise } = useOperationInvoker();
|
|
31
|
+
const { setMatch } = useGlobalSearch();
|
|
32
|
+
const [query, setQuery] = useState<string>();
|
|
33
|
+
|
|
34
|
+
const activeSpace = useActiveSpace();
|
|
35
|
+
const space = spaceProp ?? activeSpace;
|
|
36
|
+
// TODO(burdon): Re-enable full-text search when indexer is available in all environments.
|
|
37
|
+
const objects = useQuery(
|
|
38
|
+
space?.db,
|
|
39
|
+
query === undefined ? Query.select(Filter.nothing()) : Query.select(Filter.not(Filter.type(Text.Text))),
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
const results = useGlobalSearchResults(objects);
|
|
43
|
+
const allResults = useMemo(() => results.filter(({ object }) => object && Entity.getLabel(object)), [results]);
|
|
44
|
+
|
|
45
|
+
const handleSearch = useCallback(
|
|
46
|
+
(text: string) => {
|
|
47
|
+
setQuery(text);
|
|
48
|
+
setMatch?.(text);
|
|
49
|
+
},
|
|
50
|
+
[setMatch],
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
const handleSelect = useCallback(
|
|
54
|
+
async (result: SearchResult) => {
|
|
55
|
+
if (!result.object || !Obj.isObject(result.object)) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const qualifiedPath = getObjectPathFromObject(result.object);
|
|
60
|
+
await invokePromise(LayoutOperation.UpdateDialog, { state: false });
|
|
61
|
+
await invokePromise(LayoutOperation.Open, {
|
|
62
|
+
subject: [qualifiedPath],
|
|
63
|
+
pivotId,
|
|
64
|
+
positioning: 'end',
|
|
65
|
+
});
|
|
66
|
+
},
|
|
67
|
+
[pivotId, invokePromise],
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
return (
|
|
71
|
+
<Dialog.Content>
|
|
72
|
+
<Dialog.Header>
|
|
73
|
+
<Dialog.Title>{t('search-dialog.title')}</Dialog.Title>
|
|
74
|
+
<Dialog.Close asChild>
|
|
75
|
+
<Dialog.CloseIconButton />
|
|
76
|
+
</Dialog.Close>
|
|
77
|
+
</Dialog.Header>
|
|
78
|
+
<Dialog.Body>
|
|
79
|
+
<SearchList.Root onSearch={handleSearch}>
|
|
80
|
+
<SearchList.Content classNames='max-h-[24rem]'>
|
|
81
|
+
<SearchList.Input classNames='px-0' autoFocus placeholder={t('search.placeholder')} />
|
|
82
|
+
<SearchList.Viewport>
|
|
83
|
+
{allResults.map((result) => (
|
|
84
|
+
<SearchList.Item
|
|
85
|
+
key={result.id}
|
|
86
|
+
classNames='flex gap-2 items-center'
|
|
87
|
+
value={result.id}
|
|
88
|
+
label={result.label ?? (result.object ? Entity.getLabel(result.object) : undefined) ?? result.id}
|
|
89
|
+
icon={result.icon}
|
|
90
|
+
onSelect={() => void handleSelect(result)}
|
|
91
|
+
/>
|
|
92
|
+
))}
|
|
93
|
+
{query && allResults.length === 0 && <SearchList.Empty />}
|
|
94
|
+
</SearchList.Viewport>
|
|
95
|
+
</SearchList.Content>
|
|
96
|
+
</SearchList.Root>
|
|
97
|
+
</Dialog.Body>
|
|
98
|
+
</Dialog.Content>
|
|
99
|
+
);
|
|
100
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { type ComponentType, lazy } from 'react';
|
|
6
|
+
|
|
7
|
+
export type { SearchDialogProps } from './SearchDialog';
|
|
8
|
+
|
|
9
|
+
export const SearchDialog: ComponentType<any> = lazy(() => import('./SearchDialog'));
|
|
10
|
+
export const SearchArticle: ComponentType<any> = lazy(() => import('./SearchArticle'));
|
package/src/hooks/sync.test.ts
CHANGED
|
@@ -7,11 +7,11 @@ import { describe, expect, test } from 'vitest';
|
|
|
7
7
|
import { Client } from '@dxos/client';
|
|
8
8
|
import { Filter, Obj } from '@dxos/echo';
|
|
9
9
|
import { TestSchema } from '@dxos/echo/testing';
|
|
10
|
-
import {
|
|
10
|
+
import { random } from '@dxos/random';
|
|
11
11
|
|
|
12
12
|
import { filterObjectsSync } from './sync';
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
random.seed(1);
|
|
15
15
|
|
|
16
16
|
// TODO(burdon): Reconcile with agent/minisearch.
|
|
17
17
|
|
|
@@ -26,8 +26,8 @@ describe('Search', () => {
|
|
|
26
26
|
const space = await client.spaces.create();
|
|
27
27
|
Array.from({ length: 20 }).map((_, i) => {
|
|
28
28
|
const content =
|
|
29
|
-
i === 10 ?
|
|
30
|
-
return space.db.add(Obj.make(TestSchema.Expando, { title:
|
|
29
|
+
i === 10 ? random.lorem.sentence() + ` ${match}}. ` + random.lorem.sentence() : random.lorem.sentences();
|
|
30
|
+
return space.db.add(Obj.make(TestSchema.Expando, { title: random.lorem.sentence(), content }));
|
|
31
31
|
});
|
|
32
32
|
|
|
33
33
|
const objects = await space.db.query(Filter.everything()).run();
|
package/src/hooks/sync.ts
CHANGED
|
@@ -8,7 +8,7 @@ import * as SchemaAST from 'effect/SchemaAST';
|
|
|
8
8
|
import { type Entity, Obj } from '@dxos/echo';
|
|
9
9
|
import { Text } from '@dxos/schema';
|
|
10
10
|
|
|
11
|
-
import { type SearchResult } from '
|
|
11
|
+
import { type SearchResult } from '#types';
|
|
12
12
|
|
|
13
13
|
export const queryStringToMatch = (queryString?: string): RegExp | undefined => {
|
|
14
14
|
const trimmed = queryString?.trim();
|
|
@@ -6,14 +6,14 @@ import React, { type PropsWithChildren, createContext, useCallback, useContext,
|
|
|
6
6
|
|
|
7
7
|
import { raise } from '@dxos/debug';
|
|
8
8
|
import { type Entity } from '@dxos/echo';
|
|
9
|
-
import { GlobalFilterProvider } from '@dxos/react-ui-
|
|
9
|
+
import { GlobalFilterProvider } from '@dxos/react-ui-search';
|
|
10
10
|
|
|
11
|
-
import { type SearchResult } from '
|
|
11
|
+
import { type SearchResult } from '#types';
|
|
12
12
|
|
|
13
13
|
import { filterObjectsSync, queryStringToMatch } from './sync';
|
|
14
14
|
|
|
15
15
|
// Re-export for backward compatibility.
|
|
16
|
-
export { useGlobalFilteredObjects, GlobalFilterProvider } from '@dxos/react-ui-
|
|
16
|
+
export { useGlobalFilteredObjects, GlobalFilterProvider } from '@dxos/react-ui-search';
|
|
17
17
|
|
|
18
18
|
type SearchContextType = {
|
|
19
19
|
match?: RegExp;
|
|
@@ -10,9 +10,9 @@ import { log } from '@dxos/log';
|
|
|
10
10
|
import { getIconAnnotation } from '@dxos/schema';
|
|
11
11
|
import { TestSchema } from '@dxos/schema/testing';
|
|
12
12
|
|
|
13
|
-
import {
|
|
14
|
-
import { type SearchResult } from '../types';
|
|
13
|
+
import { type SearchResult } from '#types';
|
|
15
14
|
|
|
15
|
+
import { search } from '../search';
|
|
16
16
|
import { getStringProperty } from './sync';
|
|
17
17
|
|
|
18
18
|
export type UseWebSearchProps = {
|
package/src/meta.ts
CHANGED
|
@@ -6,7 +6,7 @@ import { type Plugin } from '@dxos/app-framework';
|
|
|
6
6
|
import { trim } from '@dxos/util';
|
|
7
7
|
|
|
8
8
|
export const meta: Plugin.Meta = {
|
|
9
|
-
id: 'dxos.
|
|
9
|
+
id: 'org.dxos.plugin.search',
|
|
10
10
|
name: 'Search',
|
|
11
11
|
description: trim`
|
|
12
12
|
Full-text search engine for finding content across all spaces and object types.
|
|
@@ -17,4 +17,4 @@ export const meta: Plugin.Meta = {
|
|
|
17
17
|
tags: ['labs'],
|
|
18
18
|
};
|
|
19
19
|
|
|
20
|
-
export const SEARCH_RESULT = `${meta.id}
|
|
20
|
+
export const SEARCH_RESULT = `${meta.id}.result`;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import * as Schema from 'effect/Schema';
|
|
6
|
+
|
|
7
|
+
import { Operation } from '@dxos/operation';
|
|
8
|
+
|
|
9
|
+
import { meta } from '#meta';
|
|
10
|
+
|
|
11
|
+
const SEARCH_OPERATION = `${meta.id}.operation`;
|
|
12
|
+
|
|
13
|
+
export const OpenSearch = Operation.make({
|
|
14
|
+
meta: { key: `${SEARCH_OPERATION}.open-search`, name: 'Open Search' },
|
|
15
|
+
input: Schema.Void,
|
|
16
|
+
output: Schema.Void,
|
|
17
|
+
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import * as Effect from 'effect/Effect';
|
|
6
|
+
|
|
7
|
+
import { LayoutOperation } from '@dxos/app-toolkit';
|
|
8
|
+
import { Operation } from '@dxos/operation';
|
|
9
|
+
|
|
10
|
+
import { SEARCH_DIALOG } from '../constants';
|
|
11
|
+
import { OpenSearch } from './definitions';
|
|
12
|
+
|
|
13
|
+
const handler: Operation.WithHandler<typeof OpenSearch> = OpenSearch.pipe(
|
|
14
|
+
Operation.withHandler(
|
|
15
|
+
Effect.fnUntraced(function* () {
|
|
16
|
+
yield* Operation.invoke(LayoutOperation.UpdateDialog, {
|
|
17
|
+
subject: SEARCH_DIALOG,
|
|
18
|
+
blockAlign: 'start',
|
|
19
|
+
});
|
|
20
|
+
}),
|
|
21
|
+
),
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
export default handler;
|
package/src/search/exa.ts
CHANGED
|
@@ -9,8 +9,8 @@ import * as Schema from 'effect/Schema';
|
|
|
9
9
|
import * as SchemaAST from 'effect/SchemaAST';
|
|
10
10
|
|
|
11
11
|
import { type Entity, Key, Obj, type Type } from '@dxos/echo';
|
|
12
|
-
import { ReferenceAnnotationId } from '@dxos/echo/internal';
|
|
13
12
|
import { isEncodedReference } from '@dxos/echo-protocol';
|
|
13
|
+
import { ReferenceAnnotationId } from '@dxos/echo/internal';
|
|
14
14
|
import { mapAst } from '@dxos/effect';
|
|
15
15
|
import { deepMapValues, trim } from '@dxos/util';
|
|
16
16
|
|
|
@@ -181,7 +181,7 @@ const DATA_EXTRACTION_INSTRUCTIONS = trim`
|
|
|
181
181
|
// return terms;
|
|
182
182
|
// };
|
|
183
183
|
|
|
184
|
-
const sanitizeObjects = (entries: { data: any; schema: Type.
|
|
184
|
+
const sanitizeObjects = (entries: { data: any; schema: Type.AnyObj }[]) => {
|
|
185
185
|
const idMap = new Map<string, string>();
|
|
186
186
|
|
|
187
187
|
return entries
|
package/src/translations.ts
CHANGED
|
@@ -3,21 +3,22 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import { type Resource } from '@dxos/react-ui';
|
|
6
|
+
import { translations as searchTranslations } from '@dxos/react-ui-search';
|
|
6
7
|
|
|
7
|
-
import { meta } from '
|
|
8
|
+
import { meta } from '#meta';
|
|
8
9
|
|
|
9
10
|
export const translations = [
|
|
11
|
+
...searchTranslations,
|
|
10
12
|
{
|
|
11
13
|
'en-US': {
|
|
12
14
|
[meta.id]: {
|
|
13
|
-
'plugin
|
|
14
|
-
'search
|
|
15
|
-
'search
|
|
16
|
-
'search
|
|
17
|
-
'recently
|
|
18
|
-
'pending
|
|
19
|
-
'
|
|
20
|
-
'search label': 'Search',
|
|
15
|
+
'plugin.name': 'Search',
|
|
16
|
+
'search-action.label': 'Search spaces',
|
|
17
|
+
'search.placeholder': 'Search…',
|
|
18
|
+
'search-dialog.title': 'Search',
|
|
19
|
+
'recently-closed.heading': 'Recently closed',
|
|
20
|
+
'pending-results.message': 'Searching…',
|
|
21
|
+
'search.label': 'Search',
|
|
21
22
|
},
|
|
22
23
|
},
|
|
23
24
|
},
|
package/src/types/index.ts
CHANGED
package/src/types/search.ts
CHANGED
|
@@ -2,22 +2,4 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
export type SearchResult<T extends Entity.Unknown = Entity.Unknown> = {
|
|
8
|
-
id: string;
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Type kind: "contact", "project", "org", etc.
|
|
12
|
-
*/
|
|
13
|
-
type?: string;
|
|
14
|
-
label?: string;
|
|
15
|
-
match?: RegExp;
|
|
16
|
-
snippet?: string;
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Icon id.
|
|
20
|
-
*/
|
|
21
|
-
icon?: string;
|
|
22
|
-
object?: T;
|
|
23
|
-
};
|
|
5
|
+
export type { SearchResult } from '@dxos/react-ui-search';
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
SearchOperation
|
|
3
|
-
} from "./chunk-I7YWQSUZ.mjs";
|
|
4
|
-
import {
|
|
5
|
-
meta
|
|
6
|
-
} from "./chunk-HRIWTRJV.mjs";
|
|
7
|
-
|
|
8
|
-
// src/capabilities/app-graph-builder/app-graph-builder.ts
|
|
9
|
-
import * as Effect from "effect/Effect";
|
|
10
|
-
import { Capability, Common } from "@dxos/app-framework";
|
|
11
|
-
import { Operation } from "@dxos/operation";
|
|
12
|
-
import { ClientCapabilities } from "@dxos/plugin-client";
|
|
13
|
-
import { ATTENDABLE_PATH_SEPARATOR, DECK_COMPANION_TYPE } from "@dxos/plugin-deck/types";
|
|
14
|
-
import { GraphBuilder, NodeMatcher } from "@dxos/plugin-graph";
|
|
15
|
-
import { parseId } from "@dxos/react-client/echo";
|
|
16
|
-
var app_graph_builder_default = Capability.makeModule(Effect.fnUntraced(function* () {
|
|
17
|
-
const extensions = yield* Effect.all([
|
|
18
|
-
GraphBuilder.createExtension({
|
|
19
|
-
id: `${meta.id}/space-search`,
|
|
20
|
-
match: NodeMatcher.whenRoot,
|
|
21
|
-
connector: Effect.fnUntraced(function* (node, get) {
|
|
22
|
-
const client = yield* Capability.get(ClientCapabilities.Client);
|
|
23
|
-
const layoutAtom = get(yield* Capability.atom(Common.Capability.Layout))[0];
|
|
24
|
-
const layout = layoutAtom ? get(layoutAtom) : void 0;
|
|
25
|
-
const { spaceId } = parseId(layout?.workspace);
|
|
26
|
-
const space = spaceId ? client.spaces.get(spaceId) : null;
|
|
27
|
-
return [
|
|
28
|
-
{
|
|
29
|
-
id: [
|
|
30
|
-
node.id,
|
|
31
|
-
"search"
|
|
32
|
-
].join(ATTENDABLE_PATH_SEPARATOR),
|
|
33
|
-
type: DECK_COMPANION_TYPE,
|
|
34
|
-
data: space,
|
|
35
|
-
properties: {
|
|
36
|
-
label: [
|
|
37
|
-
"search label",
|
|
38
|
-
{
|
|
39
|
-
ns: meta.id
|
|
40
|
-
}
|
|
41
|
-
],
|
|
42
|
-
icon: "ph--magnifying-glass--regular",
|
|
43
|
-
disposition: "hidden"
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
];
|
|
47
|
-
})
|
|
48
|
-
}),
|
|
49
|
-
GraphBuilder.createExtension({
|
|
50
|
-
id: meta.id,
|
|
51
|
-
match: NodeMatcher.whenRoot,
|
|
52
|
-
actions: () => Effect.succeed([
|
|
53
|
-
{
|
|
54
|
-
id: SearchOperation.OpenSearch.meta.key,
|
|
55
|
-
data: Effect.fnUntraced(function* () {
|
|
56
|
-
yield* Operation.invoke(SearchOperation.OpenSearch);
|
|
57
|
-
return false;
|
|
58
|
-
}),
|
|
59
|
-
properties: {
|
|
60
|
-
label: [
|
|
61
|
-
"search action label",
|
|
62
|
-
{
|
|
63
|
-
ns: meta.id
|
|
64
|
-
}
|
|
65
|
-
],
|
|
66
|
-
icon: "ph--magnifying-glass--regular",
|
|
67
|
-
keyBinding: {
|
|
68
|
-
macos: "shift+meta+f",
|
|
69
|
-
windows: "shift+alt+f"
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
])
|
|
74
|
-
})
|
|
75
|
-
]);
|
|
76
|
-
return Capability.contributes(Common.Capability.AppGraphBuilder, extensions);
|
|
77
|
-
}));
|
|
78
|
-
export {
|
|
79
|
-
app_graph_builder_default as default
|
|
80
|
-
};
|
|
81
|
-
//# sourceMappingURL=app-graph-builder-KZ3V2E5U.mjs.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../src/capabilities/app-graph-builder/app-graph-builder.ts"],
|
|
4
|
-
"sourcesContent": ["//\n// Copyright 2025 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\n\nimport { Capability, Common } from '@dxos/app-framework';\nimport { Operation } from '@dxos/operation';\nimport { ClientCapabilities } from '@dxos/plugin-client';\nimport { ATTENDABLE_PATH_SEPARATOR, DECK_COMPANION_TYPE } from '@dxos/plugin-deck/types';\nimport { GraphBuilder, NodeMatcher } from '@dxos/plugin-graph';\nimport { parseId } from '@dxos/react-client/echo';\n\nimport { meta } from '../../meta';\nimport { SearchOperation } from '../../types';\n\nexport default Capability.makeModule(\n Effect.fnUntraced(function* () {\n const extensions = yield* Effect.all([\n GraphBuilder.createExtension({\n id: `${meta.id}/space-search`,\n match: NodeMatcher.whenRoot,\n connector: Effect.fnUntraced(function* (node, get) {\n const client = yield* Capability.get(ClientCapabilities.Client);\n const layoutAtom = get(yield* Capability.atom(Common.Capability.Layout))[0];\n const layout = layoutAtom ? get(layoutAtom) : undefined;\n const { spaceId } = parseId(layout?.workspace);\n const space = spaceId ? client.spaces.get(spaceId) : null;\n\n return [\n {\n id: [node.id, 'search'].join(ATTENDABLE_PATH_SEPARATOR),\n type: DECK_COMPANION_TYPE,\n data: space,\n properties: {\n label: ['search label', { ns: meta.id }],\n icon: 'ph--magnifying-glass--regular',\n disposition: 'hidden',\n },\n },\n ];\n }),\n }),\n GraphBuilder.createExtension({\n id: meta.id,\n match: NodeMatcher.whenRoot,\n actions: () =>\n Effect.succeed([\n {\n id: SearchOperation.OpenSearch.meta.key,\n data: Effect.fnUntraced(function* () {\n yield* Operation.invoke(SearchOperation.OpenSearch);\n return false;\n }),\n properties: {\n label: ['search action label', { ns: meta.id }],\n icon: 'ph--magnifying-glass--regular',\n keyBinding: {\n macos: 'shift+meta+f',\n windows: 'shift+alt+f',\n },\n },\n },\n ]),\n }),\n ]);\n\n return Capability.contributes(Common.Capability.AppGraphBuilder, extensions);\n }),\n);\n"],
|
|
5
|
-
"mappings": ";;;;;;;;AAIA,YAAYA,YAAY;AAExB,SAASC,YAAYC,cAAc;AACnC,SAASC,iBAAiB;AAC1B,SAASC,0BAA0B;AACnC,SAASC,2BAA2BC,2BAA2B;AAC/D,SAASC,cAAcC,mBAAmB;AAC1C,SAASC,eAAe;AAKxB,IAAA,4BAAeC,WAAWC,WACjBC,kBAAW,aAAA;AAChB,QAAMC,aAAa,OAAcC,WAAI;IACnCC,aAAaC,gBAAgB;MAC3BC,IAAI,GAAGC,KAAKD,EAAE;MACdE,OAAOC,YAAYC;MACnBC,WAAkBV,kBAAW,WAAWW,MAAMC,KAAG;AAC/C,cAAMC,SAAS,OAAOf,WAAWc,IAAIE,mBAAmBC,MAAM;AAC9D,cAAMC,aAAaJ,IAAI,OAAOd,WAAWmB,KAAKC,OAAOpB,WAAWqB,MAAM,CAAA,EAAG,CAAA;AACzE,cAAMC,SAASJ,aAAaJ,IAAII,UAAAA,IAAcK;AAC9C,cAAM,EAAEC,QAAO,IAAKC,QAAQH,QAAQI,SAAAA;AACpC,cAAMC,QAAQH,UAAUT,OAAOa,OAAOd,IAAIU,OAAAA,IAAW;AAErD,eAAO;UACL;YACEjB,IAAI;cAACM,KAAKN;cAAI;cAAUsB,KAAKC,yBAAAA;YAC7BC,MAAMC;YACNC,MAAMN;YACNO,YAAY;cACVC,OAAO;gBAAC;gBAAgB;kBAAEC,IAAI5B,KAAKD;gBAAG;;cACtC8B,MAAM;cACNC,aAAa;YACf;UACF;;MAEJ,CAAA;IACF,CAAA;IACAjC,aAAaC,gBAAgB;MAC3BC,IAAIC,KAAKD;MACTE,OAAOC,YAAYC;MACnB4B,SAAS,MACAC,eAAQ;QACb;UACEjC,IAAIkC,gBAAgBC,WAAWlC,KAAKmC;UACpCV,MAAa/B,kBAAW,aAAA;AACtB,mBAAO0C,UAAUC,OAAOJ,gBAAgBC,UAAU;AAClD,mBAAO;UACT,CAAA;UACAR,YAAY;YACVC,OAAO;cAAC;cAAuB;gBAAEC,IAAI5B,KAAKD;cAAG;;YAC7C8B,MAAM;YACNS,YAAY;cACVC,OAAO;cACPC,SAAS;YACX;UACF;QACF;OACD;IACL,CAAA;GACD;AAED,SAAOhD,WAAWiD,YAAY7B,OAAOpB,WAAWkD,iBAAiB/C,UAAAA;AACnE,CAAA,CAAA;",
|
|
6
|
-
"names": ["Effect", "Capability", "Common", "Operation", "ClientCapabilities", "ATTENDABLE_PATH_SEPARATOR", "DECK_COMPANION_TYPE", "GraphBuilder", "NodeMatcher", "parseId", "Capability", "makeModule", "fnUntraced", "extensions", "all", "GraphBuilder", "createExtension", "id", "meta", "match", "NodeMatcher", "whenRoot", "connector", "node", "get", "client", "ClientCapabilities", "Client", "layoutAtom", "atom", "Common", "Layout", "layout", "undefined", "spaceId", "parseId", "workspace", "space", "spaces", "join", "ATTENDABLE_PATH_SEPARATOR", "type", "DECK_COMPANION_TYPE", "data", "properties", "label", "ns", "icon", "disposition", "actions", "succeed", "SearchOperation", "OpenSearch", "key", "Operation", "invoke", "keyBinding", "macos", "windows", "contributes", "AppGraphBuilder"]
|
|
7
|
-
}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
// src/meta.ts
|
|
2
|
-
import { trim } from "@dxos/util";
|
|
3
|
-
var meta = {
|
|
4
|
-
id: "dxos.org/plugin/search",
|
|
5
|
-
name: "Search",
|
|
6
|
-
description: trim`
|
|
7
|
-
Full-text search engine for finding content across all spaces and object types.
|
|
8
|
-
Quickly locate documents, tables, and other objects with instant results and relevance ranking.
|
|
9
|
-
`,
|
|
10
|
-
icon: "ph--magnifying-glass--regular",
|
|
11
|
-
source: "https://github.com/dxos/dxos/tree/main/packages/plugins/plugin-search",
|
|
12
|
-
tags: [
|
|
13
|
-
"labs"
|
|
14
|
-
]
|
|
15
|
-
};
|
|
16
|
-
var SEARCH_RESULT = `${meta.id}/result`;
|
|
17
|
-
|
|
18
|
-
export {
|
|
19
|
-
meta,
|
|
20
|
-
SEARCH_RESULT
|
|
21
|
-
};
|
|
22
|
-
//# sourceMappingURL=chunk-HRIWTRJV.mjs.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../src/meta.ts"],
|
|
4
|
-
"sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport { type Plugin } from '@dxos/app-framework';\nimport { trim } from '@dxos/util';\n\nexport const meta: Plugin.Meta = {\n id: 'dxos.org/plugin/search',\n name: 'Search',\n description: trim`\n Full-text search engine for finding content across all spaces and object types.\n Quickly locate documents, tables, and other objects with instant results and relevance ranking.\n `,\n icon: 'ph--magnifying-glass--regular',\n source: 'https://github.com/dxos/dxos/tree/main/packages/plugins/plugin-search',\n tags: ['labs'],\n};\n\nexport const SEARCH_RESULT = `${meta.id}/result`;\n"],
|
|
5
|
-
"mappings": ";AAKA,SAASA,YAAY;AAEd,IAAMC,OAAoB;EAC/BC,IAAI;EACJC,MAAM;EACNC,aAAaC;;;;EAIbC,MAAM;EACNC,QAAQ;EACRC,MAAM;IAAC;;AACT;AAEO,IAAMC,gBAAgB,GAAGR,KAAKC,EAAE;",
|
|
6
|
-
"names": ["trim", "meta", "id", "name", "description", "trim", "icon", "source", "tags", "SEARCH_RESULT"]
|
|
7
|
-
}
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
meta
|
|
3
|
-
} from "./chunk-HRIWTRJV.mjs";
|
|
4
|
-
|
|
5
|
-
// src/types/action.tsx
|
|
6
|
-
import * as Schema from "effect/Schema";
|
|
7
|
-
import { Operation } from "@dxos/operation";
|
|
8
|
-
var SEARCH_OPERATION = `${meta.id}/operation`;
|
|
9
|
-
(function(SearchOperation2) {
|
|
10
|
-
SearchOperation2.OpenSearch = Operation.make({
|
|
11
|
-
meta: {
|
|
12
|
-
key: `${SEARCH_OPERATION}/open-search`,
|
|
13
|
-
name: "Open Search"
|
|
14
|
-
},
|
|
15
|
-
schema: {
|
|
16
|
-
input: Schema.Void,
|
|
17
|
-
output: Schema.Void
|
|
18
|
-
}
|
|
19
|
-
});
|
|
20
|
-
})(SearchOperation || (SearchOperation = {}));
|
|
21
|
-
var SearchOperation;
|
|
22
|
-
|
|
23
|
-
export {
|
|
24
|
-
SearchOperation
|
|
25
|
-
};
|
|
26
|
-
//# sourceMappingURL=chunk-I7YWQSUZ.mjs.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../src/types/action.tsx"],
|
|
4
|
-
"sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport * as Schema from 'effect/Schema';\n\nimport { Operation } from '@dxos/operation';\n\nimport { meta } from '../meta';\n\nconst SEARCH_OPERATION = `${meta.id}/operation`;\n\nexport namespace SearchOperation {\n export const OpenSearch = Operation.make({\n meta: { key: `${SEARCH_OPERATION}/open-search`, name: 'Open Search' },\n schema: { input: Schema.Void, output: Schema.Void },\n });\n}\n"],
|
|
5
|
-
"mappings": ";;;;;AAIA,YAAYA,YAAY;AAExB,SAASC,iBAAiB;AAI1B,IAAMC,mBAAmB,GAAGC,KAAKC,EAAE;UAElBC,kBAAAA;mBACFC,aAAaC,UAAUC,KAAK;IACvCL,MAAM;MAAEM,KAAK,GAAGP,gBAAAA;MAAgCQ,MAAM;IAAc;IACpEC,QAAQ;MAAEC,OAAcC;MAAMC,QAAeD;IAAK;EACpD,CAAA;AACF,GALiBR,oBAAAA,kBAAAA,CAAAA,EAAAA;;",
|
|
6
|
-
"names": ["Schema", "Operation", "SEARCH_OPERATION", "meta", "id", "SearchOperation", "OpenSearch", "Operation", "make", "key", "name", "schema", "input", "Void", "output"]
|
|
7
|
-
}
|