@dxos/plugin-search 0.8.4-main.e098934 → 0.8.4-main.e8ec1fe

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/dist/lib/browser/{app-graph-builder-D2QQTIIR.mjs → app-graph-builder-HQR6P4C7.mjs} +17 -16
  2. package/dist/lib/browser/app-graph-builder-HQR6P4C7.mjs.map +7 -0
  3. package/dist/lib/browser/chunk-GN2FSWTM.mjs +22 -0
  4. package/dist/lib/browser/chunk-GN2FSWTM.mjs.map +7 -0
  5. package/dist/lib/browser/{chunk-JVMYGOKS.mjs → chunk-TCVYYI44.mjs} +5 -5
  6. package/dist/lib/browser/chunk-TCVYYI44.mjs.map +7 -0
  7. package/dist/lib/browser/{chunk-YJGLEPHU.mjs → chunk-ZEP4O5SU.mjs} +109 -8
  8. package/dist/lib/browser/chunk-ZEP4O5SU.mjs.map +7 -0
  9. package/dist/lib/browser/index.mjs +11 -11
  10. package/dist/lib/browser/index.mjs.map +2 -2
  11. package/dist/lib/browser/{intent-resolver-NXFDPFHC.mjs → intent-resolver-UYQA6UUQ.mjs} +5 -5
  12. package/dist/lib/browser/{intent-resolver-NXFDPFHC.mjs.map → intent-resolver-UYQA6UUQ.mjs.map} +1 -1
  13. package/dist/lib/browser/meta.json +1 -1
  14. package/dist/lib/browser/react-surface-H5CKQVII.mjs +307 -0
  15. package/dist/lib/browser/react-surface-H5CKQVII.mjs.map +7 -0
  16. package/dist/types/src/SearchPlugin.d.ts +1 -1
  17. package/dist/types/src/SearchPlugin.d.ts.map +1 -1
  18. package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -1
  19. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
  20. package/dist/types/src/components/Search.stories.d.ts +1 -5
  21. package/dist/types/src/components/Search.stories.d.ts.map +1 -1
  22. package/dist/types/src/components/SearchDialog.d.ts +1 -1
  23. package/dist/types/src/components/SearchDialog.d.ts.map +1 -1
  24. package/dist/types/src/components/SearchMain.d.ts +4 -5
  25. package/dist/types/src/components/SearchMain.d.ts.map +1 -1
  26. package/dist/types/src/components/SearchResults/SearchResults.d.ts +9 -9
  27. package/dist/types/src/components/SearchResults/SearchResults.d.ts.map +1 -1
  28. package/dist/types/src/components/SearchResults/SearchResults.stories.d.ts +1 -2
  29. package/dist/types/src/components/SearchResults/SearchResults.stories.d.ts.map +1 -1
  30. package/dist/types/src/components/Searchbar/Searchbar.d.ts +5 -9
  31. package/dist/types/src/components/Searchbar/Searchbar.d.ts.map +1 -1
  32. package/dist/types/src/components/Searchbar/Searchbar.stories.d.ts +1 -2
  33. package/dist/types/src/components/Searchbar/Searchbar.stories.d.ts.map +1 -1
  34. package/dist/types/src/hooks/index.d.ts +1 -0
  35. package/dist/types/src/hooks/index.d.ts.map +1 -1
  36. package/dist/types/src/hooks/sync.d.ts.map +1 -1
  37. package/dist/types/src/meta.d.ts +1 -2
  38. package/dist/types/src/meta.d.ts.map +1 -1
  39. package/dist/types/src/search/exa.d.ts +1 -1
  40. package/dist/types/src/search/exa.d.ts.map +1 -1
  41. package/dist/types/src/types/action.d.ts +3 -3
  42. package/dist/types/src/types/action.d.ts.map +1 -1
  43. package/dist/types/tsconfig.tsbuildinfo +1 -1
  44. package/package.json +39 -39
  45. package/src/SearchPlugin.tsx +41 -42
  46. package/src/capabilities/app-graph-builder.ts +14 -13
  47. package/src/capabilities/react-surface.tsx +0 -3
  48. package/src/components/Search.stories.tsx +6 -17
  49. package/src/components/SearchDialog.tsx +23 -11
  50. package/src/components/SearchMain.tsx +31 -37
  51. package/src/components/SearchResults/SearchResults.stories.tsx +4 -5
  52. package/src/components/SearchResults/SearchResults.tsx +46 -49
  53. package/src/components/Searchbar/Searchbar.stories.tsx +1 -3
  54. package/src/components/Searchbar/Searchbar.tsx +26 -45
  55. package/src/hooks/index.ts +2 -0
  56. package/src/hooks/sync.ts +5 -4
  57. package/src/hooks/useSearchResults.ts +2 -2
  58. package/src/hooks/useWebSearch.ts +1 -1
  59. package/src/meta.ts +8 -5
  60. package/src/search/exa.test.ts +8 -10
  61. package/src/search/exa.ts +6 -4
  62. package/src/types/action.tsx +3 -3
  63. package/dist/lib/browser/app-graph-builder-D2QQTIIR.mjs.map +0 -7
  64. package/dist/lib/browser/chunk-JVMYGOKS.mjs.map +0 -7
  65. package/dist/lib/browser/chunk-KNS62YL2.mjs +0 -20
  66. package/dist/lib/browser/chunk-KNS62YL2.mjs.map +0 -7
  67. package/dist/lib/browser/chunk-YJGLEPHU.mjs.map +0 -7
  68. package/dist/lib/browser/react-surface-LNREIVO7.mjs +0 -468
  69. package/dist/lib/browser/react-surface-LNREIVO7.mjs.map +0 -7
