foldkit 0.160.0 → 0.161.0

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 (56) hide show
  1. package/dist/calendar/index.d.ts +1 -1
  2. package/dist/calendar/index.d.ts.map +1 -1
  3. package/dist/calendar/index.js +1 -1
  4. package/dist/calendar/locale.d.ts +219 -10
  5. package/dist/calendar/locale.d.ts.map +1 -1
  6. package/dist/calendar/locale.js +166 -82
  7. package/dist/calendar/public.d.ts +1 -1
  8. package/dist/calendar/public.d.ts.map +1 -1
  9. package/dist/calendar/public.js +1 -1
  10. package/dist/command/index.d.ts +9 -12
  11. package/dist/command/index.d.ts.map +1 -1
  12. package/dist/command/index.js +9 -12
  13. package/dist/devTools/protocol.d.ts +9 -1
  14. package/dist/devTools/protocol.d.ts.map +1 -1
  15. package/dist/devTools/protocol.js +2 -1
  16. package/dist/devTools/serialize.d.ts.map +1 -1
  17. package/dist/devTools/serialize.js +1 -0
  18. package/dist/devTools/store.d.ts +3 -0
  19. package/dist/devTools/store.d.ts.map +1 -1
  20. package/dist/devTools/store.js +24 -0
  21. package/dist/dom/dialogRuntime.d.ts +9 -0
  22. package/dist/dom/dialogRuntime.d.ts.map +1 -0
  23. package/dist/dom/dialogRuntime.js +3 -0
  24. package/dist/dom/dom.d.ts +22 -11
  25. package/dist/dom/dom.d.ts.map +1 -1
  26. package/dist/dom/dom.js +196 -18
  27. package/dist/dom/inert.d.ts +9 -0
  28. package/dist/dom/inert.d.ts.map +1 -1
  29. package/dist/dom/inert.js +74 -2
  30. package/dist/managedResource/managedResource.d.ts +44 -2
  31. package/dist/managedResource/managedResource.d.ts.map +1 -1
  32. package/dist/managedResource/managedResource.js +40 -10
  33. package/dist/runtime/devToolsIntegration.d.ts +8 -3
  34. package/dist/runtime/devToolsIntegration.d.ts.map +1 -1
  35. package/dist/runtime/devToolsIntegration.js +20 -3
  36. package/dist/runtime/runtime.d.ts.map +1 -1
  37. package/dist/runtime/runtime.js +54 -12
  38. package/dist/subscription/fromEvent.d.ts +103 -28
  39. package/dist/subscription/fromEvent.d.ts.map +1 -1
  40. package/dist/subscription/fromEvent.js +48 -27
  41. package/dist/subscription/keyboardShortcuts.d.ts +110 -0
  42. package/dist/subscription/keyboardShortcuts.d.ts.map +1 -0
  43. package/dist/subscription/keyboardShortcuts.js +444 -0
  44. package/dist/subscription/public.d.ts +3 -1
  45. package/dist/subscription/public.d.ts.map +1 -1
  46. package/dist/subscription/public.js +1 -0
  47. package/dist/subscription/subscription.d.ts +61 -1
  48. package/dist/subscription/subscription.d.ts.map +1 -1
  49. package/dist/subscription/subscription.js +51 -8
  50. package/dist/update/public.d.ts +1 -1
  51. package/dist/update/public.d.ts.map +1 -1
  52. package/dist/update/public.js +1 -1
  53. package/dist/update/update.d.ts +189 -1
  54. package/dist/update/update.d.ts.map +1 -1
  55. package/dist/update/update.js +178 -16
  56. package/package.json +1 -1
package/dist/dom/dom.js CHANGED
@@ -1,11 +1,131 @@
1
- import { Array, Effect, Equal, Function, Match, Number, Option } from 'effect';
1
+ import { Array, Effect, Equal, Function, Match, Number, Option, Result, } from 'effect';
2
2
  import { afterCommit, afterPaint } from '../render/render.js';
3
+ import { DialogRuntime } from './dialogRuntime.js';
3
4
  import { ElementNotFound } from './error.js';
5
+ import { makeOutsideIsolation } from './inert.js';
4
6
  import { unlockScroll } from './scrollLock.js';
5
7
  const BASE_DIALOG_Z_INDEX = 2147483600;
6
8
  let openDialogCount = 0;
7
9
  const dialogHygieneById = new Map();
8
10
  let openDialogStack = [];
