@dxos/app-framework 0.7.5-main.9d2a38b → 0.7.5-main.ff8607b

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (181) hide show
  1. package/dist/lib/browser/app-graph-builder-F7VZ6LRN.mjs +137 -0
  2. package/dist/lib/browser/app-graph-builder-F7VZ6LRN.mjs.map +7 -0
  3. package/dist/lib/browser/{chunk-GNLU3GAU.mjs → chunk-ATRNTMSS.mjs} +623 -819
  4. package/dist/lib/browser/chunk-ATRNTMSS.mjs.map +7 -0
  5. package/dist/lib/browser/chunk-LDJ3T4V3.mjs +32 -0
  6. package/dist/lib/browser/chunk-LDJ3T4V3.mjs.map +7 -0
  7. package/dist/lib/browser/chunk-WS6SU6HI.mjs +285 -0
  8. package/dist/lib/browser/chunk-WS6SU6HI.mjs.map +7 -0
  9. package/dist/lib/browser/index.mjs +57 -74
  10. package/dist/lib/browser/index.mjs.map +4 -4
  11. package/dist/lib/browser/intent-dispatcher-E6J7E5Y5.mjs +11 -0
  12. package/dist/lib/browser/intent-dispatcher-E6J7E5Y5.mjs.map +7 -0
  13. package/dist/lib/browser/intent-resolver-XLE4L3LS.mjs +38 -0
  14. package/dist/lib/browser/intent-resolver-XLE4L3LS.mjs.map +7 -0
  15. package/dist/lib/browser/meta.json +1 -1
  16. package/dist/lib/browser/store-QU2IKFAI.mjs +19 -0
  17. package/dist/lib/browser/store-QU2IKFAI.mjs.map +7 -0
  18. package/dist/lib/browser/testing/index.mjs +10 -3
  19. package/dist/lib/browser/testing/index.mjs.map +3 -3
  20. package/dist/lib/browser/worker.mjs +77 -0
  21. package/dist/lib/browser/worker.mjs.map +7 -0
  22. package/dist/lib/node/app-graph-builder-JGBADFF7.cjs +146 -0
  23. package/dist/lib/node/app-graph-builder-JGBADFF7.cjs.map +7 -0
  24. package/dist/lib/node/chunk-QLVQ6PND.cjs +58 -0
  25. package/dist/lib/node/chunk-QLVQ6PND.cjs.map +7 -0
  26. package/dist/lib/node/chunk-WKC6YMEQ.cjs +1433 -0
  27. package/dist/lib/node/chunk-WKC6YMEQ.cjs.map +7 -0
  28. package/dist/lib/node/chunk-WRWRZKZU.cjs +308 -0
  29. package/dist/lib/node/chunk-WRWRZKZU.cjs.map +7 -0
  30. package/dist/lib/node/index.cjs +106 -118
  31. package/dist/lib/node/index.cjs.map +4 -4
  32. package/dist/lib/node/intent-dispatcher-CFBKDZQR.cjs +32 -0
  33. package/dist/lib/node/intent-dispatcher-CFBKDZQR.cjs.map +7 -0
  34. package/dist/lib/node/intent-resolver-3TKCXP4S.cjs +45 -0
  35. package/dist/lib/node/intent-resolver-3TKCXP4S.cjs.map +7 -0
  36. package/dist/lib/node/meta.json +1 -1
  37. package/dist/lib/node/store-4QMUUU2A.cjs +34 -0
  38. package/dist/lib/node/store-4QMUUU2A.cjs.map +7 -0
  39. package/dist/lib/node/testing/index.cjs +15 -8
  40. package/dist/lib/node/testing/index.cjs.map +3 -3
  41. package/dist/lib/node/worker.cjs +99 -0
  42. package/dist/lib/node/worker.cjs.map +7 -0
  43. package/dist/lib/node-esm/app-graph-builder-2QEX57NX.mjs +138 -0
  44. package/dist/lib/node-esm/app-graph-builder-2QEX57NX.mjs.map +7 -0
  45. package/dist/lib/node-esm/{chunk-KPMTPXQI.mjs → chunk-44J2VZBB.mjs} +623 -819
  46. package/dist/lib/node-esm/chunk-44J2VZBB.mjs.map +7 -0
  47. package/dist/lib/node-esm/chunk-CNJYZNSL.mjs +34 -0
  48. package/dist/lib/node-esm/chunk-CNJYZNSL.mjs.map +7 -0
  49. package/dist/lib/node-esm/chunk-HTLXL32I.mjs +286 -0
  50. package/dist/lib/node-esm/chunk-HTLXL32I.mjs.map +7 -0
  51. package/dist/lib/node-esm/index.mjs +57 -74
  52. package/dist/lib/node-esm/index.mjs.map +4 -4
  53. package/dist/lib/node-esm/intent-dispatcher-LDQGDZ62.mjs +12 -0
  54. package/dist/lib/node-esm/intent-dispatcher-LDQGDZ62.mjs.map +7 -0
  55. package/dist/lib/node-esm/intent-resolver-7VJWN67U.mjs +39 -0
  56. package/dist/lib/node-esm/intent-resolver-7VJWN67U.mjs.map +7 -0
  57. package/dist/lib/node-esm/meta.json +1 -1
  58. package/dist/lib/node-esm/store-VWDAYUQY.mjs +20 -0
  59. package/dist/lib/node-esm/store-VWDAYUQY.mjs.map +7 -0
  60. package/dist/lib/node-esm/testing/index.mjs +10 -3
  61. package/dist/lib/node-esm/testing/index.mjs.map +3 -3
  62. package/dist/lib/node-esm/worker.mjs +78 -0
  63. package/dist/lib/node-esm/worker.mjs.map +7 -0
  64. package/dist/types/src/App.d.ts.map +1 -1
  65. package/dist/types/src/common/capabilities.d.ts +63 -110
  66. package/dist/types/src/common/capabilities.d.ts.map +1 -1
  67. package/dist/types/src/common/events.d.ts +8 -1
  68. package/dist/types/src/common/events.d.ts.map +1 -1
  69. package/dist/types/src/common/file.d.ts +1 -1
  70. package/dist/types/src/common/file.d.ts.map +1 -1
  71. package/dist/types/src/common/graph.d.ts +2 -2
  72. package/dist/types/src/common/graph.d.ts.map +1 -1
  73. package/dist/types/src/common/index.d.ts +0 -1
  74. package/dist/types/src/common/index.d.ts.map +1 -1
  75. package/dist/types/src/common/layout.d.ts +204 -121
  76. package/dist/types/src/common/layout.d.ts.map +1 -1
  77. package/dist/types/src/common/surface.d.ts +3 -3
  78. package/dist/types/src/common/surface.d.ts.map +1 -1
  79. package/dist/types/src/common/translations.d.ts +7 -7
  80. package/dist/types/src/common/translations.d.ts.map +1 -1
  81. package/dist/types/src/core/capabilities.d.ts +6 -2
  82. package/dist/types/src/core/capabilities.d.ts.map +1 -1
  83. package/dist/types/src/core/manager.d.ts +2 -9
  84. package/dist/types/src/core/manager.d.ts.map +1 -1
  85. package/dist/types/src/core/plugin.d.ts +5 -2
  86. package/dist/types/src/core/plugin.d.ts.map +1 -1
  87. package/dist/types/src/playground/generator/Toolbar.d.ts.map +1 -1
  88. package/dist/types/src/playground/generator/generator.d.ts +2 -0
  89. package/dist/types/src/playground/generator/generator.d.ts.map +1 -1
  90. package/dist/types/src/playground/generator/plugin.d.ts.map +1 -1
  91. package/dist/types/src/playground/logger/Toolbar.d.ts.map +1 -1
  92. package/dist/types/src/playground/logger/plugin.d.ts.map +1 -1
  93. package/dist/types/src/playground/logger/schema.d.ts +1 -1
  94. package/dist/types/src/playground/logger/schema.d.ts.map +1 -1
  95. package/dist/types/src/plugin-intent/IntentPlugin.d.ts.map +1 -1
  96. package/dist/types/src/plugin-intent/actions.d.ts +1 -1
  97. package/dist/types/src/plugin-intent/actions.d.ts.map +1 -1
  98. package/dist/types/src/plugin-intent/index.d.ts +0 -1
  99. package/dist/types/src/plugin-intent/index.d.ts.map +1 -1
  100. package/dist/types/src/plugin-intent/intent-dispatcher.d.ts +27 -20
  101. package/dist/types/src/plugin-intent/intent-dispatcher.d.ts.map +1 -1
  102. package/dist/types/src/plugin-intent/intent.d.ts +3 -3
  103. package/dist/types/src/plugin-intent/intent.d.ts.map +1 -1
  104. package/dist/types/src/plugin-settings/SettingsPlugin.d.ts.map +1 -1
  105. package/dist/types/src/plugin-settings/actions.d.ts +11 -1
  106. package/dist/types/src/plugin-settings/actions.d.ts.map +1 -1
  107. package/dist/types/src/plugin-settings/app-graph-builder.d.ts +197 -0
  108. package/dist/types/src/plugin-settings/app-graph-builder.d.ts.map +1 -0
  109. package/dist/types/src/plugin-settings/intent-resolver.d.ts +4 -0
  110. package/dist/types/src/plugin-settings/intent-resolver.d.ts.map +1 -0
  111. package/dist/types/src/plugin-settings/store.d.ts +5 -0
  112. package/dist/types/src/plugin-settings/store.d.ts.map +1 -0
  113. package/dist/types/src/plugin-settings/translations.d.ts +11 -0
  114. package/dist/types/src/plugin-settings/translations.d.ts.map +1 -0
  115. package/dist/types/src/{plugin-intent → react}/IntentContext.d.ts +1 -1
  116. package/dist/types/src/react/IntentContext.d.ts.map +1 -0
  117. package/dist/types/src/react/Surface.d.ts.map +1 -1
  118. package/dist/types/src/react/Surface.stories.d.ts +16 -0
  119. package/dist/types/src/react/Surface.stories.d.ts.map +1 -0
  120. package/dist/types/src/react/common.d.ts +12 -0
  121. package/dist/types/src/react/common.d.ts.map +1 -0
  122. package/dist/types/src/react/index.d.ts +2 -0
  123. package/dist/types/src/react/index.d.ts.map +1 -1
  124. package/dist/types/src/react/useIntentResolver.d.ts +3 -0
  125. package/dist/types/src/react/useIntentResolver.d.ts.map +1 -0
  126. package/dist/types/src/testing/withPluginManager.d.ts +1 -1
  127. package/dist/types/src/testing/withPluginManager.d.ts.map +1 -1
  128. package/dist/types/src/worker.d.ts +4 -0
  129. package/dist/types/src/worker.d.ts.map +1 -0
  130. package/package.json +26 -20
  131. package/project.json +3 -3
  132. package/src/App.tsx +15 -14
  133. package/src/common/capabilities.ts +20 -11
  134. package/src/common/events.ts +10 -1
  135. package/src/common/file.ts +1 -1
  136. package/src/common/graph.ts +2 -2
  137. package/src/common/index.ts +0 -1
  138. package/src/common/layout.ts +194 -126
  139. package/src/common/surface.ts +2 -2
  140. package/src/common/translations.ts +7 -8
  141. package/src/core/capabilities.ts +16 -7
  142. package/src/core/manager.test.ts +22 -73
  143. package/src/core/manager.ts +105 -91
  144. package/src/core/plugin.ts +6 -3
  145. package/src/playground/debug/plugin.ts +1 -1
  146. package/src/playground/generator/Toolbar.tsx +11 -11
  147. package/src/playground/generator/generator.ts +25 -0
  148. package/src/playground/generator/plugin.ts +6 -1
  149. package/src/playground/layout/plugin.ts +1 -1
  150. package/src/playground/logger/Toolbar.tsx +2 -1
  151. package/src/playground/logger/plugin.ts +6 -3
  152. package/src/playground/logger/schema.ts +1 -1
  153. package/src/plugin-intent/IntentPlugin.tsx +3 -43
  154. package/src/plugin-intent/actions.ts +1 -1
  155. package/src/plugin-intent/index.ts +0 -1
  156. package/src/plugin-intent/intent-dispatcher.test.ts +48 -29
  157. package/src/plugin-intent/intent-dispatcher.ts +76 -41
  158. package/src/plugin-intent/intent.ts +5 -5
  159. package/src/plugin-settings/SettingsPlugin.ts +19 -13
  160. package/src/plugin-settings/actions.ts +11 -1
  161. package/src/plugin-settings/app-graph-builder.ts +122 -0
  162. package/src/plugin-settings/intent-resolver.ts +28 -0
  163. package/src/plugin-settings/store.ts +20 -0
  164. package/src/plugin-settings/translations.ts +17 -0
  165. package/src/{plugin-intent → react}/IntentContext.tsx +2 -2
  166. package/src/react/Surface.stories.tsx +96 -0
  167. package/src/react/Surface.tsx +11 -8
  168. package/src/react/common.ts +12 -0
  169. package/src/react/index.ts +2 -0
  170. package/src/react/useIntentResolver.ts +22 -0
  171. package/src/testing/withPluginManager.tsx +11 -3
  172. package/src/worker.ts +11 -0
  173. package/tsconfig.json +3 -3
  174. package/dist/lib/browser/chunk-GNLU3GAU.mjs.map +0 -7
  175. package/dist/lib/node/chunk-FBA4BB3J.cjs +0 -1639
  176. package/dist/lib/node/chunk-FBA4BB3J.cjs.map +0 -7
  177. package/dist/lib/node-esm/chunk-KPMTPXQI.mjs.map +0 -7
  178. package/dist/types/src/common/navigation.d.ts +0 -241
  179. package/dist/types/src/common/navigation.d.ts.map +0 -1
  180. package/dist/types/src/plugin-intent/IntentContext.d.ts.map +0 -1
  181. package/src/common/navigation.ts +0 -199
