extrojs 0.1.0 → 0.3.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 (96) hide show
  1. package/README.md +3 -3
  2. package/client.d.ts +8 -0
  3. package/dist/cli.d.ts +7 -0
  4. package/dist/cli.js +27 -0
  5. package/dist/commands/build.d.ts +5 -0
  6. package/dist/commands/build.js +26 -0
  7. package/dist/commands/dev.d.ts +7 -0
  8. package/dist/commands/dev.js +156 -0
  9. package/dist/config.d.ts +2 -2
  10. package/dist/core/asset.d.ts +10 -0
  11. package/dist/core/asset.js +10 -0
  12. package/dist/dev-assets.d.ts +3 -3
  13. package/dist/dev-assets.js +33 -12
  14. package/dist/env.d.ts +10 -0
  15. package/dist/env.js +18 -0
  16. package/dist/exports/asset.d.ts +1 -0
  17. package/dist/exports/asset.js +1 -0
  18. package/dist/exports/link.d.ts +1 -0
  19. package/dist/exports/link.js +1 -0
  20. package/dist/exports/navigation.d.ts +2 -0
  21. package/dist/exports/navigation.js +1 -0
  22. package/dist/exports/runtime.d.ts +2 -0
  23. package/dist/exports/runtime.js +3 -0
  24. package/dist/index.js +5 -136
  25. package/dist/load-config.d.ts +1 -1
  26. package/dist/logger.d.ts +34 -0
  27. package/dist/logger.js +65 -0
  28. package/dist/paths.d.ts +8 -0
  29. package/dist/paths.js +8 -0
  30. package/dist/pkg.d.ts +6 -0
  31. package/dist/pkg.js +5 -0
  32. package/dist/plugin/app-tree.d.ts +59 -0
  33. package/dist/plugin/app-tree.js +214 -0
  34. package/dist/plugin/asset-inventory.d.ts +24 -0
  35. package/dist/plugin/asset-inventory.js +9 -0
  36. package/dist/plugin/dev-reactions.d.ts +59 -0
  37. package/dist/plugin/dev-reactions.js +62 -0
  38. package/dist/plugin/emit-assets.d.ts +50 -0
  39. package/dist/plugin/emit-assets.js +40 -0
  40. package/dist/plugin/generators/html.d.ts +39 -0
  41. package/dist/plugin/generators/html.js +127 -0
  42. package/dist/plugin/generators/icons.d.ts +15 -0
  43. package/dist/plugin/generators/icons.js +16 -0
  44. package/dist/plugin/generators/public.d.ts +17 -0
  45. package/dist/plugin/generators/public.js +20 -0
  46. package/dist/plugin/icons.d.ts +5 -0
  47. package/dist/plugin/icons.js +20 -0
  48. package/dist/plugin/index.d.ts +31 -0
  49. package/dist/plugin/index.js +246 -0
  50. package/dist/plugin/internal.d.ts +14 -0
  51. package/dist/plugin/internal.js +6 -0
  52. package/dist/plugin/manifest.d.ts +29 -0
  53. package/dist/plugin/manifest.js +68 -0
  54. package/dist/plugin/public.d.ts +21 -0
  55. package/dist/plugin/public.js +63 -0
  56. package/dist/plugin/runtimes/clients/csui-mount.js +90 -0
  57. package/dist/plugin/runtimes/clients/dev-bridge.js +194 -0
  58. package/dist/plugin/runtimes/csui-mount.d.ts +18 -0
  59. package/dist/plugin/runtimes/csui-mount.js +21 -0
  60. package/dist/plugin/runtimes/dev-bridge.d.ts +22 -0
  61. package/dist/plugin/runtimes/dev-bridge.js +19 -0
  62. package/dist/plugin/runtimes/routes-module.d.ts +20 -0
  63. package/dist/plugin/runtimes/routes-module.js +51 -0
  64. package/dist/plugin/runtimes/runtime-module.d.ts +16 -0
  65. package/dist/plugin/runtimes/runtime-module.js +40 -0
  66. package/dist/plugin/surfaces.d.ts +37 -0
  67. package/dist/plugin/surfaces.js +67 -0
  68. package/dist/plugin/types/index.d.ts +9 -0
  69. package/dist/plugin/types/index.js +1 -0
  70. package/dist/plugin/utils/read-json.d.ts +1 -0
  71. package/dist/plugin/utils/read-json.js +8 -0
  72. package/dist/react/env.d.ts +13 -0
  73. package/dist/react/env.js +1 -0
  74. package/dist/router/build-tree.d.ts +46 -0
  75. package/dist/router/build-tree.js +56 -0
  76. package/dist/router/context.d.ts +13 -0
  77. package/dist/router/context.js +2 -0
  78. package/dist/router/create-router.d.ts +10 -0
  79. package/dist/router/create-router.js +126 -0
  80. package/dist/router/defaults.d.ts +24 -0
  81. package/dist/router/defaults.js +25 -0
  82. package/dist/router/error-boundary.d.ts +23 -0
  83. package/dist/router/error-boundary.js +21 -0
  84. package/dist/router/hooks.d.ts +18 -0
  85. package/dist/router/hooks.js +34 -0
  86. package/dist/router/index.d.ts +8 -0
  87. package/dist/router/index.js +7 -0
  88. package/dist/router/link.d.ts +305 -0
  89. package/dist/router/link.js +30 -0
  90. package/dist/router/match.d.ts +14 -0
  91. package/dist/router/match.js +27 -0
  92. package/dist/router/types.d.ts +55 -0
  93. package/dist/router/types.js +1 -0
  94. package/dist/types/index.d.ts +152 -0
  95. package/dist/types/index.js +1 -0
  96. package/package.json +47 -9