11
+ let modalIsolation;
12
+ let modalObserver;
13
+ let modalAllowedElements = [];
14
+ let modalAllowedOutsideElements = [];
15
+ let modalAllowedSelectors = [];
16
+ let modalAllowedAncestors = new Set();
17
+ const containsAllowedSelector = (node) => {
18
+ if (!(node instanceof Element || node instanceof DocumentFragment)) {
19
+ return false;
20
+ }
21
+ return Array.some(modalAllowedSelectors, selector => {
22
+ try {
23
+ return ((node instanceof Element && node.matches(selector)) ||
24
+ node.querySelector(selector) !== null);
25
+ }
26
+ catch {
27
+ return false;
28
+ }
29
+ });
30
+ };
31
+ const containsCurrentAllowedElement = (node) => Array.some(modalAllowedElements, element => node.contains(element));
32
+ const isRelevantModalMutation = (mutation) => {
33
+ if (mutation.type === 'attributes' &&
34
+ (mutation.attributeName === 'aria-hidden' ||
35
+ mutation.attributeName === 'inert')) {
36
+ return (mutation.target instanceof HTMLElement &&
37
+ modalIsolation?.contains(mutation.target) === true);
38
+ }
39
+ if (mutation.type === 'attributes') {
40
+ return (Array.some(modalAllowedOutsideElements, element => mutation.target.contains(element)) || containsAllowedSelector(mutation.target));
41
+ }
42
+ const changedNodes = [
43
+ ...Array.fromIterable(mutation.addedNodes),
44
+ ...Array.fromIterable(mutation.removedNodes),
45
+ ];
46
+ if (mutation.target instanceof HTMLElement &&
47
+ modalAllowedAncestors.has(mutation.target) &&
48
+ Array.some(changedNodes, node => node instanceof Element)) {
49
+ return true;
50
+ }
51
+ return Array.some(changedNodes, node => containsCurrentAllowedElement(node) || containsAllowedSelector(node));
52
+ };
53
+ const ancestorsOfAllowedElements = (allowedElements) => {
54
+ const ancestors = new Set();
55
+ for (const allowedElement of allowedElements) {
56
+ let ancestor = allowedElement.parentElement;
57
+ while (ancestor !== null) {
58
+ ancestors.add(ancestor);
59
+ if (ancestor === document.body) {
60
+ break;
61
+ }
62
+ ancestor = ancestor.parentElement;
63
+ }
64
+ }
65
+ return ancestors;
66
+ };
67
+ const recordModalAttributeMutations = (mutations) => {
68
+ for (const mutation of mutations) {
69
+ if (mutation.type === 'attributes' &&
70
+ mutation.target instanceof HTMLElement &&
71
+ (mutation.attributeName === 'aria-hidden' ||
72
+ mutation.attributeName === 'inert')) {
73
+ modalIsolation?.recordAttributeMutation(mutation.target, mutation.attributeName);
74
+ }
75
+ }
76
+ };
77
+ const synchronizeModalIsolation = () => {
78
+ if (modalObserver !== undefined) {
79
+ recordModalAttributeMutations(modalObserver.takeRecords());
80
+ }
81
+ modalObserver?.disconnect();
82
+ const maybeTopmostModal = Array.last(Array.filter(openDialogStack, dialog => dialog.isModal));
83
+ if (Option.isNone(maybeTopmostModal)) {
84
+ modalObserver?.disconnect();
85
+ modalObserver = undefined;
86
+ modalIsolation?.dispose();
87
+ modalIsolation = undefined;
88
+ modalAllowedElements = [];
89
+ modalAllowedOutsideElements = [];
90
+ modalAllowedSelectors = [];
91
+ modalAllowedAncestors = new Set();
92
+ return;
93
+ }
94
+ const { allowedOutsideSelectors } = maybeTopmostModal.value;
95
+ const dialogsAtOrAboveModal = Array.dropWhile(openDialogStack, dialog => dialog !== maybeTopmostModal.value);
96
+ const allowedOutsideElements = Array.filterMap(allowedOutsideSelectors, selector => {
97
+ try {
98
+ const outsideElement = document.querySelector(selector);
99
+ return outsideElement instanceof HTMLElement
100
+ ? Result.succeed(outsideElement)
101
+ : Result.failVoid;
102
+ }
103
+ catch {
104
+ return Result.failVoid;
105
+ }
106
+ });
107
+ const nextAllowedElements = [
108
+ ...Array.map(dialogsAtOrAboveModal, dialog => dialog.element),
109
+ ...allowedOutsideElements,
110
+ ];
111
+ modalIsolation ??= makeOutsideIsolation();
112
+ modalIsolation.update(nextAllowedElements);
113
+ modalAllowedElements = nextAllowedElements;
114
+ modalAllowedOutsideElements = allowedOutsideElements;
115
+ modalAllowedSelectors = allowedOutsideSelectors;
116
+ modalAllowedAncestors = ancestorsOfAllowedElements(nextAllowedElements);
117
+ modalObserver ??= new MutationObserver(mutations => {
118
+ if (Array.some(mutations, isRelevantModalMutation)) {
119
+ recordModalAttributeMutations(mutations);
120
+ synchronizeModalIsolation();
121
+ }
122
+ });
123
+ modalObserver.observe(document.body, {
124
+ childList: true,
125
+ subtree: true,
126
+ attributes: true,
127
+ });
128
+ };
9
129
  const FOCUSABLE_SELECTOR = Array.join([
10
130
  'a[href]:not([tabindex="-1"])',
11
131
  'button:not([disabled]):not([tabindex="-1"])',
@@ -14,6 +134,8 @@ const FOCUSABLE_SELECTOR = Array.join([
14
134
  'textarea:not([disabled]):not([tabindex="-1"])',
15
135
  '[tabindex]:not([tabindex="-1"])',
16
136
  ], ', ');
137
+ const isVisibleAndInteractiveElement = (element) => element.closest('[hidden], [inert]') === null &&
138
+ element.checkVisibility({ visibilityProperty: true });
17
139
  const isFocusableElement = (element) => {
18
140
  if (!(element instanceof HTMLElement)) {
19
141
  return false;
@@ -27,12 +149,18 @@ const isFocusableElement = (element) => {
27
149
  if (element.tabIndex < 0 && !element.hasAttribute('tabindex')) {
28
150
  return false;
29
151
  }
30
- if (element.closest('[hidden], [inert]') !== null) {
152
+ return isVisibleAndInteractiveElement(element);
153
+ };
154
+ const focusableElementsWithin = (root) => Array.filter(Array.fromIterable(root.querySelectorAll(FOCUSABLE_SELECTOR)), isFocusableElement);
155
+ const isValidReturnFocus = (element) => {
156
+ if (!document.contains(element)) {
31
157
  return false;
32
158
  }
33
- return element.checkVisibility({ visibilityProperty: true });
159
+ if (element instanceof HTMLDialogElement) {
160
+ return element.open && isVisibleAndInteractiveElement(element);
161
+ }
162
+ return isFocusableElement(element);
34
163
  };
35
- const focusableElementsWithin = (root) => Array.filter(Array.fromIterable(root.querySelectorAll(FOCUSABLE_SELECTOR)), isFocusableElement);
36
164
  const queryHTMLElement = (selector) => Effect.suspend(() => {
37
165
  const element = document.querySelector(selector);
38
166
  return element instanceof HTMLElement
@@ -101,7 +229,11 @@ export const focus = (selector, options) => Effect.gen(function* () {
101
229
  * a `CustomEvent` named `cancel`, distinguishing it from native `cancel` events
102
230
  * while preserving the dialog event contract. Uses `show()` instead of
103
231
  * `showModal()` so that DevTools (and any other high-z-index overlay) remains
104
- * interactive. The Dialog component provides its own backdrop, scroll locking,
232
+ * interactive. Pass `isModal: true` to make the background inert and hide it
233
+ * from assistive technology. `allowedOutsideSelectors` keeps separate developer
234
+ * overlays available while modal isolation is active. Stacked modal dialogs
235
+ * isolate against the topmost one, and closing it restores the dialog beneath.
236
+ * The Dialog component provides its own backdrop, scroll locking,
105
237
  * and transitions. Fails with `ElementNotFound` if the selector does not match
106
238
  * an `HTMLDialogElement`.
107
239
  *
@@ -110,12 +242,16 @@ export const focus = (selector, options) => Effect.gen(function* () {
110
242
  * falls back to the first focusable descendant and then to the dialog itself.
111
243
  *
112
244
  * Records the element that had focus when the dialog opened so `closeDialog`
113
- * can return focus there, the way `showModal()` would natively.
245
+ * can return focus there, the way `showModal()` would natively. Resolves to
246
+ * `true` when it installs the dialog resources, or `false` when that id already
247
+ * holds them. The latter makes concurrent lifecycle recovery and application
248
+ * Commands safe without duplicating focus traps or stack entries.
114
249
  *
115
250
  * @example
116
251
  * ```typescript
117
252
  * Dom.showDialog('#my-dialog')
118
253
  * Dom.showDialog('#my-dialog', { focusSelector: '#search-input' })
254
+ * Dom.showDialog('#my-dialog', { isModal: true })
119
255
  * ```
120
256
  */
121
257
  export const showDialog = (selector, options) => Effect.gen(function* () {
@@ -125,17 +261,28 @@ export const showDialog = (selector, options) => Effect.gen(function* () {
125
261
  return yield* Effect.fail(new ElementNotFound({ selector }));
126
262
  }
127
263
  const { id } = element;
264
+ const maybeDialogRuntime = yield* Effect.serviceOption(DialogRuntime);
265
+ const existingHygiene = dialogHygieneById.get(id);
266
+ if (existingHygiene !== undefined) {
267
+ return false;
268
+ }
128
269
  element.style.position = 'fixed';
129
270
  element.style.inset = '0';
130
- openDialogCount++;
131
- element.style.zIndex = String(BASE_DIALOG_Z_INDEX + openDialogCount);
132
271
  const previouslyFocused = document.activeElement;
133
272
  const returnFocus = previouslyFocused instanceof HTMLElement &&
134
273
  previouslyFocused !== document.body
135
274
  ? previouslyFocused
136
275
  : undefined;
137
276
  element.show();
138
- openDialogStack = Array.append(Array.filter(openDialogStack, dialog => dialog.element !== element), { id, element });
277
+ openDialogCount++;
278
+ element.style.zIndex = String(BASE_DIALOG_Z_INDEX + openDialogCount);
279
+ openDialogStack = Array.append(Array.filter(openDialogStack, dialog => dialog.element !== element), {
280
+ id,
281
+ element,
282
+ isModal: options?.isModal ?? false,
283
+ allowedOutsideSelectors: options?.allowedOutsideSelectors ?? [],
284
+ });
285
+ synchronizeModalIsolation();
139
286
  const handleKeydown = (event) => {
140
287
  if (!element.open) {
141
288
  return;
@@ -157,10 +304,17 @@ export const showDialog = (selector, options) => Effect.gen(function* () {
157
304
  document.addEventListener('keydown', handleKeydown);
158
305
  dialogHygieneById.set(id, {
159
306
  removeKeydownListener: () => document.removeEventListener('keydown', handleKeydown),
307
+ unregisterOwner: Option.isSome(maybeDialogRuntime)
308
+ ? () => maybeDialogRuntime.value.unregister(id)
309
+ : undefined,
160
310
  returnFocus,
161
311
  });
312
+ if (Option.isSome(maybeDialogRuntime)) {
313
+ maybeDialogRuntime.value.register(id);
314
+ }
162
315
  const focusTarget = findDialogFocusTarget(element, options?.focusSelector);
163
316
  focusTarget.focus();
317
+ return true;
164
318
  });
165
319
  const findDialogFocusTarget = (dialog, focusSelector) => {
166
320
  if (focusSelector !== undefined) {
@@ -196,9 +350,10 @@ const trapFocusWithinDialog = (event, dialog) => {
196
350
  };
197
351
  /**
198
352
  * Closes a dialog element using `.close()`.
199
- * Cleans up the keyboard handlers installed by `showDialog` and restores focus to
200
- * the element that was focused before the dialog opened (the trigger, or the
201
- * dialog beneath it when closing a stacked dialog).
353
+ * Cleans up the keyboard handlers installed by `showDialog`, restores modal
354
+ * background isolation, and then returns focus to the element that was focused
355
+ * before the dialog opened (the trigger, or the dialog beneath it when closing
356
+ * a stacked dialog).
202
357
  * Resolves to `true` when it released the keyboard handlers, the return
203
358
  * focus, and the stack entry.
204
359
  * Resolves to `false` when the dialog held none, for example when the close
@@ -224,23 +379,46 @@ const releaseDialogHygieneById = (id) => {
224
379
  if (hygiene === undefined) {
225
380
  return false;
226
381
  }
382
+ const maybeReleasedDialog = Array.findFirst(openDialogStack, dialog => dialog.id === id);
383
+ const isTopmost = Option.exists(Array.last(openDialogStack), dialog => dialog.id === id);
384
+ if (Option.isSome(maybeReleasedDialog)) {
385
+ for (const openDialog of openDialogStack) {
386
+ if (openDialog.id === id) {
387
+ continue;
388
+ }
389
+ const openHygiene = dialogHygieneById.get(openDialog.id);
390
+ const openReturnFocus = openHygiene?.returnFocus;
391
+ if (openHygiene !== undefined &&
392
+ openReturnFocus !== undefined &&
393
+ maybeReleasedDialog.value.element.contains(openReturnFocus)) {
394
+ dialogHygieneById.set(openDialog.id, {
395
+ ...openHygiene,
396
+ returnFocus: hygiene.returnFocus,
397
+ });
398
+ }
399
+ }
400
+ }
227
401
  openDialogStack = Array.filter(openDialogStack, dialog => dialog.id !== id);
402
+ synchronizeModalIsolation();
228
403
  openDialogCount = Math.max(0, Number.decrement(openDialogCount));
229
404
  hygiene.removeKeydownListener();
230
405
  dialogHygieneById.delete(id);
406
+ hygiene.unregisterOwner?.();
231
407
  const { returnFocus } = hygiene;
232
- if (returnFocus !== undefined && document.contains(returnFocus)) {
408
+ if (isTopmost &&
409
+ returnFocus !== undefined &&
410
+ isValidReturnFocus(returnFocus)) {
233
411
  returnFocus.focus();
234
412
  }
235
413
  return true;
236
414
  };
237
415
  /**
238
416
  * Releases the framework hygiene a dialog holds while open: the focus-trap
239
- * keyboard handler, the recorded return focus, the dialog stack entry, the
240
- * z-index counter, and one page scroll lock. Use this as a backstop for the
241
- * case where a dialog's element is removed from the DOM without a purposeful
242
- * close, the classic example being navigation away from a route-keyed subtree
243
- * that contains the dialog. The normal close path already releases these.
417
+ * keyboard handler, modal background isolation, the recorded return focus,
418
+ * the dialog stack entry, the z-index counter, and one page scroll lock.
419
+ * Use this when the element is removed without a close Message, such as
420
+ * navigation away from a route-keyed subtree. The runtime also calls it
421
+ * directly on disposal. The normal close path already releases these.
244
422
  * That path is `closeDialog` first, then the Dialog component's scroll unlock
245
423
  * when `closeDialog` reports a release. This function is the cleanup for the
246
424
  * case where no close Message ever reaches `update`.
@@ -1,4 +1,12 @@
1
1
  import { Effect } from 'effect';
2
+ type InertAttribute = 'aria-hidden' | 'inert';
3
+ export declare const makeOutsideIsolation: () => Readonly<{
4
+ update: (allowedElements: ReadonlyArray<HTMLElement>) => void;
5
+ contains: (element: HTMLElement) => boolean;
6
+ recordAttributeMutation: (element: HTMLElement, attributeName: InertAttribute) => void;
7
+ dispose: () => void;
8
+ }>;
9
+ export declare const isolateOutsideElements: (allowedElements: ReadonlyArray<HTMLElement>) => (() => void);
2
10
  /**
3
11
  * Marks all DOM elements outside the given selectors as `inert` and
4
12
  * `aria-hidden="true"`. Walks each allowed element up to `document.body`,
@@ -23,4 +31,5 @@ export declare const inertOthers: (id: string, allowedSelectors: ReadonlyArray<s
23
31
  * ```
24
32
  */
25
33
  export declare const restoreInert: (id: string) => Effect.Effect<void>;
34
+ export {};
26
35
  //# sourceMappingURL=inert.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"inert.d.ts","sourceRoot":"","sources":["../../src/dom/inert.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,MAAM,EAA2C,MAAM,QAAQ,CAAA;AA0F/E;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,WAAW,OAClB,MAAM,oBACQ,aAAa,CAAC,MAAM,CAAC,KACtC,MAAM,CAAC,MAAM,CAAC,IAAI,CAyBjB,CAAA;AAEJ;;;;;;;;;GASG;AACH,eAAO,MAAM,YAAY,OAAQ,MAAM,KAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAUxD,CAAA"}
1
+ {"version":3,"file":"inert.d.ts","sourceRoot":"","sources":["../../src/dom/inert.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,MAAM,EAA2C,MAAM,QAAQ,CAAA;AAc/E,KAAK,cAAc,GAAG,aAAa,GAAG,OAAO,CAAA;AAoH7C,eAAO,MAAM,oBAAoB,QAAO,QAAQ,CAAC;IAC/C,MAAM,EAAE,CAAC,eAAe,EAAE,aAAa,CAAC,WAAW,CAAC,KAAK,IAAI,CAAA;IAC7D,QAAQ,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,OAAO,CAAA;IAC3C,uBAAuB,EAAE,CACvB,OAAO,EAAE,WAAW,EACpB,aAAa,EAAE,cAAc,KAC1B,IAAI,CAAA;IACT,OAAO,EAAE,MAAM,IAAI,CAAA;CACpB,CAyCA,CAAA;AAED,eAAO,MAAM,sBAAsB,oBAChB,aAAa,CAAC,WAAW,CAAC,KAC1C,CAAC,MAAM,IAAI,CAKb,CAAA;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,WAAW,OAClB,MAAM,oBACQ,aAAa,CAAC,MAAM,CAAC,KACtC,MAAM,CAAC,MAAM,CAAC,IAAI,CAiBjB,CAAA;AAEJ;;;;;;;;;GASG;AACH,eAAO,MAAM,YAAY,OAAQ,MAAM,KAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAUxD,CAAA"}
package/dist/dom/inert.js CHANGED
@@ -39,6 +39,24 @@ const markNotInert = (element) => {
39
39
  inertState.counts.set(element, Number.decrement(count));
40
40
  }
41
41
  };
42
+ const recordCurrentAttribute = (element, attributeName) => {
43
+ const original = inertState.originals.get(element);
44
+ if (original === undefined) {
45
+ return;
46
+ }
47
+ if (attributeName === 'aria-hidden') {
48
+ inertState.originals.set(element, {
49
+ ...original,
50
+ ariaHidden: element.getAttribute('aria-hidden'),
51
+ });
52
+ }
53
+ else {
54
+ inertState.originals.set(element, {
55
+ ...original,
56
+ inert: element.inert,
57
+ });
58
+ }
59
+ };
42
60
  const resolveElements = (selectors) => Array.filterMap(selectors, selector => Result.liftPredicate(document.querySelector(selector), (element) => element instanceof HTMLElement, () => undefined));
43
61
  const ancestorsUpToBody = (element) => Array.unfold(element.parentElement, current => Predicate.isNotNull(current)
44
62
  ? Option.some([
@@ -50,6 +68,61 @@ const inertableSiblings = (parent, allowedElements) => pipe(parent.children, Arr
50
68
  !Array.some(allowedElements, allowed => child.contains(allowed))
51
69
  ? Result.succeed(child)
52
70
  : Result.failVoid));
71
+ const outsideCandidates = (allowedElements) => {
72
+ const candidates = new Set();
73
+ for (const allowedElement of allowedElements) {
74
+ for (const ancestor of ancestorsUpToBody(allowedElement)) {
75
+ for (const sibling of inertableSiblings(ancestor, allowedElements)) {
76
+ candidates.add(sibling);
77
+ }
78
+ }
79
+ }
80
+ return candidates;
81
+ };
82
+ export const makeOutsideIsolation = () => {
83
+ const cleanups = new Map();
84
+ return {
85
+ update: allowedElements => {
86
+ const candidates = outsideCandidates(allowedElements);
87
+ for (const [element, cleanup] of cleanups) {
88
+ if (!candidates.has(element)) {
89
+ cleanup();
90
+ cleanups.delete(element);
91
+ }
92
+ }
93
+ for (const element of candidates) {
94
+ if (!cleanups.has(element)) {
95
+ cleanups.set(element, markInert(element));
96
+ }
97
+ else {
98
+ if (element.getAttribute('aria-hidden') !== 'true') {
99
+ element.setAttribute('aria-hidden', 'true');
100
+ }
101
+ if (!element.inert) {
102
+ element.inert = true;
103
+ }
104
+ }
105
+ }
106
+ },
107
+ contains: element => cleanups.has(element),
108
+ recordAttributeMutation: (element, attributeName) => {
109
+ if (cleanups.has(element)) {
110
+ recordCurrentAttribute(element, attributeName);
111
+ }
112
+ },
113
+ dispose: () => {
114
+ for (const cleanup of cleanups.values()) {
115
+ cleanup();
116
+ }
117
+ cleanups.clear();
118
+ },
119
+ };
120
+ };
121
+ export const isolateOutsideElements = (allowedElements) => {
122
+ const isolation = makeOutsideIsolation();
123
+ isolation.update(allowedElements);
124
+ return isolation.dispose;
125
+ };
53
126
  /**
54
127
  * Marks all DOM elements outside the given selectors as `inert` and
55
128
  * `aria-hidden="true"`. Walks each allowed element up to `document.body`,
@@ -73,8 +146,7 @@ export const inertOthers = (id, allowedSelectors) => Effect.gen(function* () {
73
146
  return;
74
147
  }
75
148
  const allowedElements = resolveElements(allowedSelectors);
76
- const cleanupFunctions = pipe(allowedElements, Array.flatMap(ancestorsUpToBody), Array.flatMap(ancestor => Array.map(inertableSiblings(ancestor, allowedElements), markInert)));
77
- inertState.cleanups.set(id, cleanupFunctions);
149
+ inertState.cleanups.set(id, [isolateOutsideElements(allowedElements)]);
78
150
  });
79
151
  /**
80
152
  * Restores all elements previously marked inert by `inertOthers` for the
@@ -224,12 +224,54 @@ export declare const lift: <Resources extends Record<string, Entry<any, any, Opt
224
224
  readonly toChildModel: (parentModel: ParentModel) => Option.Option<ChildModelOf<Resources>>;
225
225
  readonly toParentMessage: (message: ChildMessageOf<Resources>) => ParentMessage;
226
226
  }) => { readonly [Key in keyof Resources]: Resources[Key] extends Entry<any, any, infer Requirements, infer Value, infer Service, infer OnAcquired extends (...args: ReadonlyArray<any>) => any> ? Entry<ParentModel, ParentMessage, Requirements, Value, Service, (...args: Parameters<OnAcquired>) => ParentMessage> : never; };
227
- type MergeRecords<Records extends ReadonlyArray<unknown>> = Records extends readonly [infer Head, ...infer Rest] ? Head & (Rest extends ReadonlyArray<unknown> ? MergeRecords<Rest> : {}) : {};
227
+ type RuntimeKey<Key> = Key extends string ? Key : Key extends number ? `${Key}` : never;
228
+ type RuntimeEntries<RecordType> = {
229
+ readonly [Key in keyof RecordType as RuntimeKey<Key>]: RecordType[Key];
230
+ };
231
+ type MergeRecords<Records extends ReadonlyArray<unknown>> = Records extends readonly [infer Head, ...infer Rest] ? RuntimeEntries<Head> & (Rest extends ReadonlyArray<unknown> ? MergeRecords<Rest> : {}) : {};
232
+ type AnyResources = Readonly<Record<string, Entry<any, any, any, any, any>>>;
233
+ type AnyResourcesList = readonly [AnyResources, ...ReadonlyArray<AnyResources>];
234
+ type EntriesOfRecord<ResourcesRecord> = ResourcesRecord extends unknown ? ResourcesRecord[keyof ResourcesRecord] : never;
235
+ type ModelOfEntry<AnyEntry> = [AnyEntry] extends [
236
+ Entry<infer Model, any, any, any, any>
237
+ ] ? unknown extends Model ? never : Model : never;
238
+ type MessageOfEntry<AnyEntry> = AnyEntry extends Entry<any, infer Message, any, any, any> ? Message : never;
239
+ type MessageOf<Records extends AnyResourcesList> = MessageOfEntry<EntriesOfRecord<Records[number]>>;
240
+ type ReferenceModel<Records extends ReadonlyArray<AnyResources>> = Records extends readonly [
241
+ infer Head extends AnyResources,
242
+ ...infer Rest extends ReadonlyArray<AnyResources>
243
+ ] ? [ModelOfEntry<EntriesOfRecord<Head>>] extends [never] ? ReferenceModel<Rest> : ModelOfEntry<EntriesOfRecord<Head>> : never;
244
+ type CompatibleResources<Records extends AnyResourcesList> = {
245
+ readonly [Index in keyof Records]: Records[Index] & Readonly<Record<string, Entry<ReferenceModel<Records>, MessageOf<Records>, any, any, any>>>;
246
+ };
228
247
  /**
229
248
  * Combines multiple Managed Resources records into one. Throws on duplicate
230
249
  * keys so a misconfigured aggregate fails loudly at startup rather than
231
250
  * silently overriding.
251
+ *
252
+ * Pass the records directly and the Model and Message are read off them. The
253
+ * Model of the first record is the one every later record is checked against,
254
+ * so a record from another Model universe fails at its own argument position.
255
+ * Message widens to the union across all records.
256
+ *
257
+ * The result keeps each record's keys, each entry's requirements schema and
258
+ * resource service, and the arity of each `onAcquired` handler. Read the
259
+ * service union off the result with {@link ServicesOf}.
260
+ *
261
+ * The curried form remains available for a record that has to be typed before
262
+ * its entries exist, such as a value annotated at a module boundary.
263
+ *
264
+ * @example
265
+ * ```ts
266
+ * const managedResources = ManagedResource.aggregate(
267
+ * playgroundManagedResources,
268
+ * notePlayerManagedResources,
269
+ * )
270
+ * ```
232
271
  */
233
- export declare const aggregate: <Model, Message>() => <Records extends ReadonlyArray<Record<string, Entry<Model, Message, any, any, any>>>>(...records: Records) => MergeRecords<Records>;
272
+ export declare const aggregate: {
273
+ <Model, Message>(): <Records extends ReadonlyArray<Record<string, Entry<Model, Message, any, any, any>>>>(...records: Records) => MergeRecords<Records>;
274
+ <Records extends AnyResourcesList>(...records: CompatibleResources<Records>): MergeRecords<Records>;
275
+ };
234
276
  export {};
235
277
  //# sourceMappingURL=managedResource.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"managedResource.d.ts","sourceRoot":"","sources":["../../src/managedResource/managedResource.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,EAEP,MAAM,EACN,MAAM,EAGN,KAAK,MAAM,EACX,KAAK,KAAK,EACX,MAAM,QAAQ,CAAA;;;;AAEf,oGAAoG;AACpG,qBAAa,oBAAqB,SAAQ,0BAExC;IACA,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CAC1B,CAAC;CAAG;AAEL,QAAA,MAAM,qBAAqB,EAAE,OAAO,MAEnC,CAAA;AAED,KAAK,qBAAqB,GAAG,OAAO,qBAAqB,CAAA;AAEzD,OAAO,CAAC,MAAM,oBAAoB,EAAE,OAAO,MAAM,CAAA;AAEjD,kFAAkF;AAClF,MAAM,WAAW,sBAAsB,CAAC,GAAG,SAAS,MAAM;IACxD,QAAQ,CAAC,CAAC,oBAAoB,CAAC,EAAE,GAAG,CAAA;CACrC;AAED;;;;;;GAMG;AACH,MAAM,WAAW,eAAe,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,OAAO,GAAG,OAAO;IAClE,QAAQ,CAAC,CAAC,qBAAqB,CAAC,EAAE,qBAAqB,CAAA;IACvD,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,oBAAoB,EAAE,OAAO,CAAC,CAAA;IACjE,gBAAgB;IAChB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;CACzC;AAED,sFAAsF;AACtF,eAAO,MAAM,GAAG,GACb,KAAK,QACL,KAAK,CAAC,GAAG,SAAS,MAAM,OAClB,GAAG,KACP,eAAe,CAAC,KAAK,EAAE,sBAAsB,CAAC,GAAG,CAAC,CAsBpD,CAAA;AAEH,2EAA2E;AAC3E,MAAM,MAAM,KAAK,CAAC,CAAC,IAAI,CAAC,SAAS,eAAe,CAAC,MAAM,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAA;AAE1E,sFAAsF;AACtF,MAAM,MAAM,SAAS,CAAC,CAAC,IAAI,CAAC,SAAS,eAAe,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAA;AAE9E,iFAAiF;AACjF,MAAM,MAAM,qBAAqB,CAAC,KAAK,EAAE,OAAO,IAAI;IAClD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;IACnC,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAC,GAAG,CAAC,CAAA;IACvC,QAAQ,CAAC,wBAAwB,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,GAAG,CAAA;IACxD,QAAQ,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,CAAA;IAC3E,QAAQ,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IACrD,QAAQ,CAAC,UAAU,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,OAAO,CAAA;IAC5C,QAAQ,CAAC,UAAU,EAAE,MAAM,OAAO,CAAA;IAClC,QAAQ,CAAC,cAAc,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAA;CACrD,CAAA;AAED,iFAAiF;AACjF,MAAM,MAAM,gBAAgB,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,GAAG,KAAK,IAAI,MAAM,CACrE,MAAM,EACN,qBAAqB,CAAC,KAAK,EAAE,OAAO,CAAC,CACtC,GAAG;IACF,QAAQ,CAAC,yBAAyB,CAAC,EAAE,QAAQ,CAAA;CAC9C,CAAA;AAED,KAAK,UAAU,CAAC,KAAK,EAAE,OAAO,IAAI;IAChC,QAAQ,CAAC,sBAAsB,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAA;CAC3D,CAAA;AAED;;;;GAIG;AACH,KAAK,aAAa,CAAC,YAAY,IAC7B,YAAY,SAAS,MAAM,CAAC,MAAM,CAAC,MAAM,MAAM,CAAC,GAAG,MAAM,GAAG,YAAY,CAAA;AAE1E;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,MAAM,KAAK,CACf,KAAK,EACL,OAAO,EACP,YAAY,EACZ,KAAK,EACL,OAAO,GAAG,OAAO,EACjB,UAAU,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,KAAK,OAAO,GAAG,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,IACtE;IACF,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAA;IAC5C,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAC,KAAK,EAAE,OAAO,CAAC,CAAA;IAClD,QAAQ,CAAC,wBAAwB,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,YAAY,CAAA;IACjE,QAAQ,CAAC,OAAO,EAAE,CAChB,MAAM,EAAE,aAAa,CAAC,YAAY,CAAC,KAChC,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,CAAA;IAC/C,QAAQ,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IACvD,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAA;IAC/B,QAAQ,CAAC,UAAU,EAAE,MAAM,OAAO,CAAA;IAClC,QAAQ,CAAC,cAAc,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAA;CACrD,GAAG,UAAU,CAAC,KAAK,EAAE,OAAO,CAAC,CAAA;AAE9B,uFAAuF;AACvF,MAAM,MAAM,UAAU,CAAC,SAAS,IAAI;KACjC,GAAG,IAAI,MAAM,SAAS,GAAG,SAAS,CAAC,GAAG,CAAC,SAAS;QAC/C,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAC,GAAG,EAAE,MAAM,OAAO,CAAC,CAAA;KACvD,GACG,OAAO,GACP,KAAK;CACV,CAAC,MAAM,SAAS,CAAC,CAAA;AAElB;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,YAAY,CAAC,KAAK,EAAE,OAAO,IAAI,CACzC,kBAAkB,SAAS,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,EAC7C,KAAK,EACL,OAAO,EACP,UAAU,SAAS,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,EAE5C,MAAM,EAAE,kBAAkB,EAC1B,MAAM,EAAE;IACN,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAC,KAAK,EAAE,OAAO,CAAC,CAAA;IAClD,QAAQ,CAAC,wBAAwB,EAAE,CACjC,KAAK,EAAE,KAAK,KACT,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAA;IAC3C,QAAQ,CAAC,OAAO,EAAE,CAChB,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,KAC1D,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,CAAA;IAC/C,QAAQ,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IACvD,QAAQ,CAAC,UAAU,EAAE,UAAU,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,CAAA;IAC7D,QAAQ,CAAC,UAAU,EAAE,MAAM,OAAO,CAAA;IAClC,QAAQ,CAAC,cAAc,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAA;CACrD,KACE,KAAK,CACR,KAAK,EACL,OAAO,EACP,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,EACtC,KAAK,EACL,OAAO,EACP,UAAU,CACX,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwFG;AACH,eAAO,MAAM,IAAI,GACd,KAAK,EAAE,OAAO,QAKd,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,SAClD,CAAC,KAAK,EAAE,YAAY,CAAC,KAAK,EAAE,OAAO,CAAC,KAAK,OAAO,KACtD,OAUF,CAAA;AAEH,KAAK,YAAY,CAAC,SAAS,IACzB,SAAS,CAAC,MAAM,SAAS,CAAC,SAAS,KAAK,CAAC,MAAM,UAAU,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,GAC1E,UAAU,GACV,KAAK,CAAA;AAEX,KAAK,cAAc,CAAC,SAAS,IAC3B,SAAS,CAAC,MAAM,SAAS,CAAC,SAAS,KAAK,CACtC,GAAG,EACH,MAAM,YAAY,EAClB,GAAG,EACH,GAAG,EACH,GAAG,CACJ,GACG,YAAY,GACZ,KAAK,CAAA;AAEX;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,IAAI,GAEb,SAAS,SAAS,MAAM,CACtB,MAAM,EACN,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,CAC9C,aAEU,SAAS,MAErB,WAAW,EAAE,aAAa,UAAU;IACnC,QAAQ,CAAC,YAAY,EAAE,CACrB,WAAW,EAAE,WAAW,KACrB,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,CAAA;IAC3C,QAAQ,CAAC,eAAe,EAAE,CACxB,OAAO,EAAE,cAAc,CAAC,SAAS,CAAC,KAC/B,aAAa,CAAA;CACnB,KAAG,EACF,QAAQ,EAAE,GAAG,IAAI,MAAM,SAAS,GAAG,SAAS,CAAC,GAAG,CAAC,SAAS,KAAK,CAC7D,GAAG,EACH,GAAG,EACH,MAAM,YAAY,EAClB,MAAM,KAAK,EACX,MAAM,OAAO,EACb,MAAM,UAAU,SAAS,CAAC,GAAG,IAAI,EAAE,aAAa,CAAC,GAAG,CAAC,KAAK,GAAG,CAC9D,GACG,KAAK,CACH,WAAW,EACX,aAAa,EACb,YAAY,EACZ,KAAK,EACL,OAAO,EACP,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,UAAU,CAAC,KAAK,aAAa,CACnD,GACD,KAAK,GAkBC,CAAA;AAEd,KAAK,YAAY,CAAC,OAAO,SAAS,aAAa,CAAC,OAAO,CAAC,IACtD,OAAO,SAAS,SAAS,CAAC,MAAM,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,GAChD,IAAI,GAAG,CAAC,IAAI,SAAS,aAAa,CAAC,OAAO,CAAC,GAAG,YAAY,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,GACtE,EAAE,CAAA;AAER;;;;GAIG;AACH,eAAO,MAAM,SAAS,GACnB,KAAK,EAAE,OAAO,QAEb,OAAO,SAAS,aAAa,CAC3B,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CACrD,cAEW,OAAO,KAClB,YAAY,CAAC,OAAO,CAetB,CAAA"}
1
+ {"version":3,"file":"managedResource.d.ts","sourceRoot":"","sources":["../../src/managedResource/managedResource.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { Context, Data, Effect, Option, Record, Ref, } from 'effect';
1
+ import { Array, Context, Data, Effect, Option, Record, Ref, } from 'effect';
2
2
  /** Typed error raised when a command accesses a managed resource that is not currently acquired. */
3
3
  export class ResourceNotAvailable extends Data.TaggedError('ResourceNotAvailable') {
4
4
  }
@@ -144,22 +144,52 @@ Record.map(resources, resource => ({
144
144
  onReleased: () => config.toParentMessage(resource.onReleased()),
145
145
  onAcquireError: (error) => config.toParentMessage(resource.onAcquireError(error)),
146
146
  }));
147
- /**
148
- * Combines multiple Managed Resources records into one. Throws on duplicate
149
- * keys so a misconfigured aggregate fails loudly at startup rather than
150
- * silently overriding.
151
- */
152
- export const aggregate = () => (...records) => {
147
+ const mergeResources = (records) => {
153
148
  const result = {};
154
149
  for (const record of records) {
155
150
  for (const key of Object.keys(record)) {
156
151
  if (Object.hasOwn(result, key)) {
157
152
  throw new Error(`ManagedResource.aggregate: duplicate key "${key}" across records`);
158
153
  }
159
- /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */
160
- result[key] = record[key];
154
+ Object.defineProperty(result, key, {
155
+ configurable: true,
156
+ enumerable: true,
157
+ value: record[key],
158
+ writable: true,
159
+ });
161
160
  }
162
161
  }
163
- /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */
164
162
  return result;
165
163
  };
164
+ /**
165
+ * Combines multiple Managed Resources records into one. Throws on duplicate
166
+ * keys so a misconfigured aggregate fails loudly at startup rather than
167
+ * silently overriding.
168
+ *
169
+ * Pass the records directly and the Model and Message are read off them. The
170
+ * Model of the first record is the one every later record is checked against,
171
+ * so a record from another Model universe fails at its own argument position.
172
+ * Message widens to the union across all records.
173
+ *
174
+ * The result keeps each record's keys, each entry's requirements schema and
175
+ * resource service, and the arity of each `onAcquired` handler. Read the
176
+ * service union off the result with {@link ServicesOf}.
177
+ *
178
+ * The curried form remains available for a record that has to be typed before
179
+ * its entries exist, such as a value annotated at a module boundary.
180
+ *
181
+ * @example
182
+ * ```ts
183
+ * const managedResources = ManagedResource.aggregate(
184
+ * playgroundManagedResources,
185
+ * notePlayerManagedResources,
186
+ * )
187
+ * ```
188
+ */
189
+ export const aggregate = ((...records) => {
190
+ return Array.match(records, {
191
+ onEmpty: () => (...curriedRecords) => mergeResources(curriedRecords),
192
+ onNonEmpty: mergeResources,
193
+ });
194
+ /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */
195
+ });
@@ -7,10 +7,13 @@ export type MountEvents = Readonly<{
7
7
  starts: ReadonlyArray<MountRecord>;
8
8
  ends: ReadonlyArray<MountRecord>;
9
9
  }>;
10
- /** What the DevTools history keeps about a Command: its name and arguments. */
10
+ /** A Command invocation and its runtime-local identity for DevTools history. */
11
11
  export type RecordableCommand = Readonly<{
12
- name: string;
13
- args?: Record<string, unknown>;
12
+ id: number;
13
+ command: Readonly<{
14
+ name: string;
15
+ args?: Record<string, unknown>;
16
+ }>;
14
17
  }>;
15
18
  /** The replay bridge the render side hands the store when it is installed. */
16
19
  export type DevToolsRenderBridge = Readonly<{
@@ -27,6 +30,7 @@ export type DevToolsRenderBridge = Readonly<{
27
30
  * helpers no-op until the store exists.
28
31
  */
29
32
  export type DevToolsIntegration<Model, Message> = Readonly<{
33
+ isRecordingCommands: boolean;
30
34
  mountTracker: typeof MountTracker.Service;
31
35
  mountRuntime: typeof MountRuntime.Service;
32
36
  drainMountEvents: () => MountEvents;
@@ -37,6 +41,7 @@ export type DevToolsIntegration<Model, Message> = Readonly<{
37
41
  resumeDevTools: Effect.Effect<void>;
38
42
  recordInit: (initModel: Model, initCommands: ReadonlyArray<RecordableCommand>) => Effect.Effect<void>;
39
43
  recordMessage: (message: Message, currentModel: Model, nextModel: Model, commands: ReadonlyArray<RecordableCommand>) => void;
44
+ recordCommandResult: (id: number, message: Message) => void;
40
45
  attachRenderedMounts: () => void;
41
46
  }>;
42
47
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"devToolsIntegration.d.ts","sourceRoot":"","sources":["../../src/runtime/devToolsIntegration.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,MAAM,EAIN,KAAK,KAAK,EAGX,MAAM,QAAQ,CAAA;AAEf,OAAO,EAGL,KAAK,WAAW,EAEjB,MAAM,sBAAsB,CAAA;AAE7B,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,KAAK,SAAS,EAEf,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EACL,KAAK,cAAc,EAKpB,MAAM,qBAAqB,CAAA;AAE5B,+DAA+D;AAC/D,MAAM,MAAM,WAAW,GAAG,QAAQ,CAAC;IACjC,MAAM,EAAE,aAAa,CAAC,WAAW,CAAC,CAAA;IAClC,IAAI,EAAE,aAAa,CAAC,WAAW,CAAC,CAAA;CACjC,CAAC,CAAA;AAEF,+EAA+E;AAC/E,MAAM,MAAM,iBAAiB,GAAG,QAAQ,CAAC;IACvC,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAC/B,CAAC,CAAA;AAEF,8EAA8E;AAC9E,MAAM,MAAM,oBAAoB,GAAG,QAAQ,CAAC;IAC1C,YAAY,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IACrD,iBAAiB,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;CACvC,CAAC,CAAA;AAEF;;;;;;;;GAQG;AACH,MAAM,MAAM,mBAAmB,CAAC,KAAK,EAAE,OAAO,IAAI,QAAQ,CAAC;IACzD,YAAY,EAAE,OAAO,YAAY,CAAC,OAAO,CAAA;IACzC,YAAY,EAAE,OAAO,YAAY,CAAC,OAAO,CAAA;IACzC,gBAAgB,EAAE,MAAM,WAAW,CAAA;IACnC,aAAa,EAAE,MAAM,SAAS,CAAA;IAC9B,YAAY,EAAE,CAAC,aAAa,EAAE,SAAS,KAAK,IAAI,CAAA;IAChD,WAAW,EAAE,MAAM,OAAO,CAAA;IAC1B,oBAAoB,EAAE,CACpB,MAAM,EAAE,oBAAoB,KACzB,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,CAAA;IAC5C,cAAc,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IACnC,UAAU,EAAE,CACV,SAAS,EAAE,KAAK,EAChB,YAAY,EAAE,aAAa,CAAC,iBAAiB,CAAC,KAC3C,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IACxB,aAAa,EAAE,CACb,OAAO,EAAE,OAAO,EAChB,YAAY,EAAE,KAAK,EACnB,SAAS,EAAE,KAAK,EAChB,QAAQ,EAAE,aAAa,CAAC,iBAAiB,CAAC,KACvC,IAAI,CAAA;IACT,oBAAoB,EAAE,MAAM,IAAI,CAAA;CACjC,CAAC,CAAA;AAOF;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,GAAI,KAAK,EAAE,OAAO,iEAKnD,QAAQ,CAAC;IACV,QAAQ,EAAE,cAAc,GAAG,SAAS,CAAA;IACpC,MAAM,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,KAAK,QAAQ,CAAC;QAAE,KAAK,EAAE,KAAK,CAAA;KAAE,CAAC,CAAA;IACtE,gBAAgB,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,KAAK,CAAA;IACzC,oBAAoB,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;CAChE,CAAC,KAAG,MAAM,CAAC,MAAM,CAAC,mBAAmB,CAAC,KAAK,EAAE,OAAO,CAAC,CAuOlD,CAAA"}
1
+ {"version":3,"file":"devToolsIntegration.d.ts","sourceRoot":"","sources":["../../src/runtime/devToolsIntegration.ts"],"names":[],"mappings":"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"}