@gtkx/navigation 2.0.0-beta.11 → 2.0.0-beta.13

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 (121) hide show
  1. package/README.md +3 -3
  2. package/dist/drawer/create-drawer-navigator.d.ts +3 -1
  3. package/dist/drawer/create-drawer-navigator.d.ts.map +1 -1
  4. package/dist/drawer/create-drawer-navigator.js +10 -10
  5. package/dist/drawer/create-drawer-navigator.js.map +1 -1
  6. package/dist/drawer/drawer-item-list.d.ts.map +1 -1
  7. package/dist/drawer/drawer-item-list.js +3 -2
  8. package/dist/drawer/drawer-item-list.js.map +1 -1
  9. package/dist/drawer/drawer-router.d.ts.map +1 -1
  10. package/dist/drawer/drawer-router.js.map +1 -1
  11. package/dist/drawer/drawer-status.d.ts.map +1 -1
  12. package/dist/drawer/drawer-view.d.ts.map +1 -1
  13. package/dist/drawer/drawer-view.js +6 -6
  14. package/dist/drawer/drawer-view.js.map +1 -1
  15. package/dist/drawer/types.d.ts +2 -0
  16. package/dist/drawer/types.d.ts.map +1 -1
  17. package/dist/drawer/types.js.map +1 -1
  18. package/dist/index.d.ts +6 -1
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +5 -1
  21. package/dist/index.js.map +1 -1
  22. package/dist/shared/header-bar.d.ts.map +1 -1
  23. package/dist/shared/header-bar.js +2 -2
  24. package/dist/shared/header-bar.js.map +1 -1
  25. package/dist/shared/routes.d.ts.map +1 -1
  26. package/dist/shared/scene-page.d.ts +3 -1
  27. package/dist/shared/scene-page.d.ts.map +1 -1
  28. package/dist/shared/scene-page.js +4 -7
  29. package/dist/shared/scene-page.js.map +1 -1
  30. package/dist/shared/use-has-loaded.d.ts +3 -0
  31. package/dist/shared/use-has-loaded.d.ts.map +1 -0
  32. package/dist/shared/use-has-loaded.js +10 -0
  33. package/dist/shared/use-has-loaded.js.map +1 -0
  34. package/dist/shared/use-pop-to-top-on-blur.d.ts.map +1 -1
  35. package/dist/split-view/create-split-view-navigator.d.ts +7 -2
  36. package/dist/split-view/create-split-view-navigator.d.ts.map +1 -1
  37. package/dist/split-view/create-split-view-navigator.js +2 -6
  38. package/dist/split-view/create-split-view-navigator.js.map +1 -1
  39. package/dist/split-view/split-view-collapsed.d.ts +11 -0
  40. package/dist/split-view/split-view-collapsed.d.ts.map +1 -0
  41. package/dist/split-view/split-view-collapsed.js +17 -0
  42. package/dist/split-view/split-view-collapsed.js.map +1 -0
  43. package/dist/split-view/split-view.d.ts.map +1 -1
  44. package/dist/split-view/split-view.js +41 -20
  45. package/dist/split-view/split-view.js.map +1 -1
  46. package/dist/split-view/types.d.ts +9 -2
  47. package/dist/split-view/types.d.ts.map +1 -1
  48. package/dist/split-view/types.js.map +1 -1
  49. package/dist/stack/create-stack-navigator.d.ts +3 -1
  50. package/dist/stack/create-stack-navigator.d.ts.map +1 -1
  51. package/dist/stack/create-stack-navigator.js +0 -1
  52. package/dist/stack/create-stack-navigator.js.map +1 -1
  53. package/dist/stack/stack-pages.d.ts.map +1 -1
  54. package/dist/stack/stack-pages.js +3 -5
  55. package/dist/stack/stack-pages.js.map +1 -1
  56. package/dist/stack/stack-view.d.ts.map +1 -1
  57. package/dist/stack/stack-view.js +6 -14
  58. package/dist/stack/stack-view.js.map +1 -1
  59. package/dist/stack/sync-navigation-stack.d.ts.map +1 -1
  60. package/dist/stack/types.d.ts.map +1 -1
  61. package/dist/stack/types.js.map +1 -1
  62. package/dist/tab-view/create-tab-view-navigator.d.ts +32 -0
  63. package/dist/tab-view/create-tab-view-navigator.d.ts.map +1 -0
  64. package/dist/tab-view/create-tab-view-navigator.js +21 -0
  65. package/dist/tab-view/create-tab-view-navigator.js.map +1 -0
  66. package/dist/tab-view/page-registry.d.ts +34 -0
  67. package/dist/tab-view/page-registry.d.ts.map +1 -0
  68. package/dist/tab-view/page-registry.js +70 -0
  69. package/dist/tab-view/page-registry.js.map +1 -0
  70. package/dist/tab-view/tab-view-host.d.ts +25 -0
  71. package/dist/tab-view/tab-view-host.d.ts.map +1 -0
  72. package/dist/tab-view/tab-view-host.js +284 -0
  73. package/dist/tab-view/tab-view-host.js.map +1 -0
  74. package/dist/tab-view/tab-view-router.d.ts +34 -0
  75. package/dist/tab-view/tab-view-router.d.ts.map +1 -0
  76. package/dist/tab-view/tab-view-router.js +359 -0
  77. package/dist/tab-view/tab-view-router.js.map +1 -0
  78. package/dist/tab-view/types.d.ts +240 -0
  79. package/dist/tab-view/types.d.ts.map +1 -0
  80. package/dist/tab-view/types.js +2 -0
  81. package/dist/tab-view/types.js.map +1 -0
  82. package/dist/tabs/create-tab-navigator.d.ts +3 -1
  83. package/dist/tabs/create-tab-navigator.d.ts.map +1 -1
  84. package/dist/tabs/create-tab-navigator.js +0 -1
  85. package/dist/tabs/create-tab-navigator.js.map +1 -1
  86. package/dist/tabs/tab-view.d.ts.map +1 -1
  87. package/dist/tabs/tab-view.js +5 -7
  88. package/dist/tabs/tab-view.js.map +1 -1
  89. package/dist/tabs/types.d.ts +2 -0
  90. package/dist/tabs/types.d.ts.map +1 -1
  91. package/dist/tabs/types.js.map +1 -1
  92. package/dist/theme.d.ts.map +1 -1
  93. package/dist/theme.js +2 -2
  94. package/dist/theme.js.map +1 -1
  95. package/package.json +9 -19
  96. package/src/drawer/create-drawer-navigator.tsx +23 -11
  97. package/src/drawer/drawer-item-list.tsx +16 -12
  98. package/src/drawer/drawer-router.ts +4 -2
  99. package/src/drawer/drawer-view.tsx +18 -18
  100. package/src/drawer/types.ts +6 -3
  101. package/src/index.ts +31 -5
  102. package/src/shared/header-bar.tsx +2 -2
  103. package/src/shared/scene-page.tsx +7 -8
  104. package/src/shared/use-has-loaded.ts +13 -0
  105. package/src/split-view/create-split-view-navigator.tsx +16 -1
  106. package/src/split-view/split-view-collapsed.ts +21 -0
  107. package/src/split-view/split-view.tsx +102 -49
  108. package/src/split-view/types.ts +13 -5
  109. package/src/stack/create-stack-navigator.tsx +11 -1
  110. package/src/stack/stack-pages.ts +14 -12
  111. package/src/stack/stack-view.tsx +10 -16
  112. package/src/stack/types.ts +4 -3
  113. package/src/tab-view/create-tab-view-navigator.tsx +122 -0
  114. package/src/tab-view/page-registry.ts +139 -0
  115. package/src/tab-view/tab-view-host.tsx +474 -0
  116. package/src/tab-view/tab-view-router.ts +528 -0
  117. package/src/tab-view/types.ts +291 -0
  118. package/src/tabs/create-tab-navigator.tsx +11 -1
  119. package/src/tabs/tab-view.tsx +28 -22
  120. package/src/tabs/types.ts +6 -3
  121. package/src/theme.ts +2 -3