@@ -0,0 +1,305 @@
1
+ import type { AnchorHTMLAttributes, MouseEvent } from "react";
2
+ interface LinkProps extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, "href"> {
3
+ /** Route to navigate to, e.g. "/settings". The leading "#" is added for you. */
4
+ href: string;
5
+ /** Replace the current history entry instead of pushing a new one. */
6
+ replace?: boolean;
7
+ }
8
+ /**
9
+ * @describe Hash-router-aware anchor. Renders a real `<a>` pointing at the hash
10
+ * route, so middle-click and open-in-new-tab keep working, and prepends the "#"
11
+ * for you. With `replace`, it intercepts a plain left-click and swaps the
12
+ * current entry via `router.replace` instead of pushing a new one.
13
+ * @example <Link href="/settings">Settings</Link>
14
+ */
15
+ export declare const Link: ({ href, replace, onClick, ...rest }: LinkProps) => import("react").DetailedReactHTMLElement<{
16
+ content?: string | undefined | undefined;
17
+ title?: string | undefined | undefined;
18
+ type?: string | undefined | undefined;
19
+ slot?: string | undefined | undefined;
20
+ style?: import("react").CSSProperties | undefined;
21
+ color?: string | undefined | undefined;
22
+ children?: import("react").ReactNode;
23
+ download?: any;
24
+ hrefLang?: string | undefined | undefined;
25
+ media?: string | undefined | undefined;
26
+ ping?: string | undefined | undefined;
27
+ target?: import("react").HTMLAttributeAnchorTarget | undefined;
28
+ referrerPolicy?: import("react").HTMLAttributeReferrerPolicy | undefined;
29
+ defaultChecked?: boolean | undefined | undefined;
30
+ defaultValue?: string | number | readonly string[] | undefined;
31
+ suppressContentEditableWarning?: boolean | undefined | undefined;
32
+ suppressHydrationWarning?: boolean | undefined | undefined;
33
+ accessKey?: string | undefined | undefined;
34
+ autoCapitalize?: "off" | "none" | "on" | "sentences" | "words" | "characters" | undefined | (string & {}) | undefined;
35
+ autoFocus?: boolean | undefined | undefined;
36
+ className?: string | undefined | undefined;
37
+ contentEditable?: "inherit" | (boolean | "true" | "false") | "plaintext-only" | undefined;
38
+ contextMenu?: string | undefined | undefined;
39
+ dir?: string | undefined | undefined;
40
+ draggable?: (boolean | "true" | "false") | undefined;
41
+ enterKeyHint?: "enter" | "done" | "go" | "next" | "previous" | "search" | "send" | undefined | undefined;
42
+ hidden?: boolean | undefined | undefined;
43
+ id?: string | undefined | undefined;
44
+ lang?: string | undefined | undefined;
45
+ nonce?: string | undefined | undefined;
46
+ spellCheck?: (boolean | "true" | "false") | undefined;
47
+ tabIndex?: number | undefined | undefined;
48
+ translate?: "yes" | "no" | undefined | undefined;
49
+ radioGroup?: string | undefined | undefined;
50
+ role?: import("react").AriaRole | undefined;
51
+ about?: string | undefined | undefined;
52
+ datatype?: string | undefined | undefined;
53
+ inlist?: any;
54
+ prefix?: string | undefined | undefined;
55
+ property?: string | undefined | undefined;
56
+ rel?: string | undefined | undefined;
57
+ resource?: string | undefined | undefined;
58
+ rev?: string | undefined | undefined;
59
+ typeof?: string | undefined | undefined;
60
+ vocab?: string | undefined | undefined;
61
+ autoCorrect?: string | undefined | undefined;
62
+ autoSave?: string | undefined | undefined;
63
+ itemProp?: string | undefined | undefined;
64
+ itemScope?: boolean | undefined | undefined;
65
+ itemType?: string | undefined | undefined;
66
+ itemID?: string | undefined | undefined;
67
+ itemRef?: string | undefined | undefined;
68
+ results?: number | undefined | undefined;
69
+ security?: string | undefined | undefined;
70
+ unselectable?: "on" | "off" | undefined | undefined;
71
+ popover?: "" | "auto" | "manual" | "hint" | undefined | undefined;
72
+ popoverTargetAction?: "toggle" | "show" | "hide" | undefined | undefined;
73
+ popoverTarget?: string | undefined | undefined;
74
+ inert?: boolean | undefined | undefined;
75
+ inputMode?: "none" | "text" | "tel" | "url" | "email" | "numeric" | "decimal" | "search" | undefined | undefined;
76
+ is?: string | undefined | undefined;
77
+ exportparts?: string | undefined | undefined;
78
+ part?: string | undefined | undefined;
79
+ "aria-activedescendant"?: string | undefined | undefined;
80
+ "aria-atomic"?: (boolean | "true" | "false") | undefined;
81
+ "aria-autocomplete"?: "none" | "inline" | "list" | "both" | undefined | undefined;
82
+ "aria-braillelabel"?: string | undefined | undefined;
83
+ "aria-brailleroledescription"?: string | undefined | undefined;
84
+ "aria-busy"?: (boolean | "true" | "false") | undefined;
85
+ "aria-checked"?: boolean | "false" | "mixed" | "true" | undefined | undefined;
86
+ "aria-colcount"?: number | undefined | undefined;
87
+ "aria-colindex"?: number | undefined | undefined;
88
+ "aria-colindextext"?: string | undefined | undefined;
89
+ "aria-colspan"?: number | undefined | undefined;
90
+ "aria-controls"?: string | undefined | undefined;
91
+ "aria-current"?: boolean | "false" | "true" | "page" | "step" | "location" | "date" | "time" | undefined | undefined;
92
+ "aria-describedby"?: string | undefined | undefined;
93
+ "aria-description"?: string | undefined | undefined;
94
+ "aria-details"?: string | undefined | undefined;
95
+ "aria-disabled"?: (boolean | "true" | "false") | undefined;
96
+ "aria-dropeffect"?: "none" | "copy" | "execute" | "link" | "move" | "popup" | undefined | undefined;
97
+ "aria-errormessage"?: string | undefined | undefined;
98
+ "aria-expanded"?: (boolean | "true" | "false") | undefined;
99
+ "aria-flowto"?: string | undefined | undefined;
100
+ "aria-grabbed"?: (boolean | "true" | "false") | undefined;
101
+ "aria-haspopup"?: boolean | "false" | "true" | "menu" | "listbox" | "tree" | "grid" | "dialog" | undefined | undefined;
102
+ "aria-hidden"?: (boolean | "true" | "false") | undefined;
103
+ "aria-invalid"?: boolean | "false" | "true" | "grammar" | "spelling" | undefined | undefined;
104
+ "aria-keyshortcuts"?: string | undefined | undefined;
105
+ "aria-label"?: string | undefined | undefined;
106
+ "aria-labelledby"?: string | undefined | undefined;
107
+ "aria-level"?: number | undefined | undefined;
108
+ "aria-live"?: "off" | "assertive" | "polite" | undefined | undefined;
109
+ "aria-modal"?: (boolean | "true" | "false") | undefined;
110
+ "aria-multiline"?: (boolean | "true" | "false") | undefined;
111
+ "aria-multiselectable"?: (boolean | "true" | "false") | undefined;
112
+ "aria-orientation"?: "horizontal" | "vertical" | undefined | undefined;
113
+ "aria-owns"?: string | undefined | undefined;
114
+ "aria-placeholder"?: string | undefined | undefined;
115
+ "aria-posinset"?: number | undefined | undefined;
116
+ "aria-pressed"?: boolean | "false" | "mixed" | "true" | undefined | undefined;
117
+ "aria-readonly"?: (boolean | "true" | "false") | undefined;
118
+ "aria-relevant"?: "additions" | "additions removals" | "additions text" | "all" | "removals" | "removals additions" | "removals text" | "text" | "text additions" | "text removals" | undefined | undefined;
119
+ "aria-required"?: (boolean | "true" | "false") | undefined;
120
+ "aria-roledescription"?: string | undefined | undefined;
121
+ "aria-rowcount"?: number | undefined | undefined;
122
+ "aria-rowindex"?: number | undefined | undefined;
123
+ "aria-rowindextext"?: string | undefined | undefined;
124
+ "aria-rowspan"?: number | undefined | undefined;
125
+ "aria-selected"?: (boolean | "true" | "false") | undefined;
126
+ "aria-setsize"?: number | undefined | undefined;
127
+ "aria-sort"?: "none" | "ascending" | "descending" | "other" | undefined | undefined;
128
+ "aria-valuemax"?: number | undefined | undefined;
129
+ "aria-valuemin"?: number | undefined | undefined;
130
+ "aria-valuenow"?: number | undefined | undefined;
131
+ "aria-valuetext"?: string | undefined | undefined;
132
+ dangerouslySetInnerHTML?: {
133
+ __html: string | TrustedHTML;
134
+ } | undefined | undefined;
135
+ onCopy?: import("react").ClipboardEventHandler<HTMLAnchorElement> | undefined;
136
+ onCopyCapture?: import("react").ClipboardEventHandler<HTMLAnchorElement> | undefined;
137
+ onCut?: import("react").ClipboardEventHandler<HTMLAnchorElement> | undefined;
138
+ onCutCapture?: import("react").ClipboardEventHandler<HTMLAnchorElement> | undefined;
139
+ onPaste?: import("react").ClipboardEventHandler<HTMLAnchorElement> | undefined;
140
+ onPasteCapture?: import("react").ClipboardEventHandler<HTMLAnchorElement> | undefined;
141
+ onCompositionEnd?: import("react").CompositionEventHandler<HTMLAnchorElement> | undefined;
142
+ onCompositionEndCapture?: import("react").CompositionEventHandler<HTMLAnchorElement> | undefined;
143
+ onCompositionStart?: import("react").CompositionEventHandler<HTMLAnchorElement> | undefined;
144
+ onCompositionStartCapture?: import("react").CompositionEventHandler<HTMLAnchorElement> | undefined;
145
+ onCompositionUpdate?: import("react").CompositionEventHandler<HTMLAnchorElement> | undefined;
146
+ onCompositionUpdateCapture?: import("react").CompositionEventHandler<HTMLAnchorElement> | undefined;
147
+ onFocus?: import("react").FocusEventHandler<HTMLAnchorElement> | undefined;
148
+ onFocusCapture?: import("react").FocusEventHandler<HTMLAnchorElement> | undefined;
149
+ onBlur?: import("react").FocusEventHandler<HTMLAnchorElement> | undefined;
150
+ onBlurCapture?: import("react").FocusEventHandler<HTMLAnchorElement> | undefined;
151
+ onChange?: import("react").ChangeEventHandler<HTMLAnchorElement, Element> | undefined;
152
+ onChangeCapture?: import("react").ChangeEventHandler<HTMLAnchorElement, Element> | undefined;
153
+ onBeforeInput?: import("react").InputEventHandler<HTMLAnchorElement> | undefined;
154
+ onBeforeInputCapture?: import("react").InputEventHandler<HTMLAnchorElement> | undefined;
155
+ onInput?: import("react").InputEventHandler<HTMLAnchorElement> | undefined;
156
+ onInputCapture?: import("react").InputEventHandler<HTMLAnchorElement> | undefined;
157
+ onReset?: import("react").ReactEventHandler<HTMLAnchorElement> | undefined;
158
+ onResetCapture?: import("react").ReactEventHandler<HTMLAnchorElement> | undefined;
159
+ onSubmit?: import("react").SubmitEventHandler<HTMLAnchorElement> | undefined;
160
+ onSubmitCapture?: import("react").SubmitEventHandler<HTMLAnchorElement> | undefined;
161
+ onInvalid?: import("react").ReactEventHandler<HTMLAnchorElement> | undefined;
162
+ onInvalidCapture?: import("react").ReactEventHandler<HTMLAnchorElement> | undefined;
163
+ onLoad?: import("react").ReactEventHandler<HTMLAnchorElement> | undefined;
164
+ onLoadCapture?: import("react").ReactEventHandler<HTMLAnchorElement> | undefined;
165
+ onError?: import("react").ReactEventHandler<HTMLAnchorElement> | undefined;
166
+ onErrorCapture?: import("react").ReactEventHandler<HTMLAnchorElement> | undefined;
167
+ onKeyDown?: import("react").KeyboardEventHandler<HTMLAnchorElement> | undefined;
168
+ onKeyDownCapture?: import("react").KeyboardEventHandler<HTMLAnchorElement> | undefined;
169
+ onKeyPress?: import("react").KeyboardEventHandler<HTMLAnchorElement> | undefined;
170
+ onKeyPressCapture?: import("react").KeyboardEventHandler<HTMLAnchorElement> | undefined;
171
+ onKeyUp?: import("react").KeyboardEventHandler<HTMLAnchorElement> | undefined;
172
+ onKeyUpCapture?: import("react").KeyboardEventHandler<HTMLAnchorElement> | undefined;
173
+ onAbort?: import("react").ReactEventHandler<HTMLAnchorElement> | undefined;
174
+ onAbortCapture?: import("react").ReactEventHandler<HTMLAnchorElement> | undefined;
175
+ onCanPlay?: import("react").ReactEventHandler<HTMLAnchorElement> | undefined;
176
+ onCanPlayCapture?: import("react").ReactEventHandler<HTMLAnchorElement> | undefined;
177
+ onCanPlayThrough?: import("react").ReactEventHandler<HTMLAnchorElement> | undefined;
178
+ onCanPlayThroughCapture?: import("react").ReactEventHandler<HTMLAnchorElement> | undefined;
179
+ onDurationChange?: import("react").ReactEventHandler<HTMLAnchorElement> | undefined;
180
+ onDurationChangeCapture?: import("react").ReactEventHandler<HTMLAnchorElement> | undefined;
181
+ onEmptied?: import("react").ReactEventHandler<HTMLAnchorElement> | undefined;
182
+ onEmptiedCapture?: import("react").ReactEventHandler<HTMLAnchorElement> | undefined;
183
+ onEncrypted?: import("react").ReactEventHandler<HTMLAnchorElement> | undefined;
184
+ onEncryptedCapture?: import("react").ReactEventHandler<HTMLAnchorElement> | undefined;
185
+ onEnded?: import("react").ReactEventHandler<HTMLAnchorElement> | undefined;
186
+ onEndedCapture?: import("react").ReactEventHandler<HTMLAnchorElement> | undefined;
187
+ onLoadedData?: import("react").ReactEventHandler<HTMLAnchorElement> | undefined;
188
+ onLoadedDataCapture?: import("react").ReactEventHandler<HTMLAnchorElement> | undefined;
189
+ onLoadedMetadata?: import("react").ReactEventHandler<HTMLAnchorElement> | undefined;
190
+ onLoadedMetadataCapture?: import("react").ReactEventHandler<HTMLAnchorElement> | undefined;
191
+ onLoadStart?: import("react").ReactEventHandler<HTMLAnchorElement> | undefined;
192
+ onLoadStartCapture?: import("react").ReactEventHandler<HTMLAnchorElement> | undefined;
193
+ onPause?: import("react").ReactEventHandler<HTMLAnchorElement> | undefined;
194
+ onPauseCapture?: import("react").ReactEventHandler<HTMLAnchorElement> | undefined;
195
+ onPlay?: import("react").ReactEventHandler<HTMLAnchorElement> | undefined;
196
+ onPlayCapture?: import("react").ReactEventHandler<HTMLAnchorElement> | undefined;
197
+ onPlaying?: import("react").ReactEventHandler<HTMLAnchorElement> | undefined;
198
+ onPlayingCapture?: import("react").ReactEventHandler<HTMLAnchorElement> | undefined;
199
+ onProgress?: import("react").ReactEventHandler<HTMLAnchorElement> | undefined;
200
+ onProgressCapture?: import("react").ReactEventHandler<HTMLAnchorElement> | undefined;
201
+ onRateChange?: import("react").ReactEventHandler<HTMLAnchorElement> | undefined;
202
+ onRateChangeCapture?: import("react").ReactEventHandler<HTMLAnchorElement> | undefined;
203
+ onSeeked?: import("react").ReactEventHandler<HTMLAnchorElement> | undefined;
204
+ onSeekedCapture?: import("react").ReactEventHandler<HTMLAnchorElement> | undefined;
205
+ onSeeking?: import("react").ReactEventHandler<HTMLAnchorElement> | undefined;
206
+ onSeekingCapture?: import("react").ReactEventHandler<HTMLAnchorElement> | undefined;
207
+ onStalled?: import("react").ReactEventHandler<HTMLAnchorElement> | undefined;
208
+ onStalledCapture?: import("react").ReactEventHandler<HTMLAnchorElement> | undefined;
209
+ onSuspend?: import("react").ReactEventHandler<HTMLAnchorElement> | undefined;
210
+ onSuspendCapture?: import("react").ReactEventHandler<HTMLAnchorElement> | undefined;
211
+ onTimeUpdate?: import("react").ReactEventHandler<HTMLAnchorElement> | undefined;
212
+ onTimeUpdateCapture?: import("react").ReactEventHandler<HTMLAnchorElement> | undefined;
213
+ onVolumeChange?: import("react").ReactEventHandler<HTMLAnchorElement> | undefined;
214
+ onVolumeChangeCapture?: import("react").ReactEventHandler<HTMLAnchorElement> | undefined;
215
+ onWaiting?: import("react").ReactEventHandler<HTMLAnchorElement> | undefined;
216
+ onWaitingCapture?: import("react").ReactEventHandler<HTMLAnchorElement> | undefined;
217
+ onAuxClick?: import("react").MouseEventHandler<HTMLAnchorElement> | undefined;
218
+ onAuxClickCapture?: import("react").MouseEventHandler<HTMLAnchorElement> | undefined;
219
+ onClickCapture?: import("react").MouseEventHandler<HTMLAnchorElement> | undefined;
220
+ onContextMenu?: import("react").MouseEventHandler<HTMLAnchorElement> | undefined;
221
+ onContextMenuCapture?: import("react").MouseEventHandler<HTMLAnchorElement> | undefined;
222
+ onDoubleClick?: import("react").MouseEventHandler<HTMLAnchorElement> | undefined;
223
+ onDoubleClickCapture?: import("react").MouseEventHandler<HTMLAnchorElement> | undefined;
224
+ onDrag?: import("react").DragEventHandler<HTMLAnchorElement> | undefined;
225
+ onDragCapture?: import("react").DragEventHandler<HTMLAnchorElement> | undefined;
226
+ onDragEnd?: import("react").DragEventHandler<HTMLAnchorElement> | undefined;
227
+ onDragEndCapture?: import("react").DragEventHandler<HTMLAnchorElement> | undefined;
228
+ onDragEnter?: import("react").DragEventHandler<HTMLAnchorElement> | undefined;
229
+ onDragEnterCapture?: import("react").DragEventHandler<HTMLAnchorElement> | undefined;
230
+ onDragExit?: import("react").DragEventHandler<HTMLAnchorElement> | undefined;
231
+ onDragExitCapture?: import("react").DragEventHandler<HTMLAnchorElement> | undefined;
232
+ onDragLeave?: import("react").DragEventHandler<HTMLAnchorElement> | undefined;
233
+ onDragLeaveCapture?: import("react").DragEventHandler<HTMLAnchorElement> | undefined;
234
+ onDragOver?: import("react").DragEventHandler<HTMLAnchorElement> | undefined;
235
+ onDragOverCapture?: import("react").DragEventHandler<HTMLAnchorElement> | undefined;
236
+ onDragStart?: import("react").DragEventHandler<HTMLAnchorElement> | undefined;
237
+ onDragStartCapture?: import("react").DragEventHandler<HTMLAnchorElement> | undefined;
238
+ onDrop?: import("react").DragEventHandler<HTMLAnchorElement> | undefined;
239
+ onDropCapture?: import("react").DragEventHandler<HTMLAnchorElement> | undefined;
240
+ onMouseDown?: import("react").MouseEventHandler<HTMLAnchorElement> | undefined;
241
+ onMouseDownCapture?: import("react").MouseEventHandler<HTMLAnchorElement> | undefined;
242
+ onMouseEnter?: import("react").MouseEventHandler<HTMLAnchorElement> | undefined;
243
+ onMouseLeave?: import("react").MouseEventHandler<HTMLAnchorElement> | undefined;
244
+ onMouseMove?: import("react").MouseEventHandler<HTMLAnchorElement> | undefined;
245
+ onMouseMoveCapture?: import("react").MouseEventHandler<HTMLAnchorElement> | undefined;
246
+ onMouseOut?: import("react").MouseEventHandler<HTMLAnchorElement> | undefined;
247
+ onMouseOutCapture?: import("react").MouseEventHandler<HTMLAnchorElement> | undefined;
248
+ onMouseOver?: import("react").MouseEventHandler<HTMLAnchorElement> | undefined;
249
+ onMouseOverCapture?: import("react").MouseEventHandler<HTMLAnchorElement> | undefined;
250
+ onMouseUp?: import("react").MouseEventHandler<HTMLAnchorElement> | undefined;
251
+ onMouseUpCapture?: import("react").MouseEventHandler<HTMLAnchorElement> | undefined;
252
+ onSelect?: import("react").ReactEventHandler<HTMLAnchorElement> | undefined;
253
+ onSelectCapture?: import("react").ReactEventHandler<HTMLAnchorElement> | undefined;
254
+ onTouchCancel?: import("react").TouchEventHandler<HTMLAnchorElement> | undefined;
255
+ onTouchCancelCapture?: import("react").TouchEventHandler<HTMLAnchorElement> | undefined;
256
+ onTouchEnd?: import("react").TouchEventHandler<HTMLAnchorElement> | undefined;
257
+ onTouchEndCapture?: import("react").TouchEventHandler<HTMLAnchorElement> | undefined;
258
+ onTouchMove?: import("react").TouchEventHandler<HTMLAnchorElement> | undefined;
259
+ onTouchMoveCapture?: import("react").TouchEventHandler<HTMLAnchorElement> | undefined;
260
+ onTouchStart?: import("react").TouchEventHandler<HTMLAnchorElement> | undefined;
261
+ onTouchStartCapture?: import("react").TouchEventHandler<HTMLAnchorElement> | undefined;
262
+ onPointerDown?: import("react").PointerEventHandler<HTMLAnchorElement> | undefined;
263
+ onPointerDownCapture?: import("react").PointerEventHandler<HTMLAnchorElement> | undefined;
264
+ onPointerMove?: import("react").PointerEventHandler<HTMLAnchorElement> | undefined;
265
+ onPointerMoveCapture?: import("react").PointerEventHandler<HTMLAnchorElement> | undefined;
266
+ onPointerUp?: import("react").PointerEventHandler<HTMLAnchorElement> | undefined;
267
+ onPointerUpCapture?: import("react").PointerEventHandler<HTMLAnchorElement> | undefined;
268
+ onPointerCancel?: import("react").PointerEventHandler<HTMLAnchorElement> | undefined;
269
+ onPointerCancelCapture?: import("react").PointerEventHandler<HTMLAnchorElement> | undefined;
270
+ onPointerEnter?: import("react").PointerEventHandler<HTMLAnchorElement> | undefined;
271
+ onPointerLeave?: import("react").PointerEventHandler<HTMLAnchorElement> | undefined;
272
+ onPointerOver?: import("react").PointerEventHandler<HTMLAnchorElement> | undefined;
273
+ onPointerOverCapture?: import("react").PointerEventHandler<HTMLAnchorElement> | undefined;
274
+ onPointerOut?: import("react").PointerEventHandler<HTMLAnchorElement> | undefined;
275
+ onPointerOutCapture?: import("react").PointerEventHandler<HTMLAnchorElement> | undefined;
276
+ onGotPointerCapture?: import("react").PointerEventHandler<HTMLAnchorElement> | undefined;
277
+ onGotPointerCaptureCapture?: import("react").PointerEventHandler<HTMLAnchorElement> | undefined;
278
+ onLostPointerCapture?: import("react").PointerEventHandler<HTMLAnchorElement> | undefined;
279
+ onLostPointerCaptureCapture?: import("react").PointerEventHandler<HTMLAnchorElement> | undefined;
280
+ onScroll?: import("react").UIEventHandler<HTMLAnchorElement> | undefined;
281
+ onScrollCapture?: import("react").UIEventHandler<HTMLAnchorElement> | undefined;
282
+ onScrollEnd?: import("react").UIEventHandler<HTMLAnchorElement> | undefined;
283
+ onScrollEndCapture?: import("react").UIEventHandler<HTMLAnchorElement> | undefined;
284
+ onWheel?: import("react").WheelEventHandler<HTMLAnchorElement> | undefined;
285
+ onWheelCapture?: import("react").WheelEventHandler<HTMLAnchorElement> | undefined;
286
+ onAnimationStart?: import("react").AnimationEventHandler<HTMLAnchorElement> | undefined;
287
+ onAnimationStartCapture?: import("react").AnimationEventHandler<HTMLAnchorElement> | undefined;
288
+ onAnimationEnd?: import("react").AnimationEventHandler<HTMLAnchorElement> | undefined;
289
+ onAnimationEndCapture?: import("react").AnimationEventHandler<HTMLAnchorElement> | undefined;
290
+ onAnimationIteration?: import("react").AnimationEventHandler<HTMLAnchorElement> | undefined;
291
+ onAnimationIterationCapture?: import("react").AnimationEventHandler<HTMLAnchorElement> | undefined;
292
+ onToggle?: import("react").ToggleEventHandler<HTMLAnchorElement> | undefined;
293
+ onBeforeToggle?: import("react").ToggleEventHandler<HTMLAnchorElement> | undefined;
294
+ onTransitionCancel?: import("react").TransitionEventHandler<HTMLAnchorElement> | undefined;
295
+ onTransitionCancelCapture?: import("react").TransitionEventHandler<HTMLAnchorElement> | undefined;
296
+ onTransitionEnd?: import("react").TransitionEventHandler<HTMLAnchorElement> | undefined;
297
+ onTransitionEndCapture?: import("react").TransitionEventHandler<HTMLAnchorElement> | undefined;
298
+ onTransitionRun?: import("react").TransitionEventHandler<HTMLAnchorElement> | undefined;
299
+ onTransitionRunCapture?: import("react").TransitionEventHandler<HTMLAnchorElement> | undefined;
300
+ onTransitionStart?: import("react").TransitionEventHandler<HTMLAnchorElement> | undefined;
301
+ onTransitionStartCapture?: import("react").TransitionEventHandler<HTMLAnchorElement> | undefined;
302
+ href: string;
303
+ onClick: (event: MouseEvent<HTMLAnchorElement>) => void;
304
+ }, HTMLElement>;
305
+ export {};
@@ -0,0 +1,30 @@
1
+ import { createElement } from "react";
2
+ import { useRouter } from "./hooks.js";
3
+ /**
4
+ * @describe Hash-router-aware anchor. Renders a real `<a>` pointing at the hash
5
+ * route, so middle-click and open-in-new-tab keep working, and prepends the "#"
6
+ * for you. With `replace`, it intercepts a plain left-click and swaps the
7
+ * current entry via `router.replace` instead of pushing a new one.
8
+ * @example <Link href="/settings">Settings</Link>
9
+ */
10
+ export const Link = ({ href, replace = false, onClick, ...rest }) => {
11
+ const router = useRouter();
12
+ const to = href.startsWith("#") ? href.slice(1) : href;
13
+ const handleClick = (event) => {
14
+ onClick?.(event);
15
+ // Leave modified clicks (new tab/window) and handlers that already
16
+ // prevented default to the browser; only take over a plain left-click.
17
+ if (!replace || event.defaultPrevented)
18
+ return;
19
+ if (event.button !== 0 ||
20
+ event.metaKey ||
21
+ event.ctrlKey ||
22
+ event.shiftKey ||
23
+ event.altKey) {
24
+ return;
25
+ }
26
+ event.preventDefault();
27
+ router.replace(to);
28
+ };
29
+ return createElement("a", { href: `#${to}`, onClick: handleClick, ...rest });
30
+ };
@@ -0,0 +1,14 @@
1
+ import type { Route, RouteMatch } from "./types.js";
2
+ /**
3
+ * Walks the routes array in order and returns the match chain for the first
4
+ * matching route, or null if nothing matched.
5
+ *
6
+ * Returns a single-element array. The boundary chain (layouts + errors) is
7
+ * resolved at build time and rides on the matched route's leaf
8
+ * (`route.boundaries`), so the match never needs to grow into a multi-segment
9
+ * walk (see ADR 0003).
10
+ *
11
+ * The input array is expected to be pre-sorted so static routes come before
12
+ * dynamic ones (enforced at build time by the vite plugin).
13
+ */
14
+ export declare const matchRoutes: (path: string, routes: Route[]) => RouteMatch[] | null;
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Walks the routes array in order and returns the match chain for the first
3
+ * matching route, or null if nothing matched.
4
+ *
5
+ * Returns a single-element array. The boundary chain (layouts + errors) is
6
+ * resolved at build time and rides on the matched route's leaf
7
+ * (`route.boundaries`), so the match never needs to grow into a multi-segment
8
+ * walk (see ADR 0003).
9
+ *
10
+ * The input array is expected to be pre-sorted so static routes come before
11
+ * dynamic ones (enforced at build time by the vite plugin).
12
+ */
13
+ export const matchRoutes = (path, routes) => {
14
+ for (const route of routes) {
15
+ if (route.type === "static") {
16
+ if (route.path === path)
17
+ return [{ route, params: {} }];
18
+ continue;
19
+ }
20
+ const match = path.match(route.pattern);
21
+ if (!match)
22
+ continue;
23
+ const params = Object.fromEntries(route.paramKeys.map((key, i) => [key, match[i + 1]]));
24
+ return [{ route, params }];
25
+ }
26
+ return null;
27
+ };
@@ -0,0 +1,55 @@
1
+ import type { ComponentType, ReactNode } from "react";
2
+ import type { BoundaryKind, RuntimeBoundary, RuntimeRoute } from "../types/index.js";
3
+ export type PageProps = {
4
+ params: Record<string, string>;
5
+ };
6
+ export type LayoutProps = {
7
+ children: ReactNode;
8
+ };
9
+ export type ErrorProps = {
10
+ error: Error;
11
+ reset: () => void;
12
+ };
13
+ type RouteModule = {
14
+ default: ComponentType<PageProps>;
15
+ };
16
+ type BoundaryModule = {
17
+ default: ComponentType<LayoutProps> | ComponentType<ErrorProps>;
18
+ };
19
+ export type { BoundaryKind };
20
+ /**
21
+ * The runtime Route type is *derived* from `@extrojs/types`' single source
22
+ * (ADR 0005), not re-declared: the same skeleton as the Route manifest, with
23
+ * the React module types substituted in and `pattern` materialized to a real
24
+ * RegExp. A round-trip test asserts the codegen output satisfies this.
25
+ */
26
+ export type Boundary = RuntimeBoundary<BoundaryModule>;
27
+ export type Route = RuntimeRoute<RouteModule, BoundaryModule>;
28
+ export type StaticRoute = Extract<Route, {
29
+ type: "static";
30
+ }>;
31
+ export type DynamicRoute = Extract<Route, {
32
+ type: "dynamic";
33
+ }>;
34
+ export type RouteMatch = {
35
+ route: Route;
36
+ params: Record<string, string>;
37
+ };
38
+ /** Surface-root not-found.tsx (no props, ADR 0003 §5). `null` when absent. */
39
+ export type NotFoundLoader = (() => Promise<{
40
+ default: ComponentType;
41
+ }>) | null;
42
+ /** Surface-root layout.tsx, wraps not-found. `null` when absent. */
43
+ export type RootLayoutLoader = (() => Promise<{
44
+ default: ComponentType<LayoutProps>;
45
+ }>) | null;
46
+ export type RouterSurfaceOptions = {
47
+ notFound?: NotFoundLoader;
48
+ rootLayout?: RootLayoutLoader;
49
+ };
50
+ export type CreateRouterOptions = RouterSurfaceOptions & {
51
+ /** DOM id to mount into. Defaults to "root". */
52
+ rootId?: string;
53
+ /** Human-readable surface name (popup | options | sidepanel). Used in error logs. */
54
+ surface?: string;
55
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,152 @@
1
+ export interface ManifestV3 {
2
+ manifest_version: 3;
3
+ name?: string;
4
+ description?: string;
5
+ version: string;
6
+ /** Base64 public key that pins the extension ID. Sourced from EXTRO_CRX_KEY. */
7
+ key?: string;
8
+ action?: {
9
+ default_popup: string;
10
+ };
11
+ background?: {
12
+ service_worker: string;
13
+ };
14
+ content_scripts?: {
15
+ matches: string[];
16
+ js: string[];
17
+ }[];
18
+ host_permissions?: string[];
19
+ permissions?: string[];
20
+ options_ui?: {
21
+ page: string;
22
+ open_in_tab?: boolean;
23
+ };
24
+ side_panel?: {
25
+ default_path: string;
26
+ };
27
+ icons?: Record<string, string>;
28
+ content_security_policy?: {
29
+ extension_pages?: string;
30
+ sandbox?: string;
31
+ };
32
+ web_accessible_resources?: {
33
+ resources: string[];
34
+ matches: string[];
35
+ }[];
36
+ /**
37
+ * Any other Manifest V3 field Extro does not model. Lets `manifest` and
38
+ * `transformManifest` set arbitrary fields (e.g. `minimum_chrome_version`,
39
+ * `commands`) without casting.
40
+ */
41
+ [key: string]: unknown;
42
+ }
43
+ export interface ExtroConfig {
44
+ name?: string;
45
+ version?: string;
46
+ description?: string;
47
+ icons?: Record<string, string>;
48
+ permissions?: string[];
49
+ hostPermissions?: string[];
50
+ /**
51
+ * Per-surface configuration. Currently used for content scripts —
52
+ * `content.matches` controls which URLs the content script (and CSUI)
53
+ * is injected into. Defaults to `["<all_urls>"]`.
54
+ */
55
+ content?: {
56
+ matches?: string[];
57
+ };
58
+ /**
59
+ * Raw Manifest V3 fields merged over the promoted ones. The escape hatch
60
+ * for anything Extro does not model.
61
+ */
62
+ manifest?: Partial<ManifestV3>;
63
+ /**
64
+ * Final imperative hook over the fully generated manifest. Runs last (after
65
+ * the promoted fields, the `manifest` merge, and the CRX key), so it sees
66
+ * everything and can change anything. Mutate the argument or return a
67
+ * replacement.
68
+ */
69
+ transformManifest?: (manifest: ManifestV3) => ManifestV3 | void;
70
+ /**
71
+ * Base output directory. Default `output`. Extro writes the unpacked
72
+ * extension to `<outDir>/chrome-mv3-dev` and `<outDir>/chrome-mv3-prod`.
73
+ */
74
+ outDir?: string;
75
+ /** Dev server options for `extro dev`. */
76
+ dev?: {
77
+ /** Vite dev server port. Default 5173 (auto-increments unless strictPort). */
78
+ port?: number;
79
+ /** Port for the dev bridge's HMR/reload WebSocket. Default 9012. */
80
+ bridgePort?: number;
81
+ /** Fail if `port` is taken instead of trying the next one. */
82
+ strictPort?: boolean;
83
+ };
84
+ }
85
+ /** A Route's ancestor wrapper: a layout.tsx or an error.tsx (ADR 0003 §3). */
86
+ export type BoundaryKind = "layout" | "error";
87
+ /**
88
+ * Shared Route skeleton. `TLeaf` is the per-side payload (build carries file
89
+ * paths, runtime carries lazy imports). `TPattern` is the per-side shape of a
90
+ * dynamic Route's matcher: a source string in the serializable Route
91
+ * manifest, a live RegExp at runtime. `paramKeys` is byte-identical on every
92
+ * side, so it stays in the skeleton.
93
+ *
94
+ * See ADR 0005: the Route manifest is the single typed source; the runtime
95
+ * Route type is derived from this same skeleton, never re-declared.
96
+ */
97
+ export type StaticRouteShape<TLeaf> = {
98
+ type: "static";
99
+ /** URL path, e.g. "/" or "/settings". */
100
+ path: string;
101
+ } & TLeaf;
102
+ export type DynamicRouteShape<TLeaf, TPattern> = {
103
+ type: "dynamic";
104
+ /** Human-readable pattern, e.g. "/user/:id". */
105
+ path: string;
106
+ /** Ordered param names matching the matcher's capture groups. */
107
+ paramKeys: string[];
108
+ } & TPattern & TLeaf;
109
+ export type RouteShape<TLeaf, TPattern> = StaticRouteShape<TLeaf> | DynamicRouteShape<TLeaf, TPattern>;
110
+ /** One ancestor wrapper in a Route's boundary chain, build side. */
111
+ export type ManifestBoundary = {
112
+ kind: BoundaryKind;
113
+ file: string;
114
+ };
115
+ type ManifestLeaf = {
116
+ file: string;
117
+ boundaries: ManifestBoundary[];
118
+ };
119
+ type ManifestPattern = {
120
+ patternSource: string;
121
+ };
122
+ export type ManifestRoute = RouteShape<ManifestLeaf, ManifestPattern>;
123
+ /**
124
+ * The serializable, per-Routable-surface routing contract. Produced by the
125
+ * scanner, consumed by the single codegen (`emit`) that materializes the
126
+ * `virtual:extro/routes/<surface>` Runtime module. Strings only: it
127
+ * stable-stringifies for HMR invalidation and is plain test-fixture data.
128
+ */
129
+ export type RouteManifest = {
130
+ routes: ManifestRoute[];
131
+ /** Surface-root not-found.tsx, or null. */
132
+ notFound: string | null;
133
+ /** Surface-root layout.tsx, or null. */
134
+ rootLayout: string | null;
135
+ };
136
+ /** One loaded ancestor wrapper at runtime. `TMod` is the module shape. */
137
+ export type RuntimeBoundary<TMod> = {
138
+ kind: BoundaryKind;
139
+ load: () => Promise<TMod>;
140
+ };
141
+ /**
142
+ * The runtime Route type, derived from the same `RouteShape` skeleton as the
143
+ * manifest. Generic over the page/boundary module types so `@extrojs/types`
144
+ * needs no React dependency; `@extrojs/router` instantiates them.
145
+ */
146
+ export type RuntimeRoute<TPageMod, TBoundaryMod> = RouteShape<{
147
+ load: () => Promise<TPageMod>;
148
+ boundaries: RuntimeBoundary<TBoundaryMod>[];
149
+ }, {
150
+ pattern: RegExp;
151
+ }>;
152
+ export {};
@@ -0,0 +1 @@
1
+ export {};