@fusion.dev/helix-core 0.162.0 → 0.163.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.
@@ -5501,6 +5501,117 @@
5501
5501
  }
5502
5502
  ]
5503
5503
  },
5504
+ {
5505
+ "kind": "javascript-module",
5506
+ "path": "src/controllers/upgrade-controller/upgrade-controller.ts",
5507
+ "declarations": [
5508
+ {
5509
+ "kind": "class",
5510
+ "description": "Calls back when a child that had not upgraded is defined.\n\n**A host that knows its children by their class does not know a child that\nhas not upgraded.** `instanceof` is false for it and a marker its class sets,\nsuch as `isNotification`, is missing. An upgrade changes no child list and no\nslot assignment, so neither a `MutationObserver` nor `slotchange` reports it,\nand the host keeps the answer it read before. Measured on the notification\nfeed: a row added while its definition was still loading was drawn nowhere,\nand the feed showed its empty line over it. A listbox did not select an\noption its `default-value` named, and a tree gave a late item no level.\n\nThis happens wherever a child's definition loads after the host's: a page\nthat adds children before its scripts finish, or a bundle that defines the\nhost first.\n\nIt looks when the host connects and at each child added after, and waits on\n`customElements.whenDefined` once for each name. `define` upgrades the\nelements in the document before that promise resolves, so the children have\ntheir class by the time the callback runs. The callback is the host's own\nresync, such as its `slotchange` handler, and is `requestUpdate` unless given\nsomething else to do. Watches from connection to disconnection.",
5511
+ "name": "UpgradeController",
5512
+ "members": [
5513
+ {
5514
+ "kind": "field",
5515
+ "name": "watcher",
5516
+ "type": {
5517
+ "text": "MutationObserver | undefined"
5518
+ },
5519
+ "privacy": "private",
5520
+ "default": "undefined"
5521
+ },
5522
+ {
5523
+ "kind": "field",
5524
+ "name": "waiting",
5525
+ "privacy": "private",
5526
+ "readonly": true,
5527
+ "default": "new Set<string>()",
5528
+ "description": "The names already waited on, so each is waited on once."
5529
+ },
5530
+ {
5531
+ "kind": "field",
5532
+ "name": "subtree",
5533
+ "type": {
5534
+ "text": "boolean"
5535
+ },
5536
+ "privacy": "private",
5537
+ "readonly": true
5538
+ },
5539
+ {
5540
+ "kind": "method",
5541
+ "name": "hostConnected",
5542
+ "return": {
5543
+ "type": {
5544
+ "text": "void"
5545
+ }
5546
+ }
5547
+ },
5548
+ {
5549
+ "kind": "method",
5550
+ "name": "hostDisconnected",
5551
+ "return": {
5552
+ "type": {
5553
+ "text": "void"
5554
+ }
5555
+ }
5556
+ },
5557
+ {
5558
+ "kind": "method",
5559
+ "name": "look",
5560
+ "privacy": "private",
5561
+ "return": {
5562
+ "type": {
5563
+ "text": "void"
5564
+ }
5565
+ },
5566
+ "parameters": [
5567
+ {
5568
+ "name": "element",
5569
+ "type": {
5570
+ "text": "Element"
5571
+ }
5572
+ },
5573
+ {
5574
+ "name": "added",
5575
+ "type": {
5576
+ "text": "boolean"
5577
+ }
5578
+ }
5579
+ ],
5580
+ "description": "Waits on `element`, where it was added, and on what it holds where the subtree counts."
5581
+ },
5582
+ {
5583
+ "kind": "method",
5584
+ "name": "wait",
5585
+ "privacy": "private",
5586
+ "return": {
5587
+ "type": {
5588
+ "text": "void"
5589
+ }
5590
+ },
5591
+ "parameters": [
5592
+ {
5593
+ "name": "element",
5594
+ "type": {
5595
+ "text": "Element"
5596
+ }
5597
+ }
5598
+ ]
5599
+ }
5600
+ ],
5601
+ "helix": {}
5602
+ }
5603
+ ],
5604
+ "exports": [
5605
+ {
5606
+ "kind": "js",
5607
+ "name": "UpgradeController",
5608
+ "declaration": {
5609
+ "name": "UpgradeController",
5610
+ "module": "src/controllers/upgrade-controller/upgrade-controller.ts"
5611
+ }
5612
+ }
5613
+ ]
5614
+ },
5504
5615
  {
5505
5616
  "kind": "javascript-module",
5506
5617
  "path": "src/controllers/virtualize-controller/heights.ts",
@@ -13061,6 +13172,22 @@
13061
13172
  "module": "./controllers/token-color-controller/token-color-controller.js"
13062
13173
  }