@@ -70,7 +70,17 @@ function createStackNavigator<
70
70
  const ParamList extends ParamListBase,
71
71
  const NavigatorID extends string | undefined = string | undefined,
72
72
  const TypeBag extends NavigatorTypeBagBase = StackTypeBag<ParamList, NavigatorID>,
73
- const Config extends StaticConfig<TypeBag> | undefined = undefined,
73
+ >(): TypedNavigator<TypeBag, undefined>;
74
+ /** Creates a stack navigator rendered with `AdwNavigationView`: pushes and pops animate like native Adwaita pages. */
75
+ function createStackNavigator<
76
+ const ParamList extends ParamListBase,
77
+ const NavigatorID extends string | undefined = string | undefined,
78
+ const TypeBag extends NavigatorTypeBagBase = StackTypeBag<ParamList, NavigatorID>,
79
+ const Config extends StaticConfig<TypeBag> = StaticConfig<TypeBag>,
80
+ >(config: Config): TypedNavigator<TypeBag, Config>;
81
+ function createStackNavigator<
82
+ const TypeBag extends NavigatorTypeBagBase,
83
+ const Config extends StaticConfig<TypeBag> | undefined,
74
84
  >(config?: Config): TypedNavigator<TypeBag, Config> {
75
85
  return createNavigatorFactory(StackNavigator)(config) as TypedNavigator<TypeBag, Config>;
76
86
  }
