@three-flatland/devtools 0.1.0-alpha.3

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 (148) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +82 -0
  3. package/dist/buffers-modal.cjs +491 -0
  4. package/dist/buffers-modal.cjs.map +1 -0
  5. package/dist/buffers-modal.d.cts +62 -0
  6. package/dist/buffers-modal.d.ts +62 -0
  7. package/dist/buffers-modal.js +467 -0
  8. package/dist/buffers-modal.js.map +1 -0
  9. package/dist/buffers-view.cjs +269 -0
  10. package/dist/buffers-view.cjs.map +1 -0
  11. package/dist/buffers-view.d.cts +39 -0
  12. package/dist/buffers-view.d.ts +39 -0
  13. package/dist/buffers-view.js +245 -0
  14. package/dist/buffers-view.js.map +1 -0
  15. package/dist/create-pane.cjs +203 -0
  16. package/dist/create-pane.cjs.map +1 -0
  17. package/dist/create-pane.d.cts +66 -0
  18. package/dist/create-pane.d.ts +66 -0
  19. package/dist/create-pane.js +178 -0
  20. package/dist/create-pane.js.map +1 -0
  21. package/dist/dashboard/app.tsx +42 -0
  22. package/dist/dashboard/client.ts +21 -0
  23. package/dist/dashboard/export.ts +84 -0
  24. package/dist/dashboard/hooks.ts +75 -0
  25. package/dist/dashboard/index.html +1149 -0
  26. package/dist/dashboard/index.tsx +18 -0
  27. package/dist/dashboard/panels/batches.tsx +282 -0
  28. package/dist/dashboard/panels/buffers.tsx +425 -0
  29. package/dist/dashboard/panels/env.tsx +85 -0
  30. package/dist/dashboard/panels/header-stats.tsx +30 -0
  31. package/dist/dashboard/panels/producer-select.tsx +81 -0
  32. package/dist/dashboard/panels/protocol-log.tsx +743 -0
  33. package/dist/dashboard/panels/registry.tsx +642 -0
  34. package/dist/dashboard/panels/stats.tsx +431 -0
  35. package/dist/dashboard/protocol-store.ts +312 -0
  36. package/dist/dashboard/tsconfig.json +19 -0
  37. package/dist/dashboard/vendor/hooks.module.js +1 -0
  38. package/dist/dashboard/vendor/jsx-runtime.js +22 -0
  39. package/dist/dashboard/vendor/preact.module.js +12 -0
  40. package/dist/devtools-client.cjs +870 -0
  41. package/dist/devtools-client.cjs.map +1 -0
  42. package/dist/devtools-client.d.cts +362 -0
  43. package/dist/devtools-client.d.ts +362 -0
  44. package/dist/devtools-client.js +852 -0
  45. package/dist/devtools-client.js.map +1 -0
  46. package/dist/index.cjs +42 -0
  47. package/dist/index.cjs.map +1 -0
  48. package/dist/index.d.cts +8 -0
  49. package/dist/index.d.ts +8 -0
  50. package/dist/index.js +13 -0
  51. package/dist/index.js.map +1 -0
  52. package/dist/perf-trace.cjs +103 -0
  53. package/dist/perf-trace.cjs.map +1 -0
  54. package/dist/perf-trace.d.cts +27 -0
  55. package/dist/perf-trace.d.ts +27 -0
  56. package/dist/perf-trace.js +79 -0
  57. package/dist/perf-trace.js.map +1 -0
  58. package/dist/plugins.cjs +44 -0
  59. package/dist/plugins.cjs.map +1 -0
  60. package/dist/plugins.d.cts +7 -0
  61. package/dist/plugins.d.ts +7 -0
  62. package/dist/plugins.js +9 -0
  63. package/dist/plugins.js.map +1 -0
  64. package/dist/provider-switcher.cjs +95 -0
  65. package/dist/provider-switcher.cjs.map +1 -0
  66. package/dist/provider-switcher.d.cts +18 -0
  67. package/dist/provider-switcher.d.ts +18 -0
  68. package/dist/provider-switcher.js +71 -0
  69. package/dist/provider-switcher.js.map +1 -0
  70. package/dist/react/devtools-provider.cjs +59 -0
  71. package/dist/react/devtools-provider.cjs.map +1 -0
  72. package/dist/react/devtools-provider.d.cts +39 -0
  73. package/dist/react/devtools-provider.d.ts +39 -0
  74. package/dist/react/devtools-provider.js +38 -0
  75. package/dist/react/devtools-provider.js.map +1 -0
  76. package/dist/react/use-fps-graph.cjs +49 -0
  77. package/dist/react/use-fps-graph.cjs.map +1 -0
  78. package/dist/react/use-fps-graph.d.cts +15 -0
  79. package/dist/react/use-fps-graph.d.ts +15 -0
  80. package/dist/react/use-fps-graph.js +25 -0
  81. package/dist/react/use-fps-graph.js.map +1 -0
  82. package/dist/react/use-pane-button.cjs +58 -0
  83. package/dist/react/use-pane-button.cjs.map +1 -0
  84. package/dist/react/use-pane-button.d.cts +10 -0
  85. package/dist/react/use-pane-button.d.ts +10 -0
  86. package/dist/react/use-pane-button.js +34 -0
  87. package/dist/react/use-pane-button.js.map +1 -0
  88. package/dist/react/use-pane-folder.cjs +48 -0
  89. package/dist/react/use-pane-folder.cjs.map +1 -0
  90. package/dist/react/use-pane-folder.d.cts +15 -0
  91. package/dist/react/use-pane-folder.d.ts +15 -0
  92. package/dist/react/use-pane-folder.js +24 -0
  93. package/dist/react/use-pane-folder.js.map +1 -0
  94. package/dist/react/use-pane-input.cjs +70 -0
  95. package/dist/react/use-pane-input.cjs.map +1 -0
  96. package/dist/react/use-pane-input.d.cts +44 -0
  97. package/dist/react/use-pane-input.d.ts +44 -0
  98. package/dist/react/use-pane-input.js +46 -0
  99. package/dist/react/use-pane-input.js.map +1 -0
  100. package/dist/react/use-pane-radio-grid.cjs +78 -0
  101. package/dist/react/use-pane-radio-grid.cjs.map +1 -0
  102. package/dist/react/use-pane-radio-grid.d.cts +35 -0
  103. package/dist/react/use-pane-radio-grid.d.ts +35 -0
  104. package/dist/react/use-pane-radio-grid.js +54 -0
  105. package/dist/react/use-pane-radio-grid.js.map +1 -0
  106. package/dist/react/use-pane.cjs +45 -0
  107. package/dist/react/use-pane.cjs.map +1 -0
  108. package/dist/react/use-pane.d.cts +40 -0
  109. package/dist/react/use-pane.d.ts +40 -0
  110. package/dist/react/use-pane.js +21 -0
  111. package/dist/react/use-pane.js.map +1 -0
  112. package/dist/react.cjs +50 -0
  113. package/dist/react.cjs.map +1 -0
  114. package/dist/react.d.cts +12 -0
  115. package/dist/react.d.ts +12 -0
  116. package/dist/react.js +19 -0
  117. package/dist/react.js.map +1 -0
  118. package/dist/registry-view.cjs +371 -0
  119. package/dist/registry-view.cjs.map +1 -0
  120. package/dist/registry-view.d.cts +24 -0
  121. package/dist/registry-view.d.ts +24 -0
  122. package/dist/registry-view.js +347 -0
  123. package/dist/registry-view.js.map +1 -0
  124. package/dist/stats-graph.cjs +297 -0
  125. package/dist/stats-graph.cjs.map +1 -0
  126. package/dist/stats-graph.d.cts +40 -0
  127. package/dist/stats-graph.d.ts +40 -0
  128. package/dist/stats-graph.js +273 -0
  129. package/dist/stats-graph.js.map +1 -0
  130. package/dist/stats-row.cjs +153 -0
  131. package/dist/stats-row.cjs.map +1 -0
  132. package/dist/stats-row.d.cts +24 -0
  133. package/dist/stats-row.d.ts +24 -0
  134. package/dist/stats-row.js +129 -0
  135. package/dist/stats-row.js.map +1 -0
  136. package/dist/theme.cjs +260 -0
  137. package/dist/theme.cjs.map +1 -0
  138. package/dist/theme.d.cts +10 -0
  139. package/dist/theme.d.ts +10 -0
  140. package/dist/theme.js +235 -0
  141. package/dist/theme.js.map +1 -0
  142. package/dist/vite-plugin.cjs +113 -0
  143. package/dist/vite-plugin.cjs.map +1 -0
  144. package/dist/vite-plugin.d.cts +9 -0
  145. package/dist/vite-plugin.d.ts +9 -0
  146. package/dist/vite-plugin.js +88 -0
  147. package/dist/vite-plugin.js.map +1 -0
  148. package/package.json +124 -0