13063
13174
  },
13175
+ {
13176
+ "kind": "js",
13177
+ "name": "UpgradeController",
13178
+ "declaration": {
13179
+ "name": "UpgradeController",
13180
+ "module": "./controllers/upgrade-controller/upgrade-controller.js"
13181
+ }
13182
+ },
13183
+ {
13184
+ "kind": "js",
13185
+ "name": "UpgradeOptions",
13186
+ "declaration": {
13187
+ "name": "UpgradeOptions",
13188
+ "module": "./controllers/upgrade-controller/upgrade-controller.js"
13189
+ }
13190
+ },
13064
13191
  {
13065
13192
  "kind": "js",
13066
13193
  "name": "Rendered",
@@ -33016,7 +33143,7 @@
33016
33143
  "type": {
33017
33144
  "text": "string"
33018
33145
  },
33019
- "default": "'0.162.0'",
33146
+ "default": "'0.163.0'",
33020
33147
  "description": "The version of the package this file ships in.\n\n**Written by `fusion/scripts/version.mjs`** wherever it writes the package's\n`package.json`, and stamped back into the repository beside it after a\nrelease, so the two never disagree; a spec beside this holds them to it.\nNothing else in the running code knows which release it is."
33021
33148
  }
33022
33149
  ],
@@ -33576,6 +33703,6 @@
33576
33703
  ],
33577
33704
  "helix": {
33578
33705
  "package": "@fusion.dev/helix-core",
33579
- "version": "0.162.0"
33706
+ "version": "0.163.0"
33580
33707
  }
33581
33708
  }
