@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.
- package/dist/lib/browser/index.mjs +12 -11
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/{plugin-FYTGDFFS.mjs → plugin-KEA4MEHK.mjs} +3 -3
- package/dist/lib/browser/plugin-KEA4MEHK.mjs.map +7 -0
- package/dist/lib/browser/{plugin-6XDXQ3BN.mjs → plugin-VCIF47DJ.mjs} +5 -5
- package/dist/lib/browser/plugin-VCIF47DJ.mjs.map +7 -0
- package/dist/lib/node/index.cjs +43 -42
- package/dist/lib/node/index.cjs.map +3 -3
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/{plugin-VEIZZVQP.cjs → plugin-3K3YXM6Z.cjs} +8 -8
- package/dist/lib/node/plugin-3K3YXM6Z.cjs.map +7 -0
- package/dist/lib/node/{plugin-ZJ26B7E5.cjs → plugin-ROMMITVM.cjs} +10 -10
- package/dist/lib/node/plugin-ROMMITVM.cjs.map +7 -0
- package/dist/types/src/plugins/PluginHost/PluginHost.d.ts.map +1 -1
- package/dist/types/src/plugins/SurfacePlugin/plugin.d.ts.map +1 -1
- package/dist/types/src/plugins/common/file.d.ts +1 -0
- package/dist/types/src/plugins/common/file.d.ts.map +1 -1
- package/package.json +9 -9
- package/src/plugins/IntentPlugin/plugin.tsx +2 -2
- package/src/plugins/PluginHost/PluginHost.tsx +5 -5
- package/src/plugins/SurfacePlugin/plugin.tsx +6 -7
- package/src/plugins/common/file.ts +4 -1
- package/tsconfig.json +3 -0
- package/dist/lib/browser/plugin-6XDXQ3BN.mjs.map +0 -7
- package/dist/lib/browser/plugin-FYTGDFFS.mjs.map +0 -7
- package/dist/lib/node/plugin-VEIZZVQP.cjs.map +0 -7
- 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
|
|
30
|
-
__export(
|
|
29
|
+
var plugin_3K3YXM6Z_exports = {};
|
|
30
|
+
__export(plugin_3K3YXM6Z_exports, {
|
|
31
31
|
default: () => plugin_default
|
|
32
32
|
});
|
|
33
|
-
module.exports = __toCommonJS(
|
|
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("
|
|
37
|
-
var
|
|
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 =
|
|
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__ */
|
|
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-
|
|
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
|
|
30
|
-
__export(
|
|
29
|
+
var plugin_ROMMITVM_exports = {};
|
|
30
|
+
__export(plugin_ROMMITVM_exports, {
|
|
31
31
|
default: () => plugin_default
|
|
32
32
|
});
|
|
33
|
-
module.exports = __toCommonJS(
|
|
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("
|
|
37
|
-
var
|
|
36
|
+
var import_react = __toESM(require("react"));
|
|
37
|
+
var E = __toESM(require("@dxos/echo-schema/schema"));
|
|
38
38
|
var SurfacePlugin = () => {
|
|
39
|
-
const state =
|
|
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,
|
|
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__ */
|
|
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-
|
|
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":"
|
|
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":"
|
|
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"}
|
|
@@ -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;
|
|
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.
|
|
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/
|
|
20
|
-
"@dxos/
|
|
21
|
-
"@dxos/
|
|
22
|
-
"@dxos/
|
|
23
|
-
"@dxos/
|
|
24
|
-
"@dxos/
|
|
25
|
-
"@dxos/
|
|
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 =
|
|
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
|
|
50
|
+
state.values.enabled.push(id);
|
|
52
51
|
} else {
|
|
53
|
-
|
|
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(
|
|
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 =
|
|
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 =
|
|
19
|
+
const state = E.object<SurfaceRootContext>({ components: {} });
|
|
19
20
|
|
|
20
21
|
return {
|
|
21
22
|
meta: SurfaceMeta,
|
|
22
23
|
ready: async (plugins) => {
|
|
23
|
-
state.components =
|
|
24
|
-
|
|
25
|
-
|
|
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
|
@@ -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": "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",
|
|
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
|
-
}
|