@dxos/app-framework 0.4.8-main.eb5ae94 → 0.4.8-main.fff1521

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 (28) hide show
  1. package/dist/lib/browser/index.mjs +12 -11
  2. package/dist/lib/browser/index.mjs.map +3 -3
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/lib/browser/{plugin-FYTGDFFS.mjs → plugin-KEA4MEHK.mjs} +3 -3
  5. package/dist/lib/browser/plugin-KEA4MEHK.mjs.map +7 -0
  6. package/dist/lib/browser/{plugin-6XDXQ3BN.mjs → plugin-VCIF47DJ.mjs} +5 -5
  7. package/dist/lib/browser/plugin-VCIF47DJ.mjs.map +7 -0
  8. package/dist/lib/node/index.cjs +43 -42
  9. package/dist/lib/node/index.cjs.map +3 -3
  10. package/dist/lib/node/meta.json +1 -1
  11. package/dist/lib/node/{plugin-VEIZZVQP.cjs → plugin-3K3YXM6Z.cjs} +8 -8
  12. package/dist/lib/node/plugin-3K3YXM6Z.cjs.map +7 -0
  13. package/dist/lib/node/{plugin-ZJ26B7E5.cjs → plugin-ROMMITVM.cjs} +10 -10
  14. package/dist/lib/node/plugin-ROMMITVM.cjs.map +7 -0
  15. package/dist/types/src/plugins/PluginHost/PluginHost.d.ts.map +1 -1
  16. package/dist/types/src/plugins/SurfacePlugin/plugin.d.ts.map +1 -1
  17. package/dist/types/src/plugins/common/file.d.ts +1 -0
  18. package/dist/types/src/plugins/common/file.d.ts.map +1 -1
  19. package/package.json +9 -9
  20. package/src/plugins/IntentPlugin/plugin.tsx +2 -2
  21. package/src/plugins/PluginHost/PluginHost.tsx +5 -5
  22. package/src/plugins/SurfacePlugin/plugin.tsx +6 -7
  23. package/src/plugins/common/file.ts +4 -1
  24. package/tsconfig.json +3 -0
  25. package/dist/lib/browser/plugin-6XDXQ3BN.mjs.map +0 -7
  26. package/dist/lib/browser/plugin-FYTGDFFS.mjs.map +0 -7
  27. package/dist/lib/node/plugin-VEIZZVQP.cjs.map +0 -7
  28. package/dist/lib/node/plugin-ZJ26B7E5.cjs.map +0 -7
@@ -26,15 +26,15 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
26
26
  mod
27
27
  ));