@@ -0,0 +1,312 @@
1
+ /**
2
+ * Session-scoped protocol log store, scoped per producer.
3
+ *
4
+ * One IndexedDB object store holds every inbound/outbound bus message.
5
+ * Entries carry the `providerId` they were captured against (whichever
6
+ * producer was selected at the time). Per-provider totals + caches mean
7
+ * swapping producers in the UI preserves each stream's history — no
8
+ * cross-contamination, no data loss on switch.
9
+ *
10
+ * IDB layout: one object store keyed by `id` (monotonic across the
11
+ * whole session so we never reuse numbers), with a non-unique
12
+ * `providerId` index for range queries scoped to a provider. Wiped on
13
+ * construction — the dashboard is a throwaway inspector.
14
+ *
15
+ * Writes batch through `WRITE_FLUSH_MS` into a single transaction so
16
+ * even a flood of `buffer:chunk` messages doesn't cost per-entry round
17
+ * trips.
18
+ */
19
+
20
+ /** One log record. */
21
+ export interface LogEntry {
22
+ id: number
23
+ providerId: string
24
+ at: number
25
+ direction: 'in' | 'out'
26
+ type: string
27
+ tag?: string
28
+ frame?: number
29
+ bytes: number
30
+ msg: unknown
31
+ }
32
+
33
+ const DB_NAME = 'tf-devtools-protocol'
34
+ const STORE = 'messages'
35
+ const INDEX = 'by-provider'
36
+ const WRITE_FLUSH_MS = 80
37
+ const TAIL_CACHE = 400
38
+ const LRU_MAX = 4000
39
+
40
+ type Listener = () => void
41
+
42
+ interface ProviderState {
43
+ total: number
44
+ maxId: number
45
+ /** Ids belonging to this provider, kept as a dense array. Used so
46
+ * visual-index → id mapping doesn't have to round-trip IDB. */
47
+ ids: number[]
48
+ }
49
+
50
+ export class ProtocolStore {
51
+ /** Running global byte counters — independent of provider scope. */
52
+ bytesIn = 0
53
+ bytesOut = 0
54
+ /** Union of every `type` we've seen since construction — used by the
55
+ * protocol filter UI to populate its type-multiselect. */
56
+ knownTypes = new Set<string>()
57
+
58
+ private _db: IDBDatabase | null = null
59
+ private _dbReady: Promise<IDBDatabase>
60
+ private _nextId = 1
61
+ private _providers = new Map<string, ProviderState>()
62
+ /** Cache: `${providerId}:${id}` → entry. Always contains each
63
+ * provider's most recent TAIL_CACHE entries to keep tail sync. */
64
+ private _cache = new Map<string, LogEntry>()
65
+ private _writeBuffer: LogEntry[] = []
66
+ private _flushTimer: number | null = null
67
+ private _listeners = new Set<Listener>()
68
+ private _pendingRanges = new Map<string, Promise<void>>()
69
+
70
+ constructor() {
71
+ this._dbReady = this._openAndWipe()
72
+ }
73
+
74
+ private async _openAndWipe(): Promise<IDBDatabase> {
75
+ // Try open at v1. If the store/index layout doesn't match (older
76
+ // session stored a different schema), delete the DB and reopen.
77
+ const db = await this._open()
78
+ this._db = db
79
+ // Wipe on mount — dashboard is single-session.
80
+ await new Promise<void>((resolve, reject) => {
81
+ const tx = db.transaction(STORE, 'readwrite')
82
+ tx.objectStore(STORE).clear()
83
+ tx.oncomplete = () => resolve()
84
+ tx.onerror = () => reject(tx.error ?? new Error('IndexedDB transaction failed'))
85
+ })
86
+ return db
87
+ }
88
+
89
+ private _open(): Promise<IDBDatabase> {
90
+ return new Promise<IDBDatabase>((resolve, reject) => {
91
+ const req = indexedDB.open(DB_NAME, 2)
92
+ req.onupgradeneeded = () => {
93
+ const d = req.result
94
+ if (d.objectStoreNames.contains(STORE)) d.deleteObjectStore(STORE)
95
+ const store = d.createObjectStore(STORE, { keyPath: 'id' })
96
+ store.createIndex(INDEX, 'providerId', { unique: false })
97
+ }
98
+ req.onsuccess = () => resolve(req.result)
99
+ req.onerror = () => reject(req.error ?? new Error('IndexedDB request failed'))
100
+ })
101
+ }
102
+
103
+ addListener(cb: Listener): () => void {
104
+ this._listeners.add(cb)
105
+ return () => { this._listeners.delete(cb) }
106
+ }
107
+
108
+ private _fire(): void {
109
+ for (const cb of this._listeners) {
110
+ try { cb() } catch { /* ignore */ }
111
+ }
112
+ }
113
+
114
+ /** Per-provider counters. Returns zeros if the provider isn't known. */
115
+ statsFor(providerId: string | null): { total: number; maxId: number; ids: number[] } {
116
+ if (providerId === null) return { total: 0, maxId: 0, ids: [] }
117
+ const s = this._providers.get(providerId)
118
+ return s !== undefined ? s : { total: 0, maxId: 0, ids: [] }
119
+ }
120
+
121
+ /** All provider ids currently tracked in the store. */
122
+ providers(): string[] {
123
+ return Array.from(this._providers.keys())
124
+ }
125
+
126
+ /**
127
+ * Append a new entry. Global id is monotonic across providers; per-
128
+ * provider totals and index arrays grow independently.
129
+ */
130
+ push(providerId: string, partial: Omit<LogEntry, 'id' | 'providerId'>): LogEntry {
131
+ const id = this._nextId++
132
+ const entry: LogEntry = { ...partial, id, providerId }
133
+ const key = cacheKey(providerId, id)
134
+ this._cache.set(key, entry)
135
+ let ps = this._providers.get(providerId)
136
+ if (ps === undefined) {
137
+ ps = { total: 0, maxId: 0, ids: [] }
138
+ this._providers.set(providerId, ps)
139
+ }
140
+ ps.total++
141
+ ps.maxId = id
142
+ ps.ids.push(id)
143
+
144
+ if (partial.direction === 'in') this.bytesIn += partial.bytes
145
+ else this.bytesOut += partial.bytes
146
+ this.knownTypes.add(partial.type)
147
+
148
+ this._writeBuffer.push(entry)
149
+ if (this._flushTimer === null) {
150
+ this._flushTimer = (globalThis.setTimeout as unknown as (cb: () => void, ms: number) => number)(
151
+ () => this._flush(),
152
+ WRITE_FLUSH_MS,
153
+ )
154
+ }
155
+ this._evictIfNeeded(providerId)
156
+ this._fire()
157
+ return entry
158
+ }
159
+
160
+ /** Wipe everything (memory + IDB + counters). */
161
+ clear(): void {
162
+ this._cache.clear()
163
+ this._providers.clear()
164
+ this._writeBuffer.length = 0
165
+ this._nextId = 1
166
+ this.bytesIn = 0
167
+ this.bytesOut = 0
168
+ this.knownTypes.clear()
169
+ if (this._db !== null) {
170
+ try {
171
+ const tx = this._db.transaction(STORE, 'readwrite')
172
+ tx.objectStore(STORE).clear()
173
+ } catch { /* db closing */ }
174
+ }
175
+ this._fire()
176
+ }
177
+
178
+ /** Sync cache lookup. */
179
+ peek(providerId: string, id: number): LogEntry | null {
180
+ return this._cache.get(cacheKey(providerId, id)) ?? null
181
+ }
182
+
183
+ /** Ensure the given contiguous-in-ids-array range is in the cache. */
184
+ async prefetchRange(providerId: string, startId: number, endId: number): Promise<void> {
185
+ if (startId > endId) return
186
+ const key = `${providerId}:${startId}:${endId}`
187
+ const existing = this._pendingRanges.get(key)
188
+ if (existing !== undefined) return existing
189
+ // Quick hit check.
190
+ let allHit = true
191
+ for (let id = startId; id <= endId; id++) {
192
+ if (!this._cache.has(cacheKey(providerId, id))) { allHit = false; break }
193
+ }
194
+ if (allHit) return
195
+ const promise = this._readRange(providerId, startId, endId)
196
+ this._pendingRanges.set(key, promise)
197
+ try {
198
+ await promise
199
+ } finally {
200
+ this._pendingRanges.delete(key)
201
+ }
202
+ }
203
+
204
+ /**
205
+ * Walk every entry in the store belonging to `providerId` and return
206
+ * the ids of those that satisfy `predicate`. Matching entries are
207
+ * also hydrated into the cache as a side-effect so rendering them
208
+ * afterwards is synchronous.
209
+ *
210
+ * `signal` lets the caller bail the cursor early when the filter
211
+ * changes under their feet — cursor walks on large sessions can take
212
+ * tens of ms and we don't want stale results racing fresh ones.
213
+ */
214
+ async queryFiltered(
215
+ providerId: string,
216
+ predicate: (entry: LogEntry) => boolean,
217
+ signal?: { aborted: boolean },
218
+ ): Promise<number[]> {
219
+ const db = await this._dbReady
220
+ const out: number[] = []
221
+ await new Promise<void>((resolve, reject) => {
222
+ const tx = db.transaction(STORE, 'readonly')
223
+ const store = tx.objectStore(STORE)
224
+ const index = store.index(INDEX)
225
+ const req = index.openCursor(IDBKeyRange.only(providerId))
226
+ req.onsuccess = () => {
227
+ if (signal?.aborted === true) { resolve(); return }
228
+ const cursor = req.result
229
+ if (cursor === null) { resolve(); return }
230
+ const entry = cursor.value as LogEntry
231
+ if (predicate(entry)) {
232
+ out.push(entry.id)
233
+ const key = cacheKey(providerId, entry.id)
234
+ if (!this._cache.has(key)) this._cache.set(key, entry)
235
+ }
236
+ cursor.continue()
237
+ }
238
+ req.onerror = () => reject(req.error ?? new Error('IndexedDB request failed'))
239
+ })
240
+ // Cursor yields in key order (ascending id) which matches our
241
+ // expected rendering direction (newest-first = reverse).
242
+ return out
243
+ }
244
+
245
+ private async _readRange(providerId: string, startId: number, endId: number): Promise<void> {
246
+ const db = await this._dbReady
247
+ await new Promise<void>((resolve, reject) => {
248
+ const tx = db.transaction(STORE, 'readonly')
249
+ const store = tx.objectStore(STORE)
250
+ const range = IDBKeyRange.bound(startId, endId, false, false)
251
+ const req = store.getAll(range)
252
+ req.onsuccess = () => {
253
+ for (const entry of req.result as LogEntry[]) {
254
+ if (entry.providerId !== providerId) continue
255
+ const key = cacheKey(entry.providerId, entry.id)
256
+ if (!this._cache.has(key)) this._cache.set(key, entry)
257
+ }
258
+ resolve()
259
+ }
260
+ req.onerror = () => reject(req.error ?? new Error('IndexedDB request failed'))
261
+ })
262
+ this._fire()
263
+ }
264
+
265
+ private _flush(): void {
266
+ this._flushTimer = null
267
+ if (this._writeBuffer.length === 0) return
268
+ const batch = this._writeBuffer
269
+ this._writeBuffer = []
270
+ void this._writeBatch(batch)
271
+ }
272
+
273
+ private async _writeBatch(batch: LogEntry[]): Promise<void> {
274
+ const db = await this._dbReady
275
+ try {
276
+ const tx = db.transaction(STORE, 'readwrite')
277
+ const store = tx.objectStore(STORE)
278
+ for (const entry of batch) store.put(entry)
279
+ tx.onerror = () => {
280
+ console.warn('[devtools-dashboard] IDB write failed:', tx.error)
281
+ }
282
+ } catch (err) {
283
+ console.warn('[devtools-dashboard] IDB transaction failed:', err)
284
+ }
285
+ }
286
+
287
+ /** LRU eviction, keyed per-provider. Tail always pinned. */
288
+ private _evictIfNeeded(providerId: string): void {
289
+ if (this._cache.size <= LRU_MAX) return
290
+ const ps = this._providers.get(providerId)
291
+ if (ps === undefined) return
292
+ const keepFrom = ps.maxId - TAIL_CACHE + 1
293
+ const toDrop: string[] = []
294
+ for (const k of this._cache.keys()) {
295
+ if (!k.startsWith(`${providerId}:`)) continue
296
+ const id = parseInt(k.slice(providerId.length + 1), 10)
297
+ if (id < keepFrom) toDrop.push(k)
298
+ if (this._cache.size - toDrop.length <= LRU_MAX) break
299
+ }
300
+ for (const k of toDrop) this._cache.delete(k)
301
+ }
302
+ }
303
+
304
+ function cacheKey(providerId: string, id: number): string {
305
+ return `${providerId}:${id}`
306
+ }
307
+
308
+ let _instance: ProtocolStore | null = null
309
+ export function getProtocolStore(): ProtocolStore {
310
+ if (_instance === null) _instance = new ProtocolStore()
311
+ return _instance
312
+ }
@@ -0,0 +1,19 @@
1
+ {
2
+ "extends": "../../../../tsconfig.base.json",
3
+ "compilerOptions": {
4
+ "noEmit": true,
5
+ "declaration": false,
6
+ "declarationMap": false,
7
+ "jsx": "react-jsx",
8
+ "jsxImportSource": "preact",
9
+ "allowJs": true,
10
+ "checkJs": false,
11
+ "paths": {
12
+ "preact": ["./vendor/preact.module"],
13
+ "preact/jsx-runtime": ["./vendor/jsx-runtime"],
14
+ "preact/hooks": ["./vendor/hooks.module"]
15
+ }
16
+ },
17
+ "include": ["**/*"],
18
+ "exclude": ["node_modules", "**/*.test.ts", "**/*.test.tsx"]
19
+ }
@@ -0,0 +1 @@
1
+ import{options as n}from"preact";var t,r,u,i,o=0,f=[],c=[],e=n,a=e.__b,v=e.__r,l=e.diffed,m=e.__c,s=e.unmount,d=e.__;function h(n,t){e.__h&&e.__h(r,n,o||t),o=0;var u=r.__H||(r.__H={__:[],__h:[]});return n>=u.__.length&&u.__.push({__V:c}),u.__[n]}function p(n){return o=1,y(D,n)}function y(n,u,i){var o=h(t++,2);if(o.t=n,!o.__c&&(o.__=[i?i(u):D(void 0,u),function(n){var t=o.__N?o.__N[0]:o.__[0],r=o.t(t,n);t!==r&&(o.__N=[r,o.__[1]],o.__c.setState({}))}],o.__c=r,!r.u)){var f=function(n,t,r){if(!o.__c.__H)return!0;var u=o.__c.__H.__.filter(function(n){return!!n.__c});if(u.every(function(n){return!n.__N}))return!c||c.call(this,n,t,r);var i=!1;return u.forEach(function(n){if(n.__N){var t=n.__[0];n.__=n.__N,n.__N=void 0,t!==n.__[0]&&(i=!0)}}),!(!i&&o.__c.props===n)&&(!c||c.call(this,n,t,r))};r.u=!0;var c=r.shouldComponentUpdate,e=r.componentWillUpdate;r.componentWillUpdate=function(n,t,r){if(this.__e){var u=c;c=void 0,f(n,t,r),c=u}e&&e.call(this,n,t,r)},r.shouldComponentUpdate=f}return o.__N||o.__}function _(n,u){var i=h(t++,3);!e.__s&&C(i.__H,u)&&(i.__=n,i.i=u,r.__H.__h.push(i))}function A(n,u){var i=h(t++,4);!e.__s&&C(i.__H,u)&&(i.__=n,i.i=u,r.__h.push(i))}function F(n){return o=5,q(function(){return{current:n}},[])}function T(n,t,r){o=6,A(function(){return"function"==typeof n?(n(t()),function(){return n(null)}):n?(n.current=t(),function(){return n.current=null}):void 0},null==r?r:r.concat(n))}function q(n,r){var u=h(t++,7);return C(u.__H,r)?(u.__V=n(),u.i=r,u.__h=n,u.__V):u.__}function x(n,t){return o=8,q(function(){return n},t)}function P(n){var u=r.context[n.__c],i=h(t++,9);return i.c=n,u?(null==i.__&&(i.__=!0,u.sub(r)),u.props.value):n.__}function V(n,t){e.useDebugValue&&e.useDebugValue(t?t(n):n)}function b(n){var u=h(t++,10),i=p();return u.__=n,r.componentDidCatch||(r.componentDidCatch=function(n,t){u.__&&u.__(n,t),i[1](n)}),[i[0],function(){i[1](void 0)}]}function g(){var n=h(t++,11);if(!n.__){for(var u=r.__v;null!==u&&!u.__m&&null!==u.__;)u=u.__;var i=u.__m||(u.__m=[0,0]);n.__="P"+i[0]+"-"+i[1]++}return n.__}function j(){for(var n;n=f.shift();)if(n.__P&&n.__H)try{n.__H.__h.forEach(z),n.__H.__h.forEach(B),n.__H.__h=[]}catch(t){n.__H.__h=[],e.__e(t,n.__v)}}e.__b=function(n){r=null,a&&a(n)},e.__=function(n,t){n&&t.__k&&t.__k.__m&&(n.__m=t.__k.__m),d&&d(n,t)},e.__r=function(n){v&&v(n),t=0;var i=(r=n.__c).__H;i&&(u===r?(i.__h=[],r.__h=[],i.__.forEach(function(n){n.__N&&(n.__=n.__N),n.__V=c,n.__N=n.i=void 0})):(i.__h.forEach(z),i.__h.forEach(B),i.__h=[],t=0)),u=r},e.diffed=function(n){l&&l(n);var t=n.__c;t&&t.__H&&(t.__H.__h.length&&(1!==f.push(t)&&i===e.requestAnimationFrame||((i=e.requestAnimationFrame)||w)(j)),t.__H.__.forEach(function(n){n.i&&(n.__H=n.i),n.__V!==c&&(n.__=n.__V),n.i=void 0,n.__V=c})),u=r=null},e.__c=function(n,t){t.some(function(n){try{n.__h.forEach(z),n.__h=n.__h.filter(function(n){return!n.__||B(n)})}catch(r){t.some(function(n){n.__h&&(n.__h=[])}),t=[],e.__e(r,n.__v)}}),m&&m(n,t)},e.unmount=function(n){s&&s(n);var t,r=n.__c;r&&r.__H&&(r.__H.__.forEach(function(n){try{z(n)}catch(n){t=n}}),r.__H=void 0,t&&e.__e(t,r.__v))};var k="function"==typeof requestAnimationFrame;function w(n){var t,r=function(){clearTimeout(u),k&&cancelAnimationFrame(t),setTimeout(n)},u=setTimeout(r,100);k&&(t=requestAnimationFrame(r))}function z(n){var t=r,u=n.__c;"function"==typeof u&&(n.__c=void 0,u()),r=t}function B(n){var t=r;n.__c=n.__(),r=t}function C(n,t){return!n||n.length!==t.length||t.some(function(t,r){return t!==n[r]})}function D(n,t){return"function"==typeof t?t(n):t}export{x as useCallback,P as useContext,V as useDebugValue,_ as useEffect,b as useErrorBoundary,g as useId,T as useImperativeHandle,A as useLayoutEffect,q as useMemo,y as useReducer,F as useRef,p as useState};
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Minimal Preact JSX-runtime shim.
3
+ *
4
+ * TypeScript's `jsxImportSource: "preact"` compiles JSX to `jsx(type, props)` /
5
+ * `jsxs(type, props)` calls from `preact/jsx-runtime`. This shim re-exports
6
+ * Preact's `h` under those names. Children arrive in `props.children` instead
7
+ * of as variadic arguments — Preact's `h` accepts both forms.
8
+ *
9
+ * Preact itself is vendored next door at `./preact.module.js`. This file is
10
+ * intentionally minimal so updating Preact is a single-file swap.
11
+ */
12
+ export { Fragment } from './preact.module.js'
13
+ import { h } from './preact.module.js'
14
+
15
+ export function jsx(type, props, key) {
16
+ const { children, ...rest } = props ?? {}
17
+ if (key !== undefined) rest.key = key
18
+ return h(type, rest, children)
19
+ }
20
+
21
+ export const jsxs = jsx
22
+ export const jsxDEV = jsx
@@ -0,0 +1,12 @@
1
+ /*
2
+ * Preact v10.22.0 — vendored copy.
3
+ * https://github.com/preactjs/preact
4
+ *
5
+ * Copyright (c) 2015-present Jason Miller <jasonmiller@aol.com>
6
+ * Licensed under the MIT License (https://opensource.org/licenses/MIT).
7
+ *
8
+ * Kept verbatim so the devtools dashboard ships without a runtime dep on
9
+ * Preact. Update by re-fetching `preact@X.Y.Z/dist/preact.mjs` and replacing
10
+ * this file.
11
+ */
12
+ var n,l,u,t,i,o,r,f,e,c,s,a,h={},p=[],v=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i,y=Array.isArray;function d(n,l){for(var u in l)n[u]=l[u];return n}function w(n){var l=n.parentNode;l&&l.removeChild(n)}function _(l,u,t){var i,o,r,f={};for(r in u)"key"==r?i=u[r]:"ref"==r?o=u[r]:f[r]=u[r];if(arguments.length>2&&(f.children=arguments.length>3?n.call(arguments,2):t),"function"==typeof l&&null!=l.defaultProps)for(r in l.defaultProps)void 0===f[r]&&(f[r]=l.defaultProps[r]);return g(l,f,i,o,null)}function g(n,t,i,o,r){var f={type:n,props:t,key:i,ref:o,__k:null,__:null,__b:0,__e:null,__d:void 0,__c:null,constructor:void 0,__v:null==r?++u:r,__i:-1,__u:0};return null==r&&null!=l.vnode&&l.vnode(f),f}function m(){return{current:null}}function k(n){return n.children}function b(n,l){this.props=n,this.context=l}function x(n,l){if(null==l)return n.__?x(n.__,n.__i+1):null;for(var u;l<n.__k.length;l++)if(null!=(u=n.__k[l])&&null!=u.__e)return u.__e;return"function"==typeof n.type?x(n):null}function C(n){var l,u;if(null!=(n=n.__)&&null!=n.__c){for(n.__e=n.__c.base=null,l=0;l<n.__k.length;l++)if(null!=(u=n.__k[l])&&null!=u.__e){n.__e=n.__c.base=u.__e;break}return C(n)}}function M(n){(!n.__d&&(n.__d=!0)&&i.push(n)&&!P.__r++||o!==l.debounceRendering)&&((o=l.debounceRendering)||r)(P)}function P(){var n,u,t,o,r,e,c,s;for(i.sort(f);n=i.shift();)n.__d&&(u=i.length,o=void 0,e=(r=(t=n).__v).__e,c=[],s=[],t.__P&&((o=d({},r)).__v=r.__v+1,l.vnode&&l.vnode(o),O(t.__P,o,r,t.__n,t.__P.namespaceURI,32&r.__u?[e]:null,c,null==e?x(r):e,!!(32&r.__u),s),o.__v=r.__v,o.__.__k[o.__i]=o,j(c,o,s),o.__e!=e&&C(o)),i.length>u&&i.sort(f));P.__r=0}function S(n,l,u,t,i,o,r,f,e,c,s){var a,v,y,d,w,_=t&&t.__k||p,g=l.length;for(u.__d=e,$(u,l,_),e=u.__d,a=0;a<g;a++)null!=(y=u.__k[a])&&"boolean"!=typeof y&&"function"!=typeof y&&(v=-1===y.__i?h:_[y.__i]||h,y.__i=a,O(n,y,v,i,o,r,f,e,c,s),d=y.__e,y.ref&&v.ref!=y.ref&&(v.ref&&N(v.ref,null,y),s.push(y.ref,y.__c||d,y)),null==w&&null!=d&&(w=d),65536&y.__u||v.__k===y.__k?(e&&!e.isConnected&&(e=x(v)),e=I(y,e,n)):"function"==typeof y.type&&void 0!==y.__d?e=y.__d:d&&(e=d.nextSibling),y.__d=void 0,y.__u&=-196609);u.__d=e,u.__e=w}function $(n,l,u){var t,i,o,r,f,e=l.length,c=u.length,s=c,a=0;for(n.__k=[],t=0;t<e;t++)r=t+a,null!=(i=n.__k[t]=null==(i=l[t])||"boolean"==typeof i||"function"==typeof i?null:"string"==typeof i||"number"==typeof i||"bigint"==typeof i||i.constructor==String?g(null,i,null,null,null):y(i)?g(k,{children:i},null,null,null):void 0===i.constructor&&i.__b>0?g(i.type,i.props,i.key,i.ref?i.ref:null,i.__v):i)?(i.__=n,i.__b=n.__b+1,f=L(i,u,r,s),i.__i=f,o=null,-1!==f&&(s--,(o=u[f])&&(o.__u|=131072)),null==o||null===o.__v?(-1==f&&a--,"function"!=typeof i.type&&(i.__u|=65536)):f!==r&&(f===r+1?a++:f>r?s>e-r?a+=f-r:a--:f<r?f==r-1&&(a=f-r):a=0,f!==t+a&&(i.__u|=65536))):(o=u[r])&&null==o.key&&o.__e&&0==(131072&o.__u)&&(o.__e==n.__d&&(n.__d=x(o)),V(o,o,!1),u[r]=null,s--);if(s)for(t=0;t<c;t++)null!=(o=u[t])&&0==(131072&o.__u)&&(o.__e==n.__d&&(n.__d=x(o)),V(o,o))}function I(n,l,u){var t,i;if("function"==typeof n.type){for(t=n.__k,i=0;t&&i<t.length;i++)t[i]&&(t[i].__=n,l=I(t[i],l,u));return l}n.__e!=l&&(u.insertBefore(n.__e,l||null),l=n.__e);do{l=l&&l.nextSibling}while(null!=l&&8===l.nodeType);return l}function H(n,l){return l=l||[],null==n||"boolean"==typeof n||(y(n)?n.some(function(n){H(n,l)}):l.push(n)),l}function L(n,l,u,t){var i=n.key,o=n.type,r=u-1,f=u+1,e=l[u];if(null===e||e&&i==e.key&&o===e.type&&0==(131072&e.__u))return u;if(t>(null!=e&&0==(131072&e.__u)?1:0))for(;r>=0||f<l.length;){if(r>=0){if((e=l[r])&&0==(131072&e.__u)&&i==e.key&&o===e.type)return r;r--}if(f<l.length){if((e=l[f])&&0==(131072&e.__u)&&i==e.key&&o===e.type)return f;f++}}return-1}function T(n,l,u){"-"===l[0]?n.setProperty(l,null==u?"":u):n[l]=null==u?"":"number"!=typeof u||v.test(l)?u:u+"px"}function A(n,l,u,t,i){var o;n:if("style"===l)if("string"==typeof u)n.style.cssText=u;else{if("string"==typeof t&&(n.style.cssText=t=""),t)for(l in t)u&&l in u||T(n.style,l,"");if(u)for(l in u)t&&u[l]===t[l]||T(n.style,l,u[l])}else if("o"===l[0]&&"n"===l[1])o=l!==(l=l.replace(/(PointerCapture)$|Capture$/i,"$1")),l=l.toLowerCase()in n||"onFocusOut"===l||"onFocusIn"===l?l.toLowerCase().slice(2):l.slice(2),n.l||(n.l={}),n.l[l+o]=u,u?t?u.u=t.u:(u.u=e,n.addEventListener(l,o?s:c,o)):n.removeEventListener(l,o?s:c,o);else{if("http://www.w3.org/2000/svg"==i)l=l.replace(/xlink(H|:h)/,"h").replace(/sName$/,"s");else if("width"!=l&&"height"!=l&&"href"!=l&&"list"!=l&&"form"!=l&&"tabIndex"!=l&&"download"!=l&&"rowSpan"!=l&&"colSpan"!=l&&"role"!=l&&l in n)try{n[l]=null==u?"":u;break n}catch(n){}"function"==typeof u||(null==u||!1===u&&"-"!==l[4]?n.removeAttribute(l):n.setAttribute(l,u))}}function F(n){return function(u){if(this.l){var t=this.l[u.type+n];if(null==u.t)u.t=e++;else if(u.t<t.u)return;return t(l.event?l.event(u):u)}}}function O(n,u,t,i,o,r,f,e,c,s){var a,h,p,v,w,_,g,m,x,C,M,P,$,I,H,L=u.type;if(void 0!==u.constructor)return null;128&t.__u&&(c=!!(32&t.__u),r=[e=u.__e=t.__e]),(a=l.__b)&&a(u);n:if("function"==typeof L)try{if(m=u.props,x=(a=L.contextType)&&i[a.__c],C=a?x?x.props.value:a.__:i,t.__c?g=(h=u.__c=t.__c).__=h.__E:("prototype"in L&&L.prototype.render?u.__c=h=new L(m,C):(u.__c=h=new b(m,C),h.constructor=L,h.render=q),x&&x.sub(h),h.props=m,h.state||(h.state={}),h.context=C,h.__n=i,p=h.__d=!0,h.__h=[],h._sb=[]),null==h.__s&&(h.__s=h.state),null!=L.getDerivedStateFromProps&&(h.__s==h.state&&(h.__s=d({},h.__s)),d(h.__s,L.getDerivedStateFromProps(m,h.__s))),v=h.props,w=h.state,h.__v=u,p)null==L.getDerivedStateFromProps&&null!=h.componentWillMount&&h.componentWillMount(),null!=h.componentDidMount&&h.__h.push(h.componentDidMount);else{if(null==L.getDerivedStateFromProps&&m!==v&&null!=h.componentWillReceiveProps&&h.componentWillReceiveProps(m,C),!h.__e&&(null!=h.shouldComponentUpdate&&!1===h.shouldComponentUpdate(m,h.__s,C)||u.__v===t.__v)){for(u.__v!==t.__v&&(h.props=m,h.state=h.__s,h.__d=!1),u.__e=t.__e,u.__k=t.__k,u.__k.forEach(function(n){n&&(n.__=u)}),M=0;M<h._sb.length;M++)h.__h.push(h._sb[M]);h._sb=[],h.__h.length&&f.push(h);break n}null!=h.componentWillUpdate&&h.componentWillUpdate(m,h.__s,C),null!=h.componentDidUpdate&&h.__h.push(function(){h.componentDidUpdate(v,w,_)})}if(h.context=C,h.props=m,h.__P=n,h.__e=!1,P=l.__r,$=0,"prototype"in L&&L.prototype.render){for(h.state=h.__s,h.__d=!1,P&&P(u),a=h.render(h.props,h.state,h.context),I=0;I<h._sb.length;I++)h.__h.push(h._sb[I]);h._sb=[]}else do{h.__d=!1,P&&P(u),a=h.render(h.props,h.state,h.context),h.state=h.__s}while(h.__d&&++$<25);h.state=h.__s,null!=h.getChildContext&&(i=d(d({},i),h.getChildContext())),p||null==h.getSnapshotBeforeUpdate||(_=h.getSnapshotBeforeUpdate(v,w)),S(n,y(H=null!=a&&a.type===k&&null==a.key?a.props.children:a)?H:[H],u,t,i,o,r,f,e,c,s),h.base=u.__e,u.__u&=-161,h.__h.length&&f.push(h),g&&(h.__E=h.__=null)}catch(n){u.__v=null,c||null!=r?(u.__e=e,u.__u|=c?160:32,r[r.indexOf(e)]=null):(u.__e=t.__e,u.__k=t.__k),l.__e(n,u,t)}else null==r&&u.__v===t.__v?(u.__k=t.__k,u.__e=t.__e):u.__e=z(t.__e,u,t,i,o,r,f,c,s);(a=l.diffed)&&a(u)}function j(n,u,t){u.__d=void 0;for(var i=0;i<t.length;i++)N(t[i],t[++i],t[++i]);l.__c&&l.__c(u,n),n.some(function(u){try{n=u.__h,u.__h=[],n.some(function(n){n.call(u)})}catch(n){l.__e(n,u.__v)}})}function z(l,u,t,i,o,r,f,e,c){var s,a,p,v,d,_,g,m=t.props,k=u.props,b=u.type;if("svg"===b?o="http://www.w3.org/2000/svg":"math"===b?o="http://www.w3.org/1998/Math/MathML":o||(o="http://www.w3.org/1999/xhtml"),null!=r)for(s=0;s<r.length;s++)if((d=r[s])&&"setAttribute"in d==!!b&&(b?d.localName===b:3===d.nodeType)){l=d,r[s]=null;break}if(null==l){if(null===b)return document.createTextNode(k);l=document.createElementNS(o,b,k.is&&k),r=null,e=!1}if(null===b)m===k||e&&l.data===k||(l.data=k);else{if(r=r&&n.call(l.childNodes),m=t.props||h,!e&&null!=r)for(m={},s=0;s<l.attributes.length;s++)m[(d=l.attributes[s]).name]=d.value;for(s in m)if(d=m[s],"children"==s);else if("dangerouslySetInnerHTML"==s)p=d;else if("key"!==s&&!(s in k)){if("value"==s&&"defaultValue"in k||"checked"==s&&"defaultChecked"in k)continue;A(l,s,null,d,o)}for(s in k)d=k[s],"children"==s?v=d:"dangerouslySetInnerHTML"==s?a=d:"value"==s?_=d:"checked"==s?g=d:"key"===s||e&&"function"!=typeof d||m[s]===d||A(l,s,d,m[s],o);if(a)e||p&&(a.__html===p.__html||a.__html===l.innerHTML)||(l.innerHTML=a.__html),u.__k=[];else if(p&&(l.innerHTML=""),S(l,y(v)?v:[v],u,t,i,"foreignObject"===b?"http://www.w3.org/1999/xhtml":o,r,f,r?r[0]:t.__k&&x(t,0),e,c),null!=r)for(s=r.length;s--;)null!=r[s]&&w(r[s]);e||(s="value",void 0!==_&&(_!==l[s]||"progress"===b&&!_||"option"===b&&_!==m[s])&&A(l,s,_,m[s],o),s="checked",void 0!==g&&g!==l[s]&&A(l,s,g,m[s],o))}return l}function N(n,u,t){try{"function"==typeof n?n(u):n.current=u}catch(n){l.__e(n,t)}}function V(n,u,t){var i,o;if(l.unmount&&l.unmount(n),(i=n.ref)&&(i.current&&i.current!==n.__e||N(i,null,u)),null!=(i=n.__c)){if(i.componentWillUnmount)try{i.componentWillUnmount()}catch(n){l.__e(n,u)}i.base=i.__P=null}if(i=n.__k)for(o=0;o<i.length;o++)i[o]&&V(i[o],u,t||"function"!=typeof n.type);t||null==n.__e||w(n.__e),n.__c=n.__=n.__e=n.__d=void 0}function q(n,l,u){return this.constructor(n,u)}function B(u,t,i){var o,r,f,e;l.__&&l.__(u,t),r=(o="function"==typeof i)?null:i&&i.__k||t.__k,f=[],e=[],O(t,u=(!o&&i||t).__k=_(k,null,[u]),r||h,h,t.namespaceURI,!o&&i?[i]:r?null:t.firstChild?n.call(t.childNodes):null,f,!o&&i?i:r?r.__e:t.firstChild,o,e),j(f,u,e)}function D(n,l){B(n,l,D)}function E(l,u,t){var i,o,r,f,e=d({},l.props);for(r in l.type&&l.type.defaultProps&&(f=l.type.defaultProps),u)"key"==r?i=u[r]:"ref"==r?o=u[r]:e[r]=void 0===u[r]&&void 0!==f?f[r]:u[r];return arguments.length>2&&(e.children=arguments.length>3?n.call(arguments,2):t),g(l.type,e,i||l.key,o||l.ref,null)}function G(n,l){var u={__c:l="__cC"+a++,__:n,Consumer:function(n,l){return n.children(l)},Provider:function(n){var u,t;return this.getChildContext||(u=[],(t={})[l]=this,this.getChildContext=function(){return t},this.shouldComponentUpdate=function(n){this.props.value!==n.value&&u.some(function(n){n.__e=!0,M(n)})},this.sub=function(n){u.push(n);var l=n.componentWillUnmount;n.componentWillUnmount=function(){u.splice(u.indexOf(n),1),l&&l.call(n)}}),n.children}};return u.Provider.__=u.Consumer.contextType=u}n=p.slice,l={__e:function(n,l,u,t){for(var i,o,r;l=l.__;)if((i=l.__c)&&!i.__)try{if((o=i.constructor)&&null!=o.getDerivedStateFromError&&(i.setState(o.getDerivedStateFromError(n)),r=i.__d),null!=i.componentDidCatch&&(i.componentDidCatch(n,t||{}),r=i.__d),r)return i.__E=i}catch(l){n=l}throw n}},u=0,t=function(n){return null!=n&&null==n.constructor},b.prototype.setState=function(n,l){var u;u=null!=this.__s&&this.__s!==this.state?this.__s:this.__s=d({},this.state),"function"==typeof n&&(n=n(d({},u),this.props)),n&&d(u,n),null!=n&&this.__v&&(l&&this._sb.push(l),M(this))},b.prototype.forceUpdate=function(n){this.__v&&(this.__e=!0,n&&this.__h.push(n),M(this))},b.prototype.render=k,i=[],r="function"==typeof Promise?Promise.prototype.then.bind(Promise.resolve()):setTimeout,f=function(n,l){return n.__v.__b-l.__v.__b},P.__r=0,e=0,c=F(!1),s=F(!0),a=0;export{b as Component,k as Fragment,E as cloneElement,G as createContext,_ as createElement,m as createRef,_ as h,D as hydrate,t as isValidElement,l as options,B as render,H as toChildArray};