@@ -100,27 +100,29 @@ const useStackPages = (
100
100
  ): StackPages => {
101
101
  const [tracking, setTracking] = useState<PageTracking>(() => initialTracking(state, descriptors, offset));
102
102
 
103
- if (!hasSameMembers(tracking.order, neededKeys(state, tracking.closing, offset)) ||
103
+ if (
104
+ !hasSameMembers(tracking.order, neededKeys(state, tracking.closing, offset)) ||
104
105
  tracking.focusedKey !== getFocusedKey(state, offset) ||
105
- tracking.descriptors !== descriptors) {
106
+ tracking.descriptors !== descriptors
107
+ ) {
106
108
  setTracking(advance(tracking, state, descriptors, offset));
107
109
  }
108
110
 
109
111
  const release = useCallback((key: string) => {
110
- setTracking((current) => (current.closing[key] === undefined
111
- ? current
112
- : {
113
- ...current,
114
- order: current.order.filter((entry) => entry !== key),
115
- closing: withoutKeys(current.closing, [key]),
116
- }));
112
+ setTracking((current) =>
113
+ current.closing[key] === undefined
114
+ ? current
115
+ : {
116
+ ...current,
117
+ order: current.order.filter((entry) => entry !== key),
118
+ closing: withoutKeys(current.closing, [key]),
119
+ },
120
+ );
117
121
  }, []);
118
122
 
119
123
  const sources = { state, descriptors, closing: tracking.closing };
120
124
 
121
- const pages = tracking.order
122
- .map((key) => resolvePage(key, sources, describe))
123
- .filter((page) => page !== undefined);
125
+ const pages = tracking.order.map((key) => resolvePage(key, sources, describe)).filter((page) => page !== undefined);
124
126
 
125
127
  return { pages, release };
126
128
  };
@@ -2,6 +2,7 @@ import type * as Adw from "@gtkx/gi/adw";
2
2
  import type { ParamListBase, StackNavigationState } from "@react-navigation/core";
3
3
  import type { ReactNode, RefObject } from "react";
4
4
  import { AdwNavigationPage, AdwNavigationView, AdwToolbarView } from "@gtkx/jsx/adw";
5
+ import { useLatestRef } from "@gtkx/react/internal";
5
6
  import { useCallback, useEffect, useRef } from "react";
6
7
  import type { Describe } from "./stack-pages.js";
7
8
  import type { OptionsByKey } from "./sync-navigation-stack.js";
@@ -47,16 +48,6 @@ const previousDescriptor = (
47
48
  return previousKey === undefined ? undefined : descriptors[previousKey];
48
49
  };
49
50
 
50
- const useLatest = <T,>(value: T): RefObject<T> => {
51
- const ref = useRef(value);
52
-
53
- useEffect(() => {
54
- ref.current = value;
55
- }, [value]);
56
-
57
- return ref;
58
- };
59
-
60
51
  const useStackSync = (
61
52
  viewRef: ViewRef,
62
53
  state: StackNavigationState<ParamListBase>,
@@ -84,7 +75,7 @@ const usePoppedHandler = (
84
75
  options: RefObject<OptionsByKey>,
85
76
  offset: number,
86
77
  ): (() => void) => {
87
- const navigationRef = useLatest(navigation);
78
+ const navigationRef = useLatestRef(navigation);
88
79
  const isScheduledRef = useRef(false);
89
80
 
90
81
  return useCallback(() => {
@@ -114,11 +105,14 @@ const StackPageContent = ({ descriptor, previous }: Omit<StackPageProps, "naviga
114
105
 
115
106
  const back = previous === undefined ? undefined : { title: previous.options.title ?? previous.route.name };
116
107
 
117
- const topBar = options.header === undefined
118
- ? <HeaderBar options={options} showBackButton={options.headerBackVisible ?? true} />
119
- : <>{options.header({ route, navigation, options, back })}</>;
108
+ const topBar =
109
+ options.header === undefined ? (
110
+ <HeaderBar options={options} showBackButton={options.headerBackVisible ?? true} />
111
+ ) : (
112
+ <>{options.header({ route, navigation, options, back })}</>
113
+ );
120
114
 
121
- return <AdwToolbarView topBar={topBar}>{descriptor.render()}</AdwToolbarView>;
115
+ return <AdwToolbarView top={topBar}>{descriptor.render()}</AdwToolbarView>;
122
116
  };
123
117
 
124
118
  const StackPage = ({ descriptor, previous, navigation, onHidden }: StackPageProps): ReactNode => {
@@ -166,7 +160,7 @@ const StackView = (props: StackViewProps): ReactNode => {
166
160
  const { state, navigation, descriptors, describe, popOnEscape, offset = 0 } = props;
167
161
  const viewRef = useRef<Adw.NavigationView | null>(null);
168
162
  const { pages, release } = useStackPages(state, descriptors, describe, offset);
169
- const options = useLatest<OptionsByKey>(Object.fromEntries(pages.map((page) => [page.route.key, page.options])));
163
+ const options = useLatestRef<OptionsByKey>(Object.fromEntries(pages.map((page) => [page.route.key, page.options])));
170
164
  const onPopped = usePoppedHandler(viewRef, navigation, options, offset);
171
165
  useStackSync(viewRef, state, options, offset);
172
166
 
@@ -68,7 +68,8 @@ type StackNavigationProp<
68
68
  StackNavigationState<ParamList>,
69
69
  StackNavigationOptions,
70
70
  StackNavigationEventMap
71
- > & StackActionHelpers<ParamList>;
71
+ > &
72
+ StackActionHelpers<ParamList>;
72
73
 
73
74
  /** Props a stack screen component receives. */
74
75
  type StackScreenProps<
@@ -112,8 +113,8 @@ type StackNavigatorProps = DefaultNavigatorOptions<
112
113
  StackNavigationEventMap,
113
114
  StackNavigationProp<ParamListBase>
114
115
  > &
115
- StackRouterOptions &
116
- StackNavigationConfig;
116
+ StackRouterOptions &
117
+ StackNavigationConfig;
117
118
 
118
119
  export type {
119
120
  StackDescriptor,
@@ -0,0 +1,122 @@
1
+ import type {
2
+ NavigatorTypeBagBase,
3
+ ParamListBase,
4
+ StaticConfig,
5
+ StaticScreenFactory,
6
+ TypedNavigator,
7
+ } from "@react-navigation/core";
8
+ import type { ReactNode } from "react";
9
+ import * as Adw from "@gtkx/gi/adw";
10
+ import { createNavigatorFactory, createScreenFactory, useNavigationBuilder } from "@react-navigation/core";
11
+ import { useState } from "react";
12
+ import type {
13
+ TabViewActionHelpers,
14
+ TabViewNavigationEventMap,
15
+ TabViewNavigationOptions,
16
+ TabViewNavigationProp,
17
+ TabViewNavigationState,
18
+ TabViewNavigatorProps,
19
+ TabViewRouterOptions,
20
+ } from "./types.js";
21
+ import { readExistingTabs } from "./page-registry.js";
22
+ import { TabViewHost } from "./tab-view-host.js";
23
+ import { createTabViewRouter } from "./tab-view-router.js";
24
+
25
+ /** Type bag describing the tab view navigator to React Navigation's typed APIs. */
26
+ type TabViewTypeBag<
27
+ ParamList extends ParamListBase = ParamListBase,
28
+ NavigatorID extends string | undefined = string | undefined,
29
+ > = {
30
+ /** Route names and their params. */
31
+ ParamList: ParamList;
32
+ /** Optional navigator id. */
33
+ NavigatorID: NavigatorID;
34
+ /** Shape of the navigator state. */
35
+ State: TabViewNavigationState<ParamList>;
36
+ /** Per-screen options. */
37
+ ScreenOptions: TabViewNavigationOptions;
38
+ /** Events the navigator emits. */
39
+ EventMap: TabViewNavigationEventMap;
40
+ /** Navigation object per route. */
41
+ NavigationList: {
42
+ [RouteName in keyof ParamList]: TabViewNavigationProp<ParamList, RouteName, NavigatorID>;
43
+ };
44
+ /** The navigator component. */
45
+ Navigator: typeof TabViewNavigator;
46
+ };
47
+
48
+ /** Declares a typed screen of a tab view navigator for the static configuration API. */
49
+ const createTabViewScreen: StaticScreenFactory<TabViewTypeBag> = createScreenFactory<TabViewTypeBag>();
50
+
51
+ /** Renders each open route of a {@link createTabViewNavigator} as a page of an `Adw.TabView`. */
52
+ function TabViewNavigator({
53
+ view: providedView,
54
+ tabBarVisible,
55
+ tabBarAutohide,
56
+ tabBarExpand,
57
+ tabBarInverted,
58
+ overview,
59
+ menuModel,
60
+ renderMenu,
61
+ extraDropTarget,
62
+ onExtraDragDrop,
63
+ onCreateWindow,
64
+ onSetupMenu,
65
+ shortcuts,
66
+ defaultIcon,
67
+ ...options
68
+ }: TabViewNavigatorProps): ReactNode {
69
+ const [view] = useState(() => providedView ?? new Adw.TabView());
70
+ const [router] = useState(() => createTabViewRouter(() => readExistingTabs(view)));
71
+ const { state, descriptors, navigation, render } = useNavigationBuilder<
72
+ TabViewNavigationState<ParamListBase>,
73
+ TabViewRouterOptions,
74
+ TabViewActionHelpers<ParamListBase>,
75
+ TabViewNavigationOptions,
76
+ TabViewNavigationEventMap
77
+ >(router, options);
78
+
79
+ return render(
80
+ <TabViewHost
81
+ view={view}
82
+ state={state}
83
+ navigation={navigation}
84
+ descriptors={descriptors}
85
+ tabBarVisible={tabBarVisible}
86
+ tabBarAutohide={tabBarAutohide}
87
+ tabBarExpand={tabBarExpand}
88
+ tabBarInverted={tabBarInverted}
89
+ overview={overview}
90
+ menuModel={menuModel}
91
+ renderMenu={renderMenu}
92
+ extraDropTarget={extraDropTarget}
93
+ onExtraDragDrop={onExtraDragDrop}
94
+ onCreateWindow={onCreateWindow}
95
+ onSetupMenu={onSetupMenu}
96
+ shortcuts={shortcuts}
97
+ defaultIcon={defaultIcon}
98
+ />,
99
+ );
100
+ }
101
+
102
+ /** Creates a navigator whose routes are the pages of an `Adw.TabView`, with a tab bar and an optional overview. */
103
+ function createTabViewNavigator<
104
+ const ParamList extends ParamListBase,
105
+ const NavigatorID extends string | undefined = string | undefined,
106
+ const TypeBag extends NavigatorTypeBagBase = TabViewTypeBag<ParamList, NavigatorID>,
107
+ >(): TypedNavigator<TypeBag, undefined>;
108
+ /** Creates a navigator whose routes are the pages of an `Adw.TabView`, with a tab bar and an optional overview. */
109
+ function createTabViewNavigator<
110
+ const ParamList extends ParamListBase,
111
+ const NavigatorID extends string | undefined = string | undefined,
112
+ const TypeBag extends NavigatorTypeBagBase = TabViewTypeBag<ParamList, NavigatorID>,
113
+ const Config extends StaticConfig<TypeBag> = StaticConfig<TypeBag>,
114
+ >(config: Config): TypedNavigator<TypeBag, Config>;
115
+ function createTabViewNavigator<
116
+ const TypeBag extends NavigatorTypeBagBase,
117
+ const Config extends StaticConfig<TypeBag> | undefined,
118
+ >(config?: Config): TypedNavigator<TypeBag, Config> {
119
+ return createNavigatorFactory(TabViewNavigator)(config) as TypedNavigator<TypeBag, Config>;
120
+ }
121
+
122
+ export { createTabViewNavigator, createTabViewScreen, TabViewNavigator, type TabViewTypeBag };
@@ -0,0 +1,139 @@
1
+ import type * as Gtk from "@gtkx/gi/gtk";
2
+ import * as Adw from "@gtkx/gi/adw";
3
+ import type { ParamListBase } from "@react-navigation/core";
4
+ import type { ExistingTab } from "./tab-view-router.js";
5
+ import type { TabViewNavigationOptions, TabViewNavigationState } from "./types.js";
6
+
7
+ type Route = TabViewNavigationState<ParamListBase>["routes"][number];
8
+
9
+ /** Page property values last written from a route's options. */
10
+ type AppliedOptions = Pick<
11
+ TabViewNavigationOptions,
12
+ | "icon"
13
+ | "indicatorActivatable"
14
+ | "indicatorIcon"
15
+ | "indicatorTooltip"
16
+ | "keyword"
17
+ | "liveThumbnail"
18
+ | "loading"
19
+ | "needsAttention"
20
+ | "thumbnailXalign"
21
+ | "thumbnailYalign"
22
+ | "tooltip"
23
+ > & { title?: string };
24
+
25
+ /** A native page a tab view navigator created or adopted, with the host its content renders into. */
26
+ type PageRecord = {
27
+ route: Route;
28
+ page: Adw.TabPage;
29
+ host: Adw.Bin;
30
+ applied: AppliedOptions;
31
+ };
32
+
33
+ /** The pages of one navigator by route key, notifying React when the set changes. */
34
+ type PageStore = {
35
+ get: (key: string) => PageRecord | undefined;
36
+ set: (record: PageRecord) => void;
37
+ delete: (key: string) => void;
38
+ keys: () => string[];
39
+ subscribe: (listener: () => void) => () => void;
40
+ getVersion: () => number;
41
+ /** Key of the route whose page was selected by the last sync, so native selection changes are not undone. */
42
+ lastFocus: string | undefined;
43
+ };
44
+
45
+ const records = new WeakMap<Adw.TabPage, PageRecord>();
46
+
47
+ const recordOf = (page: Adw.TabPage): PageRecord | undefined => records.get(page);
48
+
49
+ const registerPage = (record: PageRecord): void => {
50
+ records.set(record.page, record);
51
+ };
52
+
53
+ const ownerOf = (page: Adw.TabPage): Adw.TabView | null => {
54
+ let widget: Gtk.Widget | null = page.getChild();
55
+
56
+ while (widget !== null) {
57
+ if (widget instanceof Adw.TabView) {
58
+ return widget;
59
+ }
60
+
61
+ widget = widget.getParent();
62
+ }
63
+
64
+ return null;
65
+ };
66
+
67
+ const readExistingTabs = (view: Adw.TabView): ExistingTab[] => {
68
+ const selected = view.getSelectedPage();
69
+ const tabs: ExistingTab[] = [];
70
+
71
+ for (let position = 0; position < view.getNPages(); position += 1) {
72
+ const page = view.getNthPage(position);
73
+ const record = records.get(page);
74
+
75
+ if (record === undefined) {
76
+ continue;
77
+ }
78
+
79
+ const parent = page.getParent();
80
+ const parentRecord = parent === null ? undefined : records.get(parent);
81
+
82
+ tabs.push({
83
+ route: record.route,
84
+ pinned: page.getPinned(),
85
+ parent: parentRecord?.route.key,
86
+ selected: page === selected,
87
+ });
88
+ }
89
+
90
+ return tabs;
91
+ };
92
+
93
+ const createPageStore = (): PageStore => {
94
+ const byKey = new Map<string, PageRecord>();
95
+ const listeners = new Set<() => void>();
96
+ let version = 0;
97
+
98
+ const notify = (): void => {
99
+ version += 1;
100
+
101
+ for (const listener of listeners) {
102
+ listener();
103
+ }
104
+ };
105
+
106
+ return {
107
+ get: (key) => byKey.get(key),
108
+ set: (record) => {
109
+ byKey.set(record.route.key, record);
110
+ notify();
111
+ },
112
+ delete: (key) => {
113
+ if (byKey.delete(key)) {
114
+ notify();
115
+ }
116
+ },
117
+ keys: () => [...byKey.keys()],
118
+ subscribe: (listener) => {
119
+ listeners.add(listener);
120
+
121
+ return () => {
122
+ listeners.delete(listener);
123
+ };
124
+ },
125
+ getVersion: () => version,
126
+ lastFocus: undefined,
127
+ };
128
+ };
129
+
130
+ export {
131
+ type AppliedOptions,
132
+ createPageStore,
133
+ ownerOf,
134
+ type PageRecord,
135
+ type PageStore,
136
+ readExistingTabs,
137
+ recordOf,
138
+ registerPage,
139
+ };