@dxos/app-framework 0.7.4 → 0.7.5-main.499c70c
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/chunk-QG25ZU2N.mjs +320 -0
- package/dist/lib/browser/chunk-QG25ZU2N.mjs.map +7 -0
- package/dist/lib/browser/chunk-SPDTXTOV.mjs +163 -0
- package/dist/lib/browser/chunk-SPDTXTOV.mjs.map +7 -0
- package/dist/lib/browser/{chunk-653Y45CL.mjs → chunk-WBOXEHBE.mjs} +12 -2
- package/dist/lib/browser/chunk-WBOXEHBE.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +224 -109
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/{plugin-intent-LU4KL2RO.mjs → plugin-intent-T7Y3MJ5C.mjs} +14 -4
- package/dist/lib/browser/{plugin-settings-OM3G2QFY.mjs → plugin-settings-5U2L2NRU.mjs} +6 -2
- package/dist/lib/browser/{plugin-surface-LECZMKSQ.mjs → plugin-surface-OKPF3EQI.mjs} +4 -4
- package/dist/lib/node/{chunk-SOVLKUWI.cjs → chunk-BW3RNEVI.cjs} +51 -102
- package/dist/lib/node/chunk-BW3RNEVI.cjs.map +7 -0
- package/dist/lib/node/{chunk-JZ2JVKRY.cjs → chunk-FCMHRU3M.cjs} +17 -5
- package/dist/lib/node/chunk-FCMHRU3M.cjs.map +7 -0
- package/dist/lib/node/chunk-VWHAALIN.cjs +344 -0
- package/dist/lib/node/chunk-VWHAALIN.cjs.map +7 -0
- package/dist/lib/node/index.cjs +232 -114
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/plugin-intent-F3TQZIUR.cjs +53 -0
- package/dist/lib/node/plugin-intent-F3TQZIUR.cjs.map +7 -0
- package/dist/lib/node/{plugin-settings-OZ6IKAE5.cjs → plugin-settings-W6UHMH5M.cjs} +12 -8
- package/dist/lib/node/plugin-settings-W6UHMH5M.cjs.map +7 -0
- package/dist/lib/node/{plugin-surface-YWDRXQTD.cjs → plugin-surface-CCSIONYW.cjs} +15 -15
- package/dist/lib/node/plugin-surface-CCSIONYW.cjs.map +7 -0
- package/dist/lib/node-esm/{chunk-YNU7FTGJ.mjs → chunk-3T5UIJY3.mjs} +12 -2
- package/dist/lib/node-esm/chunk-3T5UIJY3.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-4GX7V5ZE.mjs +164 -0
- package/dist/lib/node-esm/chunk-4GX7V5ZE.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-CFOUYXQ6.mjs +321 -0
- package/dist/lib/node-esm/chunk-CFOUYXQ6.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +224 -109
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/{plugin-intent-V7ER24Y6.mjs → plugin-intent-W2HQC6LC.mjs} +14 -4
- package/dist/lib/node-esm/{plugin-settings-37UVWF2V.mjs → plugin-settings-H5RHNFVC.mjs} +6 -2
- package/dist/lib/node-esm/{plugin-surface-TEU42XQN.mjs → plugin-surface-V3YET3UL.mjs} +4 -4
- package/dist/types/src/plugins/common/layout.d.ts +145 -171
- package/dist/types/src/plugins/common/layout.d.ts.map +1 -1
- package/dist/types/src/plugins/common/navigation.d.ts +77 -30
- package/dist/types/src/plugins/common/navigation.d.ts.map +1 -1
- package/dist/types/src/plugins/plugin-host/HostPlugin.d.ts +2 -7
- package/dist/types/src/plugins/plugin-host/HostPlugin.d.ts.map +1 -1
- package/dist/types/src/plugins/plugin-host/index.d.ts +2 -0
- package/dist/types/src/plugins/plugin-host/index.d.ts.map +1 -1
- package/dist/types/src/plugins/plugin-host/plugin.d.ts +7 -1
- package/dist/types/src/plugins/plugin-host/plugin.d.ts.map +1 -1
- package/dist/types/src/plugins/plugin-intent/IntentContext.d.ts +7 -20
- package/dist/types/src/plugins/plugin-intent/IntentContext.d.ts.map +1 -1
- package/dist/types/src/plugins/plugin-intent/IntentPlugin.d.ts.map +1 -1
- package/dist/types/src/plugins/plugin-intent/index.d.ts +1 -0
- package/dist/types/src/plugins/plugin-intent/index.d.ts.map +1 -1
- package/dist/types/src/plugins/plugin-intent/intent-dispatcher.d.ts +107 -0
- package/dist/types/src/plugins/plugin-intent/intent-dispatcher.d.ts.map +1 -0
- package/dist/types/src/plugins/plugin-intent/intent-dispatcher.test.d.ts +2 -0
- package/dist/types/src/plugins/plugin-intent/intent-dispatcher.test.d.ts.map +1 -0
- package/dist/types/src/plugins/plugin-intent/intent.d.ts +65 -58
- package/dist/types/src/plugins/plugin-intent/intent.d.ts.map +1 -1
- package/dist/types/src/plugins/plugin-intent/meta.d.ts +1 -0
- package/dist/types/src/plugins/plugin-intent/meta.d.ts.map +1 -1
- package/dist/types/src/plugins/plugin-intent/provides.d.ts +6 -10
- package/dist/types/src/plugins/plugin-intent/provides.d.ts.map +1 -1
- package/dist/types/src/plugins/plugin-settings/provides.d.ts +15 -2
- package/dist/types/src/plugins/plugin-settings/provides.d.ts.map +1 -1
- package/dist/types/src/plugins/plugin-surface/Surface.d.ts +2 -57
- package/dist/types/src/plugins/plugin-surface/Surface.d.ts.map +1 -1
- package/dist/types/src/plugins/plugin-surface/SurfaceContext.d.ts +85 -0
- package/dist/types/src/plugins/plugin-surface/SurfaceContext.d.ts.map +1 -0
- package/dist/types/src/plugins/plugin-surface/SurfacePlugin.d.ts.map +1 -1
- package/dist/types/src/plugins/plugin-surface/index.d.ts +1 -1
- package/dist/types/src/plugins/plugin-surface/index.d.ts.map +1 -1
- package/dist/types/src/plugins/plugin-surface/provides.d.ts +5 -4
- package/dist/types/src/plugins/plugin-surface/provides.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -0
- package/package.json +14 -12
- package/src/plugins/common/layout.ts +125 -107
- package/src/plugins/common/navigation.ts +59 -30
- package/src/plugins/plugin-host/HostPlugin.tsx +2 -10
- package/src/plugins/plugin-host/PluginContainer.tsx +1 -1
- package/src/plugins/plugin-host/index.ts +4 -0
- package/src/plugins/plugin-host/plugin.ts +8 -1
- package/src/plugins/plugin-intent/IntentContext.tsx +13 -36
- package/src/plugins/plugin-intent/IntentPlugin.tsx +44 -120
- package/src/plugins/plugin-intent/index.ts +1 -0
- package/src/plugins/plugin-intent/intent-dispatcher.test.ts +279 -0
- package/src/plugins/plugin-intent/intent-dispatcher.ts +285 -0
- package/src/plugins/plugin-intent/intent.ts +126 -65
- package/src/plugins/plugin-intent/meta.ts +3 -1
- package/src/plugins/plugin-intent/provides.ts +8 -20
- package/src/plugins/plugin-settings/provides.ts +10 -5
- package/src/plugins/plugin-surface/Surface.tsx +25 -158
- package/src/plugins/plugin-surface/SurfaceContext.ts +112 -0
- package/src/plugins/plugin-surface/SurfacePlugin.tsx +19 -7
- package/src/plugins/plugin-surface/index.ts +1 -1
- package/src/plugins/plugin-surface/provides.ts +8 -7
- package/tsconfig.json +38 -1
- package/dist/lib/browser/chunk-653Y45CL.mjs.map +0 -7
- package/dist/lib/browser/chunk-FRXJ25VI.mjs +0 -214
- package/dist/lib/browser/chunk-FRXJ25VI.mjs.map +0 -7
- package/dist/lib/browser/chunk-YXM35XRE.mjs +0 -213
- package/dist/lib/browser/chunk-YXM35XRE.mjs.map +0 -7
- package/dist/lib/node/chunk-JZ2JVKRY.cjs.map +0 -7
- package/dist/lib/node/chunk-QSVP5HOW.cjs +0 -238
- package/dist/lib/node/chunk-QSVP5HOW.cjs.map +0 -7
- package/dist/lib/node/chunk-SOVLKUWI.cjs.map +0 -7
- package/dist/lib/node/plugin-intent-FVFR2LKB.cjs +0 -43
- package/dist/lib/node/plugin-intent-FVFR2LKB.cjs.map +0 -7
- package/dist/lib/node/plugin-settings-OZ6IKAE5.cjs.map +0 -7
- package/dist/lib/node/plugin-surface-YWDRXQTD.cjs.map +0 -7
- package/dist/lib/node-esm/chunk-2R4GVK7O.mjs +0 -215
- package/dist/lib/node-esm/chunk-2R4GVK7O.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-YFMFQBB4.mjs +0 -214
- package/dist/lib/node-esm/chunk-YFMFQBB4.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-YNU7FTGJ.mjs.map +0 -7
- package/dist/types/src/plugins/plugin-intent/helpers.d.ts +0 -6
- package/dist/types/src/plugins/plugin-intent/helpers.d.ts.map +0 -1
- package/dist/types/src/plugins/plugin-surface/SurfaceRootContext.d.ts +0 -39
- package/dist/types/src/plugins/plugin-surface/SurfaceRootContext.d.ts.map +0 -1
- package/src/plugins/plugin-intent/helpers.ts +0 -11
- package/src/plugins/plugin-surface/SurfaceRootContext.tsx +0 -60
- /package/dist/lib/browser/{plugin-intent-LU4KL2RO.mjs.map → plugin-intent-T7Y3MJ5C.mjs.map} +0 -0
- /package/dist/lib/browser/{plugin-settings-OM3G2QFY.mjs.map → plugin-settings-5U2L2NRU.mjs.map} +0 -0
- /package/dist/lib/browser/{plugin-surface-LECZMKSQ.mjs.map → plugin-surface-OKPF3EQI.mjs.map} +0 -0
- /package/dist/lib/node-esm/{plugin-intent-V7ER24Y6.mjs.map → plugin-intent-W2HQC6LC.mjs.map} +0 -0
- /package/dist/lib/node-esm/{plugin-settings-37UVWF2V.mjs.map → plugin-settings-H5RHNFVC.mjs.map} +0 -0
- /package/dist/lib/node-esm/{plugin-surface-TEU42XQN.mjs.map → plugin-surface-V3YET3UL.mjs.map} +0 -0
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
import {
|
|
2
|
+
filterPlugins
|
|
3
|
+
} from "./chunk-3E7RY3CE.mjs";
|
|
4
|
+
|
|
5
|
+
// packages/sdk/app-framework/src/plugins/plugin-intent/IntentPlugin.tsx
|
|
6
|
+
import { Effect as Effect2 } from "effect";
|
|
7
|
+
import React from "react";
|
|
8
|
+
import { create } from "@dxos/live-object";
|
|
9
|
+
|
|
10
|
+
// packages/sdk/app-framework/src/plugins/plugin-intent/IntentContext.tsx
|
|
11
|
+
import { createContext, useContext, useEffect } from "react";
|
|
12
|
+
import { raise } from "@dxos/debug";
|
|
13
|
+
import { pick } from "@dxos/util";
|
|
14
|
+
var IntentContext = /* @__PURE__ */ createContext(void 0);
|
|
15
|
+
var useIntentDispatcher = () => {
|
|
16
|
+
const context = useContext(IntentContext) ?? raise(new Error("IntentContext not found"));
|
|
17
|
+
return pick(context, [
|
|
18
|
+
"dispatch",
|
|
19
|
+
"dispatchPromise"
|
|
20
|
+
]);
|
|
21
|
+
};
|
|
22
|
+
var useIntentResolver = (pluginId, resolver) => {
|
|
23
|
+
const { registerResolver } = useContext(IntentContext) ?? raise(new Error("IntentContext not found"));
|
|
24
|
+
useEffect(() => {
|
|
25
|
+
return registerResolver(pluginId, resolver);
|
|
26
|
+
}, [
|
|
27
|
+
pluginId,
|
|
28
|
+
resolver
|
|
29
|
+
]);
|
|
30
|
+
};
|
|
31
|
+
var IntentProvider = IntentContext.Provider;
|
|
32
|
+
|
|
33
|
+
// packages/sdk/app-framework/src/plugins/plugin-intent/intent-dispatcher.ts
|
|
34
|
+
import { Effect, Ref } from "effect";
|
|
35
|
+
import { pick as pick2 } from "@dxos/util";
|
|
36
|
+
|
|
37
|
+
// packages/sdk/app-framework/src/plugins/plugin-intent/intent.ts
|
|
38
|
+
import { S } from "@dxos/echo-schema";
|
|
39
|
+
|
|
40
|
+
// packages/sdk/app-framework/src/plugins/plugin-intent/meta.ts
|
|
41
|
+
var INTENT_PLUGIN = "dxos.org/plugin/intent";
|
|
42
|
+
var IntentMeta = {
|
|
43
|
+
id: INTENT_PLUGIN
|
|
44
|
+
};
|
|
45
|
+
var meta_default = IntentMeta;
|
|
46
|
+
|
|
47
|
+
// packages/sdk/app-framework/src/plugins/plugin-intent/intent.ts
|
|
48
|
+
var createIntent = (schema, data = {}, params = {}) => {
|
|
49
|
+
const _ = S.validateSync(schema.fields.input)(data);
|
|
50
|
+
const intent = {
|
|
51
|
+
...params,
|
|
52
|
+
_schema: schema,
|
|
53
|
+
action: schema._tag,
|
|
54
|
+
data
|
|
55
|
+
};
|
|
56
|
+
return {
|
|
57
|
+
first: intent,
|
|
58
|
+
last: intent,
|
|
59
|
+
all: [
|
|
60
|
+
intent
|
|
61
|
+
]
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
var chain = (schema, data = {}, params = {}) => (intent) => {
|
|
65
|
+
const intents = "all" in intent ? intent.all : [
|
|
66
|
+
intent
|
|
67
|
+
];
|
|
68
|
+
const first = intents[0];
|
|
69
|
+
const last = {
|
|
70
|
+
...params,
|
|
71
|
+
_schema: schema,
|
|
72
|
+
action: schema._tag,
|
|
73
|
+
data
|
|
74
|
+
};
|
|
75
|
+
return {
|
|
76
|
+
first,
|
|
77
|
+
last,
|
|
78
|
+
all: [
|
|
79
|
+
...intents,
|
|
80
|
+
last
|
|
81
|
+
]
|
|
82
|
+
};
|
|
83
|
+
};
|
|
84
|
+
var Label = S.Union(S.String, S.mutable(S.Tuple(S.String, S.mutable(S.Struct({
|
|
85
|
+
ns: S.String,
|
|
86
|
+
count: S.optional(S.Number)
|
|
87
|
+
})))));
|
|
88
|
+
var INTENT_ACTION = `${INTENT_PLUGIN}/action`;
|
|
89
|
+
var IntentAction;
|
|
90
|
+
(function(IntentAction2) {
|
|
91
|
+
class ShowUndo extends S.TaggedClass()(`${INTENT_ACTION}/show-undo`, {
|
|
92
|
+
input: S.Struct({
|
|
93
|
+
message: Label
|
|
94
|
+
}),
|
|
95
|
+
output: S.Void
|
|
96
|
+
}) {
|
|
97
|
+
}
|
|
98
|
+
IntentAction2.ShowUndo = ShowUndo;
|
|
99
|
+
})(IntentAction || (IntentAction = {}));
|
|
100
|
+
|
|
101
|
+
// packages/sdk/app-framework/src/plugins/plugin-intent/intent-dispatcher.ts
|
|
102
|
+
var EXECUTION_LIMIT = 100;
|
|
103
|
+
var HISTORY_LIMIT = 100;
|
|
104
|
+
var createResolver = (schema, effect, params = {}) => ({
|
|
105
|
+
action: schema._tag,
|
|
106
|
+
effect,
|
|
107
|
+
...params
|
|
108
|
+
});
|
|
109
|
+
var isUndoable = (historyEntry) => historyEntry.length > 0 && historyEntry.every(({ undoable }) => !!undoable);
|
|
110
|
+
var createDispatcher = (resolvers, { executionLimit = EXECUTION_LIMIT, historyLimit = HISTORY_LIMIT } = {}) => {
|
|
111
|
+
const historyRef = Effect.runSync(Ref.make([]));
|
|
112
|
+
const handleIntent = (intent) => {
|
|
113
|
+
return Effect.gen(function* () {
|
|
114
|
+
const candidates = Object.entries(resolvers).filter(([id, _]) => intent.plugin ? id === intent.plugin : true).flatMap(([_, resolvers2]) => resolvers2).filter((r) => r.action === intent.action).filter((r) => !r.filter || r.filter(intent.data)).toSorted(({ disposition: a = "static" }, { disposition: b = "static" }) => {
|
|
115
|
+
return a === b ? 0 : a === "hoist" || b === "fallback" ? -1 : b === "hoist" || a === "fallback" ? 1 : 0;
|
|
116
|
+
});
|
|
117
|
+
if (candidates.length === 0) {
|
|
118
|
+
return {
|
|
119
|
+
_intent: intent,
|
|
120
|
+
error: new Error(`No resolver found for action: ${intent.action}`)
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
const effect = candidates[0].effect(intent.data, intent.undo ?? false);
|
|
124
|
+
const result = Effect.isEffect(effect) ? yield* effect : yield* Effect.promise(async () => effect);
|
|
125
|
+
return {
|
|
126
|
+
_intent: intent,
|
|
127
|
+
...result
|
|
128
|
+
};
|
|
129
|
+
});
|
|
130
|
+
};
|
|
131
|
+
const dispatch = (intentChain, depth = 0) => {
|
|
132
|
+
return Effect.gen(function* () {
|
|
133
|
+
if (depth > executionLimit) {
|
|
134
|
+
yield* Effect.fail(new Error("Intent execution limit exceeded. This is likely due to an infinite loop within intent resolvers."));
|
|
135
|
+
}
|
|
136
|
+
const resultsRef = yield* Ref.make([]);
|
|
137
|
+
for (const intent of intentChain.all) {
|
|
138
|
+
const { data: prev } = (yield* resultsRef.get)[0] ?? {};
|
|
139
|
+
const result2 = yield* handleIntent({
|
|
140
|
+
...intent,
|
|
141
|
+
data: {
|
|
142
|
+
...intent.data,
|
|
143
|
+
...prev
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
yield* Ref.update(resultsRef, (results2) => [
|
|
147
|
+
result2,
|
|
148
|
+
...results2
|
|
149
|
+
]);
|
|
150
|
+
if (result2.error) {
|
|
151
|
+
break;
|
|
152
|
+
}
|
|
153
|
+
if (result2.intents) {
|
|
154
|
+
for (const intent2 of result2.intents) {
|
|
155
|
+
yield* dispatch(intent2, depth + 1);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
const results = yield* resultsRef.get;
|
|
160
|
+
const result = results[0];
|
|
161
|
+
if (result) {
|
|
162
|
+
yield* Ref.update(historyRef, (history) => {
|
|
163
|
+
const next = [
|
|
164
|
+
...history,
|
|
165
|
+
results
|
|
166
|
+
];
|
|
167
|
+
if (next.length > historyLimit) {
|
|
168
|
+
next.splice(0, next.length - historyLimit);
|
|
169
|
+
}
|
|
170
|
+
return next;
|
|
171
|
+
});
|
|
172
|
+
if (result.undoable && isUndoable(results)) {
|
|
173
|
+
yield* dispatch(createIntent(IntentAction.ShowUndo, {
|
|
174
|
+
message: result.undoable.message
|
|
175
|
+
}));
|
|
176
|
+
}
|
|
177
|
+
return pick2(result, [
|
|
178
|
+
"data",
|
|
179
|
+
"error"
|
|
180
|
+
]);
|
|
181
|
+
} else {
|
|
182
|
+
return {
|
|
183
|
+
data: {},
|
|
184
|
+
error: new Error("No results")
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
};
|
|
189
|
+
const dispatchPromise = (intentChain) => {
|
|
190
|
+
const program = dispatch(intentChain);
|
|
191
|
+
return Effect.runPromise(program);
|
|
192
|
+
};
|
|
193
|
+
const undo = () => {
|
|
194
|
+
return Effect.gen(function* () {
|
|
195
|
+
const history = yield* historyRef.get;
|
|
196
|
+
const last = history.findLastIndex(isUndoable);
|
|
197
|
+
const result = last !== -1 ? history[last] : void 0;
|
|
198
|
+
if (result) {
|
|
199
|
+
const all = result.map(({ _intent, undoable }) => {
|
|
200
|
+
const data = _intent.data;
|
|
201
|
+
const undoData = undoable?.data ?? {};
|
|
202
|
+
return {
|
|
203
|
+
..._intent,
|
|
204
|
+
data: {
|
|
205
|
+
...data,
|
|
206
|
+
...undoData
|
|
207
|
+
},
|
|
208
|
+
undo: true
|
|
209
|
+
};
|
|
210
|
+
});
|
|
211
|
+
const intent = {
|
|
212
|
+
first: all[0],
|
|
213
|
+
last: all.at(-1),
|
|
214
|
+
all
|
|
215
|
+
};
|
|
216
|
+
yield* Ref.update(historyRef, (h) => h.filter((_, index) => index !== last));
|
|
217
|
+
return yield* dispatch(intent);
|
|
218
|
+
}
|
|
219
|
+
});
|
|
220
|
+
};
|
|
221
|
+
const undoPromise = () => {
|
|
222
|
+
const program = undo();
|
|
223
|
+
return Effect.runPromise(program);
|
|
224
|
+
};
|
|
225
|
+
const registerResolver = (id, resolver) => {
|
|
226
|
+
resolvers[id] = [
|
|
227
|
+
...resolvers[id] ?? [],
|
|
228
|
+
resolver
|
|
229
|
+
];
|
|
230
|
+
return () => {
|
|
231
|
+
resolvers[id] = resolvers[id].filter((r) => r !== resolver);
|
|
232
|
+
};
|
|
233
|
+
};
|
|
234
|
+
return {
|
|
235
|
+
dispatch,
|
|
236
|
+
dispatchPromise,
|
|
237
|
+
undo,
|
|
238
|
+
undoPromise,
|
|
239
|
+
registerResolver
|
|
240
|
+
};
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
// packages/sdk/app-framework/src/plugins/plugin-intent/provides.ts
|
|
244
|
+
var parseIntentPlugin = (plugin) => plugin.provides.intent?.dispatch ? plugin : void 0;
|
|
245
|
+
var parseIntentResolverPlugin = (plugin) => plugin.provides.intent?.resolvers ? plugin : void 0;
|
|
246
|
+
|
|
247
|
+
// packages/sdk/app-framework/src/plugins/plugin-intent/IntentPlugin.tsx
|
|
248
|
+
var defaultEffect = () => Effect2.fail(new Error("Intent runtime not ready"));
|
|
249
|
+
var defaultPromise = () => Effect2.runPromise(defaultEffect());
|
|
250
|
+
var IntentPlugin = () => {
|
|
251
|
+
const state = create({
|
|
252
|
+
dispatch: defaultEffect,
|
|
253
|
+
dispatchPromise: defaultPromise,
|
|
254
|
+
undo: defaultEffect,
|
|
255
|
+
undoPromise: defaultPromise,
|
|
256
|
+
registerResolver: () => () => {
|
|
257
|
+
}
|
|
258
|
+
});
|
|
259
|
+
return {
|
|
260
|
+
meta: meta_default,
|
|
261
|
+
ready: async ({ plugins }) => {
|
|
262
|
+
const resolvers = Object.fromEntries(filterPlugins(plugins, parseIntentResolverPlugin).map((plugin) => {
|
|
263
|
+
const resolvers2 = reduceResolvers(plugin.provides.intent.resolvers({
|
|
264
|
+
plugins,
|
|
265
|
+
dispatch: (intent) => state.dispatch(intent),
|
|
266
|
+
dispatchPromise: (intent) => state.dispatchPromise(intent),
|
|
267
|
+
undo: () => state.undo(),
|
|
268
|
+
undoPromise: () => state.undoPromise(),
|
|
269
|
+
registerResolver: (id, resolver) => state.registerResolver(id, resolver)
|
|
270
|
+
}));
|
|
271
|
+
return [
|
|
272
|
+
plugin.meta.id,
|
|
273
|
+
resolvers2
|
|
274
|
+
];
|
|
275
|
+
}));
|
|
276
|
+
const { dispatch, dispatchPromise, undo, undoPromise, registerResolver } = createDispatcher(resolvers);
|
|
277
|
+
state.dispatch = dispatch;
|
|
278
|
+
state.dispatchPromise = dispatchPromise;
|
|
279
|
+
state.undo = undo;
|
|
280
|
+
state.undoPromise = undoPromise;
|
|
281
|
+
state.registerResolver = registerResolver;
|
|
282
|
+
},
|
|
283
|
+
provides: {
|
|
284
|
+
intent: state,
|
|
285
|
+
context: ({ children }) => /* @__PURE__ */ React.createElement(IntentProvider, {
|
|
286
|
+
value: state
|
|
287
|
+
}, children)
|
|
288
|
+
}
|
|
289
|
+
};
|
|
290
|
+
};
|
|
291
|
+
var reduceResolvers = (definitions, resolvers = []) => {
|
|
292
|
+
if (Array.isArray(definitions)) {
|
|
293
|
+
return definitions.reduce((acc, definition) => reduceResolvers(definition, acc), resolvers);
|
|
294
|
+
}
|
|
295
|
+
return [
|
|
296
|
+
...resolvers,
|
|
297
|
+
definitions
|
|
298
|
+
];
|
|
299
|
+
};
|
|
300
|
+
|
|
301
|
+
// packages/sdk/app-framework/src/plugins/plugin-intent/index.ts
|
|
302
|
+
var plugin_intent_default = IntentPlugin;
|
|
303
|
+
|
|
304
|
+
export {
|
|
305
|
+
useIntentDispatcher,
|
|
306
|
+
useIntentResolver,
|
|
307
|
+
IntentProvider,
|
|
308
|
+
meta_default,
|
|
309
|
+
createIntent,
|
|
310
|
+
chain,
|
|
311
|
+
Label,
|
|
312
|
+
INTENT_ACTION,
|
|
313
|
+
IntentAction,
|
|
314
|
+
createResolver,
|
|
315
|
+
createDispatcher,
|
|
316
|
+
parseIntentPlugin,
|
|
317
|
+
parseIntentResolverPlugin,
|
|
318
|
+
plugin_intent_default
|
|
319
|
+
};
|
|
320
|
+
//# sourceMappingURL=chunk-QG25ZU2N.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/plugins/plugin-intent/IntentPlugin.tsx", "../../../src/plugins/plugin-intent/IntentContext.tsx", "../../../src/plugins/plugin-intent/intent-dispatcher.ts", "../../../src/plugins/plugin-intent/intent.ts", "../../../src/plugins/plugin-intent/meta.ts", "../../../src/plugins/plugin-intent/provides.ts", "../../../src/plugins/plugin-intent/index.ts"],
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport { Effect } from 'effect';\nimport React from 'react';\n\nimport { create } from '@dxos/live-object';\n\nimport { IntentProvider } from './IntentContext';\nimport { createDispatcher, type AnyIntentResolver, type IntentContext } from './intent-dispatcher';\nimport IntentMeta from './meta';\nimport { type IntentPluginProvides, type ResolverDefinitions, parseIntentResolverPlugin } from './provides';\nimport { filterPlugins } from '../helpers';\nimport { type PluginDefinition } from '../plugin-host';\n\nconst defaultEffect = () => Effect.fail(new Error('Intent runtime not ready'));\nconst defaultPromise = () => Effect.runPromise(defaultEffect());\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 */\nexport const IntentPlugin = (): PluginDefinition<IntentPluginProvides> => {\n const state = create<IntentContext>({\n dispatch: defaultEffect,\n dispatchPromise: defaultPromise,\n undo: defaultEffect,\n undoPromise: defaultPromise,\n registerResolver: () => () => {},\n });\n\n return {\n meta: IntentMeta,\n ready: async ({ plugins }) => {\n const resolvers = Object.fromEntries(\n filterPlugins(plugins, parseIntentResolverPlugin).map((plugin): [string, AnyIntentResolver[]] => {\n const resolvers = reduceResolvers(\n plugin.provides.intent.resolvers({\n plugins,\n dispatch: (intent) => state.dispatch(intent),\n dispatchPromise: (intent) => state.dispatchPromise(intent),\n undo: () => state.undo(),\n undoPromise: () => state.undoPromise(),\n registerResolver: (id, resolver) => state.registerResolver(id, resolver),\n }),\n );\n return [plugin.meta.id, resolvers];\n }),\n );\n const { dispatch, dispatchPromise, undo, undoPromise, registerResolver } = createDispatcher(resolvers);\n\n state.dispatch = dispatch;\n state.dispatchPromise = dispatchPromise;\n state.undo = undo;\n state.undoPromise = undoPromise;\n state.registerResolver = registerResolver;\n },\n provides: {\n intent: state,\n context: ({ children }) => <IntentProvider value={state}>{children}</IntentProvider>,\n },\n };\n};\n\nconst reduceResolvers = (\n definitions: ResolverDefinitions,\n resolvers: AnyIntentResolver[] = [],\n): AnyIntentResolver[] => {\n if (Array.isArray(definitions)) {\n return definitions.reduce((acc: AnyIntentResolver[], definition) => reduceResolvers(definition, acc), resolvers);\n }\n\n return [...resolvers, definitions];\n};\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { type Context, createContext, useContext, type Provider, useEffect } from 'react';\n\nimport { raise } from '@dxos/debug';\nimport { pick } from '@dxos/util';\n\nimport { type AnyIntentResolver, type IntentContext } from './intent-dispatcher';\n\nconst IntentContext: Context<IntentContext | undefined> = createContext<IntentContext | undefined>(undefined);\n\nexport const useIntentDispatcher = (): Pick<IntentContext, 'dispatch' | 'dispatchPromise'> => {\n const context = useContext(IntentContext) ?? raise(new Error('IntentContext not found'));\n return pick(context, ['dispatch', 'dispatchPromise']);\n};\n\nexport const useIntentResolver = (pluginId: string, resolver: AnyIntentResolver) => {\n const { registerResolver } = useContext(IntentContext) ?? raise(new Error('IntentContext not found'));\n useEffect(() => {\n return registerResolver(pluginId, resolver);\n }, [pluginId, resolver]);\n};\n\nexport const IntentProvider: Provider<IntentContext | undefined> = IntentContext.Provider;\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { Effect, Ref } from 'effect';\n\nimport { type MaybePromise, pick } from '@dxos/util';\n\nimport {\n createIntent,\n IntentAction,\n type AnyIntent,\n type AnyIntentChain,\n type Intent,\n type IntentChain,\n type IntentData,\n type IntentParams,\n type IntentResultData,\n type IntentSchema,\n type Label,\n} from './intent';\n\nconst EXECUTION_LIMIT = 100;\nconst HISTORY_LIMIT = 100;\n\n/**\n * The return value of an intent effect.\n */\nexport type IntentEffectResult<Fields extends IntentParams> = {\n /**\n * The output of the action that was performed.\n *\n * If the intent is apart of a chain of intents, the data will be passed to the next intent.\n */\n data?: IntentResultData<Fields>;\n\n /**\n * If provided, the action will be undoable.\n */\n undoable?: {\n /**\n * Message to display to the user when indicating that the action can be undone.\n */\n message: Label;\n\n /**\n * Will be merged with the original intent data when firing the undo intent.\n */\n data?: Partial<IntentData<Fields>>;\n };\n\n /**\n * An error that occurred while performing the action.\n *\n * If the intent is apart of a chain of intents and an error occurs, the chain will be aborted.\n */\n error?: Error;\n\n /**\n * Other intent chains to be triggered.\n */\n intents?: AnyIntentChain[];\n};\n\nexport type AnyIntentEffectResult = IntentEffectResult<any>;\n\n/**\n * The result of an intent dispatcher.\n */\nexport type IntentDispatcherResult<Fields extends IntentParams> = Pick<IntentEffectResult<Fields>, 'data' | 'error'>;\n\n/**\n * Determines the priority of the effect when multiple intent resolvers are matched.\n *\n * - `static` - The effect is selected in the order it was resolved.\n * - `hoist` - The effect is selected before `static` effects.\n * - `fallback` - The effect is selected after `static` effects.\n */\nexport type IntentDisposition = 'static' | 'hoist' | 'fallback';\n\n/**\n * The implementation of an intent effect.\n */\nexport type IntentEffectDefinition<Fields extends IntentParams> = (\n data: IntentData<Fields>,\n undo: boolean,\n) => MaybePromise<IntentEffectResult<Fields> | void> | Effect.Effect<IntentEffectResult<Fields> | void>;\n\n/**\n * Intent resolver to match intents to their effects.\n */\nexport type IntentResolver<Tag extends string, Fields extends IntentParams> = {\n action: Tag;\n disposition?: IntentDisposition;\n // TODO(wittjosiah): Would be nice to make this a guard for intents with optional data.\n filter?: (data: IntentData<Fields>) => boolean;\n effect: IntentEffectDefinition<Fields>;\n};\n\nexport type AnyIntentResolver = IntentResolver<any, any>;\n\n/**\n * Creates an intent resolver to match intents to their effects.\n * @param schema Schema of the intent. Must be a tagged class with input and output schemas.\n * @param effect Effect to be performed when the intent is resolved.\n * @param params.disposition Determines the priority of the resolver when multiple are resolved.\n * @param params.filter Optional filter to determine if the resolver should be used.\n */\nexport const createResolver = <Tag extends string, Fields extends IntentParams>(\n schema: IntentSchema<Tag, Fields>,\n effect: IntentEffectDefinition<Fields>,\n params: Pick<IntentResolver<Tag, Fields>, 'disposition' | 'filter'> = {},\n): IntentResolver<Tag, Fields> => ({\n action: schema._tag,\n effect,\n ...params,\n});\n\n/**\n * Invokes intents and returns the result.\n */\nexport type PromiseIntentDispatcher = <Fields extends IntentParams>(\n intent: IntentChain<any, any, any, Fields>,\n) => Promise<IntentDispatcherResult<Fields>>;\n\n/**\n * Creates an effect for intents.\n */\nexport type IntentDispatcher = <Fields extends IntentParams>(\n intent: IntentChain<any, any, any, Fields>,\n depth?: number,\n) => Effect.Effect<IntentDispatcherResult<Fields>, Error>;\n\ntype IntentResult<Tag extends string, Fields extends IntentParams> = IntentEffectResult<Fields> & {\n _intent: Intent<Tag, Fields>;\n};\n\ntype AnyIntentResult = IntentResult<any, any>;\n\n/**\n * Invokes the most recent undoable intent with undo flags.\n */\nexport type PromiseIntentUndo = () => Promise<IntentDispatcherResult<any> | undefined>;\n\n/**\n * Creates an effect which undoes the last intent.\n */\nexport type IntentUndo = () => Effect.Effect<IntentDispatcherResult<any> | undefined, Error>;\n\n/**\n * Check if a chain of results is undoable.\n */\nconst isUndoable = (historyEntry: AnyIntentResult[]): boolean =>\n historyEntry.length > 0 && historyEntry.every(({ undoable }) => !!undoable);\n\nexport type IntentContext = {\n dispatch: IntentDispatcher;\n dispatchPromise: PromiseIntentDispatcher;\n undo: IntentUndo;\n undoPromise: PromiseIntentUndo;\n registerResolver: (id: string, resolver: AnyIntentResolver) => () => void;\n};\n\n/**\n * Sets of an intent dispatcher.\n *\n * @param resolvers An array of available intent resolvers.\n * @param params.historyLimit The maximum number of intent results to keep in history.\n * @param params.executionLimit The maximum recursion depth of intent chains.\n */\nexport const createDispatcher = (\n resolvers: Record<string, AnyIntentResolver[]>,\n { executionLimit = EXECUTION_LIMIT, historyLimit = HISTORY_LIMIT } = {},\n): IntentContext => {\n const historyRef = Effect.runSync(Ref.make<AnyIntentResult[][]>([]));\n\n const handleIntent = (intent: AnyIntent) => {\n return Effect.gen(function* () {\n const candidates = Object.entries(resolvers)\n .filter(([id, _]) => (intent.plugin ? id === intent.plugin : true))\n .flatMap(([_, resolvers]) => resolvers)\n .filter((r) => r.action === intent.action)\n .filter((r) => !r.filter || r.filter(intent.data))\n .toSorted(({ disposition: a = 'static' }, { disposition: b = 'static' }) => {\n return a === b ? 0 : a === 'hoist' || b === 'fallback' ? -1 : b === 'hoist' || a === 'fallback' ? 1 : 0;\n });\n if (candidates.length === 0) {\n return {\n _intent: intent,\n error: new Error(`No resolver found for action: ${intent.action}`),\n } satisfies AnyIntentResult;\n }\n\n const effect = candidates[0].effect(intent.data, intent.undo ?? false);\n const result = Effect.isEffect(effect) ? yield* effect : yield* Effect.promise(async () => effect);\n return { _intent: intent, ...result } satisfies AnyIntentResult;\n });\n };\n\n const dispatch: IntentDispatcher = (intentChain, depth = 0) => {\n return Effect.gen(function* () {\n if (depth > executionLimit) {\n yield* Effect.fail(\n new Error('Intent execution limit exceeded. This is likely due to an infinite loop within intent resolvers.'),\n );\n }\n\n const resultsRef = yield* Ref.make<AnyIntentResult[]>([]);\n for (const intent of intentChain.all) {\n const { data: prev } = (yield* resultsRef.get)[0] ?? {};\n const result = yield* handleIntent({ ...intent, data: { ...intent.data, ...prev } });\n yield* Ref.update(resultsRef, (results) => [result, ...results]);\n if (result.error) {\n break;\n }\n if (result.intents) {\n for (const intent of result.intents) {\n // Returned intents are dispatched but not yielded into results,\n // as such they cannot be undone.\n // TODO(wittjosiah): Use higher execution concurrency?\n yield* dispatch(intent, depth + 1);\n }\n }\n }\n\n const results = yield* resultsRef.get;\n const result = results[0];\n if (result) {\n yield* Ref.update(historyRef, (history) => {\n const next = [...history, results];\n if (next.length > historyLimit) {\n next.splice(0, next.length - historyLimit);\n }\n return next;\n });\n\n if (result.undoable && isUndoable(results)) {\n // TODO(wittjosiah): Is there a better way to handle showing undo for chains?\n yield* dispatch(createIntent(IntentAction.ShowUndo, { message: result.undoable.message }));\n }\n\n return pick(result, ['data', 'error']);\n } else {\n return { data: {}, error: new Error('No results') };\n }\n });\n };\n\n const dispatchPromise: PromiseIntentDispatcher = (intentChain) => {\n const program = dispatch(intentChain);\n return Effect.runPromise(program);\n };\n\n const undo: IntentUndo = () => {\n return Effect.gen(function* () {\n const history = yield* historyRef.get;\n const last = history.findLastIndex(isUndoable);\n const result = last !== -1 ? history[last] : undefined;\n if (result) {\n const all = result.map(({ _intent, undoable }): AnyIntent => {\n const data = _intent.data;\n const undoData = undoable?.data ?? {};\n return { ..._intent, data: { ...data, ...undoData }, undo: true } satisfies AnyIntent;\n });\n const intent = { first: all[0], last: all.at(-1)!, all } satisfies AnyIntentChain;\n yield* Ref.update(historyRef, (h) => h.filter((_, index) => index !== last));\n return yield* dispatch(intent);\n }\n });\n };\n\n const undoPromise: PromiseIntentUndo = () => {\n const program = undo();\n return Effect.runPromise(program);\n };\n\n const registerResolver = (id: string, resolver: AnyIntentResolver) => {\n resolvers[id] = [...(resolvers[id] ?? []), resolver];\n return () => {\n resolvers[id] = resolvers[id].filter((r) => r !== resolver);\n };\n };\n\n return { dispatch, dispatchPromise, undo, undoPromise, registerResolver };\n};\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { S } from '@dxos/echo-schema';\n\nimport { INTENT_PLUGIN } from './meta';\n\nexport type IntentParams = {\n readonly input: S.Schema.All;\n readonly output: S.Schema.All;\n};\n\nexport type IntentData<Fields extends IntentParams> =\n S.Schema.Type<S.Struct<Fields>> extends { readonly input: any } ? S.Schema.Type<S.Struct<Fields>>['input'] : any;\n\nexport type IntentResultData<Fields extends IntentParams> =\n S.Schema.Type<S.Struct<Fields>> extends { readonly output: any } ? S.Schema.Type<S.Struct<Fields>>['output'] : any;\n\nexport type IntentSchema<Tag extends string, Fields extends IntentParams> = S.TaggedClass<any, Tag, Fields>;\n\n/**\n * An intent is an abstract description of an operation to be performed.\n * Intents allow actions to be performed across plugins.\n */\nexport type Intent<Tag extends string, Fields extends IntentParams> = {\n _schema: IntentSchema<Tag, Fields>;\n\n /**\n * The action to perform.\n */\n action: Tag;\n\n /**\n * Any data needed to perform the desired action.\n */\n data: IntentData<Fields>;\n\n /**\n * Plugin ID.\n * If specified, the intent will be sent explicitly to the plugin.\n * Otherwise, the intent will be sent to all plugins, in order and the first to resolve a non-null value will be used.\n */\n plugin?: string;\n\n /**\n * Whether or not the intent is being undone.\n */\n undo?: boolean;\n};\n\nexport type AnyIntent = Intent<any, any>;\n\n/**\n * Chain of intents to be executed together.\n * The result of each intent is merged into the next intent's input data.\n */\nexport type IntentChain<\n FirstTag extends string,\n LastTag extends string,\n FirstFields extends IntentParams,\n LastFields extends IntentParams,\n> = {\n first: Intent<FirstTag, FirstFields>;\n last: Intent<LastTag, LastFields>;\n all: AnyIntent[];\n};\n\nexport type AnyIntentChain = IntentChain<any, any, any, any>;\n\n/**\n * Creates a typed intent.\n * @param schema Schema of the intent. Must be a tagged class with input and output schemas.\n * @param data Data fulfilling the input schema of the intent.\n * @param params.plugin Optional plugin ID to send the intent to.\n * @param params.undo Optional flag to indicate that the intent is being undone. Generally not set manually.\n */\nexport const createIntent = <Tag extends string, Fields extends IntentParams>(\n schema: IntentSchema<Tag, Fields>,\n data: IntentData<Fields> = {},\n params: Pick<AnyIntent, 'plugin' | 'undo'> = {},\n): IntentChain<Tag, Tag, Fields, Fields> => {\n // The output of validateSync breaks proxy objects so this is just used for validation.\n // TODO(wittjosiah): Is there a better way to make theses types align?\n const _ = S.validateSync(schema.fields.input as S.Schema<any, any, unknown>)(data);\n const intent = {\n ...params,\n _schema: schema,\n action: schema._tag,\n data,\n } satisfies Intent<Tag, Fields>;\n\n return {\n first: intent,\n last: intent,\n all: [intent],\n };\n};\n\n// TODO(wittjosiah): Add a function for mapping the output of one intent to the input of another.\n\n/**\n * Chain two intents together.\n *\n * NOTE: Chaining of intents depends on the data inputs and outputs being structs.\n */\nexport const chain =\n <\n FirstTag extends string,\n NextTag extends string,\n FirstFields extends IntentParams,\n LastFields extends IntentParams,\n NextFields extends IntentParams,\n >(\n schema: IntentSchema<NextTag, NextFields>,\n data: Omit<IntentData<NextFields>, keyof IntentResultData<LastFields>> = {},\n params: Pick<AnyIntent, 'plugin' | 'undo'> = {},\n ) =>\n (\n intent: IntentChain<FirstTag, any, FirstFields, LastFields>,\n ): IntentChain<FirstTag, NextTag, FirstFields, NextFields> => {\n const intents = 'all' in intent ? intent.all : [intent];\n const first = intents[0];\n const last = {\n ...params,\n _schema: schema,\n action: schema._tag,\n data,\n } satisfies Intent<NextTag, NextFields>;\n\n return {\n first,\n last,\n all: [...intents, last],\n };\n };\n\n//\n// Intents\n//\n\n// NOTE: Should maintain compatibility with `i18next` (and @dxos/react-ui).\n// TODO(wittjosiah): Making this immutable breaks type compatibility.\nexport const Label = S.Union(\n S.String,\n S.mutable(S.Tuple(S.String, S.mutable(S.Struct({ ns: S.String, count: S.optional(S.Number) })))),\n);\nexport type Label = S.Schema.Type<typeof Label>;\n\nexport const INTENT_ACTION = `${INTENT_PLUGIN}/action`;\n\nexport namespace IntentAction {\n /**\n * Fired after an intent is dispatched if the intent is undoable.\n */\n export class ShowUndo extends S.TaggedClass<ShowUndo>()(`${INTENT_ACTION}/show-undo`, {\n input: S.Struct({\n message: Label,\n }),\n output: S.Void,\n }) {}\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nexport const INTENT_PLUGIN = 'dxos.org/plugin/intent';\n\nconst IntentMeta = {\n id: INTENT_PLUGIN,\n};\n\nexport default IntentMeta;\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { type IntentContext, type AnyIntentResolver } from './intent-dispatcher';\nimport { type HostContext, type Plugin } from '../plugin-host';\n\ntype Context = HostContext & IntentContext;\n\nexport type ResolverDefinitions = AnyIntentResolver | AnyIntentResolver[] | ResolverDefinitions[];\n\nexport type IntentResolverProvides = {\n intent: {\n resolvers: (context: Context) => ResolverDefinitions;\n };\n};\n\nexport type IntentPluginProvides = {\n intent: IntentContext;\n};\n\nexport const parseIntentPlugin = (plugin: Plugin) =>\n (plugin.provides as any).intent?.dispatch ? (plugin as Plugin<IntentPluginProvides>) : undefined;\n\nexport const parseIntentResolverPlugin = (plugin: Plugin) =>\n (plugin.provides as any).intent?.resolvers ? (plugin as Plugin<IntentResolverProvides>) : undefined;\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { IntentPlugin } from './IntentPlugin';\n\nexport * from './intent';\nexport * from './intent-dispatcher';\nexport * from './provides';\n\nexport * from './IntentContext';\n\nexport default IntentPlugin;\n"],
|
|
5
|
+
"mappings": ";;;;;AAIA,SAASA,UAAAA,eAAc;AACvB,OAAOC,WAAW;AAElB,SAASC,cAAc;;;ACHvB,SAAuBC,eAAeC,YAA2BC,iBAAiB;AAElF,SAASC,aAAa;AACtB,SAASC,YAAY;AAIrB,IAAMC,gBAAoDC,8BAAyCC,MAAAA;AAE5F,IAAMC,sBAAsB,MAAA;AACjC,QAAMC,UAAUC,WAAWL,aAAAA,KAAkBM,MAAM,IAAIC,MAAM,yBAAA,CAAA;AAC7D,SAAOC,KAAKJ,SAAS;IAAC;IAAY;GAAkB;AACtD;AAEO,IAAMK,oBAAoB,CAACC,UAAkBC,aAAAA;AAClD,QAAM,EAAEC,iBAAgB,IAAKP,WAAWL,aAAAA,KAAkBM,MAAM,IAAIC,MAAM,yBAAA,CAAA;AAC1EM,YAAU,MAAA;AACR,WAAOD,iBAAiBF,UAAUC,QAAAA;EACpC,GAAG;IAACD;IAAUC;GAAS;AACzB;AAEO,IAAMG,iBAAsDd,cAAce;;;ACrBjF,SAASC,QAAQC,WAAW;AAE5B,SAA4BC,QAAAA,aAAY;;;ACFxC,SAASC,SAAS;;;ACAX,IAAMC,gBAAgB;AAE7B,IAAMC,aAAa;EACjBC,IAAIF;AACN;AAEA,IAAA,eAAeC;;;ADmER,IAAME,eAAe,CAC1BC,QACAC,OAA2B,CAAC,GAC5BC,SAA6C,CAAC,MAAC;AAI/C,QAAMC,IAAIC,EAAEC,aAAaL,OAAOM,OAAOC,KAAK,EAAiCN,IAAAA;AAC7E,QAAMO,SAAS;IACb,GAAGN;IACHO,SAAST;IACTU,QAAQV,OAAOW;IACfV;EACF;AAEA,SAAO;IACLW,OAAOJ;IACPK,MAAML;IACNM,KAAK;MAACN;;EACR;AACF;AASO,IAAMO,QACX,CAOEf,QACAC,OAAyE,CAAC,GAC1EC,SAA6C,CAAC,MAEhD,CACEM,WAAAA;AAEA,QAAMQ,UAAU,SAASR,SAASA,OAAOM,MAAM;IAACN;;AAChD,QAAMI,QAAQI,QAAQ,CAAA;AACtB,QAAMH,OAAO;IACX,GAAGX;IACHO,SAAST;IACTU,QAAQV,OAAOW;IACfV;EACF;AAEA,SAAO;IACLW;IACAC;IACAC,KAAK;SAAIE;MAASH;;EACpB;AACF;AAQK,IAAMI,QAAQb,EAAEc,MACrBd,EAAEe,QACFf,EAAEgB,QAAQhB,EAAEiB,MAAMjB,EAAEe,QAAQf,EAAEgB,QAAQhB,EAAEkB,OAAO;EAAEC,IAAInB,EAAEe;EAAQK,OAAOpB,EAAEqB,SAASrB,EAAEsB,MAAM;AAAE,CAAA,CAAA,CAAA,CAAA,CAAA;AAItF,IAAMC,gBAAgB,GAAGC,aAAAA;;UAEfC,eAAAA;EAIR,MAAMC,iBAAiB1B,EAAE2B,YAAW,EAAa,GAAGJ,aAAAA,cAA2B;IACpFpB,OAAOH,EAAEkB,OAAO;MACdU,SAASf;IACX,CAAA;IACAgB,QAAQ7B,EAAE8B;EACZ,CAAA,EAAA;EAAI;AANH,EAAAL,cACYC,WAAAA;AAMf,GAViBD,iBAAAA,eAAAA,CAAAA,EAAAA;;;ADjIjB,IAAMM,kBAAkB;AACxB,IAAMC,gBAAgB;AAqFf,IAAMC,iBAAiB,CAC5BC,QACAC,QACAC,SAAsE,CAAC,OACtC;EACjCC,QAAQH,OAAOI;EACfH;EACA,GAAGC;AACL;AAoCA,IAAMG,aAAa,CAACC,iBAClBA,aAAaC,SAAS,KAAKD,aAAaE,MAAM,CAAC,EAAEC,SAAQ,MAAO,CAAC,CAACA,QAAAA;AAiB7D,IAAMC,mBAAmB,CAC9BC,WACA,EAAEC,iBAAiBf,iBAAiBgB,eAAef,cAAa,IAAK,CAAC,MAAC;AAEvE,QAAMgB,aAAaC,OAAOC,QAAQC,IAAIC,KAA0B,CAAA,CAAE,CAAA;AAElE,QAAMC,eAAe,CAACC,WAAAA;AACpB,WAAOL,OAAOM,IAAI,aAAA;AAChB,YAAMC,aAAaC,OAAOC,QAAQb,SAAAA,EAC/Bc,OAAO,CAAC,CAACC,IAAIC,CAAAA,MAAQP,OAAOQ,SAASF,OAAON,OAAOQ,SAAS,IAAA,EAC5DC,QAAQ,CAAC,CAACF,GAAGhB,UAAAA,MAAeA,UAAAA,EAC5Bc,OAAO,CAACK,MAAMA,EAAE3B,WAAWiB,OAAOjB,MAAM,EACxCsB,OAAO,CAACK,MAAM,CAACA,EAAEL,UAAUK,EAAEL,OAAOL,OAAOW,IAAI,CAAA,EAC/CC,SAAS,CAAC,EAAEC,aAAaC,IAAI,SAAQ,GAAI,EAAED,aAAaE,IAAI,SAAQ,MAAE;AACrE,eAAOD,MAAMC,IAAI,IAAID,MAAM,WAAWC,MAAM,aAAa,KAAKA,MAAM,WAAWD,MAAM,aAAa,IAAI;MACxG,CAAA;AACF,UAAIZ,WAAWf,WAAW,GAAG;AAC3B,eAAO;UACL6B,SAAShB;UACTiB,OAAO,IAAIC,MAAM,iCAAiClB,OAAOjB,MAAM,EAAE;QACnE;MACF;AAEA,YAAMF,SAASqB,WAAW,CAAA,EAAGrB,OAAOmB,OAAOW,MAAMX,OAAOmB,QAAQ,KAAA;AAChE,YAAMC,SAASzB,OAAO0B,SAASxC,MAAAA,IAAU,OAAOA,SAAS,OAAOc,OAAO2B,QAAQ,YAAYzC,MAAAA;AAC3F,aAAO;QAAEmC,SAAShB;QAAQ,GAAGoB;MAAO;IACtC,CAAA;EACF;AAEA,QAAMG,WAA6B,CAACC,aAAaC,QAAQ,MAAC;AACxD,WAAO9B,OAAOM,IAAI,aAAA;AAChB,UAAIwB,QAAQjC,gBAAgB;AAC1B,eAAOG,OAAO+B,KACZ,IAAIR,MAAM,kGAAA,CAAA;MAEd;AAEA,YAAMS,aAAa,OAAO9B,IAAIC,KAAwB,CAAA,CAAE;AACxD,iBAAWE,UAAUwB,YAAYI,KAAK;AACpC,cAAM,EAAEjB,MAAMkB,KAAI,KAAM,OAAOF,WAAWG,KAAK,CAAA,KAAM,CAAC;AACtD,cAAMV,UAAS,OAAOrB,aAAa;UAAE,GAAGC;UAAQW,MAAM;YAAE,GAAGX,OAAOW;YAAM,GAAGkB;UAAK;QAAE,CAAA;AAClF,eAAOhC,IAAIkC,OAAOJ,YAAY,CAACK,aAAY;UAACZ;aAAWY;SAAQ;AAC/D,YAAIZ,QAAOH,OAAO;AAChB;QACF;AACA,YAAIG,QAAOa,SAAS;AAClB,qBAAWjC,WAAUoB,QAAOa,SAAS;AAInC,mBAAOV,SAASvB,SAAQyB,QAAQ,CAAA;UAClC;QACF;MACF;AAEA,YAAMO,UAAU,OAAOL,WAAWG;AAClC,YAAMV,SAASY,QAAQ,CAAA;AACvB,UAAIZ,QAAQ;AACV,eAAOvB,IAAIkC,OAAOrC,YAAY,CAACwC,YAAAA;AAC7B,gBAAMC,OAAO;eAAID;YAASF;;AAC1B,cAAIG,KAAKhD,SAASM,cAAc;AAC9B0C,iBAAKC,OAAO,GAAGD,KAAKhD,SAASM,YAAAA;UAC/B;AACA,iBAAO0C;QACT,CAAA;AAEA,YAAIf,OAAO/B,YAAYJ,WAAW+C,OAAAA,GAAU;AAE1C,iBAAOT,SAASc,aAAaC,aAAaC,UAAU;YAAEC,SAASpB,OAAO/B,SAASmD;UAAQ,CAAA,CAAA;QACzF;AAEA,eAAOC,MAAKrB,QAAQ;UAAC;UAAQ;SAAQ;MACvC,OAAO;AACL,eAAO;UAAET,MAAM,CAAC;UAAGM,OAAO,IAAIC,MAAM,YAAA;QAAc;MACpD;IACF,CAAA;EACF;AAEA,QAAMwB,kBAA2C,CAAClB,gBAAAA;AAChD,UAAMmB,UAAUpB,SAASC,WAAAA;AACzB,WAAO7B,OAAOiD,WAAWD,OAAAA;EAC3B;AAEA,QAAMxB,OAAmB,MAAA;AACvB,WAAOxB,OAAOM,IAAI,aAAA;AAChB,YAAMiC,UAAU,OAAOxC,WAAWoC;AAClC,YAAMe,OAAOX,QAAQY,cAAc7D,UAAAA;AACnC,YAAMmC,SAASyB,SAAS,KAAKX,QAAQW,IAAAA,IAAQE;AAC7C,UAAI3B,QAAQ;AACV,cAAMQ,MAAMR,OAAO4B,IAAI,CAAC,EAAEhC,SAAS3B,SAAQ,MAAE;AAC3C,gBAAMsB,OAAOK,QAAQL;AACrB,gBAAMsC,WAAW5D,UAAUsB,QAAQ,CAAC;AACpC,iBAAO;YAAE,GAAGK;YAASL,MAAM;cAAE,GAAGA;cAAM,GAAGsC;YAAS;YAAG9B,MAAM;UAAK;QAClE,CAAA;AACA,cAAMnB,SAAS;UAAEkD,OAAOtB,IAAI,CAAA;UAAIiB,MAAMjB,IAAIuB,GAAG,EAAC;UAAKvB;QAAI;AACvD,eAAO/B,IAAIkC,OAAOrC,YAAY,CAAC0D,MAAMA,EAAE/C,OAAO,CAACE,GAAG8C,UAAUA,UAAUR,IAAAA,CAAAA;AACtE,eAAO,OAAOtB,SAASvB,MAAAA;MACzB;IACF,CAAA;EACF;AAEA,QAAMsD,cAAiC,MAAA;AACrC,UAAMX,UAAUxB,KAAAA;AAChB,WAAOxB,OAAOiD,WAAWD,OAAAA;EAC3B;AAEA,QAAMY,mBAAmB,CAACjD,IAAYkD,aAAAA;AACpCjE,cAAUe,EAAAA,IAAM;SAAKf,UAAUe,EAAAA,KAAO,CAAA;MAAKkD;;AAC3C,WAAO,MAAA;AACLjE,gBAAUe,EAAAA,IAAMf,UAAUe,EAAAA,EAAID,OAAO,CAACK,MAAMA,MAAM8C,QAAAA;IACpD;EACF;AAEA,SAAO;IAAEjC;IAAUmB;IAAiBvB;IAAMmC;IAAaC;EAAiB;AAC1E;;;AGvQO,IAAME,oBAAoB,CAACC,WAC/BA,OAAOC,SAAiBC,QAAQC,WAAYH,SAA0CI;AAElF,IAAMC,4BAA4B,CAACL,WACvCA,OAAOC,SAAiBC,QAAQI,YAAaN,SAA4CI;;;ALT5F,IAAMG,gBAAgB,MAAMC,QAAOC,KAAK,IAAIC,MAAM,0BAAA,CAAA;AAClD,IAAMC,iBAAiB,MAAMH,QAAOI,WAAWL,cAAAA,CAAAA;AAMxC,IAAMM,eAAe,MAAA;AAC1B,QAAMC,QAAQC,OAAsB;IAClCC,UAAUT;IACVU,iBAAiBN;IACjBO,MAAMX;IACNY,aAAaR;IACbS,kBAAkB,MAAM,MAAA;IAAO;EACjC,CAAA;AAEA,SAAO;IACLC,MAAMC;IACNC,OAAO,OAAO,EAAEC,QAAO,MAAE;AACvB,YAAMC,YAAYC,OAAOC,YACvBC,cAAcJ,SAASK,yBAAAA,EAA2BC,IAAI,CAACC,WAAAA;AACrD,cAAMN,aAAYO,gBAChBD,OAAOE,SAASC,OAAOT,UAAU;UAC/BD;UACAR,UAAU,CAACkB,WAAWpB,MAAME,SAASkB,MAAAA;UACrCjB,iBAAiB,CAACiB,WAAWpB,MAAMG,gBAAgBiB,MAAAA;UACnDhB,MAAM,MAAMJ,MAAMI,KAAI;UACtBC,aAAa,MAAML,MAAMK,YAAW;UACpCC,kBAAkB,CAACe,IAAIC,aAAatB,MAAMM,iBAAiBe,IAAIC,QAAAA;QACjE,CAAA,CAAA;AAEF,eAAO;UAACL,OAAOV,KAAKc;UAAIV;;MAC1B,CAAA,CAAA;AAEF,YAAM,EAAET,UAAUC,iBAAiBC,MAAMC,aAAaC,iBAAgB,IAAKiB,iBAAiBZ,SAAAA;AAE5FX,YAAME,WAAWA;AACjBF,YAAMG,kBAAkBA;AACxBH,YAAMI,OAAOA;AACbJ,YAAMK,cAAcA;AACpBL,YAAMM,mBAAmBA;IAC3B;IACAa,UAAU;MACRC,QAAQpB;MACRwB,SAAS,CAAC,EAAEC,SAAQ,MAAO,sBAAA,cAACC,gBAAAA;QAAeC,OAAO3B;SAAQyB,QAAAA;IAC5D;EACF;AACF;AAEA,IAAMP,kBAAkB,CACtBU,aACAjB,YAAiC,CAAA,MAAE;AAEnC,MAAIkB,MAAMC,QAAQF,WAAAA,GAAc;AAC9B,WAAOA,YAAYG,OAAO,CAACC,KAA0BC,eAAef,gBAAgBe,YAAYD,GAAAA,GAAMrB,SAAAA;EACxG;AAEA,SAAO;OAAIA;IAAWiB;;AACxB;;;AM9DA,IAAA,wBAAeM;",
|
|
6
|
+
"names": ["Effect", "React", "create", "createContext", "useContext", "useEffect", "raise", "pick", "IntentContext", "createContext", "undefined", "useIntentDispatcher", "context", "useContext", "raise", "Error", "pick", "useIntentResolver", "pluginId", "resolver", "registerResolver", "useEffect", "IntentProvider", "Provider", "Effect", "Ref", "pick", "S", "INTENT_PLUGIN", "IntentMeta", "id", "createIntent", "schema", "data", "params", "_", "S", "validateSync", "fields", "input", "intent", "_schema", "action", "_tag", "first", "last", "all", "chain", "intents", "Label", "Union", "String", "mutable", "Tuple", "Struct", "ns", "count", "optional", "Number", "INTENT_ACTION", "INTENT_PLUGIN", "IntentAction", "ShowUndo", "TaggedClass", "message", "output", "Void", "EXECUTION_LIMIT", "HISTORY_LIMIT", "createResolver", "schema", "effect", "params", "action", "_tag", "isUndoable", "historyEntry", "length", "every", "undoable", "createDispatcher", "resolvers", "executionLimit", "historyLimit", "historyRef", "Effect", "runSync", "Ref", "make", "handleIntent", "intent", "gen", "candidates", "Object", "entries", "filter", "id", "_", "plugin", "flatMap", "r", "data", "toSorted", "disposition", "a", "b", "_intent", "error", "Error", "undo", "result", "isEffect", "promise", "dispatch", "intentChain", "depth", "fail", "resultsRef", "all", "prev", "get", "update", "results", "intents", "history", "next", "splice", "createIntent", "IntentAction", "ShowUndo", "message", "pick", "dispatchPromise", "program", "runPromise", "last", "findLastIndex", "undefined", "map", "undoData", "first", "at", "h", "index", "undoPromise", "registerResolver", "resolver", "parseIntentPlugin", "plugin", "provides", "intent", "dispatch", "undefined", "parseIntentResolverPlugin", "resolvers", "defaultEffect", "Effect", "fail", "Error", "defaultPromise", "runPromise", "IntentPlugin", "state", "create", "dispatch", "dispatchPromise", "undo", "undoPromise", "registerResolver", "meta", "IntentMeta", "ready", "plugins", "resolvers", "Object", "fromEntries", "filterPlugins", "parseIntentResolverPlugin", "map", "plugin", "reduceResolvers", "provides", "intent", "id", "resolver", "createDispatcher", "context", "children", "IntentProvider", "value", "definitions", "Array", "isArray", "reduce", "acc", "definition", "IntentPlugin"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import {
|
|
2
|
+
filterPlugins
|
|
3
|
+
} from "./chunk-3E7RY3CE.mjs";
|
|
4
|
+
|
|
5
|
+
// packages/sdk/app-framework/src/plugins/plugin-surface/SurfacePlugin.tsx
|
|
6
|
+
import React from "react";
|
|
7
|
+
import { create } from "@dxos/live-object";
|
|
8
|
+
|
|
9
|
+
// packages/sdk/app-framework/src/plugins/plugin-surface/SurfaceContext.ts
|
|
10
|
+
import { createContext, useContext } from "react";
|
|
11
|
+
import { raise } from "@dxos/debug";
|
|
12
|
+
var createSurface = (definition) => definition;
|
|
13
|
+
var SurfaceContext = createContext(void 0);
|
|
14
|
+
var useSurfaceRoot = () => useContext(SurfaceContext) ?? raise(new Error("Missing SurfaceContext"));
|
|
15
|
+
var SurfaceProvider = SurfaceContext.Provider;
|
|
16
|
+
|
|
17
|
+
// packages/sdk/app-framework/src/plugins/plugin-surface/meta.ts
|
|
18
|
+
var SurfaceMeta = {
|
|
19
|
+
id: "dxos.org/plugin/surface"
|
|
20
|
+
};
|
|
21
|
+
var meta_default = SurfaceMeta;
|
|
22
|
+
|
|
23
|
+
// packages/sdk/app-framework/src/plugins/plugin-surface/provides.ts
|
|
24
|
+
var parseRootSurfacePlugin = (plugin) => plugin?.provides?.surface?.surfaces ? plugin : void 0;
|
|
25
|
+
var parseSurfacePlugin = (plugin) => plugin?.provides?.surface?.definitions ? plugin : void 0;
|
|
26
|
+
|
|
27
|
+
// packages/sdk/app-framework/src/plugins/plugin-surface/SurfacePlugin.tsx
|
|
28
|
+
var SurfacePlugin = () => {
|
|
29
|
+
const state = create({
|
|
30
|
+
surfaces: {},
|
|
31
|
+
debugInfo: /* @__PURE__ */ new Map()
|
|
32
|
+
});
|
|
33
|
+
return {
|
|
34
|
+
meta: meta_default,
|
|
35
|
+
ready: async (context) => {
|
|
36
|
+
state.surfaces = filterPlugins(context.plugins, parseSurfacePlugin).reduce((acc, plugin) => reduceSurfaces(plugin.provides.surface.definitions(context), acc), {});
|
|
37
|
+
},
|
|
38
|
+
provides: {
|
|
39
|
+
surface: state,
|
|
40
|
+
context: ({ children }) => /* @__PURE__ */ React.createElement(SurfaceProvider, {
|
|
41
|
+
value: state
|
|
42
|
+
}, children)
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
};
|
|
46
|
+
var reduceSurfaces = (definitions, surfaces = {}) => {
|
|
47
|
+
if (Array.isArray(definitions)) {
|
|
48
|
+
return definitions.reduce((acc, definition) => reduceSurfaces(definition, acc), surfaces);
|
|
49
|
+
}
|
|
50
|
+
return {
|
|
51
|
+
...surfaces,
|
|
52
|
+
[definitions.id]: definitions
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
// packages/sdk/app-framework/src/plugins/plugin-surface/helpers.ts
|
|
57
|
+
var isObject = (data) => !!data && typeof data === "object";
|
|
58
|
+
|
|
59
|
+
// packages/sdk/app-framework/src/plugins/plugin-surface/ErrorBoundary.tsx
|
|
60
|
+
import React2, { Component } from "react";
|
|
61
|
+
var ErrorBoundary = class extends Component {
|
|
62
|
+
constructor(props) {
|
|
63
|
+
super(props);
|
|
64
|
+
this.state = {
|
|
65
|
+
error: void 0
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
static getDerivedStateFromError(error) {
|
|
69
|
+
return {
|
|
70
|
+
error
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
componentDidUpdate(prevProps) {
|
|
74
|
+
if (prevProps.data !== this.props.data) {
|
|
75
|
+
this.resetError();
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
render() {
|
|
79
|
+
if (this.state.error) {
|
|
80
|
+
return /* @__PURE__ */ React2.createElement(this.props.fallback, {
|
|
81
|
+
data: this.props.data,
|
|
82
|
+
error: this.state.error,
|
|
83
|
+
reset: this.resetError
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
return this.props.children;
|
|
87
|
+
}
|
|
88
|
+
resetError() {
|
|
89
|
+
this.setState({
|
|
90
|
+
error: void 0
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
// packages/sdk/app-framework/src/plugins/plugin-surface/Surface.tsx
|
|
96
|
+
import React3, { Suspense, forwardRef, memo, useEffect, useId, useMemo } from "react";
|
|
97
|
+
import { useDefaultValue } from "@dxos/react-hooks";
|
|
98
|
+
var Surface = /* @__PURE__ */ memo(/* @__PURE__ */ forwardRef(({ id: _id, role, data: _data, limit, fallback, placeholder, ...rest }, forwardedRef) => {
|
|
99
|
+
const { surfaces, debugInfo } = useSurfaceRoot();
|
|
100
|
+
const data = useDefaultValue(_data, () => ({}));
|
|
101
|
+
const reactId = useId();
|
|
102
|
+
const id = _id ?? reactId;
|
|
103
|
+
useEffect(() => {
|
|
104
|
+
debugInfo?.set(id, {
|
|
105
|
+
id,
|
|
106
|
+
created: Date.now(),
|
|
107
|
+
role,
|
|
108
|
+
renderCount: 0
|
|
109
|
+
});
|
|
110
|
+
return () => {
|
|
111
|
+
debugInfo?.delete(id);
|
|
112
|
+
};
|
|
113
|
+
}, [
|
|
114
|
+
id
|
|
115
|
+
]);
|
|
116
|
+
if (debugInfo?.get(id)) {
|
|
117
|
+
debugInfo.get(id).renderCount++;
|
|
118
|
+
}
|
|
119
|
+
const candidates = useMemo(() => {
|
|
120
|
+
const definitions = Object.values(surfaces).filter((definition) => Array.isArray(definition.role) ? definition.role.includes(role) : definition.role === role).filter(({ filter }) => filter ? filter(data) : true).toSorted(({ disposition: a = "static" }, { disposition: b = "static" }) => {
|
|
121
|
+
return a === b ? 0 : a === "hoist" || b === "fallback" ? -1 : b === "hoist" || a === "fallback" ? 1 : 0;
|
|
122
|
+
});
|
|
123
|
+
return limit ? definitions.slice(0, limit) : definitions;
|
|
124
|
+
}, [
|
|
125
|
+
surfaces,
|
|
126
|
+
role,
|
|
127
|
+
data,
|
|
128
|
+
limit
|
|
129
|
+
]);
|
|
130
|
+
const nodes = candidates.map(({ component: Component2, id: id2 }) => /* @__PURE__ */ React3.createElement(Component2, {
|
|
131
|
+
ref: forwardedRef,
|
|
132
|
+
key: id2,
|
|
133
|
+
id: id2,
|
|
134
|
+
role,
|
|
135
|
+
data,
|
|
136
|
+
limit,
|
|
137
|
+
...rest
|
|
138
|
+
}));
|
|
139
|
+
const suspense = placeholder ? /* @__PURE__ */ React3.createElement(Suspense, {
|
|
140
|
+
fallback: placeholder
|
|
141
|
+
}, nodes) : nodes;
|
|
142
|
+
return fallback ? /* @__PURE__ */ React3.createElement(ErrorBoundary, {
|
|
143
|
+
data,
|
|
144
|
+
fallback
|
|
145
|
+
}, suspense) : suspense;
|
|
146
|
+
}));
|
|
147
|
+
|
|
148
|
+
// packages/sdk/app-framework/src/plugins/plugin-surface/index.ts
|
|
149
|
+
var plugin_surface_default = SurfacePlugin;
|
|
150
|
+
|
|
151
|
+
export {
|
|
152
|
+
createSurface,
|
|
153
|
+
useSurfaceRoot,
|
|
154
|
+
SurfaceProvider,
|
|
155
|
+
meta_default,
|
|
156
|
+
parseRootSurfacePlugin,
|
|
157
|
+
parseSurfacePlugin,
|
|
158
|
+
isObject,
|
|
159
|
+
ErrorBoundary,
|
|
160
|
+
Surface,
|
|
161
|
+
plugin_surface_default
|
|
162
|
+
};
|
|
163
|
+
//# sourceMappingURL=chunk-SPDTXTOV.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/plugins/plugin-surface/SurfacePlugin.tsx", "../../../src/plugins/plugin-surface/SurfaceContext.ts", "../../../src/plugins/plugin-surface/meta.ts", "../../../src/plugins/plugin-surface/provides.ts", "../../../src/plugins/plugin-surface/helpers.ts", "../../../src/plugins/plugin-surface/ErrorBoundary.tsx", "../../../src/plugins/plugin-surface/Surface.tsx", "../../../src/plugins/plugin-surface/index.ts"],
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport React from 'react';\n\nimport { create } from '@dxos/live-object';\n\nimport { SurfaceProvider, type SurfaceContextValue } from './SurfaceContext';\nimport SurfaceMeta from './meta';\nimport { parseSurfacePlugin, type SurfacePluginProvides, type SurfaceDefinitions } from './provides';\nimport { filterPlugins } from '../helpers';\nimport { type PluginDefinition } from '../plugin-host';\n\n/**\n * Provides a registry of surface components.\n */\nexport const SurfacePlugin = (): PluginDefinition<SurfacePluginProvides> => {\n const state = create<SurfaceContextValue>({ surfaces: {}, debugInfo: new Map() });\n\n return {\n meta: SurfaceMeta,\n ready: async (context) => {\n state.surfaces = filterPlugins(context.plugins, parseSurfacePlugin).reduce(\n (acc, plugin) => reduceSurfaces(plugin.provides.surface.definitions(context), acc),\n {},\n );\n },\n provides: {\n surface: state,\n context: ({ children }) => <SurfaceProvider value={state}>{children}</SurfaceProvider>,\n },\n };\n};\n\nconst reduceSurfaces = (\n definitions: SurfaceDefinitions,\n surfaces: SurfaceContextValue['surfaces'] = {},\n): SurfaceContextValue['surfaces'] => {\n if (Array.isArray(definitions)) {\n return definitions.reduce((acc, definition) => reduceSurfaces(definition, acc), surfaces);\n }\n\n return { ...surfaces, [definitions.id]: definitions };\n};\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { createContext, useContext, type JSX, type ForwardedRef, type PropsWithChildren, type ReactNode } from 'react';\n\nimport { raise } from '@dxos/debug';\nimport { type GuardedType, type MakeOptional } from '@dxos/util';\n\nimport { type ErrorBoundary } from './ErrorBoundary';\n\n/**\n * SurfaceProps are the props that are passed to the Surface component.\n */\nexport type SurfaceProps<T extends Record<string, any> = Record<string, unknown>> = PropsWithChildren<{\n /**\n * If specified, the Surface will be wrapped in an error boundary.\n * The fallback component will be rendered if an error occurs.\n */\n fallback?: ErrorBoundary['props']['fallback'];\n\n /**\n * If specified, the Surface will be wrapped in a suspense boundary.\n * The placeholder component will be rendered while the surface component is loading.\n */\n placeholder?: ReactNode;\n}> &\n MakeOptional<CoreSurfaceProps<T>, 'id' | 'data'> & {\n /**\n * Additional props to pass to the component.\n * These props are not used by Surface itself but may be used by components which resolve the surface.\n */\n [key: string]: unknown;\n };\n\n// NOTE: If `[key: string]: unknown` is included in shared types, when re-used other fields become unknown as well.\ntype CoreSurfaceProps<T extends Record<string, any> = Record<string, unknown>> = {\n /**\n * ID for debugging.\n */\n id: string;\n\n /**\n * Role defines how the data should be rendered.\n */\n role: string;\n\n /**\n * The data to be rendered by the surface.\n */\n data: T;\n\n /**\n * If more than one component is resolved, the limit determines how many are rendered.\n */\n limit?: number | undefined;\n};\n\ntype SurfaceComponentProps<T extends Record<string, any> = Record<string, unknown>> = PropsWithChildren<\n CoreSurfaceProps<T> & { [key: string]: unknown }\n>;\n\n/**\n * React component used to render a surface once is has matched.\n */\nexport type SurfaceComponent<T extends Record<string, any> = Record<string, unknown>> = (\n props: SurfaceComponentProps<T>,\n forwardedRef: ForwardedRef<HTMLElement>,\n) => JSX.Element | null;\n\n/**\n * Determines the priority of the surface when multiple components are resolved.\n *\n * - `static` - The component is rendered in the order it was resolved.\n * - `hoist` - The component is rendered before `static` components.\n * - `fallback` - The component is rendered after `static` components.\n */\nexport type SurfaceDisposition = 'static' | 'hoist' | 'fallback';\n\n/**\n * Definition of when a SurfaceComponent should be rendered.\n */\nexport type SurfaceDefinition<T extends Record<string, any> = any> = {\n id: string;\n role: string | string[];\n disposition?: SurfaceDisposition;\n filter?: (data: Record<string, unknown>) => data is T;\n component: SurfaceComponent<GuardedType<SurfaceDefinition<T>['filter']>>;\n};\n\nexport const createSurface = <T extends Record<string, any> = any>(definition: SurfaceDefinition<T>) => definition;\n\n/**\n * Surface debug info.\n * NOTE: Short-term measure to track perf issues.\n */\nexport type DebugInfo = {\n id: string;\n created: number;\n renderCount: number;\n} & Pick<SurfaceProps, 'role'>;\n\nexport type SurfaceContextValue = {\n surfaces: Record<string, SurfaceDefinition>;\n debugInfo?: Map<string, DebugInfo>;\n};\n\nconst SurfaceContext = createContext<SurfaceContextValue | undefined>(undefined);\n\nexport const useSurfaceRoot = () => useContext(SurfaceContext) ?? raise(new Error('Missing SurfaceContext'));\n\nexport const SurfaceProvider = SurfaceContext.Provider;\n", "//\n// Copyright 2023 DXOS.org\n//\n\nconst SurfaceMeta = {\n id: 'dxos.org/plugin/surface',\n};\n\nexport default SurfaceMeta;\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { type SurfaceDefinition, type SurfaceContextValue } from './SurfaceContext';\nimport { type HostContext, type Plugin } from '../plugin-host';\n\nexport type SurfaceDefinitions = SurfaceDefinition | SurfaceDefinition[] | SurfaceDefinitions[];\n\nexport type SurfaceProvides = {\n surface: {\n /**\n * Used by the `Surface` resolver to find a component to render.\n */\n definitions: (context: HostContext) => SurfaceDefinitions;\n };\n};\n\nexport type SurfacePluginProvides = {\n surface: SurfaceContextValue;\n};\n\nexport const parseRootSurfacePlugin = (plugin?: Plugin) =>\n (plugin?.provides as any)?.surface?.surfaces ? (plugin as Plugin<SurfacePluginProvides>) : undefined;\n\nexport const parseSurfacePlugin = (plugin?: Plugin) =>\n (plugin?.provides as any)?.surface?.definitions ? (plugin as Plugin<SurfaceProvides>) : undefined;\n", "//\n// Copyright 2023 DXOS.org\n//\n\n/**\n * Checks if the given data is an object and not null.\n *\n * Useful inside surface component resolvers as a type guard.\n *\n * @example\n * ```ts\n * const old =\n * data.content &&\n * typeof data.content === 'object' &&\n * 'id' in data.content &&\n * typeof data.content.id === 'string';\n *\n * // becomes\n * const new = isObject(data.content) && typeof data.content.id === 'string';\n * ```\n */\nexport const isObject = (data: unknown): data is { [key: string]: unknown } => !!data && typeof data === 'object';\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport React, { Component, type FC, type PropsWithChildren } from 'react';\n\ntype Props = PropsWithChildren<{ data?: any; fallback: FC<{ data?: any; error: Error; reset: () => void }> }>;\ntype State = { error: Error | undefined };\n\n/**\n * Surface error boundary.\n *\n * For basic usage prefer providing a fallback component to `Surface`.\n *\n * For more information on error boundaries, see:\n * https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary\n */\nexport class ErrorBoundary extends Component<Props, State> {\n constructor(props: Props) {\n super(props);\n this.state = { error: undefined };\n }\n\n static getDerivedStateFromError(error: Error) {\n return { error };\n }\n\n override componentDidUpdate(prevProps: Props): void {\n if (prevProps.data !== this.props.data) {\n this.resetError();\n }\n }\n\n override render() {\n if (this.state.error) {\n return <this.props.fallback data={this.props.data} error={this.state.error} reset={this.resetError} />;\n }\n\n return this.props.children;\n }\n\n private resetError() {\n this.setState({ error: undefined });\n }\n}\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport React, { Suspense, forwardRef, memo, useEffect, useId, useMemo } from 'react';\n\nimport { useDefaultValue } from '@dxos/react-hooks';\n\nimport { ErrorBoundary } from './ErrorBoundary';\nimport { type SurfaceProps, useSurfaceRoot } from './SurfaceContext';\n\n/**\n * A surface is a named region of the screen that can be populated by plugins.\n */\nexport const Surface = memo(\n forwardRef<HTMLElement, SurfaceProps>(\n ({ id: _id, role, data: _data, limit, fallback, placeholder, ...rest }, forwardedRef) => {\n const { surfaces, debugInfo } = useSurfaceRoot();\n const data = useDefaultValue(_data, () => ({}));\n\n // Track debug info.\n const reactId = useId();\n const id = _id ?? reactId;\n useEffect(() => {\n debugInfo?.set(id, { id, created: Date.now(), role, renderCount: 0 });\n return () => {\n debugInfo?.delete(id);\n };\n }, [id]);\n\n if (debugInfo?.get(id)) {\n debugInfo.get(id)!.renderCount++;\n }\n\n const candidates = useMemo(() => {\n const definitions = Object.values(surfaces)\n .filter((definition) =>\n Array.isArray(definition.role) ? definition.role.includes(role) : definition.role === role,\n )\n .filter(({ filter }) => (filter ? filter(data) : true))\n .toSorted(({ disposition: a = 'static' }, { disposition: b = 'static' }) => {\n return a === b ? 0 : a === 'hoist' || b === 'fallback' ? -1 : b === 'hoist' || a === 'fallback' ? 1 : 0;\n });\n return limit ? definitions.slice(0, limit) : definitions;\n }, [surfaces, role, data, limit]);\n\n const nodes = candidates.map(({ component: Component, id }) => (\n <Component ref={forwardedRef} key={id} id={id} role={role} data={data} limit={limit} {...rest} />\n ));\n\n const suspense = placeholder ? <Suspense fallback={placeholder}>{nodes}</Suspense> : nodes;\n\n return fallback ? (\n <ErrorBoundary data={data} fallback={fallback}>\n {suspense}\n </ErrorBoundary>\n ) : (\n suspense\n );\n },\n ),\n);\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { SurfacePlugin } from './SurfacePlugin';\n\nexport * from './helpers';\nexport * from './provides';\n\nexport * from './ErrorBoundary';\nexport * from './Surface';\nexport * from './SurfaceContext';\n\nexport default SurfacePlugin;\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["React", "create", "createContext", "useContext", "raise", "createSurface", "definition", "SurfaceContext", "createContext", "undefined", "useSurfaceRoot", "useContext", "raise", "Error", "SurfaceProvider", "Provider", "SurfaceMeta", "id", "parseRootSurfacePlugin", "plugin", "provides", "surface", "surfaces", "undefined", "parseSurfacePlugin", "definitions", "SurfacePlugin", "state", "create", "surfaces", "debugInfo", "Map", "meta", "SurfaceMeta", "ready", "context", "filterPlugins", "plugins", "parseSurfacePlugin", "reduce", "acc", "plugin", "reduceSurfaces", "provides", "surface", "definitions", "children", "SurfaceProvider", "value", "Array", "isArray", "definition", "id", "isObject", "data", "React", "Component", "ErrorBoundary", "Component", "constructor", "props", "state", "error", "undefined", "getDerivedStateFromError", "componentDidUpdate", "prevProps", "data", "resetError", "render", "React", "this", "fallback", "reset", "children", "setState", "React", "Suspense", "forwardRef", "memo", "useEffect", "useId", "useMemo", "useDefaultValue", "Surface", "memo", "forwardRef", "id", "_id", "role", "data", "_data", "limit", "fallback", "placeholder", "rest", "forwardedRef", "surfaces", "debugInfo", "useSurfaceRoot", "useDefaultValue", "reactId", "useId", "useEffect", "set", "created", "Date", "now", "renderCount", "delete", "get", "candidates", "useMemo", "definitions", "Object", "values", "filter", "definition", "Array", "isArray", "includes", "toSorted", "disposition", "a", "b", "slice", "nodes", "map", "component", "Component", "React", "ref", "key", "suspense", "Suspense", "ErrorBoundary", "SurfacePlugin"]
|
|
7
|
+
}
|
|
@@ -19,6 +19,7 @@ var SettingsPlugin = () => {
|
|
|
19
19
|
};
|
|
20
20
|
|
|
21
21
|
// packages/sdk/app-framework/src/plugins/plugin-settings/provides.ts
|
|
22
|
+
import { S } from "@dxos/echo-schema";
|
|
22
23
|
var parseSettingsPlugin = (plugin) => {
|
|
23
24
|
return typeof plugin.provides.settingsStore === "object" ? plugin : void 0;
|
|
24
25
|
};
|
|
@@ -26,7 +27,14 @@ var SETTINGS_PLUGIN = "dxos.org/plugin/settings";
|
|
|
26
27
|
var SETTINGS_ACTION = `${SETTINGS_PLUGIN}/action`;
|
|
27
28
|
var SettingsAction;
|
|
28
29
|
(function(SettingsAction2) {
|
|
29
|
-
|
|
30
|
+
class Open extends S.TaggedClass()(`${SETTINGS_ACTION}/open`, {
|
|
31
|
+
input: S.Struct({
|
|
32
|
+
plugin: S.optional(S.String)
|
|
33
|
+
}),
|
|
34
|
+
output: S.Void
|
|
35
|
+
}) {
|
|
36
|
+
}
|
|
37
|
+
SettingsAction2.Open = Open;
|
|
30
38
|
})(SettingsAction || (SettingsAction = {}));
|
|
31
39
|
|
|
32
40
|
// packages/sdk/app-framework/src/plugins/plugin-settings/index.ts
|
|
@@ -35,7 +43,9 @@ var plugin_settings_default = SettingsPlugin;
|
|
|
35
43
|
export {
|
|
36
44
|
meta_default,
|
|
37
45
|
parseSettingsPlugin,
|
|
46
|
+
SETTINGS_PLUGIN,
|
|
47
|
+
SETTINGS_ACTION,
|
|
38
48
|
SettingsAction,
|
|
39
49
|
plugin_settings_default
|
|
40
50
|
};
|
|
41
|
-
//# sourceMappingURL=chunk-
|
|
51
|
+
//# sourceMappingURL=chunk-WBOXEHBE.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/plugins/plugin-settings/SettingsPlugin.tsx", "../../../src/plugins/plugin-settings/meta.ts", "../../../src/plugins/plugin-settings/provides.ts", "../../../src/plugins/plugin-settings/index.ts"],
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nimport { RootSettingsStore } from '@dxos/local-storage';\n\nimport SettingsMeta from './meta';\nimport { type SettingsPluginProvides } from './provides';\nimport { type PluginDefinition } from '../plugin-host';\n\nexport const SettingsPlugin = (): PluginDefinition<SettingsPluginProvides> => {\n // Global settings singleton.\n // TODO(burdon): Make settings storage extensible so that other plugins can decide the persistence of them.\n const settingsStore = new RootSettingsStore();\n\n return {\n meta: SettingsMeta,\n provides: {\n settingsStore,\n },\n };\n};\n", "//\n// Copyright 2023 DXOS.org\n//\n\nconst SettingsMeta = {\n id: 'dxos.org/plugin/settings',\n};\n\nexport default SettingsMeta;\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { S } from '@dxos/echo-schema';\nimport { type SettingsStoreFactory, type SettingsValue } from '@dxos/local-storage';\n\nimport { type Plugin } from '../plugin-host';\n\nexport type SettingsProvides<T extends SettingsValue> = {\n settings: T;\n};\n\nexport type SettingsPluginProvides = {\n settingsStore: SettingsStoreFactory;\n};\n\nexport const parseSettingsPlugin = (plugin: Plugin) => {\n return typeof (plugin.provides as any).settingsStore === 'object'\n ? (plugin as Plugin<SettingsPluginProvides>)\n : undefined;\n};\n\nexport const SETTINGS_PLUGIN = 'dxos.org/plugin/settings';\nexport const SETTINGS_ACTION = `${SETTINGS_PLUGIN}/action`;\n\nexport namespace SettingsAction {\n export class Open extends S.TaggedClass<Open>()(`${SETTINGS_ACTION}/open`, {\n input: S.Struct({\n plugin: S.optional(S.String),\n }),\n output: S.Void,\n }) {}\n}\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { SettingsPlugin } from './SettingsPlugin';\n\nexport * from './provides';\n\nexport default SettingsPlugin;\n"],
|
|
5
|
+
"mappings": ";AAIA,SAASA,yBAAyB;;;ACAlC,IAAMC,eAAe;EACnBC,IAAI;AACN;AAEA,IAAA,eAAeD;;;ADER,IAAME,iBAAiB,MAAA;AAG5B,QAAMC,gBAAgB,IAAIC,kBAAAA;AAE1B,SAAO;IACLC,MAAMC;IACNC,UAAU;MACRJ;IACF;EACF;AACF;;;AEjBA,SAASK,SAAS;AAaX,IAAMC,sBAAsB,CAACC,WAAAA;AAClC,SAAO,OAAQA,OAAOC,SAAiBC,kBAAkB,WACpDF,SACDG;AACN;AAEO,IAAMC,kBAAkB;AACxB,IAAMC,kBAAkB,GAAGD,eAAAA;;UAEjBE,iBAAAA;EACR,MAAMC,aAAaC,EAAEC,YAAW,EAAS,GAAGJ,eAAAA,SAAwB;IACzEK,OAAOF,EAAEG,OAAO;MACdX,QAAQQ,EAAEI,SAASJ,EAAEK,MAAM;IAC7B,CAAA;IACAC,QAAQN,EAAEO;EACZ,CAAA,EAAA;EAAI;kBALSR,OAAAA;AAMf,GAPiBD,mBAAAA,iBAAAA,CAAAA,EAAAA;;;AClBjB,IAAA,0BAAeU;",
|
|
6
|
+
"names": ["RootSettingsStore", "SettingsMeta", "id", "SettingsPlugin", "settingsStore", "RootSettingsStore", "meta", "SettingsMeta", "provides", "S", "parseSettingsPlugin", "plugin", "provides", "settingsStore", "undefined", "SETTINGS_PLUGIN", "SETTINGS_ACTION", "SettingsAction", "Open", "S", "TaggedClass", "input", "Struct", "optional", "String", "output", "Void", "SettingsPlugin"]
|
|
7
|
+
}
|