@@ -0,0 +1,47 @@
1
+ import type { ReactiveController, ReactiveControllerHost } from 'lit';
2
+ /** Where an `UpgradeController` looks for children that have not upgraded. */
3
+ export interface UpgradeOptions {
4
+ /**
5
+ * Whether to look through every descendant. Off, it looks at the host's own
6
+ * children. Turn it on for a host that finds its items inside wrappers, as a
7
+ * radio group does.
8
+ */
9
+ subtree?: boolean;
10
+ }
11
+ /**
12
+ * Calls back when a child that had not upgraded is defined.
13
+ *
14
+ * **A host that knows its children by their class does not know a child that
15
+ * has not upgraded.** `instanceof` is false for it and a marker its class sets,
16
+ * such as `isNotification`, is missing. An upgrade changes no child list and no
17
+ * slot assignment, so neither a `MutationObserver` nor `slotchange` reports it,
18
+ * and the host keeps the answer it read before. Measured on the notification
19
+ * feed: a row added while its definition was still loading was drawn nowhere,
20
+ * and the feed showed its empty line over it. A listbox did not select an
21
+ * option its `default-value` named, and a tree gave a late item no level.
22
+ *
23
+ * This happens wherever a child's definition loads after the host's: a page
24
+ * that adds children before its scripts finish, or a bundle that defines the
25
+ * host first.
26
+ *
27
+ * It looks when the host connects and at each child added after, and waits on
28
+ * `customElements.whenDefined` once for each name. `define` upgrades the
29
+ * elements in the document before that promise resolves, so the children have
30
+ * their class by the time the callback runs. The callback is the host's own
31
+ * resync, such as its `slotchange` handler, and is `requestUpdate` unless given
32
+ * something else to do. Watches from connection to disconnection.
33
+ */
34
+ export declare class UpgradeController implements ReactiveController {
35
+ private readonly host;
36
+ private readonly upgraded;
37
+ private watcher;
38
+ /** The names already waited on, so each is waited on once. */
39
+ private readonly waiting;
40
+ private readonly subtree;
41
+ constructor(host: ReactiveControllerHost & Element, upgraded?: () => void, options?: UpgradeOptions);
42
+ hostConnected(): void;
43
+ hostDisconnected(): void;
44
+ /** Waits on `element`, where it was added, and on what it holds where the subtree counts. */
45
+ private look;
46
+ private wait;
47
+ }
@@ -0,0 +1,53 @@
1
+ export class UpgradeController {
2
+ constructor(host, upgraded = () => host.requestUpdate(), options = {}) {
3
+ this.host = host;
4
+ this.upgraded = upgraded;
5
+ this.watcher = undefined;
6
+ this.waiting = new Set();
7
+ this.subtree = options.subtree ?? false;
8
+ host.addController(this);
9
+ }
10
+ hostConnected() {
11
+ if (typeof MutationObserver === 'undefined' || typeof customElements === 'undefined') {
12
+ return;
13
+ }
14
+ this.look(this.host, false);
15
+ this.watcher ??= new MutationObserver((records) => {
16
+ for (const record of records) {
17
+ for (const node of record.addedNodes) {
18
+ if (node.nodeType === Node.ELEMENT_NODE) {
19
+ this.look(node, true);
20
+ }
21
+ }
22
+ }
23
+ });
24
+ this.watcher.observe(this.host, { childList: true, subtree: this.subtree });
25
+ }
26
+ hostDisconnected() {
27
+ this.watcher?.disconnect();
28
+ }
29
+ look(element, added) {
30
+ if (added) {
31
+ this.wait(element);
32
+ }
33
+ const inside = this.subtree
34
+ ? element.querySelectorAll('*')
35
+ : element === this.host
36
+ ? element.children
37
+ : [];
38
+ for (const child of inside) {
39
+ this.wait(child);
40
+ }
41
+ }
42
+ wait(element) {
43
+ const name = element.localName;
44
+ if (!name.includes('-') || this.waiting.has(name) || customElements.get(name) !== undefined) {
45
+ return;
46
+ }
47
+ this.waiting.add(name);
48
+ void customElements.whenDefined(name).then(() => {
49
+ this.waiting.delete(name);
50
+ this.upgraded();
51
+ });
52
+ }
53
+ }
package/dist/index.d.ts CHANGED
@@ -31,6 +31,7 @@ export { SourceController, type SourceHost, } from './controllers/source-control
31
31
  export { drawStatus, type SayOptions, StatusController, } from './controllers/status-controller/status-controller.js';
32
32
  export { SwipeController, type SwipeOptions, } from './controllers/swipe-controller/swipe-controller.js';
33
33
  export { type TokenColor, TokenColorController, } from './controllers/token-color-controller/token-color-controller.js';
34
+ export { UpgradeController, type UpgradeOptions, } from './controllers/upgrade-controller/upgrade-controller.js';
34
35
  export { type Rendered, VirtualizeController, type VirtualizeOptions, type Window as VirtualizeWindow, } from './controllers/virtualize-controller/virtualize-controller.js';
35
36
  export { eventsForTag, registerElementEvents } from './events/element-events.js';