@@ -1,5 +1,94 @@
1
1
  import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
2
2
 
3
+ // packages/sdk/app-framework/src/plugin-intent/intent-dispatcher.ts
4
+ import { Effect as Effect2, Option, pipe as pipe2, Ref } from "effect";
5
+ import { create as create3 } from "@dxos/live-object";
6
+ import { byPosition } from "@dxos/util";
7
+
8
+ // packages/sdk/app-framework/src/plugin-intent/actions.ts
9
+ import { Schema as S2 } from "@effect/schema";
10
+
11
+ // packages/sdk/app-framework/src/plugin-intent/intent.ts
12
+ import { Schema as S } from "@effect/schema";
13
+ var createIntent = (schema, data = {}, params = {}) => {
14
+ const _ = S.validateSync(schema.fields.input)(data);
15
+ const intent = {
16
+ ...params,
17
+ _schema: schema,
18
+ id: schema._tag,
19
+ data
20
+ };
21
+ return {
22
+ first: intent,
23
+ last: intent,
24
+ all: [
25
+ intent
26
+ ]
27
+ };
28
+ };
29
+ var chain = (schema, data = {}, params = {}) => (intent) => {
30
+ const intents = "all" in intent ? intent.all : [
31
+ intent
32
+ ];
33
+ const first = intents[0];
34
+ const last = {
35
+ ...params,
36
+ _schema: schema,
37
+ id: schema._tag,
38
+ data
39
+ };
40
+ return {
41
+ first,
42
+ last,
43
+ all: [
44
+ ...intents,
45
+ last
46
+ ]
47
+ };
48
+ };
49
+ var Label = S.Union(S.String, S.mutable(S.Tuple(S.String, S.mutable(S.Struct({
50
+ ns: S.String,
51
+ count: S.optional(S.Number)
52
+ })))));
53
+
54
+ // packages/sdk/app-framework/src/plugin-intent/actions.ts
55
+ var INTENT_PLUGIN = "dxos.org/plugin/intent";
56
+ var INTENT_ACTION = `${INTENT_PLUGIN}/action`;
57
+ var IntentAction;
58
+ (function(IntentAction2) {
59
+ class ShowUndo extends S2.TaggedClass()(`${INTENT_ACTION}/show-undo`, {
60
+ input: S2.Struct({
61
+ message: Label
62
+ }),
63
+ output: S2.Void
64
+ }) {
65
+ }
66
+ IntentAction2.ShowUndo = ShowUndo;
67
+ })(IntentAction || (IntentAction = {}));
68
+
69
+ // packages/sdk/app-framework/src/plugin-intent/errors.ts
70
+ var BaseError = class extends Error {
71
+ constructor(code, message, context) {
72
+ super(message ?? code);
73
+ this.code = code;
74
+ this.context = context;
75
+ this.name = code;
76
+ Object.setPrototypeOf(this, new.target.prototype);
77
+ }
78
+ };
79
+ var NoResolversError = class extends BaseError {
80
+ constructor(action) {
81
+ super("NO_RESOLVERS", "No resolvers were found for the action", {
82
+ action
83
+ });
84
+ }
85
+ };
86
+ var CycleDetectedError = class extends BaseError {
87
+ constructor(context) {
88
+ super("CYCLE_DETECTED", "Intent execution limit exceeded. This is likely due to an infinite loop within intent resolvers.", context);
89
+ }
90
+ };
91
+
3
92
  // packages/sdk/app-framework/src/core/capabilities.ts
4
93
  import { effect, untracked } from "@preact/signals-core";
5
94
  import { Trigger } from "@dxos/async";
@@ -26,9 +115,10 @@ var contributes = (interfaceDef, implementation, deactivate) => {
26
115
  deactivate
27
116
  };
28
117
  };