@@ -2,11 +2,9 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import '@dxos-theme';
6
-
7
5
  import { type Meta, type StoryObj } from '@storybook/react-vite';
8
6
 
9
- import { withTheme } from '@dxos/storybook-utils';
7
+ import { withTheme } from '@dxos/react-ui/testing';
10
8
 
11
9
  import { Searchbar } from './Searchbar';
12
10
 
@@ -2,66 +2,47 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import React, { type KeyboardEvent, useEffect, useRef, useState } from 'react';
5
+ import React, { type KeyboardEvent, useCallback, useRef } from 'react';
6
6
 
7
- import { Icon, Input, type TextInputProps } from '@dxos/react-ui';
7
+ import { Input, type TextInputProps, type ThemedClassName, Toolbar, useControlledState } from '@dxos/react-ui';
8
8
 
9
- export type SearchbarProps = Pick<TextInputProps, 'variant' | 'placeholder'> & {
10
- classes?: {
11
- root?: string;
12
- input?: string;
13
- };
14
- value?: string;
15
- onChange?: (text?: string) => void;
16
- onSubmit?: (text?: string) => void;
17
- delay?: number;
18
- };
9
+ export type SearchbarProps = ThemedClassName<
10
+ Pick<TextInputProps, 'variant' | 'placeholder'> & {
11
+ delay?: number;
12
+ value?: string;
13
+ onChange?: (text?: string) => void;
14
+ onSubmit?: (text?: string) => void;
15
+ }
16
+ >;
19
17
 