28
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
- var plugin_VEIZZVQP_exports = {};
30
- __export(plugin_VEIZZVQP_exports, {
29
+ var plugin_3K3YXM6Z_exports = {};
30
+ __export(plugin_3K3YXM6Z_exports, {
31
31
  default: () => plugin_default
32
32
  });
33
- module.exports = __toCommonJS(plugin_VEIZZVQP_exports);
33
+ module.exports = __toCommonJS(plugin_3K3YXM6Z_exports);
34
34
  var import_chunk_DFST5IG5 = require("./chunk-DFST5IG5.cjs");
35
35
  var import_chunk_62W6CMGM = require("./chunk-62W6CMGM.cjs");
36
- var import_react = require("deepsignal/react");
37
- var import_react2 = __toESM(require("react"));
36
+ var import_react = __toESM(require("react"));
37
+ var E = __toESM(require("@dxos/echo-schema/schema"));
38
38
  var import_log = require("@dxos/log");
39
39
  const import_meta = {};
40
40
  var isUndoable = (chain) => chain.length > 0 && chain.every(({ result }) => result.undoable);
@@ -42,7 +42,7 @@ var __dxlog_file = "/home/runner/work/dxos/dxos/packages/sdk/app-framework/src/p
42
42
  var EXECUTION_LIMIT = 1e3;
43
43
  var HISTORY_LIMIT = 100;
44
44
  var IntentPlugin = () => {
45
- const state = (0, import_react.deepSignal)({
45
+ const state = E.object({
46
46
  dispatch: async () => ({}),
47
47
  undo: async () => ({}),
48
48
  history: [],
@@ -174,11 +174,11 @@ var IntentPlugin = () => {
174
174
  },
175
175
  provides: {
176
176
  intent: state,
177
- context: ({ children }) => /* @__PURE__ */ import_react2.default.createElement(import_chunk_DFST5IG5.IntentProvider, {
177
+ context: ({ children }) => /* @__PURE__ */ import_react.default.createElement(import_chunk_DFST5IG5.IntentProvider, {
178
178
  value: state
179
179
  }, children)
180
180
  }
181
181
  };
182
182
  };
183
183
  var plugin_default = IntentPlugin;
184
- //# sourceMappingURL=plugin-VEIZZVQP.cjs.map
184
+ //# sourceMappingURL=plugin-3K3YXM6Z.cjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/plugins/IntentPlugin/plugin.tsx", "../../../src/plugins/IntentPlugin/helpers.ts"],
4
+ "sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport React from 'react';\n\nimport * as E from '@dxos/echo-schema/schema';\nimport { log } from '@dxos/log';\n\nimport { type IntentContext, IntentProvider, type IntentExecution } from './IntentContext';\nimport { isUndoable } from './helpers';\nimport type { Intent, IntentResolver } from './intent';\nimport IntentMeta from './meta';\nimport {\n type IntentPluginProvides,\n type IntentResolverProvides,\n parseIntentResolverPlugin,\n IntentAction,\n} from './provides';\nimport type { PluginDefinition } from '../PluginHost';\nimport { filterPlugins, findPlugin } from '../helpers';\n\nconst EXECUTION_LIMIT = 1000;\nconst HISTORY_LIMIT = 100;\n\n/**\n * Allows plugins to register intent handlers and routes sent intents to the appropriate plugin.\n * Inspired by https://developer.android.com/reference/android/content/Intent.\n */\nconst IntentPlugin = (): PluginDefinition<IntentPluginProvides> => {\n const state = E.object<IntentContext>({\n dispatch: async () => ({}),\n undo: async () => ({}),\n history: [],\n registerResolver: () => () => {},\n });\n\n const dynamicResolvers = new Set<{ plugin: string; resolver: IntentResolver }>();\n\n return {\n meta: IntentMeta,\n ready: async (plugins) => {\n // Dispatch intent to associated plugin.\n const dispatch = async (intent: Intent) => {\n log('dispatch', { action: intent.action, intent });\n if (intent.plugin) {\n for (const entry of dynamicResolvers) {\n if (entry.plugin === intent.plugin) {\n const result = await entry.resolver(intent, plugins);\n if (result) {\n return result;\n }\n }\n }\n\n const plugin = findPlugin<IntentResolverProvides>(plugins, intent.plugin);\n const result = plugin?.provides.intent.resolver(intent, plugins);\n return result;\n }\n\n for (const entry of dynamicResolvers) {\n const result = await entry.resolver(intent, plugins);\n if (result) {\n return result;\n }\n }\n\n // Return resolved value from first plugin that handles the intent.\n for (const plugin of filterPlugins(plugins, parseIntentResolverPlugin)) {\n const result = await plugin.provides.intent.resolver(intent, plugins);\n if (result) {\n return result;\n }\n }\n\n // https://vitejs.dev/guide/env-and-mode#env-variables\n // TODO(wittjosiah): How to handle this more generically?\n if (import.meta?.env?.DEV) {\n log.warn('No plugin found to handle intent', intent);\n }\n };\n\n // Sequentially dispatch array of invents.\n const dispatchChain = async (intentOrArray: Intent | Intent[], depth = 0) => {\n if (depth > EXECUTION_LIMIT) {\n return {\n error: new Error(\n `Intent execution limit exceeded (${EXECUTION_LIMIT} iterations). This is likely due to an infinite loop within intent resolvers.`,\n ),\n };\n }\n\n const executionResults: IntentExecution[] = [];\n const chain = Array.isArray(intentOrArray) ? intentOrArray : [intentOrArray];\n for (const intent of chain) {\n const { result: prevResult } = executionResults.at(-1) ?? {};\n const data = intent.data ? { result: prevResult?.data, ...intent.data } : prevResult?.data;\n const result = await dispatch({ ...intent, data });\n\n if (!result || result?.error) {\n break;\n }\n\n executionResults.push({ intent, result });\n\n // TODO(wittjosiah): How does undo work with returned intents?\n result?.intents?.forEach((intents) => {\n void dispatchChain(intents, depth + 1);\n });\n }\n\n state.history = [...state.history.slice(0, HISTORY_LIMIT - 2), executionResults];\n\n if (isUndoable(executionResults)) {\n void dispatch({ action: IntentAction.SHOW_UNDO, data: { results: executionResults } });\n }\n\n return executionResults.at(-1)?.result;\n };\n\n const undo = async () => {\n const last = state.history.findLastIndex(isUndoable);\n const chain =\n last !== -1 &&\n state.history[last]?.map(({ intent, result }): Intent => {\n const data = result.undoable?.data ? { ...intent.data, ...result.undoable.data } : intent.data;\n return { ...intent, data, undo: true };\n });\n if (chain) {\n const result = await dispatchChain(chain);\n state.history = state.history.filter((_, index) => index !== last);\n return result;\n }\n };\n\n state.dispatch = dispatchChain;\n state.undo = undo;\n state.registerResolver = (plugin, resolver) => {\n const entry = { plugin, resolver };\n dynamicResolvers.add(entry);\n return () => dynamicResolvers.delete(entry);\n };\n },\n provides: {\n intent: state,\n context: ({ children }) => <IntentProvider value={state}>{children}</IntentProvider>,\n },\n };\n};\n\nexport default IntentPlugin;\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { type IntentExecution } from './IntentContext';\n\n/**\n * Check if the chain of intents is undoable.\n */\nexport const isUndoable = (chain: IntentExecution[]): boolean =>\n chain.length > 0 && chain.every(({ result }) => result.undoable);\n"],
5
+ "mappings": "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",
6
+ "names": ["isUndoable", "chain", "length", "every", "result", "undoable", "EXECUTION_LIMIT", "HISTORY_LIMIT", "IntentPlugin", "state", "object", "dispatch", "undo", "history", "registerResolver", "dynamicResolvers", "Set", "meta", "IntentMeta", "ready", "plugins", "intent", "log", "action", "plugin", "entry", "resolver", "findPlugin", "provides", "filterPlugins", "parseIntentResolverPlugin", "env", "DEV", "warn", "dispatchChain", "intentOrArray", "depth", "error", "Error", "executionResults", "Array", "isArray", "prevResult", "at", "data", "push", "intents", "forEach", "slice", "IntentAction", "SHOW_UNDO", "results", "last", "findLastIndex", "map", "filter", "_", "index", "add", "delete", "context", "children", "React", "IntentProvider", "value"]
7
+ }
@@ -26,36 +26,36 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
26
26
  mod
27
27
  ));
28
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
- var plugin_ZJ26B7E5_exports = {};
30
- __export(plugin_ZJ26B7E5_exports, {
29
+ var plugin_ROMMITVM_exports = {};
30
+ __export(plugin_ROMMITVM_exports, {
31
31
  default: () => plugin_default
32
32
  });
33
- module.exports = __toCommonJS(plugin_ZJ26B7E5_exports);
33
+ module.exports = __toCommonJS(plugin_ROMMITVM_exports);
34
34
  var import_chunk_BTZLKXA2 = require("./chunk-BTZLKXA2.cjs");
35
35
  var import_chunk_62W6CMGM = require("./chunk-62W6CMGM.cjs");
36
- var import_react = require("deepsignal/react");
37
- var import_react2 = __toESM(require("react"));
36
+ var import_react = __toESM(require("react"));
37
+ var E = __toESM(require("@dxos/echo-schema/schema"));
38
38
  var SurfacePlugin = () => {
39
- const state = (0, import_react.deepSignal)({
39
+ const state = E.object({
40
40
  components: {}
41
41
  });
42
42
  return {
43
43
  meta: import_chunk_BTZLKXA2.meta_default,
44
44
  ready: async (plugins) => {
45
- state.components = (0, import_react.shallow)((0, import_chunk_62W6CMGM.filterPlugins)(plugins, import_chunk_BTZLKXA2.parseSurfacePlugin).reduce((acc, plugin) => {
45
+ state.components = (0, import_chunk_62W6CMGM.filterPlugins)(plugins, import_chunk_BTZLKXA2.parseSurfacePlugin).reduce((acc, plugin) => {
46
46
  return {
47
47
  ...acc,
48
48
  [plugin.meta.id]: plugin.provides.surface.component
49
49
  };
50
- }, {}));
50
+ }, {});
51
51
  },
52
52
  provides: {
53
53
  surface: state,
54
- context: ({ children }) => /* @__PURE__ */ import_react2.default.createElement(import_chunk_BTZLKXA2.SurfaceProvider, {
54
+ context: ({ children }) => /* @__PURE__ */ import_react.default.createElement(import_chunk_BTZLKXA2.SurfaceProvider, {
55
55
  value: state
56
56
  }, children)
57
57
  }
58
58
  };
59
59
  };
60
60
  var plugin_default = SurfacePlugin;
61
- //# sourceMappingURL=plugin-ZJ26B7E5.cjs.map
61
+ //# sourceMappingURL=plugin-ROMMITVM.cjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/plugins/SurfacePlugin/plugin.tsx"],
4
+ "sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport React from 'react';\n\nimport * as E from '@dxos/echo-schema/schema';\n\nimport { SurfaceProvider, type SurfaceRootContext } from './SurfaceRootContext';\nimport SurfaceMeta from './meta';\nimport { parseSurfacePlugin, type SurfacePluginProvides } from './provides';\nimport type { PluginDefinition } from '../PluginHost';\nimport { filterPlugins } from '../helpers';\n\n/**\n * Provides a registry of surface components.\n */\nconst SurfacePlugin = (): PluginDefinition<SurfacePluginProvides> => {\n const state = E.object<SurfaceRootContext>({ components: {} });\n\n return {\n meta: SurfaceMeta,\n ready: async (plugins) => {\n state.components = filterPlugins(plugins, parseSurfacePlugin).reduce((acc, plugin) => {\n return { ...acc, [plugin.meta.id]: plugin.provides.surface.component };\n }, {});\n },\n provides: {\n surface: state,\n context: ({ children }) => <SurfaceProvider value={state}>{children}</SurfaceProvider>,\n },\n };\n};\n\nexport default SurfacePlugin;\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAIA,mBAAkB;AAElB,QAAmB;AAWnB,IAAMA,gBAAgB,MAAA;AACpB,QAAMC,QAAUC,EAAAA,OAA2B;IAAEC,YAAY,CAAC;EAAE,CAAA;AAE5D,SAAO;IACLC,MAAMC;IACNC,OAAO,OAAOC,YAAAA;AACZN,YAAME,iBAAaK,qCAAcD,SAASE,wCAAAA,EAAoBC,OAAO,CAACC,KAAKC,WAAAA;AACzE,eAAO;UAAE,GAAGD;UAAK,CAACC,OAAOR,KAAKS,EAAE,GAAGD,OAAOE,SAASC,QAAQC;QAAU;MACvE,GAAG,CAAC,CAAA;IACN;IACAF,UAAU;MACRC,SAASd;MACTgB,SAAS,CAAC,EAAEC,SAAQ,MAAO,6BAAAC,QAAA,cAACC,uCAAAA;QAAgBC,OAAOpB;SAAQiB,QAAAA;IAC7D;EACF;AACF;AAEA,IAAA,iBAAelB;",
6
+ "names": ["SurfacePlugin", "state", "object", "components", "meta", "SurfaceMeta", "ready", "plugins", "filterPlugins", "parseSurfacePlugin", "reduce", "acc", "plugin", "id", "provides", "surface", "component", "context", "children", "React", "SurfaceProvider", "value"]
7
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"PluginHost.d.ts","sourceRoot":"","sources":["../../../../../src/plugins/PluginHost/PluginHost.tsx"],"names":[],"mappings":"AAKA,OAAc,EAA8C,KAAK,SAAS,EAAY,MAAM,OAAO,CAAC;AAKpG,OAAO,EAAE,KAAK,aAAa,EAAkB,MAAM,iBAAiB,CAAC;AACrE,OAAO,EAAE,KAAK,MAAM,EAAE,KAAK,gBAAgB,EAAuB,MAAM,UAAU,CAAC;AACnF,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEjD,MAAM,MAAM,sBAAsB,GAAG;IACnC,KAAK,EAAE,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC;IAClC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC;IACzD,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,QAAQ,CAAC,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC,UAAU,CAAC,CAAC;IAC9C,WAAW,CAAC,EAAE,SAAS,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,OAAO,EAAE,aAAa,CAAC;CACxB,CAAC;AAEF,eAAO,MAAM,eAAe,WAAY,MAAM,2CACwD,CAAC;AAIvG;;GAEG;AACH,eAAO,MAAM,UAAU,4EAOpB,sBAAsB,KAAG,iBAAiB,kBAAkB,CAkC9D,CAAC;AAmFF;;GAEG;AACH,eAAO,MAAM,gBAAgB,4EAS5B,CAAC"}
1
+ {"version":3,"file":"PluginHost.d.ts","sourceRoot":"","sources":["../../../../../src/plugins/PluginHost/PluginHost.tsx"],"names":[],"mappings":"AAIA,OAAc,EAA8C,KAAK,SAAS,EAAY,MAAM,OAAO,CAAC;AAKpG,OAAO,EAAE,KAAK,aAAa,EAAkB,MAAM,iBAAiB,CAAC;AACrE,OAAO,EAAE,KAAK,MAAM,EAAE,KAAK,gBAAgB,EAAuB,MAAM,UAAU,CAAC;AACnF,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEjD,MAAM,MAAM,sBAAsB,GAAG;IACnC,KAAK,EAAE,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC;IAClC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC;IACzD,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,QAAQ,CAAC,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC,UAAU,CAAC,CAAC;IAC9C,WAAW,CAAC,EAAE,SAAS,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,OAAO,EAAE,aAAa,CAAC;CACxB,CAAC;AAEF,eAAO,MAAM,eAAe,WAAY,MAAM,2CACwD,CAAC;AAIvG;;GAEG;AACH,eAAO,MAAM,UAAU,4EAOpB,sBAAsB,KAAG,iBAAiB,kBAAkB,CAmC9D,CAAC;AAmFF;;GAEG;AACH,eAAO,MAAM,gBAAgB,4EAS5B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../../../../src/plugins/SurfacePlugin/plugin.tsx"],"names":[],"mappings":"AASA,OAAO,EAAsB,KAAK,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAC5E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAGtD;;GAEG;AACH,QAAA,MAAM,aAAa,QAAO,iBAAiB,qBAAqB,CAiB/D,CAAC;AAEF,eAAe,aAAa,CAAC"}
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../../../../src/plugins/SurfacePlugin/plugin.tsx"],"names":[],"mappings":"AAUA,OAAO,EAAsB,KAAK,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAC5E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAGtD;;GAEG;AACH,QAAA,MAAM,aAAa,QAAO,iBAAiB,qBAAqB,CAe/D,CAAC;AAEF,eAAe,aAAa,CAAC"}
@@ -5,6 +5,7 @@ export declare const defaultFileTypes: {
5
5
  text: string[];
6
6
  };
7
7
  export type FileInfo = {
8
+ url?: string;
8
9
  cid?: string;
9
10
  };
10
11
  export type FileUploader = (file: File) => Promise<FileInfo | undefined>;
@@ -1 +1 @@
1
- {"version":3,"file":"file.d.ts","sourceRoot":"","sources":["../../../../../src/plugins/common/file.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,eAAe,CAAC;AAE5C,eAAO,MAAM,gBAAgB;;;;CAI5B,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC,CAAC;AAEzE,MAAM,MAAM,mBAAmB,GAAG;IAChC,IAAI,EAAE;QACJ,MAAM,CAAC,EAAE,YAAY,CAAC;KACvB,CAAC;CACH,CAAC;AAGF,eAAO,MAAM,sBAAsB,WAAY,MAAM,4CAEpD,CAAC"}
1
+ {"version":3,"file":"file.d.ts","sourceRoot":"","sources":["../../../../../src/plugins/common/file.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,eAAe,CAAC;AAI5C,eAAO,MAAM,gBAAgB;;;;CAI5B,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC,CAAC;AAEzE,MAAM,MAAM,mBAAmB,GAAG;IAChC,IAAI,EAAE;QACJ,MAAM,CAAC,EAAE,YAAY,CAAC;KACvB,CAAC;CACH,CAAC;AAGF,eAAO,MAAM,sBAAsB,WAAY,MAAM,4CAEpD,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/app-framework",
3
- "version": "0.4.8-main.eb5ae94",
3
+ "version": "0.4.8-main.fff1521",
4
4
  "description": "A framework for building applications from composible plugins.",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -14,15 +14,15 @@
14
14
  "dependencies": {
15
15
  "@phosphor-icons/react": "^2.0.5",
16
16
  "@preact/signals-core": "^1.5.1",
17
- "deepsignal": "^1.5.0",
18
17
  "zod": "^3.22.4",
19
- "@dxos/app-graph": "0.4.8-main.eb5ae94",
20
- "@dxos/async": "0.4.8-main.eb5ae94",
21
- "@dxos/debug": "0.4.8-main.eb5ae94",
22
- "@dxos/invariant": "0.4.8-main.eb5ae94",
23
- "@dxos/local-storage": "0.4.8-main.eb5ae94",
24
- "@dxos/log": "0.4.8-main.eb5ae94",
25
- "@dxos/util": "0.4.8-main.eb5ae94"
18
+ "@dxos/debug": "0.4.8-main.fff1521",
19
+ "@dxos/echo-schema": "0.4.8-main.fff1521",
20
+ "@dxos/app-graph": "0.4.8-main.fff1521",
21
+ "@dxos/async": "0.4.8-main.fff1521",
22
+ "@dxos/invariant": "0.4.8-main.fff1521",
23
+ "@dxos/local-storage": "0.4.8-main.fff1521",
24
+ "@dxos/log": "0.4.8-main.fff1521",
25
+ "@dxos/util": "0.4.8-main.fff1521"
26
26
  },
27
27
  "devDependencies": {
28
28
  "@types/react": "^18.0.21",
@@ -2,9 +2,9 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import { deepSignal } from 'deepsignal/react';
6
5
  import React from 'react';
7
6
 
7
+ import * as E from '@dxos/echo-schema/schema';
8
8
  import { log } from '@dxos/log';
9
9
 
10
10
  import { type IntentContext, IntentProvider, type IntentExecution } from './IntentContext';
@@ -28,7 +28,7 @@ const HISTORY_LIMIT = 100;
28
28
  * Inspired by https://developer.android.com/reference/android/content/Intent.
29
29
  */
30
30
  const IntentPlugin = (): PluginDefinition<IntentPluginProvides> => {
31
- const state = deepSignal<IntentContext>({
31
+ const state = E.object<IntentContext>({
32
32
  dispatch: async () => ({}),
33
33
  undo: async () => ({}),
34
34
  history: [],
@@ -2,7 +2,6 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import { shallow } from 'deepsignal/react';
6
5
  import React, { useEffect, type FC, type PropsWithChildren, type ReactNode, useState } from 'react';
7
6
 
8
7
  import { LocalStorageStore } from '@dxos/local-storage';
@@ -48,14 +47,15 @@ export const PluginHost = ({
48
47
  available: order.filter(({ id }) => !core.includes(id)),
49
48
  setPlugin: (id: string, enabled: boolean) => {
50
49
  if (enabled) {
51
- state.values.enabled = [...state.values.enabled, id];
50
+ state.values.enabled.push(id);
52
51
  } else {
53
- state.values.enabled = state.values.enabled.filter((enabled) => enabled !== id);
52
+ const index = state.values.enabled.findIndex((enabled) => enabled === id);
53
+ index !== -1 && state.values.enabled.splice(index, 1);
54
54
  }
55
55
  },
56
56
  });
57
57
 
58
- state.prop(state.values.$enabled!, 'enabled', LocalStorageStore.json);
58
+ state.prop({ key: 'enabled', type: LocalStorageStore.json<string[]>() });
59
59
 
60
60
  return {
61
61
  meta: {
@@ -129,7 +129,7 @@ const Root = ({ order, core: corePluginIds, definitions, state, placeholder }: R
129
129
  await Promise.all(enabled.map((pluginDefinition) => pluginDefinition.ready?.(plugins)));
130
130
  log('plugins ready', { plugins });
131
131
 
132
- state.plugins = shallow(plugins);
132
+ state.plugins = plugins;
133
133
  state.ready = true;
134
134
  } catch (err) {
135
135
  setError(err);
@@ -2,9 +2,10 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import { deepSignal, shallow } from 'deepsignal/react';
6
5
  import React from 'react';
7
6
 
7
+ import * as E from '@dxos/echo-schema/schema';
8
+
8
9
  import { SurfaceProvider, type SurfaceRootContext } from './SurfaceRootContext';
9
10
  import SurfaceMeta from './meta';
10
11
  import { parseSurfacePlugin, type SurfacePluginProvides } from './provides';
@@ -15,16 +16,14 @@ import { filterPlugins } from '../helpers';
15
16
  * Provides a registry of surface components.
16
17
  */
17
18
  const SurfacePlugin = (): PluginDefinition<SurfacePluginProvides> => {
18
- const state = deepSignal<SurfaceRootContext>({ components: {} });
19
+ const state = E.object<SurfaceRootContext>({ components: {} });
19
20
 
20
21
  return {
21
22
  meta: SurfaceMeta,
22
23
  ready: async (plugins) => {
23
- state.components = shallow(
24
- filterPlugins(plugins, parseSurfacePlugin).reduce((acc, plugin) => {
25
- return { ...acc, [plugin.meta.id]: plugin.provides.surface.component };
26
- }, {}),
27
- );
24
+ state.components = filterPlugins(plugins, parseSurfacePlugin).reduce((acc, plugin) => {
25
+ return { ...acc, [plugin.meta.id]: plugin.provides.surface.component };
26
+ }, {});
28
27
  },
29
28
  provides: {
30
29
  surface: state,
@@ -4,13 +4,16 @@
4
4
 
5
5
  import { type Plugin } from '../PluginHost';
6
6
 
7
+ // TODO(burdon): See Accept attribute (uses MIME types).
8
+ // E.g., 'image/*': ['.jpg', '.jpeg', '.png', '.gif'],
7
9
  export const defaultFileTypes = {
8
- images: ['png', 'jpg', 'jpeg'],
10
+ images: ['png', 'jpg', 'jpeg', 'gif'],
9
11
  media: ['mp3', 'mp4', 'mov', 'avi'],
10
12
  text: ['pdf', 'txt', 'md'],
11
13
  };
12
14
 
13
15
  export type FileInfo = {
16
+ url?: string;
14
17
  cid?: string; // TODO(burdon): Meta key? Or other common properties with other file management system?
15
18
  };
16
19
 
package/tsconfig.json CHANGED
@@ -35,6 +35,9 @@
35
35
  {
36
36
  "path": "../../common/util"
37
37
  },
38
+ {
39
+ "path": "../../core/echo/echo-schema"
40
+ },
38
41
  {
39
42
  "path": "../app-graph"
40
43
  }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/plugins/SurfacePlugin/plugin.tsx"],
4
- "sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport { deepSignal, shallow } from 'deepsignal/react';\nimport React from 'react';\n\nimport { SurfaceProvider, type SurfaceRootContext } from './SurfaceRootContext';\nimport SurfaceMeta from './meta';\nimport { parseSurfacePlugin, type SurfacePluginProvides } from './provides';\nimport type { PluginDefinition } from '../PluginHost';\nimport { filterPlugins } from '../helpers';\n\n/**\n * Provides a registry of surface components.\n */\nconst SurfacePlugin = (): PluginDefinition<SurfacePluginProvides> => {\n const state = deepSignal<SurfaceRootContext>({ components: {} });\n\n return {\n meta: SurfaceMeta,\n ready: async (plugins) => {\n state.components = shallow(\n filterPlugins(plugins, parseSurfacePlugin).reduce((acc, plugin) => {\n return { ...acc, [plugin.meta.id]: plugin.provides.surface.component };\n }, {}),\n );\n },\n provides: {\n surface: state,\n context: ({ children }) => <SurfaceProvider value={state}>{children}</SurfaceProvider>,\n },\n };\n};\n\nexport default SurfacePlugin;\n"],
5
- "mappings": ";;;;;;;;;;AAIA,SAASA,YAAYC,eAAe;AACpC,OAAOC,WAAW;AAWlB,IAAMC,gBAAgB,MAAA;AACpB,QAAMC,QAAQC,WAA+B;IAAEC,YAAY,CAAC;EAAE,CAAA;AAE9D,SAAO;IACLC,MAAMC;IACNC,OAAO,OAAOC,YAAAA;AACZN,YAAME,aAAaK,QACjBC,cAAcF,SAASG,kBAAAA,EAAoBC,OAAO,CAACC,KAAKC,WAAAA;AACtD,eAAO;UAAE,GAAGD;UAAK,CAACC,OAAOT,KAAKU,EAAE,GAAGD,OAAOE,SAASC,QAAQC;QAAU;MACvE,GAAG,CAAC,CAAA,CAAA;IAER;IACAF,UAAU;MACRC,SAASf;MACTiB,SAAS,CAAC,EAAEC,SAAQ,MAAO,sBAAA,cAACC,iBAAAA;QAAgBC,OAAOpB;SAAQkB,QAAAA;IAC7D;EACF;AACF;AAEA,IAAA,iBAAenB;",
6
- "names": ["deepSignal", "shallow", "React", "SurfacePlugin", "state", "deepSignal", "components", "meta", "SurfaceMeta", "ready", "plugins", "shallow", "filterPlugins", "parseSurfacePlugin", "reduce", "acc", "plugin", "id", "provides", "surface", "component", "context", "children", "SurfaceProvider", "value"]
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/plugins/IntentPlugin/plugin.tsx", "../../../src/plugins/IntentPlugin/helpers.ts"],
4
- "sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport { deepSignal } from 'deepsignal/react';\nimport React from 'react';\n\nimport { log } from '@dxos/log';\n\nimport { type IntentContext, IntentProvider, type IntentExecution } from './IntentContext';\nimport { isUndoable } from './helpers';\nimport type { Intent, IntentResolver } from './intent';\nimport IntentMeta from './meta';\nimport {\n type IntentPluginProvides,\n type IntentResolverProvides,\n parseIntentResolverPlugin,\n IntentAction,\n} from './provides';\nimport type { PluginDefinition } from '../PluginHost';\nimport { filterPlugins, findPlugin } from '../helpers';\n\nconst EXECUTION_LIMIT = 1000;\nconst HISTORY_LIMIT = 100;\n\n/**\n * Allows plugins to register intent handlers and routes sent intents to the appropriate plugin.\n * Inspired by https://developer.android.com/reference/android/content/Intent.\n */\nconst IntentPlugin = (): PluginDefinition<IntentPluginProvides> => {\n const state = deepSignal<IntentContext>({\n dispatch: async () => ({}),\n undo: async () => ({}),\n history: [],\n registerResolver: () => () => {},\n });\n\n const dynamicResolvers = new Set<{ plugin: string; resolver: IntentResolver }>();\n\n return {\n meta: IntentMeta,\n ready: async (plugins) => {\n // Dispatch intent to associated plugin.\n const dispatch = async (intent: Intent) => {\n log('dispatch', { action: intent.action, intent });\n if (intent.plugin) {\n for (const entry of dynamicResolvers) {\n if (entry.plugin === intent.plugin) {\n const result = await entry.resolver(intent, plugins);\n if (result) {\n return result;\n }\n }\n }\n\n const plugin = findPlugin<IntentResolverProvides>(plugins, intent.plugin);\n const result = plugin?.provides.intent.resolver(intent, plugins);\n return result;\n }\n\n for (const entry of dynamicResolvers) {\n const result = await entry.resolver(intent, plugins);\n if (result) {\n return result;\n }\n }\n\n // Return resolved value from first plugin that handles the intent.\n for (const plugin of filterPlugins(plugins, parseIntentResolverPlugin)) {\n const result = await plugin.provides.intent.resolver(intent, plugins);\n if (result) {\n return result;\n }\n }\n\n // https://vitejs.dev/guide/env-and-mode#env-variables\n // TODO(wittjosiah): How to handle this more generically?\n if (import.meta?.env?.DEV) {\n log.warn('No plugin found to handle intent', intent);\n }\n };\n\n // Sequentially dispatch array of invents.\n const dispatchChain = async (intentOrArray: Intent | Intent[], depth = 0) => {\n if (depth > EXECUTION_LIMIT) {\n return {\n error: new Error(\n `Intent execution limit exceeded (${EXECUTION_LIMIT} iterations). This is likely due to an infinite loop within intent resolvers.`,\n ),\n };\n }\n\n const executionResults: IntentExecution[] = [];\n const chain = Array.isArray(intentOrArray) ? intentOrArray : [intentOrArray];\n for (const intent of chain) {\n const { result: prevResult } = executionResults.at(-1) ?? {};\n const data = intent.data ? { result: prevResult?.data, ...intent.data } : prevResult?.data;\n const result = await dispatch({ ...intent, data });\n\n if (!result || result?.error) {\n break;\n }\n\n executionResults.push({ intent, result });\n\n // TODO(wittjosiah): How does undo work with returned intents?\n result?.intents?.forEach((intents) => {\n void dispatchChain(intents, depth + 1);\n });\n }\n\n state.history = [...state.history.slice(0, HISTORY_LIMIT - 2), executionResults];\n\n if (isUndoable(executionResults)) {\n void dispatch({ action: IntentAction.SHOW_UNDO, data: { results: executionResults } });\n }\n\n return executionResults.at(-1)?.result;\n };\n\n const undo = async () => {\n const last = state.history.findLastIndex(isUndoable);\n const chain =\n last !== -1 &&\n state.history[last]?.map(({ intent, result }): Intent => {\n const data = result.undoable?.data ? { ...intent.data, ...result.undoable.data } : intent.data;\n return { ...intent, data, undo: true };\n });\n if (chain) {\n const result = await dispatchChain(chain);\n state.history = state.history.filter((_, index) => index !== last);\n return result;\n }\n };\n\n state.dispatch = dispatchChain;\n state.undo = undo;\n state.registerResolver = (plugin, resolver) => {\n const entry = { plugin, resolver };\n dynamicResolvers.add(entry);\n return () => dynamicResolvers.delete(entry);\n };\n },\n provides: {\n intent: state,\n context: ({ children }) => <IntentProvider value={state}>{children}</IntentProvider>,\n },\n };\n};\n\nexport default IntentPlugin;\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { type IntentExecution } from './IntentContext';\n\n/**\n * Check if the chain of intents is undoable.\n */\nexport const isUndoable = (chain: IntentExecution[]): boolean =>\n chain.length > 0 && chain.every(({ result }) => result.undoable);\n"],
5
- "mappings": ";;;;;;;;;;;;AAIA,SAASA,kBAAkB;AAC3B,OAAOC,WAAW;AAElB,SAASC,WAAW;;;ACEb,IAAMC,aAAa,CAACC,UACzBA,MAAMC,SAAS,KAAKD,MAAME,MAAM,CAAC,EAAEC,OAAM,MAAOA,OAAOC,QAAQ;;;;ADYjE,IAAMC,kBAAkB;AACxB,IAAMC,gBAAgB;AAMtB,IAAMC,eAAe,MAAA;AACnB,QAAMC,QAAQC,WAA0B;IACtCC,UAAU,aAAa,CAAC;IACxBC,MAAM,aAAa,CAAC;IACpBC,SAAS,CAAA;IACTC,kBAAkB,MAAM,MAAA;IAAO;EACjC,CAAA;AAEA,QAAMC,mBAAmB,oBAAIC,IAAAA;AAE7B,SAAO;IACLC,MAAMC;IACNC,OAAO,OAAOC,YAAAA;AAEZ,YAAMT,WAAW,OAAOU,WAAAA;AACtBC,YAAI,YAAY;UAAEC,QAAQF,OAAOE;UAAQF;QAAO,GAAA;;;;;;AAChD,YAAIA,OAAOG,QAAQ;AACjB,qBAAWC,SAASV,kBAAkB;AACpC,gBAAIU,MAAMD,WAAWH,OAAOG,QAAQ;AAClC,oBAAME,UAAS,MAAMD,MAAME,SAASN,QAAQD,OAAAA;AAC5C,kBAAIM,SAAQ;AACV,uBAAOA;cACT;YACF;UACF;AAEA,gBAAMF,SAASI,WAAmCR,SAASC,OAAOG,MAAM;AACxE,gBAAME,SAASF,QAAQK,SAASR,OAAOM,SAASN,QAAQD,OAAAA;AACxD,iBAAOM;QACT;AAEA,mBAAWD,SAASV,kBAAkB;AACpC,gBAAMW,SAAS,MAAMD,MAAME,SAASN,QAAQD,OAAAA;AAC5C,cAAIM,QAAQ;AACV,mBAAOA;UACT;QACF;AAGA,mBAAWF,UAAUM,cAAcV,SAASW,yBAAAA,GAA4B;AACtE,gBAAML,SAAS,MAAMF,OAAOK,SAASR,OAAOM,SAASN,QAAQD,OAAAA;AAC7D,cAAIM,QAAQ;AACV,mBAAOA;UACT;QACF;AAIA,YAAI,aAAaM,KAAKC,KAAK;AACzBX,cAAIY,KAAK,oCAAoCb,QAAAA;;;;;;QAC/C;MACF;AAGA,YAAMc,gBAAgB,OAAOC,eAAkCC,QAAQ,MAAC;AACtE,YAAIA,QAAQ/B,iBAAiB;AAC3B,iBAAO;YACLgC,OAAO,IAAIC,MACT,oCAAoCjC,eAAAA,+EAA8F;UAEtI;QACF;AAEA,cAAMkC,mBAAsC,CAAA;AAC5C,cAAMC,QAAQC,MAAMC,QAAQP,aAAAA,IAAiBA,gBAAgB;UAACA;;AAC9D,mBAAWf,UAAUoB,OAAO;AAC1B,gBAAM,EAAEf,QAAQkB,WAAU,IAAKJ,iBAAiBK,GAAG,EAAC,KAAM,CAAC;AAC3D,gBAAMC,OAAOzB,OAAOyB,OAAO;YAAEpB,QAAQkB,YAAYE;YAAM,GAAGzB,OAAOyB;UAAK,IAAIF,YAAYE;AACtF,gBAAMpB,SAAS,MAAMf,SAAS;YAAE,GAAGU;YAAQyB;UAAK,CAAA;AAEhD,cAAI,CAACpB,UAAUA,QAAQY,OAAO;AAC5B;UACF;AAEAE,2BAAiBO,KAAK;YAAE1B;YAAQK;UAAO,CAAA;AAGvCA,kBAAQsB,SAASC,QAAQ,CAACD,YAAAA;AACxB,iBAAKb,cAAca,SAASX,QAAQ,CAAA;UACtC,CAAA;QACF;AAEA5B,cAAMI,UAAU;aAAIJ,MAAMI,QAAQqC,MAAM,GAAG3C,gBAAgB,CAAA;UAAIiC;;AAE/D,YAAIW,WAAWX,gBAAAA,GAAmB;AAChC,eAAK7B,SAAS;YAAEY,QAAQ6B,aAAaC;YAAWP,MAAM;cAAEQ,SAASd;YAAiB;UAAE,CAAA;QACtF;AAEA,eAAOA,iBAAiBK,GAAG,EAAC,GAAInB;MAClC;AAEA,YAAMd,OAAO,YAAA;AACX,cAAM2C,OAAO9C,MAAMI,QAAQ2C,cAAcL,UAAAA;AACzC,cAAMV,QACJc,SAAS,MACT9C,MAAMI,QAAQ0C,IAAAA,GAAOE,IAAI,CAAC,EAAEpC,QAAQK,OAAM,MAAE;AAC1C,gBAAMoB,OAAOpB,OAAOgC,UAAUZ,OAAO;YAAE,GAAGzB,OAAOyB;YAAM,GAAGpB,OAAOgC,SAASZ;UAAK,IAAIzB,OAAOyB;AAC1F,iBAAO;YAAE,GAAGzB;YAAQyB;YAAMlC,MAAM;UAAK;QACvC,CAAA;AACF,YAAI6B,OAAO;AACT,gBAAMf,SAAS,MAAMS,cAAcM,KAAAA;AACnChC,gBAAMI,UAAUJ,MAAMI,QAAQ8C,OAAO,CAACC,GAAGC,UAAUA,UAAUN,IAAAA;AAC7D,iBAAO7B;QACT;MACF;AAEAjB,YAAME,WAAWwB;AACjB1B,YAAMG,OAAOA;AACbH,YAAMK,mBAAmB,CAACU,QAAQG,aAAAA;AAChC,cAAMF,QAAQ;UAAED;UAAQG;QAAS;AACjCZ,yBAAiB+C,IAAIrC,KAAAA;AACrB,eAAO,MAAMV,iBAAiBgD,OAAOtC,KAAAA;MACvC;IACF;IACAI,UAAU;MACRR,QAAQZ;MACRuD,SAAS,CAAC,EAAEC,SAAQ,MAAO,sBAAA,cAACC,gBAAAA;QAAeC,OAAO1D;SAAQwD,QAAAA;IAC5D;EACF;AACF;AAEA,IAAA,iBAAezD;",
6
- "names": ["deepSignal", "React", "log", "isUndoable", "chain", "length", "every", "result", "undoable", "EXECUTION_LIMIT", "HISTORY_LIMIT", "IntentPlugin", "state", "deepSignal", "dispatch", "undo", "history", "registerResolver", "dynamicResolvers", "Set", "meta", "IntentMeta", "ready", "plugins", "intent", "log", "action", "plugin", "entry", "result", "resolver", "findPlugin", "provides", "filterPlugins", "parseIntentResolverPlugin", "env", "DEV", "warn", "dispatchChain", "intentOrArray", "depth", "error", "Error", "executionResults", "chain", "Array", "isArray", "prevResult", "at", "data", "push", "intents", "forEach", "slice", "isUndoable", "IntentAction", "SHOW_UNDO", "results", "last", "findLastIndex", "map", "undoable", "filter", "_", "index", "add", "delete", "context", "children", "IntentProvider", "value"]
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/plugins/IntentPlugin/plugin.tsx", "../../../src/plugins/IntentPlugin/helpers.ts"],
4
- "sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport { deepSignal } from 'deepsignal/react';\nimport React from 'react';\n\nimport { log } from '@dxos/log';\n\nimport { type IntentContext, IntentProvider, type IntentExecution } from './IntentContext';\nimport { isUndoable } from './helpers';\nimport type { Intent, IntentResolver } from './intent';\nimport IntentMeta from './meta';\nimport {\n type IntentPluginProvides,\n type IntentResolverProvides,\n parseIntentResolverPlugin,\n IntentAction,\n} from './provides';\nimport type { PluginDefinition } from '../PluginHost';\nimport { filterPlugins, findPlugin } from '../helpers';\n\nconst EXECUTION_LIMIT = 1000;\nconst HISTORY_LIMIT = 100;\n\n/**\n * Allows plugins to register intent handlers and routes sent intents to the appropriate plugin.\n * Inspired by https://developer.android.com/reference/android/content/Intent.\n */\nconst IntentPlugin = (): PluginDefinition<IntentPluginProvides> => {\n const state = deepSignal<IntentContext>({\n dispatch: async () => ({}),\n undo: async () => ({}),\n history: [],\n registerResolver: () => () => {},\n });\n\n const dynamicResolvers = new Set<{ plugin: string; resolver: IntentResolver }>();\n\n return {\n meta: IntentMeta,\n ready: async (plugins) => {\n // Dispatch intent to associated plugin.\n const dispatch = async (intent: Intent) => {\n log('dispatch', { action: intent.action, intent });\n if (intent.plugin) {\n for (const entry of dynamicResolvers) {\n if (entry.plugin === intent.plugin) {\n const result = await entry.resolver(intent, plugins);\n if (result) {\n return result;\n }\n }\n }\n\n const plugin = findPlugin<IntentResolverProvides>(plugins, intent.plugin);\n const result = plugin?.provides.intent.resolver(intent, plugins);\n return result;\n }\n\n for (const entry of dynamicResolvers) {\n const result = await entry.resolver(intent, plugins);\n if (result) {\n return result;\n }\n }\n\n // Return resolved value from first plugin that handles the intent.\n for (const plugin of filterPlugins(plugins, parseIntentResolverPlugin)) {\n const result = await plugin.provides.intent.resolver(intent, plugins);\n if (result) {\n return result;\n }\n }\n\n // https://vitejs.dev/guide/env-and-mode#env-variables\n // TODO(wittjosiah): How to handle this more generically?\n if (import.meta?.env?.DEV) {\n log.warn('No plugin found to handle intent', intent);\n }\n };\n\n // Sequentially dispatch array of invents.\n const dispatchChain = async (intentOrArray: Intent | Intent[], depth = 0) => {\n if (depth > EXECUTION_LIMIT) {\n return {\n error: new Error(\n `Intent execution limit exceeded (${EXECUTION_LIMIT} iterations). This is likely due to an infinite loop within intent resolvers.`,\n ),\n };\n }\n\n const executionResults: IntentExecution[] = [];\n const chain = Array.isArray(intentOrArray) ? intentOrArray : [intentOrArray];\n for (const intent of chain) {\n const { result: prevResult } = executionResults.at(-1) ?? {};\n const data = intent.data ? { result: prevResult?.data, ...intent.data } : prevResult?.data;\n const result = await dispatch({ ...intent, data });\n\n if (!result || result?.error) {\n break;\n }\n\n executionResults.push({ intent, result });\n\n // TODO(wittjosiah): How does undo work with returned intents?\n result?.intents?.forEach((intents) => {\n void dispatchChain(intents, depth + 1);\n });\n }\n\n state.history = [...state.history.slice(0, HISTORY_LIMIT - 2), executionResults];\n\n if (isUndoable(executionResults)) {\n void dispatch({ action: IntentAction.SHOW_UNDO, data: { results: executionResults } });\n }\n\n return executionResults.at(-1)?.result;\n };\n\n const undo = async () => {\n const last = state.history.findLastIndex(isUndoable);\n const chain =\n last !== -1 &&\n state.history[last]?.map(({ intent, result }): Intent => {\n const data = result.undoable?.data ? { ...intent.data, ...result.undoable.data } : intent.data;\n return { ...intent, data, undo: true };\n });\n if (chain) {\n const result = await dispatchChain(chain);\n state.history = state.history.filter((_, index) => index !== last);\n return result;\n }\n };\n\n state.dispatch = dispatchChain;\n state.undo = undo;\n state.registerResolver = (plugin, resolver) => {\n const entry = { plugin, resolver };\n dynamicResolvers.add(entry);\n return () => dynamicResolvers.delete(entry);\n };\n },\n provides: {\n intent: state,\n context: ({ children }) => <IntentProvider value={state}>{children}</IntentProvider>,\n },\n };\n};\n\nexport default IntentPlugin;\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { type IntentExecution } from './IntentContext';\n\n/**\n * Check if the chain of intents is undoable.\n */\nexport const isUndoable = (chain: IntentExecution[]): boolean =>\n chain.length > 0 && chain.every(({ result }) => result.undoable);\n"],
5
- "mappings": "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",
6
- "names": ["import_react", "isUndoable", "chain", "length", "every", "result", "undoable", "EXECUTION_LIMIT", "HISTORY_LIMIT", "IntentPlugin", "state", "deepSignal", "dispatch", "undo", "history", "registerResolver", "dynamicResolvers", "Set", "meta", "IntentMeta", "ready", "plugins", "intent", "log", "action", "plugin", "entry", "resolver", "findPlugin", "provides", "filterPlugins", "parseIntentResolverPlugin", "env", "DEV", "warn", "dispatchChain", "intentOrArray", "depth", "error", "Error", "executionResults", "Array", "isArray", "prevResult", "at", "data", "push", "intents", "forEach", "slice", "IntentAction", "SHOW_UNDO", "results", "last", "findLastIndex", "map", "filter", "_", "index", "add", "delete", "context", "children", "React", "IntentProvider", "value"]
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/plugins/SurfacePlugin/plugin.tsx"],
4
- "sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport { deepSignal, shallow } from 'deepsignal/react';\nimport React from 'react';\n\nimport { SurfaceProvider, type SurfaceRootContext } from './SurfaceRootContext';\nimport SurfaceMeta from './meta';\nimport { parseSurfacePlugin, type SurfacePluginProvides } from './provides';\nimport type { PluginDefinition } from '../PluginHost';\nimport { filterPlugins } from '../helpers';\n\n/**\n * Provides a registry of surface components.\n */\nconst SurfacePlugin = (): PluginDefinition<SurfacePluginProvides> => {\n const state = deepSignal<SurfaceRootContext>({ components: {} });\n\n return {\n meta: SurfaceMeta,\n ready: async (plugins) => {\n state.components = shallow(\n filterPlugins(plugins, parseSurfacePlugin).reduce((acc, plugin) => {\n return { ...acc, [plugin.meta.id]: plugin.provides.surface.component };\n }, {}),\n );\n },\n provides: {\n surface: state,\n context: ({ children }) => <SurfaceProvider value={state}>{children}</SurfaceProvider>,\n },\n };\n};\n\nexport default SurfacePlugin;\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAIA,mBAAoC;AACpC,IAAAA,gBAAkB;AAWlB,IAAMC,gBAAgB,MAAA;AACpB,QAAMC,YAAQC,yBAA+B;IAAEC,YAAY,CAAC;EAAE,CAAA;AAE9D,SAAO;IACLC,MAAMC;IACNC,OAAO,OAAOC,YAAAA;AACZN,YAAME,iBAAaK,0BACjBC,qCAAcF,SAASG,wCAAAA,EAAoBC,OAAO,CAACC,KAAKC,WAAAA;AACtD,eAAO;UAAE,GAAGD;UAAK,CAACC,OAAOT,KAAKU,EAAE,GAAGD,OAAOE,SAASC,QAAQC;QAAU;MACvE,GAAG,CAAC,CAAA,CAAA;IAER;IACAF,UAAU;MACRC,SAASf;MACTiB,SAAS,CAAC,EAAEC,SAAQ,MAAO,8BAAAC,QAAA,cAACC,uCAAAA;QAAgBC,OAAOrB;SAAQkB,QAAAA;IAC7D;EACF;AACF;AAEA,IAAA,iBAAenB;",
6
- "names": ["import_react", "SurfacePlugin", "state", "deepSignal", "components", "meta", "SurfaceMeta", "ready", "plugins", "shallow", "filterPlugins", "parseSurfacePlugin", "reduce", "acc", "plugin", "id", "provides", "surface", "component", "context", "children", "React", "SurfaceProvider", "value"]
7
- }