36
37
  export { type ActivateDetail, type AuraFallbackDetail, type BandDetail, type CanvasView, type CaretDetail, type ChangeDetail, type CompleteDetail, type ConnectDetail, type ConsoleDetail, type CopyDetail, type CreateDetail, type DismissDetail, type FacetDetail, type FilterDetail, type GraphFilterDetail, type GraphLayoutDetail, type GraphPartChangeDetail, type GraphSignalDetail, HelixActionEvent, HelixActivateEvent, HelixAuraFallbackEvent, HelixBandEvent, HelixBeforeActivateEvent, HelixBeforeChangeEvent, HelixBeforeCloseEvent, HelixBeforeCollapseEvent, HelixBeforeEditEvent, HelixBeforeMoveEvent, HelixBeforeOpenEvent, HelixBeforePanelResizeEvent, HelixBeforePinEvent, HelixBeforeReconnectEvent, HelixBeforeRelabelEvent, HelixBeforeReorderEvent, HelixBeforeResizeEvent, HelixBeforeSplitEvent, HelixBeforeToggleEvent, HelixCanvasEditEvent, HelixCanvasPanEvent, HelixCanvasViewEvent, HelixCanvasZoomEvent, HelixCaretEvent, HelixClearEvent, HelixCollapseEvent, HelixCompleteEvent, HelixConnectEvent, HelixConsoleEvent, HelixCopyErrorEvent, HelixCopyEvent, HelixCreateEvent, HelixDismissEvent, HelixEditEvent, HelixEndEvent, HelixExpandEvent, HelixFacetEvent, HelixFilterEvent, HelixFilteredEvent, HelixGraphFilterEvent, HelixGraphLayoutEvent, HelixGraphPanEvent, HelixGraphPartChangeEvent, HelixGraphReadyEvent, HelixGraphSignalEvent, HelixGraphZoomEvent, HelixHistoryEvent, HelixLoadEvent, HelixLoadMoreEvent, HelixMapClusterEvent, HelixMapPanEvent, HelixMapPartChangeEvent, HelixMapReadyEvent, HelixMapRotateEvent, HelixMapTiltEvent, HelixMapZoomEvent, HelixMoveEvent, HelixNavigateEvent, HelixNextEvent, HelixPanelResizeEvent, HelixPinEvent, HelixPressEvent, HelixPreviewEvent, HelixPreviousEvent, HelixRangeChangeEvent, HelixReadEvent, HelixReadingChangeEvent, HelixReadingPressEvent, HelixReconnectEvent, HelixRejectEvent, HelixRelabelEvent, HelixRemoveEvent, HelixReorderEvent, HelixReorderedEvent, HelixResizedEvent, HelixResizeEvent, HelixSampleEndEvent, HelixSampleStartEvent, HelixScrolledEvent, HelixSelectEvent, HelixSelectedEvent, HelixSendEvent, HelixShortcutEvent, HelixSortEvent, HelixSortedEvent, HelixSplitEvent, HelixStrandsFallbackEvent, HelixToggleEvent, HelixTourAskEvent, HelixTourStatusEvent, HelixTypingEvent, type MapClusterDetail, type MapPanDetail, type MapPartChangeDetail, type MapRotateDetail, type MapTiltDetail, type MapZoomDetail, type MoveDetail, type NavigateDetail, type OpenDetail, type PressDetail, type PressPointerType, type RangeDetail, type ReadDetail, type ReadingDetail, type ReconnectDetail, type Refusal, type RefusedFile, type RejectDetail, type RelabelDetail, type RemoveDetail, type ReorderDetail, type ResizeDetail, type ScrolledDetail, type SelectDetail, type SendDetail, type ShortcutDetail, type SkipDetail, type SortDetail, type StrandsFallbackDetail, type ToggleDetail, type TourStatusDetail, type TypingDetail, type ViewportPanDetail, type ViewportZoomDetail, } from './events/events.js';
package/dist/index.js CHANGED
@@ -31,6 +31,7 @@ export { SourceController, } from './controllers/source-controller/source-contro
31
31
  export { drawStatus, StatusController, } from './controllers/status-controller/status-controller.js';
32
32
  export { SwipeController, } from './controllers/swipe-controller/swipe-controller.js';
33
33
  export { TokenColorController, } from './controllers/token-color-controller/token-color-controller.js';
34
+ export { UpgradeController, } from './controllers/upgrade-controller/upgrade-controller.js';
34
35
  export { VirtualizeController, } from './controllers/virtualize-controller/virtualize-controller.js';
35
36
  export { eventsForTag, registerElementEvents } from './events/element-events.js';