20
- export const Searchbar = ({ classes, variant, placeholder, value, onChange, onSubmit }: SearchbarProps) => {
18
+ export const Searchbar = ({ classNames, variant, placeholder, value, onChange, onSubmit }: SearchbarProps) => {
19
+ const [text, setText] = useControlledState(value, onChange);
21
20
  const inputRef = useRef<HTMLInputElement>(null);
22
- const [text, setText] = useState(value);
23
- useEffect(() => {
24
- setText(value);
25
- }, [value]);
26
- const handleChange = (text?: string) => {
27
- setText(text);
28
- onChange?.(text);
29
- };
30
-
31
- const handleReset = () => {
32
- handleChange(undefined);
33
- inputRef.current?.focus();
34
- };
35
21
 
36
- const handleKeyDown = (event: KeyboardEvent<HTMLInputElement>) => {
37
- switch (event.key) {
38
- case 'Enter':
39
- onSubmit?.(text);
40
- break;
41
- case 'Escape':
42
- handleReset();
43
- break;
44
- }
45
- };
22
+ const handleKeyDown = useCallback(
23
+ (event: KeyboardEvent<HTMLInputElement>) => {
24
+ switch (event.key) {
25
+ case 'Enter':
26
+ onSubmit?.(text);
27
+ break;
28
+ }
29
+ },
30
+ [text, onSubmit],
31
+ );
46
32
 
47
33
  return (
48
- <div className='flex shrink-0w-full items-center pli-1 pbs-1'>
34
+ <Toolbar.Root classNames={classNames}>
49
35
  <Input.Root>
50
36
  <Input.TextInput
51
37
  ref={inputRef}
52
38
  placeholder={placeholder}
39
+ autoFocus
53
40
  variant={variant}
54
41
  value={text ?? ''}
55
- classNames={['pl-3 pr-10', classes?.input]}
56
- onChange={({ target }) => handleChange(target.value)}
42
+ onChange={({ target }) => setText(target.value)}
57
43
  onKeyDown={handleKeyDown}
58
44
  />
59
-
60
- {/* TODO(burdon): Margin should be density specific. */}
61
- <div role='button' className='-ml-7 p-0 cursor-pointer' onClick={handleReset}>
62
- <Icon icon='ph--magnifying-glass--regular' size={5} />
63
- </div>
64
45
  </Input.Root>
65
- </div>
46
+ </Toolbar.Root>
66
47
  );
67
48
  };
@@ -3,5 +3,7 @@
3
3
  //
4
4
 
5
5
  export * from './sync';
6
+
6
7
  export * from './useGlobalSearch';
7
8
  export * from './useSearchResults';
9
+ export * from './useWebSearch';
package/src/hooks/sync.ts CHANGED
@@ -2,10 +2,11 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import { type Schema, SchemaAST } from 'effect';
5
+ import type * as Schema from 'effect/Schema';
6
+ import * as SchemaAST from 'effect/SchemaAST';
6
7
 
7
8
  import { Obj } from '@dxos/echo';
8
- import { DataType } from '@dxos/schema';
9
+ import { Text } from '@dxos/schema';
9
10
 
10
11
  import { type SearchResult } from '../types';
11
12
 
@@ -45,7 +46,7 @@ export const filterObjectsSync = <T extends Record<string, any>>(objects: T[], m
45
46
 
46
47
  return objects.reduce<SearchResult[]>((results, object) => {
47
48
  // TODO(burdon): Hack to ignore Text objects.
48
- if (object instanceof DataType.Text) {
49
+ if (object instanceof Text.Text) {
49
50
  return results;
50
51
  }
51
52
 
@@ -111,7 +112,7 @@ const getKeys = (object: Record<string, unknown>): string[] => {
111
112
  export const mapObjectToTextFields = <T extends Record<string, unknown>>(object: T): TextFields => {
112
113
  return getKeys(object).reduce<TextFields>((fields, key) => {
113
114
  const value = object[key] as any;
114
- if (typeof value === 'string' || value instanceof DataType.Text) {
115
+ if (typeof value === 'string' || value instanceof Text.Text) {
115
116
  try {
116
117
  fields[key] = String(value);
117
118
  } catch (err) {
@@ -5,7 +5,7 @@
5
5
  import { yieldOrContinue } from 'main-thread-scheduling';
6
6
  import { useEffect, useState } from 'react';
7
7
 
8
- import { DataType } from '@dxos/schema';
8
+ import { Text } from '@dxos/schema';
9
9
 
10
10
  // TODO(thure): Deprecate search-sync, move still-relevant utilities elsewhere (here, probably).
11
11
  import { mapObjectToTextFields, queryStringToMatch } from './sync';
@@ -20,7 +20,7 @@ export const filterObjects = async <T extends Record<string, any>>(
20
20
  }
21
21
  await Promise.all(
22
22
  objects
23
- .filter((object) => !(object instanceof DataType.Text))
23
+ .filter((object) => !(object instanceof Text.Text))
24
24
  .map(async (object) => {
25
25
  await yieldOrContinue('interactive');
26
26
  const fields = mapObjectToTextFields<T>(object);
@@ -27,7 +27,7 @@ export const useWebSearch = ({ query, context }: { query?: string; context?: str
27
27
  const results = await search({
28
28
  query,
29
29
  context,
30
- schema: [Testing.Project, Testing.Organization, Testing.Contact],
30
+ schema: [Testing.Project, Testing.Organization, Testing.Person],
31
31
  exaApiKey: EXA_API_KEY,
32
32
  });
33
33
 
package/src/meta.ts CHANGED
@@ -3,15 +3,18 @@
3
3
  //
4
4
 
5
5
  import { type PluginMeta } from '@dxos/app-framework';
6
-
7
- export const SEARCH_PLUGIN = 'dxos.org/plugin/search';
8
- export const SEARCH_RESULT = `${SEARCH_PLUGIN}/result`;
6
+ import { trim } from '@dxos/util';
9
7
 
10
8
  export const meta: PluginMeta = {
11
- id: SEARCH_PLUGIN,
9
+ id: 'dxos.org/plugin/search',
12
10
  name: 'Search',
13
- description: 'Search ECHO spaces for content.',
11
+ description: trim`
12
+ Full-text search engine for finding content across all spaces and object types.
13
+ Quickly locate documents, tables, and other objects with instant results and relevance ranking.
14
+ `,
14
15
  icon: 'ph--magnifying-glass--regular',
15
16
  source: 'https://github.com/dxos/dxos/tree/main/packages/plugins/plugin-search',
16
17
  tags: ['labs'],
17
18
  };
19
+
20
+ export const SEARCH_RESULT = `${meta.id}/result`;
@@ -7,7 +7,6 @@ import { describe, test } from 'vitest';
7
7
  import { EXA_API_KEY } from '@dxos/ai/testing';
8
8
  import { log } from '@dxos/log';
9
9
  import { Testing } from '@dxos/schema/testing';
10
- import { trim } from '@dxos/util';
11
10
 
12
11
  import { search } from './exa';
13
12
 
@@ -16,7 +15,7 @@ describe.skip('Search', () => {
16
15
  test.skip('contacts', { timeout: 60_000 }, async () => {
17
16
  const objects = await search({
18
17
  query: 'top executives at google',
19
- schema: [Testing.Contact],
18
+ schema: [Testing.Person],
20
19
  exaApiKey: EXA_API_KEY,
21
20
  });
22
21
 
@@ -26,7 +25,7 @@ describe.skip('Search', () => {
26
25
  test.skip('contacts projects and orgs', { timeout: 60_000 }, async () => {
27
26
  const objects = await search({
28
27
  query: 'top executives at google',
29
- schema: [Testing.Contact, Testing.Project, Testing.Organization],
28
+ schema: [Testing.Person, Testing.Project, Testing.Organization],
30
29
  exaApiKey: EXA_API_KEY,
31
30
  });
32
31
 
@@ -36,7 +35,7 @@ describe.skip('Search', () => {
36
35
  test('a19z org, projects they invest in and team', { timeout: 60_000 }, async () => {
37
36
  const objects = await search({
38
37
  query: 'a19z org, projects they invest in and team',
39
- schema: [Testing.Project, Testing.Organization, Testing.Contact],
38
+ schema: [Testing.Project, Testing.Organization, Testing.Person],
40
39
  exaApiKey: EXA_API_KEY,
41
40
  });
42
41
 
@@ -46,7 +45,7 @@ describe.skip('Search', () => {
46
45
  test('companies building CRDTs', { timeout: 60_000 }, async () => {
47
46
  const objects = await search({
48
47
  query: 'companies building CRDTs',
49
- schema: [Testing.Project, Testing.Organization, Testing.Contact],
48
+ schema: [Testing.Project, Testing.Organization, Testing.Person],
50
49
  exaApiKey: EXA_API_KEY,
51
50
  });
52
51
 
@@ -58,7 +57,7 @@ describe.skip('Search', () => {
58
57
  test('composer context-based search', { timeout: 60_000 }, async () => {
59
58
  const objects = await search({
60
59
  context: COMPOSER_DXOS_DOC,
61
- schema: [Testing.Project, Testing.Organization, Testing.Contact],
60
+ schema: [Testing.Project, Testing.Organization, Testing.Person],
62
61
  exaApiKey: EXA_API_KEY,
63
62
  });
64
63
 
@@ -68,7 +67,7 @@ describe.skip('Search', () => {
68
67
  test.only('edge architecture', { timeout: 60_000 }, async () => {
69
68
  const objects = await search({
70
69
  context: EDGE_ARCHITECTURE_DOC,
71
- schema: [Testing.Project, Testing.Organization, Testing.Contact],
70
+ schema: [Testing.Project, Testing.Organization, Testing.Person],
72
71
  exaApiKey: EXA_API_KEY,
73
72
  });
74
73
 
@@ -77,8 +76,7 @@ describe.skip('Search', () => {
77
76
  });
78
77
  });
79
78
 
80
- // TODO(dmaretskyi): Import as txt.
81
- const COMPOSER_DXOS_DOC = trim`
79
+ const COMPOSER_DXOS_DOC = `
82
80
  ![img](https://dxos.network/dxos-logotype-blue.png)
83
81
  # Welcome to Composer by DXOS
84
82
 
@@ -86,7 +84,7 @@ const COMPOSER_DXOS_DOC = trim`
86
84
 
87
85
  Composer is an extensible application that includes familiar components such as documents, diagrams, and tables. It leverages DXOS — a full stack framework for building collaborative local-first applications.
88
86
 
89
- With our upcoming SDK, you'll be able to build custom plugins, leverage external APIs and integrate with LLMs. All inside of a private collaborative workspace.
87
+ With our SDK, you'll be able to build custom plugins, leverage external APIs and integrate with LLMs. All inside of a private collaborative workspace.
90
88
 
91
89
  ## Disclaimer
92
90
 
package/src/search/exa.ts CHANGED
@@ -4,11 +4,13 @@
4
4
 
5
5
  // ISSUE(burdon): deprecated types: MixedStreamParser => effect
6
6
 
7
- import { Option, Schema, SchemaAST } from 'effect';
7
+ import * as Option from 'effect/Option';
8
+ import * as Schema from 'effect/Schema';
9
+ import * as SchemaAST from 'effect/SchemaAST';
8
10
 
9
11
  import { Key, Obj } from '@dxos/echo';
12
+ import { ReferenceAnnotationId } from '@dxos/echo/internal';
10
13
  import { isEncodedReference } from '@dxos/echo-protocol';
11
- import { ReferenceAnnotationId } from '@dxos/echo-schema';
12
14
  import { mapAst } from '@dxos/effect';
13
15
  import { deepMapValues, trim } from '@dxos/util';
14
16
 
@@ -61,7 +63,7 @@ export const search = async <Schema extends Schema.Schema.AnyNoContext>(
61
63
  // model: '@anthropic/claude-3-5-haiku-20241022',
62
64
  // systemPrompt,
63
65
  // history: [
64
- // Obj.make(DataType.Message, {
66
+ // Obj.make(Message.Message, {
65
67
  // created: new Date().toISOString(),
66
68
  // sender: { role: 'user' },
67
69
  // blocks: context.results.map(
@@ -157,7 +159,7 @@ const DATA_EXTRACTION_INSTRUCTIONS = trim`
157
159
  // Prefer own names of people, companies, and projects, technologies, and other entities.
158
160
  // `,
159
161
  // history: [
160
- // Obj.make(DataType.Message, {
162
+ // Obj.make(Message.Message, {
161
163
  // created: new Date().toISOString(),
162
164
  // sender: { role: 'user' },
163
165
  // blocks: [
@@ -2,12 +2,12 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import { Schema } from 'effect';
5
+ import * as Schema from 'effect/Schema';
6
6
 
7
- import { SEARCH_PLUGIN } from '../meta';
7
+ import { meta } from '../meta';
8
8
 
9
9
  export namespace SearchAction {
10
- const SEARCH_ACTION = `${SEARCH_PLUGIN}/action`;
10
+ const SEARCH_ACTION = `${meta.id}/action`;
11
11
 
12
12
  export class OpenSearch extends Schema.TaggedClass<OpenSearch>()(`${SEARCH_ACTION}/open-search`, {
13
13
  input: Schema.Void,
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/capabilities/app-graph-builder.ts"],
4
- "sourcesContent": ["//\n// Copyright 2025 DXOS.org\n//\n\nimport { Rx } from '@effect-rx/rx-react';\nimport { Option, pipe } from 'effect';\n\nimport { Capabilities, type PluginContext, contributes, createIntent } from '@dxos/app-framework';\nimport { ClientCapabilities } from '@dxos/plugin-client';\nimport { ATTENDABLE_PATH_SEPARATOR, DECK_COMPANION_TYPE } from '@dxos/plugin-deck/types';\nimport { ROOT_ID, createExtension, rxFromSignal } from '@dxos/plugin-graph';\nimport { parseId } from '@dxos/react-client/echo';\n\nimport { SEARCH_PLUGIN } from '../meta';\nimport { SearchAction } from '../types';\n\nexport default (context: PluginContext) =>\n contributes(Capabilities.AppGraphBuilder, [\n createExtension({\n id: `${SEARCH_PLUGIN}/space-search`,\n connector: (node) =>\n Rx.make((get) =>\n pipe(\n get(node),\n Option.flatMap((node) => (node.id === ROOT_ID ? Option.some(node) : Option.none())),\n Option.map((node) => {\n const workspace = get(rxFromSignal(() => context.getCapability(Capabilities.Layout).workspace));\n const client = context.getCapability(ClientCapabilities.Client);\n const { spaceId } = parseId(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: SEARCH_PLUGIN }],\n icon: 'ph--magnifying-glass--regular',\n disposition: 'hidden',\n },\n },\n ];\n }),\n Option.getOrElse(() => []),\n ),\n ),\n }),\n createExtension({\n id: SEARCH_PLUGIN,\n actions: (node) =>\n Rx.make((get) =>\n pipe(\n get(node),\n Option.flatMap((node) => (node.id === ROOT_ID ? Option.some(node) : Option.none())),\n Option.map(() => {\n return [\n {\n id: SearchAction.OpenSearch._tag,\n data: async () => {\n const { dispatchPromise: dispatch } = context.getCapability(Capabilities.IntentDispatcher);\n await dispatch(createIntent(SearchAction.OpenSearch));\n },\n properties: {\n label: ['search action label', { ns: SEARCH_PLUGIN }],\n icon: 'ph--magnifying-glass--regular',\n keyBinding: {\n macos: 'shift+meta+f',\n windows: 'shift+alt+f',\n },\n },\n },\n ];\n }),\n Option.getOrElse(() => []),\n ),\n ),\n }),\n ]);\n"],
5
- "mappings": ";;;;;;;;AAIA,SAASA,UAAU;AACnB,SAASC,QAAQC,YAAY;AAE7B,SAASC,cAAkCC,aAAaC,oBAAoB;AAC5E,SAASC,0BAA0B;AACnC,SAASC,2BAA2BC,2BAA2B;AAC/D,SAASC,SAASC,iBAAiBC,oBAAoB;AACvD,SAASC,eAAe;AAKxB,IAAA,4BAAe,CAACC,YACdC,YAAYC,aAAaC,iBAAiB;EACxCC,gBAAgB;IACdC,IAAI,GAAGC,aAAAA;IACPC,WAAW,CAACC,SACVC,GAAGC,KAAK,CAACC,QACPC,KACED,IAAIH,IAAAA,GACJK,OAAOC,QAAQ,CAACN,UAAUA,MAAKH,OAAOU,UAAUF,OAAOG,KAAKR,KAAAA,IAAQK,OAAOI,KAAI,CAAA,GAC/EJ,OAAOK,IAAI,CAACV,UAAAA;AACV,YAAMW,YAAYR,IAAIS,aAAa,MAAMpB,QAAQqB,cAAcnB,aAAaoB,MAAM,EAAEH,SAAS,CAAA;AAC7F,YAAMI,SAASvB,QAAQqB,cAAcG,mBAAmBC,MAAM;AAC9D,YAAM,EAAEC,QAAO,IAAKC,QAAQR,SAAAA;AAC5B,YAAMS,QAAQF,UAAUH,OAAOM,OAAOlB,IAAIe,OAAAA,IAAW;AAErD,aAAO;QACL;UACErB,IAAI;YAACG,MAAKH;YAAI;YAAUyB,KAAKC,yBAAAA;UAC7BC,MAAMC;UACNC,MAAMN;UACNO,YAAY;YACVC,OAAO;cAAC;cAAgB;gBAAEC,IAAI/B;cAAc;;YAC5CgC,MAAM;YACNC,aAAa;UACf;QACF;;IAEJ,CAAA,GACA1B,OAAO2B,UAAU,MAAM,CAAA,CAAE,CAAA,CAAA;EAGjC,CAAA;EACApC,gBAAgB;IACdC,IAAIC;IACJmC,SAAS,CAACjC,SACRC,GAAGC,KAAK,CAACC,QACPC,KACED,IAAIH,IAAAA,GACJK,OAAOC,QAAQ,CAACN,UAAUA,MAAKH,OAAOU,UAAUF,OAAOG,KAAKR,KAAAA,IAAQK,OAAOI,KAAI,CAAA,GAC/EJ,OAAOK,IAAI,MAAA;AACT,aAAO;QACL;UACEb,IAAIqC,aAAaC,WAAWC;UAC5BV,MAAM,YAAA;AACJ,kBAAM,EAAEW,iBAAiBC,SAAQ,IAAK9C,QAAQqB,cAAcnB,aAAa6C,gBAAgB;AACzF,kBAAMD,SAASE,aAAaN,aAAaC,UAAU,CAAA;UACrD;UACAR,YAAY;YACVC,OAAO;cAAC;cAAuB;gBAAEC,IAAI/B;cAAc;;YACnDgC,MAAM;YACNW,YAAY;cACVC,OAAO;cACPC,SAAS;YACX;UACF;QACF;;IAEJ,CAAA,GACAtC,OAAO2B,UAAU,MAAM,CAAA,CAAE,CAAA,CAAA;EAGjC,CAAA;CACD;",
6
- "names": ["Rx", "Option", "pipe", "Capabilities", "contributes", "createIntent", "ClientCapabilities", "ATTENDABLE_PATH_SEPARATOR", "DECK_COMPANION_TYPE", "ROOT_ID", "createExtension", "rxFromSignal", "parseId", "context", "contributes", "Capabilities", "AppGraphBuilder", "createExtension", "id", "SEARCH_PLUGIN", "connector", "node", "Rx", "make", "get", "pipe", "Option", "flatMap", "ROOT_ID", "some", "none", "map", "workspace", "rxFromSignal", "getCapability", "Layout", "client", "ClientCapabilities", "Client", "spaceId", "parseId", "space", "spaces", "join", "ATTENDABLE_PATH_SEPARATOR", "type", "DECK_COMPANION_TYPE", "data", "properties", "label", "ns", "icon", "disposition", "getOrElse", "actions", "SearchAction", "OpenSearch", "_tag", "dispatchPromise", "dispatch", "IntentDispatcher", "createIntent", "keyBinding", "macos", "windows"]
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/types/action.tsx"],
4
- "sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport { Schema } from 'effect';\n\nimport { SEARCH_PLUGIN } from '../meta';\n\nexport namespace SearchAction {\n const SEARCH_ACTION = `${SEARCH_PLUGIN}/action`;\n\n export class OpenSearch extends Schema.TaggedClass<OpenSearch>()(`${SEARCH_ACTION}/open-search`, {\n input: Schema.Void,\n output: Schema.Void,\n }) {}\n}\n"],
5
- "mappings": ";;;;;AAIA,SAASA,cAAc;UAINC,eAAAA;AACf,QAAMC,gBAAgB,GAAGC,aAAAA;EAElB,MAAMC,mBAAmBC,OAAOC,YAAW,EAAe,GAAGJ,aAAAA,gBAA6B;IAC/FK,OAAOF,OAAOG;IACdC,QAAQJ,OAAOG;EACjB,CAAA,EAAA;EAAI;gBAHSJ,aAAAA;AAIf,GAPiBH,iBAAAA,eAAAA,CAAAA,EAAAA;;",
6
- "names": ["Schema", "SearchAction", "SEARCH_ACTION", "SEARCH_PLUGIN", "OpenSearch", "Schema", "TaggedClass", "input", "Void", "output"]
7
- }
@@ -1,20 +0,0 @@
1
- // src/meta.ts
2
- var SEARCH_PLUGIN = "dxos.org/plugin/search";
3
- var SEARCH_RESULT = `${SEARCH_PLUGIN}/result`;
4
- var meta = {
5
- id: SEARCH_PLUGIN,
6
- name: "Search",
7
- description: "Search ECHO spaces for content.",
8
- icon: "ph--magnifying-glass--regular",
9
- source: "https://github.com/dxos/dxos/tree/main/packages/plugins/plugin-search",
10
- tags: [
11
- "labs"
12
- ]
13
- };
14
-
15
- export {
16
- SEARCH_PLUGIN,
17
- SEARCH_RESULT,
18
- meta
19
- };
20
- //# sourceMappingURL=chunk-KNS62YL2.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 PluginMeta } from '@dxos/app-framework';\n\nexport const SEARCH_PLUGIN = 'dxos.org/plugin/search';\nexport const SEARCH_RESULT = `${SEARCH_PLUGIN}/result`;\n\nexport const meta: PluginMeta = {\n id: SEARCH_PLUGIN,\n name: 'Search',\n description: 'Search ECHO spaces for content.',\n icon: 'ph--magnifying-glass--regular',\n source: 'https://github.com/dxos/dxos/tree/main/packages/plugins/plugin-search',\n tags: ['labs'],\n};\n"],
5
- "mappings": ";AAMO,IAAMA,gBAAgB;AACtB,IAAMC,gBAAgB,GAAGD,aAAAA;AAEzB,IAAME,OAAmB;EAC9BC,IAAIH;EACJI,MAAM;EACNC,aAAa;EACbC,MAAM;EACNC,QAAQ;EACRC,MAAM;IAAC;;AACT;",
6
- "names": ["SEARCH_PLUGIN", "SEARCH_RESULT", "meta", "id", "name", "description", "icon", "source", "tags"]
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/hooks/sync.ts", "../../../src/hooks/useGlobalSearch.tsx", "../../../src/hooks/useSearchResults.ts"],
4
- "sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport { type Schema, SchemaAST } from 'effect';\n\nimport { Obj } from '@dxos/echo';\nimport { DataType } from '@dxos/schema';\n\nimport { type SearchResult } from '../types';\n\nexport const queryStringToMatch = (queryString?: string): RegExp | undefined => {\n const trimmed = queryString?.trim();\n return trimmed ? new RegExp(trimmed, 'i') : undefined;\n};\n\n// TODO(burdon): Type name registry linked to schema?\nconst getIcon = (schema: Schema.Schema.AnyNoContext | undefined): string | undefined => {\n if (!(schema && SchemaAST.isTypeLiteral(schema.ast))) {\n return undefined;\n }\n const keys = schema.ast.propertySignatures.map((p) => p.name);\n if (keys.indexOf('email') !== -1) {\n return 'user';\n }\n if (keys.indexOf('website') !== -1) {\n return 'organization';\n }\n if (keys.indexOf('repo') !== -1) {\n return 'project';\n }\n\n return undefined;\n};\n\n// Plain text fields.\n// TODO(burdon): Reconcile with agent index.\nexport type TextFields = Record<string, string>;\n\n// TODO(thure): This returns `SearchResult[]` which is not just a narrower set of objects as the name implies.\nexport const filterObjectsSync = <T extends Record<string, any>>(objects: T[], match?: RegExp): SearchResult[] => {\n if (!match) {\n return [];\n }\n\n return objects.reduce<SearchResult[]>((results, object) => {\n // TODO(burdon): Hack to ignore Text objects.\n if (object instanceof DataType.Text) {\n return results;\n }\n\n const fields = mapObjectToTextFields(object);\n Object.entries(fields).some(([, value]) => {\n const result = value.match(match);\n if (result) {\n // TODO(burdon): Use schema.\n const label = getStringProperty(object, ['label', 'name', 'title']);\n\n results.push({\n id: object.id,\n type: getIcon(Obj.getSchema(object)),\n label,\n match,\n // TODO(burdon): Truncate.\n // TODO(burdon): Issue with sketch documents.\n snippet: value !== label ? value : (fields.content ?? fields.description ?? undefined),\n object,\n });\n\n return true;\n }\n\n return false;\n });\n\n return results;\n }, []);\n};\n\n// TODO(burdon): Use schema?\nexport const getStringProperty = (object: any, keys: string[]): string | undefined => {\n let label;\n keys.some((key) => {\n const value = object[key];\n if (typeof value === 'string') {\n label = value;\n return true;\n }\n\n return false;\n });\n\n return label;\n};\n\n// TODO(burdon): Filter system fields.\nconst getKeys = (object: Record<string, unknown>): string[] => {\n try {\n const obj = JSON.parse(JSON.stringify(object));\n return Object.keys(obj).filter(\n (key) => key !== 'id' && key !== 'identityKey' && key[0] !== '_' && key[0] !== '@',\n ) as string[];\n } catch (err) {\n // TODO(burdon): Error with TLDraw sketch.\n // Uncaught Error: Type with the name content has already been defined with a different constructor\n return [];\n }\n};\n\n// TODO(burdon): Use ECHO schema.\nexport const mapObjectToTextFields = <T extends Record<string, unknown>>(object: T): TextFields => {\n return getKeys(object).reduce<TextFields>((fields, key) => {\n const value = object[key] as any;\n if (typeof value === 'string' || value instanceof DataType.Text) {\n try {\n fields[key] = String(value);\n } catch (err) {\n // TODO(burdon): Exception when parsing sketch document.\n }\n }\n\n return fields;\n }, {});\n};\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport React, { type PropsWithChildren, createContext, useContext, useMemo, useState } from 'react';\n\nimport { raise } from '@dxos/debug';\n\nimport { type SearchResult } from '../types';\n\nimport { filterObjectsSync, queryStringToMatch } from './sync';\n\ntype SearchContextType = {\n match?: RegExp;\n setMatch?: (text?: string) => void;\n};\n\nconst SearchContext = createContext<SearchContextType>({});\n\nexport const SearchContextProvider = ({ children }: PropsWithChildren) => {\n const [match, setMatch] = useState<RegExp>();\n const handleMatch = (text?: string) => setMatch(queryStringToMatch(text));\n return <SearchContext.Provider value={{ match, setMatch: handleMatch }}>{children}</SearchContext.Provider>;\n};\n\nexport const useGlobalSearch = () => {\n return useContext(SearchContext) ?? raise(new Error('Missing SearchContext.'));\n};\n\nexport const useGlobalSearchResults = <T extends Record<string, any>>(objects?: T[]): SearchResult[] => {\n const { match } = useGlobalSearch();\n return objects && match ? filterObjectsSync(objects, match) : [];\n};\n\nexport const useGlobalFilteredObjects = <T extends Record<string, any>>(objects?: T[]): T[] => {\n const { match } = useGlobalSearch();\n if (!match || !objects) {\n return objects ?? [];\n }\n\n return useMemo(() => filterObjectsSync(objects, match).map((result) => result.object), [objects, match]);\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { yieldOrContinue } from 'main-thread-scheduling';\nimport { useEffect, useState } from 'react';\n\nimport { DataType } from '@dxos/schema';\n\n// TODO(thure): Deprecate search-sync, move still-relevant utilities elsewhere (here, probably).\nimport { mapObjectToTextFields, queryStringToMatch } from './sync';\n\nexport const filterObjects = async <T extends Record<string, any>>(\n objects: T[],\n match?: RegExp,\n): Promise<Map<T, string[][]>> => {\n const result = new Map<T, string[][]>();\n if (!match) {\n return result;\n }\n await Promise.all(\n objects\n .filter((object) => !(object instanceof DataType.Text))\n .map(async (object) => {\n await yieldOrContinue('interactive');\n const fields = mapObjectToTextFields<T>(object);\n Object.entries(fields)\n .filter(([_, value]) => value.match(match))\n .forEach(([key, value]) => {\n if (!result.has(object)) {\n result.set(object, []);\n }\n result.set(object, [...result.get(object)!, [key, value]]);\n });\n }),\n );\n return result;\n};\n\nexport const useSearchResults = <T extends Record<string, any>>(\n queryString?: string,\n objects?: T[],\n delay: number = 400,\n): [boolean, Map<T, string[][]>] => {\n const [results, setResults] = useState<Map<T, string[][]>>(new Map());\n const [pending, setPending] = useState(false);\n\n useEffect(() => {\n setPending(!!(objects && queryString));\n const timeout = setTimeout(async () => {\n const nextResults =\n objects && queryString ? await filterObjects(objects, queryStringToMatch(queryString)) : new Map();\n setResults(nextResults);\n setPending(false);\n }, delay);\n\n return () => clearTimeout(timeout);\n }, [queryString, objects]);\n\n return [pending, results];\n};\n"],
5
- "mappings": "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",
6
- "names": ["SchemaAST", "Obj", "DataType", "queryStringToMatch", "queryString", "trimmed", "trim", "RegExp", "undefined", "getIcon", "schema", "SchemaAST", "isTypeLiteral", "ast", "keys", "propertySignatures", "map", "p", "name", "indexOf", "filterObjectsSync", "objects", "match", "reduce", "results", "object", "DataType", "Text", "fields", "mapObjectToTextFields", "Object", "entries", "some", "value", "result", "label", "getStringProperty", "push", "id", "type", "Obj", "getSchema", "snippet", "content", "description", "key", "getKeys", "obj", "JSON", "parse", "stringify", "filter", "err", "String", "React", "createContext", "useContext", "useMemo", "useState", "raise", "SearchContext", "createContext", "SearchContextProvider", "children", "match", "setMatch", "useState", "handleMatch", "text", "queryStringToMatch", "Provider", "value", "useGlobalSearch", "useContext", "raise", "Error", "useGlobalSearchResults", "objects", "filterObjectsSync", "useGlobalFilteredObjects", "useMemo", "map", "result", "object", "yieldOrContinue", "useEffect", "useState", "DataType", "filterObjects", "objects", "match", "result", "Map", "Promise", "all", "filter", "object", "DataType", "Text", "map", "yieldOrContinue", "fields", "mapObjectToTextFields", "Object", "entries", "_", "value", "forEach", "key", "has", "set", "get", "useSearchResults", "queryString", "delay", "results", "setResults", "useState", "pending", "setPending", "useEffect", "timeout", "setTimeout", "nextResults", "queryStringToMatch", "clearTimeout"]
7
- }