29
- var lazy = (c) => (props) => c().then(({ default: getCapability }) => {
30
- return getCapability(props);
31
- });
118
+ var lazy = (c) => async (props) => {
119
+ const { default: getCapability } = await c();
120
+ return async () => getCapability(props);
121
+ };
32
122
  var PluginsContext = class {
33
123
  constructor({ activate, reset }) {
34
124
  this._definedCapabilities = /* @__PURE__ */ new Map();
@@ -50,10 +140,11 @@ var PluginsContext = class {
50
140
  current.push(new CapabilityImpl(moduleId, implementation));
51
141
  log("capability contributed", {
52
142
  id: interfaceDef.identifier,
143
+ moduleId,
53
144
  count: untracked(() => current.length)
54
145
  }, {
55
146
  F: __dxlog_file,
56
- L: 139,
147
+ L: 142,
57
148
  S: this,
58
149
  C: (f, a) => f(...a)
59
150
  });
@@ -74,7 +165,16 @@ var PluginsContext = class {
74
165
  count: untracked(() => current.length)
75
166
  }, {
76
167
  F: __dxlog_file,
77
- L: 154,
168
+ L: 161,
169
+ S: this,
170
+ C: (f, a) => f(...a)
171
+ });
172
+ } else {
173
+ log.warn("capability not removed", {
174
+ id: interfaceDef.identifier
175
+ }, {
176
+ F: __dxlog_file,
177
+ L: 163,
78
178
  S: this,
79
179
  C: (f, a) => f(...a)
80
180
  });
@@ -107,7 +207,7 @@ var PluginsContext = class {
107
207
  const capability = this.requestCapabilities(interfaceDef, filter)[0];
108
208
  invariant(capability, `No capability found for ${interfaceDef.identifier}`, {
109
209
  F: __dxlog_file,
110
- L: 190,
210
+ L: 199,
111
211
  S: this,
112
212
  A: [
113
213
  "capability",
@@ -158,7 +258,7 @@ var getEvents = (events) => "type" in events ? events.events : [
158
258
 
159
259
  // packages/sdk/app-framework/src/core/manager.ts
160
260
  import { untracked as untracked2 } from "@preact/signals-core";
161
- import { Effect, Either, Match } from "effect";
261
+ import { Array as A, Effect, Either, Match, pipe } from "effect";
162
262
  import { Event } from "@dxos/async";
163
263
  import { create as create2 } from "@dxos/live-object";
164
264
  import { log as log2 } from "@dxos/log";
@@ -181,7 +281,6 @@ var PluginManager = class {
181
281
  enabled,
182
282
  modules: [],
183
283
  active: [],
184
- pendingRemoval: [],
185
284
  pendingReset: [],
186
285
  eventsFired: []
187
286
  });
@@ -230,14 +329,6 @@ var PluginManager = class {
230
329
  return this._state.active;
231
330
  }
232
331
  /**
233
- * Ids of modules which are pending removal.
234
- *
235
- * @reactive
236
- */
237
- get pendingRemoval() {
238
- return this._state.pendingRemoval;
239
- }
240
- /**
241
332
  * Ids of events which have been fired.
242
333
  *
243
334
  * @reactive
@@ -263,7 +354,7 @@ var PluginManager = class {
263
354
  id
264
355
  }, {
265
356
  F: __dxlog_file2,
266
- L: 157,
357
+ L: 146,
267
358
  S: this,
268
359
  C: (f, a) => f(...a)
269
360
  });
@@ -277,12 +368,12 @@ var PluginManager = class {
277
368
  * @param id The id of the plugin.
278
369
  */
279
370
  enable(id) {
280
- return untracked2(() => {
371
+ return untracked2(async () => {
281
372
  log2("enable plugin", {
282
373
  id
283
374
  }, {
284
375
  F: __dxlog_file2,
285
- L: 170,
376
+ L: 159,
286
377
  S: this,
287
378
  C: (f, a) => f(...a)
288
379
  });
@@ -297,6 +388,19 @@ var PluginManager = class {
297
388
  this._addModule(module);
298
389
  this._setPendingResetByModule(module);
299
390
  });
391
+ log2("pending reset", {
392
+ events: [
393
+ ...this.pendingReset
394
+ ]
395
+ }, {
396
+ F: __dxlog_file2,
397
+ L: 174,
398
+ S: this,
399
+ C: (f, a) => f(...a)
400
+ });
401
+ await Effect.runPromise(Effect.all(this.pendingReset.map((event) => this._activate(event)), {
402
+ concurrency: "unbounded"
403
+ }));
300
404
  return true;
301
405
  });
302
406
  }
@@ -310,7 +414,7 @@ var PluginManager = class {
310
414
  id
311
415
  }, {
312
416
  F: __dxlog_file2,
313
- L: 194,
417
+ L: 192,
314
418
  S: this,
315
419
  C: (f, a) => f(...a)
316
420
  });
@@ -327,12 +431,12 @@ var PluginManager = class {
327
431
  * @param id The id of the plugin.
328
432
  */
329
433
  disable(id) {
330
- return untracked2(() => {
434
+ return untracked2(async () => {
331
435
  log2("disable plugin", {
332
436
  id
333
437
  }, {
334
438
  F: __dxlog_file2,
335
- L: 211,
439
+ L: 209,
336
440
  S: this,
337
441
  C: (f, a) => f(...a)
338
442
  });
@@ -346,15 +450,9 @@ var PluginManager = class {
346
450
  const enabledIndex = this._state.enabled.findIndex((enabled) => enabled === id);
347
451
  if (enabledIndex !== -1) {
348
452
  this._state.enabled.splice(enabledIndex, 1);
453
+ await Effect.runPromise(this._deactivate(id));
349
454
  plugin.modules.forEach((module) => {
350
- if (this._state.active.includes(module.id)) {
351
- this._setPendingResetByModule(module);
352
- if (!this._state.pendingRemoval.includes(module.id)) {
353
- this._state.pendingRemoval.push(module.id);
354
- }
355
- } else {
356
- this._removeModule(module.id);
357
- }
455
+ this._removeModule(module.id);
358
456
  });
359
457
  }
360
458
  return true;
@@ -390,7 +488,7 @@ var PluginManager = class {
390
488
  id: plugin.meta.id
391
489
  }, {
392
490
  F: __dxlog_file2,
393
- L: 270,
491
+ L: 262,
394
492
  S: this,
395
493
  C: (f, a) => f(...a)
396
494
  });
@@ -405,7 +503,7 @@ var PluginManager = class {
405
503
  id
406
504
  }, {
407
505
  F: __dxlog_file2,
408
- L: 279,
506
+ L: 271,
409
507
  S: this,
410
508
  C: (f, a) => f(...a)
411
509
  });
@@ -421,7 +519,7 @@ var PluginManager = class {
421
519
  id: module.id
422
520
  }, {
423
521
  F: __dxlog_file2,
424
- L: 289,
522
+ L: 281,
425
523
  S: this,
426
524
  C: (f, a) => f(...a)
427
525
  });
@@ -436,7 +534,7 @@ var PluginManager = class {
436
534
  id
437
535
  }, {
438
536
  F: __dxlog_file2,
439
- L: 298,
537
+ L: 290,
440
538
  S: this,
441
539
  C: (f, a) => f(...a)
442
540
  });
@@ -464,20 +562,13 @@ var PluginManager = class {
464
562
  _setPendingResetByModule(module) {
465
563
  return untracked2(() => {
466
564
  const activationEvents = getEvents(module.activatesOn).map(eventKey).filter((key) => this._state.eventsFired.includes(key));
467
- const parentEvents = activationEvents.flatMap((event) => {
468
- const modules = this._getActiveModules().filter((module2) => module2.activatesBefore?.map(eventKey).includes(event));
469
- return modules.flatMap((module2) => getEvents(module2.activatesOn)).map(eventKey);
470
- });
471
- const pendingReset = Array.from(/* @__PURE__ */ new Set([
472
- ...activationEvents,
473
- ...parentEvents
474
- ])).filter((event) => !this._state.pendingReset.includes(event));
565
+ const pendingReset = Array.from(new Set(activationEvents)).filter((event) => !this._state.pendingReset.includes(event));
475
566
  if (pendingReset.length > 0) {
476
567
  log2("pending reset", {
477
568
  events: pendingReset
478
569
  }, {
479
570
  F: __dxlog_file2,
480
- L: 342,
571
+ L: 328,
481
572
  S: this,
482
573
  C: (f, a) => f(...a)
483
574
  });
@@ -485,59 +576,87 @@ var PluginManager = class {
485
576
  }
486
577
  });
487
578
  }
579
+ /**
580
+ * @internal
581
+ */
488
582
  // TODO(wittjosiah): Improve error typing.
489
583
  _activate(event) {
490
- const self = this;
491
- return Effect.gen(function* () {
584
+ return Effect.gen(this, function* () {
492
585
  const key = typeof event === "string" ? event : eventKey(event);
493
586
  log2("activating", {
494
587
  key
495
588
  }, {
496
589
  F: __dxlog_file2,
497
- L: 353,
590
+ L: 341,
498
591
  S: this,
499
592
  C: (f, a) => f(...a)
500
593
  });
501
- const pendingIndex = self._state.pendingReset.findIndex((event2) => event2 === key);
594
+ const pendingIndex = this._state.pendingReset.findIndex((event2) => event2 === key);
502
595
  if (pendingIndex !== -1) {
503
- self._state.pendingReset.splice(pendingIndex, 1);
596
+ this._state.pendingReset.splice(pendingIndex, 1);
504
597
  }
505
- const modules = self._getInactiveModulesByEvent(key);
598
+ const modules = this._getInactiveModulesByEvent(key).filter((module) => {
599
+ const allOf2 = isAllOf(module.activatesOn);
600
+ if (!allOf2) {
601
+ return true;
602
+ }
603
+ const events = module.activatesOn.events.filter((event2) => eventKey(event2) !== key);
604
+ return events.every((event2) => this._state.eventsFired.includes(eventKey(event2)));
605
+ });
506
606
  if (modules.length === 0) {
507
607
  log2("no modules to activate", {
508
608
  key
509
609
  }, {
510
610
  F: __dxlog_file2,
511
- L: 361,
611
+ L: 357,
512
612
  S: this,
513
613
  C: (f, a) => f(...a)
514
614
  });
615
+ if (!this._state.eventsFired.includes(key)) {
616
+ this._state.eventsFired.push(key);
617
+ }
515
618
  return false;
516
619
  }
517
- self.activation.emit({
620
+ log2("activating modules", {
621
+ key,
622
+ modules: modules.map((module) => module.id)
623
+ }, {
624
+ F: __dxlog_file2,
625
+ L: 364,
626
+ S: this,
627
+ C: (f, a) => f(...a)
628
+ });
629
+ this.activation.emit({
518
630
  event: key,
519
631
  state: "activating"
520
632
  });
521
- for (const module of modules) {
522
- if (isAllOf(module.activatesOn) && !module.activatesOn.events.filter((event2) => eventKey(event2) !== key).every((event2) => self._state.eventsFired.includes(eventKey(event2)))) {
523
- continue;
524
- }
525
- yield* Effect.all(module.activatesBefore?.map((event2) => self._activate(event2)) ?? []);
526
- const result = yield* self._activateModule(module).pipe(Effect.either);
527
- if (Either.isLeft(result)) {
528
- self.activation.emit({
529
- event: key,
530
- state: "error",
531
- error: result.left
532
- });
533
- yield* Effect.fail(result.left);
534
- }
535
- yield* Effect.all(module.activatesAfter?.map((event2) => self._activate(event2)) ?? []);
633
+ const getCapabilities = yield* Effect.all(modules.map(({ activate }) => Effect.tryPromise({
634
+ try: async () => activate(this.context),
635
+ catch: (error) => error
636
+ })), {
637
+ concurrency: "unbounded"
638
+ });
639
+ const result = yield* pipe(
640
+ modules,
641
+ A.zip(getCapabilities),
642
+ A.map(([module, getCapabilities2]) => this._activateModule(module, getCapabilities2)),
643
+ // TODO(wittjosiah): This currently can't be run in parallel.
644
+ // Running this with concurrency causes races with `allOf` activation events.
645
+ Effect.all,
646
+ Effect.either
647
+ );
648
+ if (Either.isLeft(result)) {
649
+ this.activation.emit({
650
+ event: key,
651
+ state: "error",
652
+ error: result.left
653
+ });
654
+ yield* Effect.fail(result.left);
536
655
  }
537
- if (!self._state.eventsFired.includes(key)) {
538
- self._state.eventsFired.push(key);
656
+ if (!this._state.eventsFired.includes(key)) {
657
+ this._state.eventsFired.push(key);
539
658
  }
540
- self.activation.emit({
659
+ this.activation.emit({
541
660
  event: key,
542
661
  state: "activated"
543
662
  });
@@ -545,79 +664,105 @@ var PluginManager = class {
545
664
  key
546
665
  }, {
547
666
  F: __dxlog_file2,
548
- L: 393,
667
+ L: 398,
549
668
  S: this,
550
669
  C: (f, a) => f(...a)
551
670
  });
552
671
  return true;
553
672
  });
554
673
  }
555
- _activateModule(module) {
556
- const self = this;
557
- return Effect.gen(function* () {
558
- const program = module.activate(self.context);
559
- const maybeCapabilities = yield* Match.value(program).pipe(Match.when(Effect.isEffect, (effect3) => effect3), Match.when(isPromise, (promise) => Effect.tryPromise({
560
- try: () => promise,
561
- catch: (error) => error
562
- })), Match.orElse((program2) => Effect.succeed(program2)));
563
- const capabilities = Match.value(maybeCapabilities).pipe(Match.when(Array.isArray, (array) => array), Match.orElse((value) => [
674
+ _activateModule(module, getCapabilities) {
675
+ return Effect.gen(this, function* () {
676
+ yield* Effect.all(module.activatesBefore?.map((event) => this._activate(event)) ?? [], {
677
+ concurrency: "unbounded"
678
+ });
679
+ log2("activating module...", {
680
+ module: module.id
681
+ }, {
682
+ F: __dxlog_file2,
683
+ L: 413,
684
+ S: this,
685
+ C: (f, a) => f(...a)
686
+ });
687
+ const maybeCapabilities = typeof getCapabilities === "function" ? getCapabilities() : getCapabilities;
688
+ const resolvedCapabilities = yield* Match.value(maybeCapabilities).pipe(
689
+ // TODO(wittjosiah): Activate with an effect?
690
+ // Match.when(Effect.isEffect, (effect) => effect),
691
+ Match.when(isPromise, (promise) => Effect.tryPromise({
692
+ try: () => promise,
693
+ catch: (error) => error
694
+ })),
695
+ Match.orElse((program) => Effect.succeed(program))
696
+ );
697
+ const capabilities = Match.value(resolvedCapabilities).pipe(Match.when(Array.isArray, (array) => array), Match.orElse((value) => [
564
698
  value
565
699
  ]));
566
700
  capabilities.forEach((capability) => {
567
- self.context.contributeCapability({
701
+ this.context.contributeCapability({
568
702
  module: module.id,
569
703
  ...capability
570
704
  });
571
705
  });
572
- self._state.active.push(module.id);
573
- self._capabilities.set(module.id, capabilities);
706
+ this._state.active.push(module.id);
707
+ this._capabilities.set(module.id, capabilities);
708
+ log2("activated module", {
709
+ module: module.id
710
+ }, {
711
+ F: __dxlog_file2,
712
+ L: 436,
713
+ S: this,
714
+ C: (f, a) => f(...a)
715
+ });
716
+ yield* Effect.all(module.activatesAfter?.map((event) => this._activate(event)) ?? [], {
717
+ concurrency: "unbounded"
718
+ });
574
719
  });
575
720
  }
576
721
  _deactivate(id) {
577
- const self = this;
578
- return Effect.gen(function* () {
579
- const plugin = self._getPlugin(id);
722
+ return Effect.gen(this, function* () {
723
+ const plugin = this._getPlugin(id);
580
724
  if (!plugin) {
581
725
  return false;
582
726
  }
583
727
  const modules = plugin.modules;
584
- const results = yield* Effect.all(modules.map((module) => self._deactivateModule(module)));
728
+ const results = yield* Effect.all(modules.map((module) => this._deactivateModule(module)), {
729
+ concurrency: "unbounded"
730
+ });
585
731
  return results.every((result) => result);
586
732
  });
587
733
  }
588
734
  _deactivateModule(module) {
589
- const self = this;
590
- return Effect.gen(function* () {
735
+ return Effect.gen(this, function* () {
591
736
  const id = module.id;
592
737
  log2("deactivating", {
593
738
  id
594
739
  }, {
595
740
  F: __dxlog_file2,
596
- L: 444,
741
+ L: 463,
597
742
  S: this,
598
743
  C: (f, a) => f(...a)
599
744
  });
600
- const capabilities = self._capabilities.get(id);
745
+ const capabilities = this._capabilities.get(id);
601
746
  if (capabilities) {
602
747
  for (const capability of capabilities) {
603
- self.context.removeCapability(capability.interface, capability.implementation);
748
+ this.context.removeCapability(capability.interface, capability.implementation);
604
749
  const program = capability.deactivate?.();
605
- yield* Match.value(program).pipe(Match.when(Effect.isEffect, (effect3) => effect3), Match.when(isPromise, (promise) => Effect.tryPromise({
750
+ yield* Match.value(program).pipe(Match.when(Effect.isEffect, (effect2) => effect2), Match.when(isPromise, (promise) => Effect.tryPromise({
606
751
  try: () => promise,
607
752
  catch: (error) => error
608
753
  })), Match.orElse((program2) => Effect.succeed(program2)));
609
754
  }
610
- self._capabilities.delete(id);
755
+ this._capabilities.delete(id);
611
756
  }
612
- const activeIndex = self._state.active.findIndex((event) => event === id);
757
+ const activeIndex = this._state.active.findIndex((event) => event === id);
613
758
  if (activeIndex !== -1) {
614
- self._state.active.splice(activeIndex, 1);
759
+ this._state.active.splice(activeIndex, 1);
615
760
  }
616
761
  log2("deactivated", {
617
762
  id
618
763
  }, {
619
764
  F: __dxlog_file2,
620
- L: 470,
765
+ L: 489,
621
766
  S: this,
622
767
  C: (f, a) => f(...a)
623
768
  });
@@ -625,27 +770,22 @@ var PluginManager = class {
625
770
  });
626
771
  }
627
772
  _reset(event) {
628
- const self = this;
629
- return Effect.gen(function* () {
773
+ return Effect.gen(this, function* () {
630
774
  const key = typeof event === "string" ? event : eventKey(event);
631
775
  log2("reset", {
632
776
  key
633
777
  }, {
634
778
  F: __dxlog_file2,
635
- L: 479,
779
+ L: 497,
636
780
  S: this,
637
781
  C: (f, a) => f(...a)
638
782
  });
639
- const modules = self._getActiveModulesByEvent(key);
640
- const results = yield* Effect.all(modules.map((module) => self._deactivateModule(module)));
641
- if (self._state.pendingRemoval.length > 0) {
642
- self._state.pendingRemoval.forEach((id) => {
643
- self._removeModule(id);
644
- });
645
- self._state.pendingRemoval.splice(0, self._state.pendingRemoval.length);
646
- }
783
+ const modules = this._getActiveModulesByEvent(key);
784
+ const results = yield* Effect.all(modules.map((module) => this._deactivateModule(module)), {
785
+ concurrency: "unbounded"
786
+ });
647
787
  if (results.every((result) => result)) {
648
- return yield* self._activate(key);
788
+ return yield* this._activate(key);
649
789
  } else {
650
790
  return false;
651
791
  }
@@ -685,9 +825,6 @@ var Capabilities;
685
825
  Capabilities2.IntentResolver = defineCapability("dxos.org/app-framework/capability/intent-resolver");
686
826
  Capabilities2.IntentDispatcher = defineCapability("dxos.org/app-framework/capability/intent-dispatcher");
687
827
  Capabilities2.Layout = defineCapability("dxos.org/app-framework/capability/layout");
688
- Capabilities2.MutableLayout = defineCapability("dxos.org/app-framework/capability/layout");
689
- Capabilities2.Location = defineCapability("dxos.org/app-framework/capability/location");
690
- Capabilities2.MutableLocation = defineCapability("dxos.org/app-framework/capability/location");
691
828
  Capabilities2.Translations = defineCapability("dxos.org/app-framework/capability/translations");
692
829
  Capabilities2.AppGraph = defineCapability("dxos.org/app-framework/capability/app-graph");
693
830
  Capabilities2.AppGraphBuilder = defineCapability("dxos.org/app-framework/capability/app-graph-builder");
@@ -702,6 +839,8 @@ var Capabilities;
702
839
  var Events;
703
840
  (function(Events2) {
704
841
  Events2.Startup = defineEvent("dxos.org/app-framework/event/startup");
842
+ Events2.SetupSurfaces = defineEvent("dxos.org/app-framework/event/setup-surfaces");
843
+ Events2.SetupMetadata = defineEvent("dxos.org/app-framework/event/setup-metadata");
705
844
  Events2.SetupIntents = defineEvent("dxos.org/app-framework/event/setup-intents");
706
845
  Events2.SetupSettings = defineEvent("dxos.org/app-framework/event/setup-settings");
707
846
  Events2.SetupAppGraph = defineEvent("dxos.org/app-framework/event/setup-graph");
@@ -711,11 +850,10 @@ var Events;
711
850
  Events2.AppGraphReady = defineEvent("dxos.org/app-framework/event/graph-ready");
712
851
  Events2.createStateEvent = (specifier) => defineEvent("dxos.org/app-framework/event/state", specifier);
713
852
  Events2.LayoutReady = Events2.createStateEvent(Capabilities.Layout.identifier);
714
- Events2.LocationReady = Events2.createStateEvent(Capabilities.Location.identifier);
715
853
  })(Events || (Events = {}));
716
854
 
717
855
  // packages/sdk/app-framework/src/common/file.ts
718
- import { S } from "@dxos/echo-schema";
856
+ import { Schema as S3 } from "@effect/schema";
719
857
  var defaultFileTypes = {
720
858
  images: [
721
859
  "png",
@@ -735,127 +873,367 @@ var defaultFileTypes = {
735
873
  "md"
736
874
  ]
737
875
  };
738
- var FileInfoSchema = S.Struct({
739
- name: S.String,
740
- type: S.String,
741
- url: S.optional(S.String),
742
- cid: S.optional(S.String)
876
+ var FileInfoSchema = S3.Struct({
877
+ name: S3.String,
878
+ type: S3.String,
879
+ url: S3.optional(S3.String),
880
+ cid: S3.optional(S3.String)
743
881
  });
744
882
 
745
- // packages/sdk/app-framework/src/plugin-intent/intent.ts
746
- import { S as S2 } from "@dxos/echo-schema";
747
- var createIntent = (schema, data = {}, params = {}) => {
748
- const _ = S2.validateSync(schema.fields.input)(data);
749
- const intent = {
750
- ...params,
751
- _schema: schema,
752
- action: schema._tag,
753
- data
754
- };
755
- return {
756
- first: intent,
757
- last: intent,
758
- all: [
759
- intent
760
- ]
761
- };
762
- };
763
- var chain = (schema, data = {}, params = {}) => (intent) => {
764
- const intents = "all" in intent ? intent.all : [
765
- intent
766
- ];
767
- const first = intents[0];
768
- const last = {
769
- ...params,
770
- _schema: schema,
771
- action: schema._tag,
772
- data
773
- };
774
- return {
775
- first,
776
- last,
777
- all: [
778
- ...intents,
779
- last
780
- ]
781
- };
782
- };
783
- var Label = S2.Union(S2.String, S2.mutable(S2.Tuple(S2.String, S2.mutable(S2.Struct({
784
- ns: S2.String,
785
- count: S2.optional(S2.Number)
786
- })))));
883
+ // packages/sdk/app-framework/src/common/layout.ts
884
+ import { Schema as S4 } from "@effect/schema";
787
885
 
788
- // packages/sdk/app-framework/src/plugin-intent/actions.ts
789
- import { S as S3 } from "@dxos/echo-schema";
790
- var INTENT_PLUGIN = "dxos.org/plugin/intent";
791
- var INTENT_ACTION = `${INTENT_PLUGIN}/action`;
792
- var IntentAction;
793
- (function(IntentAction2) {
794
- class ShowUndo extends S3.TaggedClass()(`${INTENT_ACTION}/show-undo`, {
795
- input: S3.Struct({
796
- message: Label
886
+ // packages/sdk/app-framework/src/plugin-intent/IntentPlugin.tsx
887
+ var IntentPlugin = () => definePlugin({
888
+ id: INTENT_PLUGIN
889
+ }, [
890
+ defineModule({
891
+ id: `${INTENT_PLUGIN}/module/dispatcher`,
892
+ // TODO(wittjosiah): This will mean that startup needs to be reset when intents are added or removed.
893
+ // This is fine for now because it's how it worked prior to capabilities api anyways.
894
+ // In the future, the intent dispatcher should be able to be reset without resetting the entire app.
895
+ activatesOn: Events.Startup,
896
+ activatesAfter: [
897
+ Events.DispatcherReady
898
+ ],
899
+ activate: lazy(() => import("./intent-dispatcher-LDQGDZ62.mjs"))
900
+ })
901
+ ]);
902
+
903
+ // packages/sdk/app-framework/src/common/layout.ts
904
+ var LAYOUT_PLUGIN = "dxos.org/plugin/layout";
905
+ var LAYOUT_ACTION = `${LAYOUT_PLUGIN}/action`;
906
+ var LayoutAction;
907
+ (function(LayoutAction2) {
908
+ LayoutAction2.UPDATE_LAYOUT = `${LAYOUT_ACTION}/update-layout`;
909
+ class UpdateLayout extends S4.TaggedClass()(LayoutAction2.UPDATE_LAYOUT, {
910
+ input: S4.Struct({
911
+ part: S4.String.annotations({
912
+ description: "The part of the layout to mutate."
913
+ }),
914
+ subject: S4.optional(S4.Any.annotations({
915
+ description: "The subject of the layout update."
916
+ })),
917
+ options: S4.optional(S4.Record({
918
+ key: S4.String,
919
+ value: S4.Any
920
+ }).annotations({
921
+ description: "Additional options for the layout action."
922
+ }))
797
923
  }),
798
- output: S3.Void
924
+ output: S4.Void
799
925
  }) {
800
926
  }
801
- IntentAction2.ShowUndo = ShowUndo;
802
- })(IntentAction || (IntentAction = {}));
803
-
804
- // packages/sdk/app-framework/src/plugin-intent/intent-dispatcher.ts
805
- import { Effect as Effect2, Option, pipe, Ref } from "effect";
806
- import { byDisposition } from "@dxos/util";
807
-
808
- // packages/sdk/app-framework/src/plugin-intent/errors.ts
809
- var BaseError = class extends Error {
810
- constructor(code, message, context) {
811
- super(message ?? code);
812
- this.code = code;
813
- this.context = context;
814
- this.name = code;
815
- Object.setPrototypeOf(this, new.target.prototype);
927
+ LayoutAction2.UpdateLayout = UpdateLayout;
928
+ class SetLayoutMode extends S4.TaggedClass()(LayoutAction2.UPDATE_LAYOUT, {
929
+ input: S4.Struct({
930
+ part: S4.Literal("mode").annotations({
931
+ description: "Setting the layout mode."
932
+ }),
933
+ subject: S4.optional(S4.String.annotations({
934
+ description: "Item which is the subject of the new layout mode."
935
+ })),
936
+ options: S4.Union(S4.Struct({
937
+ mode: S4.String.annotations({
938
+ description: "The new layout mode."
939
+ })
940
+ }), S4.Struct({
941
+ revert: S4.Boolean.annotations({
942
+ description: "Revert to the previous layout mode."
943
+ })
944
+ }))
945
+ }),
946
+ output: S4.Void
947
+ }) {
816
948
  }
817
- };
818
- var NoResolversError = class extends BaseError {
819
- constructor(action) {
820
- super("NO_RESOLVERS", "No resolvers were found for the action", {
821
- action
822
- });
949
+ LayoutAction2.SetLayoutMode = SetLayoutMode;
950
+ class UpdateSidebar extends S4.TaggedClass()(LayoutAction2.UPDATE_LAYOUT, {
951
+ input: S4.Struct({
952
+ part: S4.Literal("sidebar").annotations({
953
+ description: "Updating the sidebar."
954
+ }),
955
+ subject: S4.optional(S4.String.annotations({
956
+ description: "URI of the component to display in the sidebar."
957
+ })),
958
+ options: S4.optional(S4.Struct({
959
+ state: S4.Literal("closed", "collapsed", "expanded").annotations({
960
+ description: "Whether the sidebar is closed, collapsed, or expanded."
961
+ })
962
+ }))
963
+ }),
964
+ output: S4.Void
965
+ }) {
823
966
  }
824
- };
825
- var CycleDetectedError = class extends BaseError {
826
- constructor(context) {
827
- super("CYCLE_DETECTED", "Intent execution limit exceeded. This is likely due to an infinite loop within intent resolvers.", context);
967
+ LayoutAction2.UpdateSidebar = UpdateSidebar;
968
+ class UpdateComplementary extends S4.TaggedClass()(LayoutAction2.UPDATE_LAYOUT, {
969
+ input: S4.Struct({
970
+ part: S4.Literal("complementary").annotations({
971
+ description: "Updating the complementary sidebar."
972
+ }),
973
+ subject: S4.optional(S4.String.annotations({
974
+ description: "URI of the component to display in the complementary area."
975
+ })),
976
+ options: S4.optional(S4.Struct({
977
+ state: S4.Literal("closed", "collapsed", "expanded").annotations({
978
+ description: "Whether the complementary sidebar is closed, collapsed, or expanded."
979
+ })
980
+ }))
981
+ }),
982
+ output: S4.Void
983
+ }) {
828
984
  }
829
- };
985
+ LayoutAction2.UpdateComplementary = UpdateComplementary;
986
+ class UpdateDialog extends S4.TaggedClass()(LayoutAction2.UPDATE_LAYOUT, {
987
+ input: S4.Struct({
988
+ part: S4.Literal("dialog").annotations({
989
+ description: "Updating the dialog."
990
+ }),
991
+ subject: S4.optional(S4.String.annotations({
992
+ description: "URI of the component to display in the dialog."
993
+ })),
994
+ options: S4.Struct({
995
+ state: S4.optional(S4.Boolean.annotations({
996
+ description: "Whether the dialog is open or closed."
997
+ })),
998
+ blockAlign: S4.optional(S4.Literal("start", "center").annotations({
999
+ description: "The alignment of the dialog."
1000
+ })),
1001
+ type: S4.optional(S4.Literal("default", "alert").annotations({
1002
+ description: "The type of dialog."
1003
+ })),
1004
+ props: S4.optional(S4.Record({
1005
+ key: S4.String,
1006
+ value: S4.Any
1007
+ }).annotations({
1008
+ description: "Additional props for the dialog."
1009
+ }))
1010
+ })
1011
+ }),
1012
+ output: S4.Void
1013
+ }) {
1014
+ }
1015
+ LayoutAction2.UpdateDialog = UpdateDialog;
1016
+ class UpdatePopover extends S4.TaggedClass()(LayoutAction2.UPDATE_LAYOUT, {
1017
+ input: S4.Struct({
1018
+ part: S4.Literal("popover").annotations({
1019
+ description: "Updating the popover."
1020
+ }),
1021
+ subject: S4.optional(S4.String.annotations({
1022
+ description: "URI of the component to display in the popover."
1023
+ })),
1024
+ options: S4.Struct({
1025
+ anchorId: S4.String.annotations({
1026
+ description: "The id of the element to anchor the popover to."
1027
+ }),
1028
+ state: S4.optional(S4.Boolean.annotations({
1029
+ description: "Whether the popover is open or closed."
1030
+ })),
1031
+ props: S4.optional(S4.Record({
1032
+ key: S4.String,
1033
+ value: S4.Any
1034
+ }).annotations({
1035
+ description: "Additional props for the popover."
1036
+ }))
1037
+ })
1038
+ }),
1039
+ output: S4.Void
1040
+ }) {
1041
+ }
1042
+ LayoutAction2.UpdatePopover = UpdatePopover;
1043
+ LayoutAction2.Toast = S4.Struct({
1044
+ id: S4.String.annotations({
1045
+ description: "The id of the toast."
1046
+ }),
1047
+ title: S4.optional(Label.annotations({
1048
+ description: "The title of the toast."
1049
+ })),
1050
+ description: S4.optional(Label.annotations({
1051
+ description: "The description of the toast."
1052
+ })),
1053
+ icon: S4.optional(S4.String.annotations({
1054
+ description: "The icon of the toast."
1055
+ })),
1056
+ duration: S4.optional(S4.Number.annotations({
1057
+ description: "The duration of the toast."
1058
+ })),
1059
+ closeLabel: S4.optional(Label.annotations({
1060
+ description: "The label of the close button."
1061
+ })),
1062
+ actionLabel: S4.optional(Label.annotations({
1063
+ description: "The label of the action button."
1064
+ })),
1065
+ actionAlt: S4.optional(Label.annotations({
1066
+ description: "The alt text of the action button."
1067
+ })),
1068
+ onAction: S4.optional(S4.Any.annotations({
1069
+ description: "The action to perform when the action button is clicked."
1070
+ }))
1071
+ });
1072
+ class AddToast extends S4.TaggedClass()(LayoutAction2.UPDATE_LAYOUT, {
1073
+ input: S4.Struct({
1074
+ part: S4.Literal("toast").annotations({
1075
+ description: "Adding a toast."
1076
+ }),
1077
+ subject: LayoutAction2.Toast.annotations({
1078
+ description: "The toast to add."
1079
+ })
1080
+ }),
1081
+ output: S4.Void
1082
+ }) {
1083
+ }
1084
+ LayoutAction2.AddToast = AddToast;
1085
+ class SwitchWorkspace extends S4.TaggedClass()(LayoutAction2.UPDATE_LAYOUT, {
1086
+ input: S4.Struct({
1087
+ part: S4.Literal("workspace").annotations({
1088
+ description: "Switching the workspace."
1089
+ }),
1090
+ subject: S4.String.annotations({
1091
+ description: "The id of the workspace to switch to."
1092
+ })
1093
+ }),
1094
+ output: S4.Void
1095
+ }) {
1096
+ }
1097
+ LayoutAction2.SwitchWorkspace = SwitchWorkspace;
1098
+ class Open extends S4.TaggedClass()(LayoutAction2.UPDATE_LAYOUT, {
1099
+ input: S4.Struct({
1100
+ part: S4.Literal("main").annotations({
1101
+ description: "Opening an item in the main content area."
1102
+ }),
1103
+ subject: S4.Array(S4.String.annotations({
1104
+ description: "Ids of the items to open."
1105
+ })),
1106
+ options: S4.optional(S4.Struct({
1107
+ state: S4.optional(S4.Literal(true).annotations({
1108
+ description: "The items are being added."
1109
+ })),
1110
+ key: S4.optional(S4.String.annotations({
1111
+ description: "If provided, will replace item with a matching key (id prefix)."
1112
+ })),
1113
+ scrollIntoView: S4.optional(S4.Boolean.annotations({
1114
+ description: "Scroll the items into view."
1115
+ })),
1116
+ pivotId: S4.optional(S4.String.annotations({
1117
+ description: "The id of the item to place new items next to."
1118
+ })),
1119
+ positioning: S4.optional(S4.Union(S4.Literal("start").annotations({
1120
+ description: "The items are being added before the pivot item."
1121
+ }), S4.Literal("end").annotations({
1122
+ description: "The items are being added after the pivot item."
1123
+ })))
1124
+ }))
1125
+ }),
1126
+ output: S4.Void
1127
+ }) {
1128
+ }
1129
+ LayoutAction2.Open = Open;
1130
+ class Set2 extends S4.TaggedClass()(LayoutAction2.UPDATE_LAYOUT, {
1131
+ input: S4.Struct({
1132
+ part: S4.Literal("main").annotations({
1133
+ description: "Setting items in the main content area."
1134
+ }),
1135
+ subject: S4.Array(S4.String.annotations({
1136
+ description: "Ids of the items to set."
1137
+ })),
1138
+ options: S4.Struct({
1139
+ override: S4.Literal(true).annotations({
1140
+ description: "Override the current items in the main content area."
1141
+ })
1142
+ })
1143
+ }),
1144
+ output: S4.Void
1145
+ }) {
1146
+ }
1147
+ LayoutAction2.Set = Set2;
1148
+ class Close extends S4.TaggedClass()(LayoutAction2.UPDATE_LAYOUT, {
1149
+ input: S4.Struct({
1150
+ part: S4.Literal("main").annotations({
1151
+ description: "Closing items in the main content area."
1152
+ }),
1153
+ subject: S4.Array(S4.String.annotations({
1154
+ description: "Ids of the items to close."
1155
+ })),
1156
+ options: S4.Struct({
1157
+ state: S4.Literal(false).annotations({
1158
+ description: "The items are being removed."
1159
+ })
1160
+ })
1161
+ }),
1162
+ output: S4.Void
1163
+ }) {
1164
+ }
1165
+ LayoutAction2.Close = Close;
1166
+ class ScrollIntoView extends S4.TaggedClass()(LayoutAction2.UPDATE_LAYOUT, {
1167
+ input: S4.Struct({
1168
+ part: S4.Literal("current").annotations({
1169
+ description: "Setting the current item"
1170
+ }),
1171
+ subject: S4.optional(S4.String.annotations({
1172
+ description: "The id of the item to set as current."
1173
+ })),
1174
+ options: S4.optional(S4.Record({
1175
+ key: S4.String,
1176
+ value: S4.Any
1177
+ }).annotations({
1178
+ description: "Additional options for the scroll into view."
1179
+ }))
1180
+ }),
1181
+ output: S4.Void
1182
+ }) {
1183
+ }
1184
+ LayoutAction2.ScrollIntoView = ScrollIntoView;
1185
+ class Expose extends S4.TaggedClass()(LayoutAction2.UPDATE_LAYOUT, {
1186
+ input: S4.Struct({
1187
+ part: S4.Literal("navigation").annotations({
1188
+ description: "Exposing an item in the navigation area."
1189
+ }),
1190
+ subject: S4.String.annotations({
1191
+ description: "The id of the item to expose."
1192
+ })
1193
+ }),
1194
+ output: S4.Void
1195
+ }) {
1196
+ }
1197
+ LayoutAction2.Expose = Expose;
1198
+ })(LayoutAction || (LayoutAction = {}));
1199
+
1200
+ // packages/sdk/app-framework/src/common/surface.ts
1201
+ var createSurface = (definition) => definition;
1202
+
1203
+ // packages/sdk/app-framework/src/common/translations.ts
1204
+ import { Schema as S5 } from "@effect/schema";
1205
+ var ResourceKey = S5.Union(S5.String, S5.Record({
1206
+ key: S5.String,
1207
+ value: S5.Any
1208
+ }));
1209
+ var ResourceLanguage = S5.Record({
1210
+ key: S5.String,
1211
+ value: ResourceKey
1212
+ });
1213
+ var Resource = S5.Record({
1214
+ key: S5.String,
1215
+ value: ResourceLanguage
1216
+ });
830
1217
 
831
1218
  // packages/sdk/app-framework/src/plugin-intent/intent-dispatcher.ts
832
1219
  var EXECUTION_LIMIT = 100;
833
1220
  var HISTORY_LIMIT = 100;
834
- var createResolver = (schema, effect3, params = {}) => ({
835
- action: schema._tag,
836
- effect: effect3,
837
- ...params
838
- });
1221
+ var createResolver = (resolver) => resolver;
839
1222
  var isUndoable = (historyEntry) => historyEntry.length > 0 && historyEntry.every(({ undoable }) => !!undoable);
840
1223
  var createDispatcher = (getResolvers, { executionLimit = EXECUTION_LIMIT, historyLimit = HISTORY_LIMIT } = {}) => {
841
1224
  const historyRef = Effect2.runSync(Ref.make([]));
842
- const handleIntent = (intent) => {
843
- return Effect2.gen(function* () {
844
- const candidates = getResolvers(intent.module).filter((r) => r.action === intent.action).filter((r) => !r.filter || r.filter(intent.data)).toSorted(byDisposition);
845
- if (candidates.length === 0) {
846
- return {
847
- _intent: intent,
848
- error: new NoResolversError(intent.action)
849
- };
850
- }
851
- const effect3 = candidates[0].effect(intent.data, intent.undo ?? false);
852
- const result = Effect2.isEffect(effect3) ? yield* effect3 : yield* Effect2.promise(async () => effect3);
853
- return {
854
- _intent: intent,
855
- ...result
856
- };
857
- });
858
- };
1225
+ const handleIntent = (intent) => Effect2.gen(function* () {
1226
+ const candidates = getResolvers(intent.module).filter((r) => r.intent._tag === intent.id).filter((r) => !r.filter || r.filter(intent.data)).toSorted(byPosition);
1227
+ if (candidates.length === 0) {
1228
+ yield* Effect2.fail(new NoResolversError(intent.id));
1229
+ }
1230
+ const effect2 = candidates[0].resolve(intent.data, intent.undo ?? false);
1231
+ const result = Effect2.isEffect(effect2) ? yield* effect2 : yield* Effect2.promise(async () => effect2);
1232
+ return {
1233
+ _intent: intent,
1234
+ ...result
1235
+ };
1236
+ });
859
1237
  const dispatch = (intentChain, depth = 0) => {
860
1238
  return Effect2.gen(function* () {
861
1239
  if (depth > executionLimit) {
@@ -897,7 +1275,7 @@ var createDispatcher = (getResolvers, { executionLimit = EXECUTION_LIMIT, histor
897
1275
  return next;
898
1276
  });
899
1277
  if (result.undoable && isUndoable(results)) {
900
- yield* pipe(dispatch(createIntent(IntentAction.ShowUndo, {
1278
+ yield* pipe2(dispatch(createIntent(IntentAction.ShowUndo, {
901
1279
  message: result.undoable.message
902
1280
  })), Effect2.catchSome((err) => err instanceof NoResolversError ? Option.some(Effect2.succeed(void 0)) : Option.none()));
903
1281
  }
@@ -953,578 +1331,32 @@ var createDispatcher = (getResolvers, { executionLimit = EXECUTION_LIMIT, histor
953
1331
  undoPromise
954
1332
  };
955
1333
  };
956
-
957
- // packages/sdk/app-framework/src/react/ErrorBoundary.tsx
958
- import React, { Component } from "react";
959
- var ErrorBoundary = class extends Component {
960
- constructor(props) {
961
- super(props);
962
- this.state = {
963
- error: void 0
964
- };
965
- }
966
- static getDerivedStateFromError(error) {
967
- return {
968
- error
969
- };
970
- }
971
- componentDidUpdate(prevProps) {
972
- if (prevProps.data !== this.props.data) {
973
- this.resetError();
974
- }
975
- }
976
- render() {
977
- if (this.state.error) {
978
- return /* @__PURE__ */ React.createElement(this.props.fallback, {
979
- data: this.props.data,
980
- error: this.state.error,
981
- reset: this.resetError
982
- });
983
- }
984
- return this.props.children;
985
- }
986
- resetError() {
987
- this.setState({
988
- error: void 0
989
- });
990
- }
991
- };
992
-
993
- // packages/sdk/app-framework/src/react/PluginManagerProvider.ts
994
- import { createContext, useContext } from "react";
995
- import { raise } from "@dxos/debug";
996
- var PluginManagerContext = createContext(void 0);
997
- var usePluginManager = () => useContext(PluginManagerContext) ?? raise(new Error("Missing PluginManagerContext"));
998
- var PluginManagerProvider = PluginManagerContext.Provider;
999
-
1000
- // packages/sdk/app-framework/src/react/useCapabilities.ts
1001
- import { computed } from "@preact/signals-core";
1002
- import { useMemo } from "react";
1003
- var useCapabilities = (interfaceDef, filter) => {
1004
- const manager = usePluginManager();
1005
- const signal = useMemo(() => computed(() => manager.context.requestCapabilities(interfaceDef, filter)), [
1006
- interfaceDef
1007
- ]);
1008
- return signal.value;
1009
- };
1010
- var useCapability = (interfaceDef, filter) => {
1011
- const manager = usePluginManager();
1012
- const signal = useMemo(() => computed(() => manager.context.requestCapability(interfaceDef, filter)), [
1013
- interfaceDef
1014
- ]);
1015
- return signal.value;
1016
- };
1017
-
1018
- // packages/sdk/app-framework/src/react/Surface.tsx
1019
- import React3, { memo, forwardRef, Suspense, useMemo as useMemo2 } from "react";
1020
- import { useDefaultValue } from "@dxos/react-hooks";
1021
- import { byDisposition as byDisposition2 } from "@dxos/util";
1022
-
1023
- // packages/sdk/app-framework/src/common/layout.ts
1024
- import { S as S4 } from "@dxos/echo-schema";
1025
-
1026
- // packages/sdk/app-framework/src/plugin-intent/IntentContext.tsx
1027
- import { createContext as createContext2, useContext as useContext2, useEffect } from "react";
1028
- import { raise as raise2 } from "@dxos/debug";
1029
- import { pick } from "@dxos/util";
1030
- var IntentContext = /* @__PURE__ */ createContext2(void 0);
1031
- var useIntentDispatcher = () => {
1032
- const context = useContext2(IntentContext) ?? raise2(new Error("IntentContext not found"));
1033
- return pick(context, [
1034
- "dispatch",
1035
- "dispatchPromise"
1036
- ]);
1037
- };
1038
- var useIntentResolver = (module, resolver) => {
1039
- const manager = usePluginManager();
1040
- useEffect(() => {
1041
- manager.context.contributeCapability({
1042
- module,
1043
- interface: Capabilities.IntentResolver,
1044
- implementation: resolver
1045
- });
1046
- return () => manager.context.removeCapability(Capabilities.IntentResolver, resolver);
1047
- }, [
1048
- module,
1049
- resolver
1050
- ]);
1051
- };
1052
- var IntentProvider = IntentContext.Provider;
1053
-
1054
- // packages/sdk/app-framework/src/plugin-intent/IntentPlugin.tsx
1055
- import { Effect as Effect3 } from "effect";
1056
- import React2 from "react";
1057
- import { create as create3 } from "@dxos/live-object";
1058
- var defaultEffect = () => Effect3.fail(new Error("Intent runtime not ready"));
1059
- var defaultPromise = () => Effect3.runPromise(defaultEffect());
1060
- var IntentPlugin = () => definePlugin({
1061
- id: INTENT_PLUGIN
1062
- }, [
1063
- defineModule({
1064
- id: `${INTENT_PLUGIN}/module/dispatcher`,
1065
- // TODO(wittjosiah): This will mean that startup needs to be reset when intents are added or removed.
1066
- // This is fine for now because it's how it worked prior to capabilities api anyways.
1067
- // In the future, the intent dispatcher should be able to be reset without resetting the entire app.
1068
- activatesOn: Events.Startup,
1069
- activatesBefore: [
1070
- Events.SetupIntents
1071
- ],
1072
- activatesAfter: [
1073
- Events.DispatcherReady
1074
- ],
1075
- activate: (context) => {
1076
- const state = create3({
1077
- dispatch: defaultEffect,
1078
- dispatchPromise: defaultPromise,
1079
- undo: defaultEffect,
1080
- undoPromise: defaultPromise
1081
- });
1082
- const { dispatch, dispatchPromise, undo, undoPromise } = createDispatcher((module) => context.requestCapabilities(Capabilities.IntentResolver, (c, moduleId) => {
1083
- return module ? moduleId === module : true;
1084
- }).flat());
1085
- state.dispatch = dispatch;
1086
- state.dispatchPromise = dispatchPromise;
1087
- state.undo = undo;
1088
- state.undoPromise = undoPromise;
1089
- return [
1090
- contributes(Capabilities.IntentDispatcher, state),
1091
- contributes(Capabilities.ReactContext, {
1092
- id: INTENT_PLUGIN,
1093
- context: ({ children }) => /* @__PURE__ */ React2.createElement(IntentProvider, {
1094
- value: state
1095
- }, children)
1096
- })
1097
- ];
1098
- }
1099
- })
1100
- ]);
1101
-
1102
- // packages/sdk/app-framework/src/common/layout.ts
1103
- var Toast = S4.Struct({
1104
- id: S4.String,
1105
- title: S4.optional(Label),
1106
- description: S4.optional(Label),
1107
- icon: S4.optional(S4.String),
1108
- duration: S4.optional(S4.Number),
1109
- closeLabel: S4.optional(Label),
1110
- actionLabel: S4.optional(Label),
1111
- actionAlt: S4.optional(Label),
1112
- // TODO(wittjosiah): Make class with customizable method?
1113
- onAction: S4.optional(S4.Any)
1114
- });
1115
- var LayoutMode = S4.Union(S4.Literal("deck"), S4.Literal("solo"), S4.Literal("fullscreen"));
1116
- var isLayoutMode = (value) => S4.is(LayoutMode)(value);
1117
- var Layout = S4.mutable(S4.Struct({
1118
- layoutMode: LayoutMode,
1119
- sidebarOpen: S4.Boolean,
1120
- complementarySidebarOpen: S4.Boolean,
1121
- /**
1122
- * @deprecated Data to be passed to the complementary sidebar Surface.
1123
- */
1124
- complementarySidebarContent: S4.optional(S4.Any),
1125
- dialogOpen: S4.Boolean,
1126
- /**
1127
- * Data to be passed to the dialog Surface.
1128
- */
1129
- dialogContent: S4.optional(S4.Any),
1130
- // TODO(wittjosiah): Custom properties?
1131
- dialogBlockAlign: S4.optional(S4.Literal("start", "center")),
1132
- dialogType: S4.optional(S4.Literal("default", "alert")),
1133
- popoverOpen: S4.Boolean,
1134
- /**
1135
- * Data to be passed to the popover Surface.
1136
- */
1137
- popoverContent: S4.optional(S4.Any),
1138
- popoverAnchorId: S4.optional(S4.String),
1139
- toasts: S4.mutable(S4.Array(Toast)),
1140
- /**
1141
- * The identifier of a component to scroll into view when it is mounted.
1142
- */
1143
- scrollIntoView: S4.optional(S4.String)
1144
- }));
1145
- var LAYOUT_PLUGIN = "dxos.org/plugin/layout";
1146
- var LAYOUT_ACTION = `${LAYOUT_PLUGIN}/action`;
1147
- var LayoutAction;
1148
- (function(LayoutAction2) {
1149
- class SetLayout extends S4.TaggedClass()(`${LAYOUT_ACTION}/set-layout`, {
1150
- input: S4.Struct({
1151
- /**
1152
- * Element to set the state of.
1153
- */
1154
- element: S4.Literal("fullscreen", "sidebar", "complementary", "dialog", "popover", "toast"),
1155
- /**
1156
- * Whether the element is on or off.
1157
- *
1158
- * If omitted, the element's state will be toggled or set based on other provided data.
1159
- * For example, if `component` is provided, the state will be set to `true`.
1160
- */
1161
- state: S4.optional(S4.Boolean),
1162
- /**
1163
- * Component to render in the dialog or popover.
1164
- */
1165
- component: S4.optional(S4.String),
1166
- /**
1167
- * Data to be passed to the dialog or popover Surface.
1168
- */
1169
- subject: S4.optional(S4.Any),
1170
- /**
1171
- * Anchor ID for the popover.
1172
- */
1173
- anchorId: S4.optional(S4.String),
1174
- // TODO(wittjosiah): Custom properties?
1175
- /**
1176
- * Block alignment for the dialog.
1177
- */
1178
- dialogBlockAlign: S4.optional(S4.Literal("start", "center")),
1179
- /**
1180
- * Type of dialog.
1181
- */
1182
- dialogType: S4.optional(S4.Literal("default", "alert"))
1183
- }),
1184
- output: S4.Void
1185
- }) {
1186
- }
1187
- LayoutAction2.SetLayout = SetLayout;
1188
- class SetLayoutMode extends S4.TaggedClass()(`${LAYOUT_ACTION}/set-layout-mode`, {
1189
- input: S4.Union(S4.Struct({
1190
- layoutMode: LayoutMode
1191
- }), S4.Struct({
1192
- revert: S4.Literal(true)
1193
- })),
1194
- output: S4.Void
1195
- }) {
1196
- }
1197
- LayoutAction2.SetLayoutMode = SetLayoutMode;
1198
- class ScrollIntoView extends S4.TaggedClass()(`${LAYOUT_ACTION}/scroll-into-view`, {
1199
- input: S4.Struct({
1200
- id: S4.optional(S4.String),
1201
- // TODO(wittjosiah): Factor out to thread scroll into view action?
1202
- cursor: S4.optional(S4.String),
1203
- ref: S4.optional(S4.String)
1204
- }),
1205
- output: S4.Void
1206
- }) {
1207
- }
1208
- LayoutAction2.ScrollIntoView = ScrollIntoView;
1209
- })(LayoutAction || (LayoutAction = {}));
1210
-
1211
- // packages/sdk/app-framework/src/common/navigation.ts
1212
- import { Schema as S5 } from "@effect/schema";
1213
- import { pick as pick2 } from "@dxos/util";
1214
- var SLUG_LIST_SEPARATOR = "+";
1215
- var SLUG_ENTRY_SEPARATOR = "_";
1216
- var SLUG_KEY_VALUE_SEPARATOR = "-";
1217
- var SLUG_PATH_SEPARATOR = "~";
1218
- var SLUG_COLLECTION_INDICATOR = "";
1219
- var LayoutEntrySchema = S5.mutable(S5.Struct({
1220
- id: S5.String,
1221
- path: S5.optional(S5.String)
1222
- }));
1223
- var LayoutPartSchema = S5.Union(S5.Literal("sidebar"), S5.Literal("main"), S5.Literal("solo"), S5.Literal("complementary"), S5.Literal("fullScreen"));
1224
- var LayoutPartsSchema = S5.partial(S5.mutable(S5.Record({
1225
- key: LayoutPartSchema,
1226
- value: S5.mutable(S5.Array(LayoutEntrySchema))
1227
- })));
1228
- var LayoutCoordinateSchema = S5.mutable(S5.Struct({
1229
- part: LayoutPartSchema,
1230
- entryId: S5.String
1231
- }));
1232
- var PartAdjustmentSchema = S5.Union(S5.Literal("increment-start"), S5.Literal("increment-end"), S5.Literal("pin-start"), S5.Literal("pin-end"), S5.Literal("close"), S5.Literal("solo"));
1233
- var LayoutAdjustmentSchema = S5.mutable(S5.Struct({
1234
- layoutCoordinate: LayoutCoordinateSchema,
1235
- type: PartAdjustmentSchema
1236
- }));
1237
- var ActiveParts = S5.Record({
1238
- key: S5.String,
1239
- value: S5.Union(S5.String, S5.mutable(S5.Array(S5.String)))
1240
- });
1241
- var LocationProvidesSchema = S5.mutable(S5.Struct({
1242
- location: S5.Struct({
1243
- active: LayoutPartsSchema,
1244
- closed: S5.Array(S5.String)
1245
- })
1246
- }));
1247
- var isLayoutParts = (value) => {
1248
- return S5.is(LayoutPartsSchema)(value);
1249
- };
1250
- var isLayoutAdjustment = (value) => {
1251
- return S5.is(LayoutAdjustmentSchema)(value);
1252
- };
1253
- var openIds = (layout, parts) => {
1254
- return Object.values(parts ? pick2(layout, parts) : layout).flatMap((part) => part?.map((entry) => entry.id) ?? []).filter((id) => id !== void 0);
1255
- };
1256
- var firstIdInPart = (layout, part) => {
1257
- if (!layout) {
1258
- return void 0;
1259
- }
1260
- return layout[part]?.at(0)?.id;
1261
- };
1262
- var indexInPart = (layout, layoutCoordinate) => {
1263
- if (!layout || !layoutCoordinate) {
1264
- return void 0;
1265
- }
1266
- const { part, entryId } = layoutCoordinate;
1267
- return layout[part]?.findIndex((entry) => entry.id === entryId);
1268
- };
1269
- var partLength = (layout, part) => {
1270
- if (!layout || !part) {
1271
- return 0;
1272
- }
1273
- return layout[part]?.length ?? 0;
1274
- };
1275
- var NAVIGATION_PLUGIN = "dxos.org/plugin/navigation";
1276
- var NAVIGATION_ACTION = `${NAVIGATION_PLUGIN}/action`;
1277
- var NavigationAction;
1278
- (function(NavigationAction2) {
1279
- class Open extends S5.TaggedClass()(`${NAVIGATION_ACTION}/open`, {
1280
- input: S5.Struct({
1281
- activeParts: ActiveParts,
1282
- noToggle: S5.optional(S5.Boolean)
1283
- }),
1284
- output: S5.Struct({
1285
- open: S5.Array(S5.String)
1286
- })
1287
- }) {
1288
- }
1289
- NavigationAction2.Open = Open;
1290
- class AddToActive extends S5.TaggedClass()(`${NAVIGATION_ACTION}/add-to-active`, {
1291
- input: S5.Struct({
1292
- id: S5.String,
1293
- part: LayoutPartSchema,
1294
- scrollIntoView: S5.optional(S5.Boolean),
1295
- pivotId: S5.optional(S5.String),
1296
- positioning: S5.optional(S5.Literal("start", "end"))
1297
- }),
1298
- output: S5.Void
1299
- }) {
1300
- }
1301
- NavigationAction2.AddToActive = AddToActive;
1302
- class Set2 extends S5.TaggedClass()(`${NAVIGATION_ACTION}/set`, {
1303
- input: S5.Struct({
1304
- activeParts: ActiveParts
1305
- }),
1306
- output: S5.Void
1307
- }) {
1308
- }
1309
- NavigationAction2.Set = Set2;
1310
- class Close extends S5.TaggedClass()(`${NAVIGATION_ACTION}/close`, {
1311
- input: S5.Struct({
1312
- activeParts: ActiveParts,
1313
- noToggle: S5.optional(S5.Boolean)
1314
- }),
1315
- output: S5.Void
1316
- }) {
1317
- }
1318
- NavigationAction2.Close = Close;
1319
- class Adjust extends S5.TaggedClass()(`${NAVIGATION_ACTION}/adjust`, {
1320
- input: LayoutAdjustmentSchema,
1321
- output: S5.Void
1322
- }) {
1323
- }
1324
- NavigationAction2.Adjust = Adjust;
1325
- class Expose extends S5.TaggedClass()(`${NAVIGATION_ACTION}/expose`, {
1326
- input: S5.Struct({
1327
- id: S5.String
1328
- }),
1329
- output: S5.Void
1330
- }) {
1331
- }
1332
- NavigationAction2.Expose = Expose;
1333
- })(NavigationAction || (NavigationAction = {}));
1334
-
1335
- // packages/sdk/app-framework/src/common/surface.ts
1336
- var createSurface = (definition) => definition;
1337
-
1338
- // packages/sdk/app-framework/src/common/translations.ts
1339
- import { z } from "zod";
1340
- var ResourceKey = z.union([
1341
- z.string(),
1342
- z.record(z.any())
1343
- ]);
1344
- var ResourceLanguage = z.record(ResourceKey);
1345
- var Resource = z.record(ResourceLanguage);
1346
-
1347
- // packages/sdk/app-framework/src/react/Surface.tsx
1348
- var useSurfaces = () => {
1349
- const surfaces = useCapabilities(Capabilities.ReactSurface);
1350
- return useMemo2(() => surfaces.flat(), [
1351
- surfaces
1352
- ]);
1353
- };
1354
- var findCandidates = (surfaces, { role, data }) => {
1355
- return Object.values(surfaces).filter((definition) => Array.isArray(definition.role) ? definition.role.includes(role) : definition.role === role).filter(({ filter }) => filter ? filter(data ?? {}) : true).toSorted(byDisposition2);
1356
- };
1357
- var isSurfaceAvailable = (context, { role, data }) => {
1358
- const surfaces = context.requestCapabilities(Capabilities.ReactSurface);
1359
- const candidates = findCandidates(surfaces.flat(), {
1360
- role,
1361
- data
1334
+ var defaultEffect = () => Effect2.fail(new Error("Intent runtime not ready"));
1335
+ var defaultPromise = () => Effect2.runPromise(defaultEffect());
1336
+ var intent_dispatcher_default = (context) => {
1337
+ const state = create3({
1338
+ dispatch: defaultEffect,
1339
+ dispatchPromise: defaultPromise,
1340
+ undo: defaultEffect,
1341
+ undoPromise: defaultPromise
1362
1342
  });
1363
- return candidates.length > 0;
1364
- };
1365
- var Surface = /* @__PURE__ */ memo(/* @__PURE__ */ forwardRef(({ id: _id, role, data: _data, limit, fallback, placeholder, ...rest }, forwardedRef) => {
1366
- const surfaces = useSurfaces();
1367
- const data = useDefaultValue(_data, () => ({}));
1368
- const candidates = useMemo2(() => {
1369
- const definitions = findCandidates(surfaces, {
1370
- role,
1371
- data
1343
+ const { dispatch, dispatchPromise, undo, undoPromise } = createDispatcher((module) => context.requestCapabilities(Capabilities.IntentResolver, (c, moduleId) => {
1344
+ return module ? moduleId === module : true;
1345
+ }).flat());
1346
+ const manager = context.requestCapability(Capabilities.PluginManager);
1347
+ state.dispatch = (intentChain, depth) => {
1348
+ return Effect2.gen(function* () {
1349
+ yield* manager._activate(Events.SetupIntents);
1350
+ return yield* dispatch(intentChain, depth);
1372
1351
  });
1373
- return limit ? definitions.slice(0, limit) : definitions;
1374
- }, [
1375
- surfaces,
1376
- role,
1377
- data,
1378
- limit
1379
- ]);
1380
- const nodes = candidates.map(({ component: Component2, id }) => /* @__PURE__ */ React3.createElement(Component2, {
1381
- ref: forwardedRef,
1382
- key: id,
1383
- id,
1384
- role,
1385
- data,
1386
- limit,
1387
- ...rest
1388
- }));
1389
- const suspense = placeholder ? /* @__PURE__ */ React3.createElement(Suspense, {
1390
- fallback: placeholder
1391
- }, nodes) : nodes;
1392
- return fallback ? /* @__PURE__ */ React3.createElement(ErrorBoundary, {
1393
- data,
1394
- fallback
1395
- }, suspense) : suspense;
1396
- }));
1397
-
1398
- // packages/sdk/app-framework/src/App.tsx
1399
- import { effect as effect2 } from "@preact/signals-core";
1400
- import React4 from "react";
1401
- import { invariant as invariant2 } from "@dxos/invariant";
1402
- import { create as create4 } from "@dxos/live-object";
1403
-
1404
- // packages/sdk/app-framework/src/helpers.ts
1405
- var topologicalSort = (nodes) => {
1406
- const getDependencies = (nodeId, seen = /* @__PURE__ */ new Set(), path = /* @__PURE__ */ new Set()) => {
1407
- if (path.has(nodeId)) {
1408
- throw new Error(`Circular dependency detected involving ${nodeId}`);
1409
- }
1410
- if (seen.has(nodeId)) {
1411
- return [];
1412
- }
1413
- const node = nodes.find((n) => n.id === nodeId);
1414
- if (!node) {
1415
- throw new Error(`Node ${nodeId} not found but is listed as a dependency`);
1416
- }
1417
- const newPath = /* @__PURE__ */ new Set([
1418
- ...path,
1419
- nodeId
1420
- ]);
1421
- const newSeen = /* @__PURE__ */ new Set([
1422
- ...seen,
1423
- nodeId
1424
- ]);
1425
- const dependsOn = node.dependsOn ?? [];
1426
- return [
1427
- ...dependsOn.flatMap((depId) => getDependencies(depId, newSeen, newPath)),
1428
- nodeId
1429
- ];
1430
1352
  };
1431
- const allDependencies = nodes.map((node) => node.id).flatMap((id) => getDependencies(id)).filter((id, index, self) => self.indexOf(id) === index);
1432
- return allDependencies.map((id) => nodes.find((node) => node.id === id)).filter((node) => node !== void 0);
1433
- };
1434
-
1435
- // packages/sdk/app-framework/src/App.tsx
1436
- var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/sdk/app-framework/src/App.tsx";
1437
- var ENABLED_KEY = "dxos.org/app-framework/enabled";
1438
- var createApp = ({ pluginManager, pluginLoader: _pluginLoader, plugins = [], core = plugins.map(({ meta }) => meta.id), defaults = [], placeholder = null, fallback = DefaultFallback, cacheEnabled = false }) => {
1439
- const pluginLoader = _pluginLoader ?? ((id) => {
1440
- const plugin = plugins.find((plugin2) => plugin2.meta.id === id);
1441
- invariant2(plugin, `Plugin not found: ${id}`, {
1442
- F: __dxlog_file3,
1443
- L: 68,
1444
- S: void 0,
1445
- A: [
1446
- "plugin",
1447
- "`Plugin not found: ${id}`"
1448
- ]
1449
- });
1450
- return plugin;
1451
- });
1452
- const state = create4({
1453
- ready: false,
1454
- error: null
1455
- });
1456
- const cached = JSON.parse(localStorage.getItem(ENABLED_KEY) ?? "[]");
1457
- const enabled = cacheEnabled && cached.length > 0 ? cached : defaults;
1458
- const manager = pluginManager ?? new PluginManager({
1459
- pluginLoader,
1460
- plugins,
1461
- core,
1462
- enabled
1463
- });
1464
- manager.activation.on(({ event, state: _state, error }) => {
1465
- if (event === Events.Startup.id) {
1466
- state.ready = _state === "activated";
1467
- }
1468
- if (error && !state.ready && !state.error) {
1469
- state.error = error;
1470
- }
1471
- });
1472
- effect2(() => {
1473
- cacheEnabled && localStorage.setItem(ENABLED_KEY, JSON.stringify(manager.enabled));
1474
- });
1475
- manager.context.contributeCapability({
1476
- interface: Capabilities.PluginManager,
1477
- implementation: manager,
1478
- module: "dxos.org/app-framework/plugin-manager"
1479
- });
1480
- setupDevtools(manager);
1481
- void manager.activate(Events.Startup);
1482
- return () => /* @__PURE__ */ React4.createElement(ErrorBoundary, {
1483
- fallback
1484
- }, /* @__PURE__ */ React4.createElement(App, {
1485
- placeholder,
1486
- manager,
1487
- state
1488
- }));
1489
- };
1490
- var App = ({ placeholder, manager, state }) => {
1491
- if (state.error) {
1492
- throw state.error;
1493
- }
1494
- if (!state.ready) {
1495
- return /* @__PURE__ */ React4.createElement(React4.Fragment, null, placeholder);
1496
- }
1497
- const reactContexts = manager.context.requestCapabilities(Capabilities.ReactContext);
1498
- const reactRoots = manager.context.requestCapabilities(Capabilities.ReactRoot);
1499
- const ComposedContext = composeContexts(reactContexts);
1500
- return /* @__PURE__ */ React4.createElement(PluginManagerProvider, {
1501
- value: manager
1502
- }, /* @__PURE__ */ React4.createElement(ComposedContext, null, reactRoots.map(({ id, root: Component2 }) => /* @__PURE__ */ React4.createElement(Component2, {
1503
- key: id
1504
- }))));
1505
- };
1506
- var DefaultFallback = ({ error }) => {
1507
- return /* @__PURE__ */ React4.createElement("div", {
1508
- style: {
1509
- padding: "1rem"
1510
- }
1511
- }, /* @__PURE__ */ React4.createElement("h1", {
1512
- style: {
1513
- fontSize: "1.2rem",
1514
- fontWeight: 700,
1515
- margin: "0.5rem 0"
1516
- }
1517
- }, error.message), /* @__PURE__ */ React4.createElement("pre", null, error.stack));
1518
- };
1519
- var composeContexts = (contexts) => {
1520
- if (contexts.length === 0) {
1521
- return ({ children }) => /* @__PURE__ */ React4.createElement(React4.Fragment, null, children);
1522
- }
1523
- return topologicalSort(contexts).map(({ context }) => context).reduce((Acc, Next) => ({ children }) => /* @__PURE__ */ React4.createElement(Acc, null, /* @__PURE__ */ React4.createElement(Next, null, children)));
1524
- };
1525
- var setupDevtools = (manager) => {
1526
- globalThis.composer ??= {};
1527
- globalThis.composer.manager = manager;
1353
+ state.dispatchPromise = async (intentChain) => {
1354
+ await manager.activate(Events.SetupIntents);
1355
+ return await dispatchPromise(intentChain);
1356
+ };
1357
+ state.undo = undo;
1358
+ state.undoPromise = undoPromise;
1359
+ return contributes(Capabilities.IntentDispatcher, state);
1528
1360
  };
1529
1361
 
1530
1362
  export {
@@ -1556,42 +1388,14 @@ export {
1556
1388
  IntentAction,
1557
1389
  createResolver,
1558
1390
  createDispatcher,
1559
- ErrorBoundary,
1560
- usePluginManager,
1561
- PluginManagerProvider,
1562
- useCapabilities,
1563
- useCapability,
1564
- isSurfaceAvailable,
1565
- Surface,
1566
- useIntentDispatcher,
1567
- useIntentResolver,
1568
- IntentProvider,
1391
+ intent_dispatcher_default,
1569
1392
  IntentPlugin,
1570
- Toast,
1571
- isLayoutMode,
1572
- Layout,
1573
1393
  LAYOUT_PLUGIN,
1574
1394
  LAYOUT_ACTION,
1575
1395
  LayoutAction,
1576
- SLUG_LIST_SEPARATOR,
1577
- SLUG_ENTRY_SEPARATOR,
1578
- SLUG_KEY_VALUE_SEPARATOR,
1579
- SLUG_PATH_SEPARATOR,
1580
- SLUG_COLLECTION_INDICATOR,
1581
- ActiveParts,
1582
- isLayoutParts,
1583
- isLayoutAdjustment,
1584
- openIds,
1585
- firstIdInPart,
1586
- indexInPart,
1587
- partLength,
1588
- NAVIGATION_PLUGIN,
1589
- NAVIGATION_ACTION,
1590
- NavigationAction,
1591
1396
  createSurface,
1592
1397
  ResourceKey,
1593
1398
  ResourceLanguage,
1594
- Resource,
1595
- createApp
1399
+ Resource
1596
1400
  };
1597
- //# sourceMappingURL=chunk-KPMTPXQI.mjs.map
1401
+ //# sourceMappingURL=chunk-44J2VZBB.mjs.map