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

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