36
37
  export { HelixActionEvent, HelixActivateEvent, HelixAuraFallbackEvent, HelixBandEvent, HelixBeforeActivateEvent, HelixBeforeChangeEvent, HelixBeforeCloseEvent, HelixBeforeCollapseEvent, HelixBeforeEditEvent, HelixBeforeMoveEvent, HelixBeforeOpenEvent, HelixBeforePanelResizeEvent, HelixBeforePinEvent, HelixBeforeReconnectEvent, HelixBeforeRelabelEvent, HelixBeforeReorderEvent, HelixBeforeResizeEvent, HelixBeforeSplitEvent, HelixBeforeToggleEvent, HelixCanvasEditEvent, HelixCanvasPanEvent, HelixCanvasViewEvent, HelixCanvasZoomEvent, HelixCaretEvent, HelixClearEvent, HelixCollapseEvent, HelixCompleteEvent, HelixConnectEvent, HelixConsoleEvent, HelixCopyErrorEvent, HelixCopyEvent, HelixCreateEvent, HelixDismissEvent, HelixEditEvent, HelixEndEvent, HelixExpandEvent, HelixFacetEvent, HelixFilterEvent, HelixFilteredEvent, HelixGraphFilterEvent, HelixGraphLayoutEvent, HelixGraphPanEvent, HelixGraphPartChangeEvent, HelixGraphReadyEvent, HelixGraphSignalEvent, HelixGraphZoomEvent, HelixHistoryEvent, HelixLoadEvent, HelixLoadMoreEvent, HelixMapClusterEvent, HelixMapPanEvent, HelixMapPartChangeEvent, HelixMapReadyEvent, HelixMapRotateEvent, HelixMapTiltEvent, HelixMapZoomEvent, HelixMoveEvent, HelixNavigateEvent, HelixNextEvent, HelixPanelResizeEvent, HelixPinEvent, HelixPressEvent, HelixPreviewEvent, HelixPreviousEvent, HelixRangeChangeEvent, HelixReadEvent, HelixReadingChangeEvent, HelixReadingPressEvent, HelixReconnectEvent, HelixRejectEvent, HelixRelabelEvent, HelixRemoveEvent, HelixReorderEvent, HelixReorderedEvent, HelixResizedEvent, HelixResizeEvent, HelixSampleEndEvent, HelixSampleStartEvent, HelixScrolledEvent, HelixSelectEvent, HelixSelectedEvent, HelixSendEvent, HelixShortcutEvent, HelixSortEvent, HelixSortedEvent, HelixSplitEvent, HelixStrandsFallbackEvent, HelixToggleEvent, HelixTourAskEvent, HelixTourStatusEvent, HelixTypingEvent, } from './events/events.js';
package/dist/version.d.ts CHANGED
@@ -6,4 +6,4 @@
6
6
  * release, so the two never disagree; a spec beside this holds them to it.
7
7
  * Nothing else in the running code knows which release it is.
8
8
  */
9
- export declare const VERSION = "0.162.0";
9
+ export declare const VERSION = "0.163.0";
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const VERSION = '0.162.0';
1
+ export const VERSION = '0.163.0';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@fusion.dev/helix-core",
3
3
  "description": "Helix element primitives: base classes, mixins, decorators, utilities.",
4
- "version": "0.162.0",
4
+ "version": "0.163.0",
5
5
  "license": "MIT",
6
6
  "author": "Ross Sheppard <ross.sheppard@fusion.dev>",
7
7
  "repository": {
@@ -56,11 +56,11 @@
56
56
  "bugs": "https://github.com/project-fusion/fusion/issues",
57
57
  "dependencies": {
58
58
  "@floating-ui/dom": "^1.8.0",
59
- "@fusion.dev/helix-icons": "0.162.0"
59
+ "@fusion.dev/helix-icons": "0.163.0"
60
60
  },
61
61
  "devDependencies": {
62
- "@fusion.dev/helix-cem": "0.162.0",
63
- "@fusion.dev/helix-testing": "0.162.0",
62
+ "@fusion.dev/helix-cem": "0.163.0",
63
+ "@fusion.dev/helix-testing": "0.163.0",
64
64
  "@lit-labs/ssr": "^4.1.0",
65
65
  "lit": "^3.2.1"
66
66
  },