@solidrt/core 0.0.36 → 0.0.37

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solidrt/core",
3
- "version": "0.0.36",
3
+ "version": "0.0.37",
4
4
  "license": "MIT",
5
5
  "author": "Antoine van Wel",
6
6
  "type": "module",
@@ -27,7 +27,7 @@
27
27
  "colord": "^2.9.3"
28
28
  },
29
29
  "devDependencies": {
30
- "@solidrt/flux-types": "0.0.36"
30
+ "@solidrt/flux-types": "0.0.37"
31
31
  },
32
32
  "peerDependencies": {
33
33
  "@solidjs/signals": "2.0.0-beta.20",
package/src/index.ts CHANGED
@@ -3,7 +3,8 @@ export { setFocus, getFocusedNodeId, measureText, getBoundingBox, getBoundingBox
3
3
  export type { BoundingBox } from "./core"
4
4
  export { parseColor, mixColors, brightness, createLinearGradient, createRadialGradient } from "./color"
5
5
  export type { Gradient, GradientStop } from "./color"
6
- export { onFrame, onLayout, onResize, onWindowFocus, onWindowBlur } from "./window"
6
+ export { onFrame, onLayout, onResize, onWindowFocus, onWindowBlur, onBack, exit } from "./window"
7
+ export type { BackEvent } from "./window"
7
8
  export { windowSize, safeArea, displayScale, windowFocused, keyboardHeight } from "./window"
8
9
  export { env } from "./environment"
9
10
  export type { InputDevices, SystemTheme, Orientation } from "./environment"
@@ -31,6 +31,17 @@ declare module "srt:events" {
31
31
  export function once(event: string, callback: (data: any) => void): () => void
32
32
  }
33
33
 
34
+ // The running application's own surface (lattice), present in every build.
35
+ declare module "srt:app" {
36
+ /**
37
+ * Leave the current app, unconditionally: back to the launcher in a dev
38
+ * client, quit when standalone or at the launcher root (on Android the
39
+ * client backgrounds instead of dying). The default action of an
40
+ * unprevented `back` event; prefer the @solidrt/core re-export.
41
+ */
42
+ export function exit(): void
43
+ }
44
+
34
45
  // Dev-server control surface (lattice). Present only in dev/go builds; in other
35
46
  // builds `available` is false and the functions are no-ops.
36
47
  declare module "srt:dev" {
@@ -63,8 +74,13 @@ declare module "srt:apps" {
63
74
  export type InstalledApp = { id: string; name: string; version: string }
64
75
  /** Installed apps, sorted by name. */
65
76
  export function list(): InstalledApp[]
66
- /** A stored version: id (manifest hash), bytes on disk, whether it is the current one. */
67
- export type AppVersion = { id: string; size: number; current: boolean }
77
+ /**
78
+ * A stored version: id (manifest hash), bytes on disk, whether it is the
79
+ * current one, and the SolidRT (CLI) release that built it per its
80
+ * manifest ("unknown" from an in-repo CLI or when the manifest predates
81
+ * the field).
82
+ */
83
+ export type AppVersion = { id: string; size: number; current: boolean; solidrtVersion: string }
68
84
  /** One file in a listing: a relative path and its size in bytes. */
69
85
  export type AppFile = { path: string; size: number }
70
86
  /**
package/src/types.d.ts CHANGED
@@ -198,8 +198,18 @@ export interface WheelEvent extends PointerEvent {
198
198
  deltaY: number
199
199
  }
200
200
 
201
+ // Key events use the W3C UI Events vocabulary: `key` is the logical,
202
+ // layout-dependent value ("a", "!", "Enter", "ArrowLeft"); `code` is the
203
+ // physical, layout-independent key position ("KeyA", "Digit1", "NumpadEnter").
204
+ // Printable characters for text entry arrive via onTextInput, not here.
201
205
  export interface KeyEvent {
202
206
  key: string
207
+ code: string
208
+ repeat: boolean
209
+ shiftKey: boolean
210
+ ctrlKey: boolean
211
+ altKey: boolean
212
+ metaKey: boolean
203
213
  }
204
214
 
205
215
  export interface TextEvent {
package/src/window.ts CHANGED
@@ -2,9 +2,19 @@ import { createSignal, onCleanup, onSettled, flush } from "@solidjs/signals"
2
2
  import { requestFrame } from "flux:rendertree"
3
3
  import { renderFrame } from "srt:render"
4
4
  import { on, once } from "srt:events"
5
+ import { exit } from "srt:app"
5
6
  import { getEventHandler, getFocusedNodeId, setFocus } from "./core"
6
7
  import { scanForOrphans } from "./renderer"
7
8
 
9
+ /**
10
+ * Leaves the current app, unconditionally: back to the launcher in a dev
11
+ * client, quitting when standalone or at the launcher itself (on Android the
12
+ * client backgrounds instead of dying). The default action of an unprevented
13
+ * `back` event; call it directly to exit programmatically, e.g. after
14
+ * intercepting back for an unsaved-changes dialog.
15
+ */
16
+ export { exit }
17
+
8
18
  // ------ Pointer routing -----------------
9
19
 
10
20
  // Hit path frozen at pointerDown, pointerId -> targets. While a pointer has an
@@ -179,6 +189,30 @@ export function onWindowBlur(fn: () => void) {
179
189
  return unsubscribe
180
190
  }
181
191
 
192
+ // ------ Back ----------------
193
+
194
+ export type BackEvent = { preventDefault: () => void }
195
+
196
+ // App handlers for the window-level back event, run in registration order.
197
+ // Kept in a local registry (not per-handler bus subscriptions) so the default
198
+ // action runs exactly once, after every handler has had its say.
199
+ let backHandlers = new Set<(e: BackEvent) => void>()
200
+
201
+ /**
202
+ * Calls `fn` on the user's back intent (Android back button/gesture, the
203
+ * desktop dev chord). Call `e.preventDefault()` when back means in-app
204
+ * navigation right now (close a modal, previous screen); unprevented, the
205
+ * default action runs: exit(). Apps without a handler exit on back
206
+ * everywhere, which is the correct zero-effort default.
207
+ * Returns a cleanup function; also auto-cleans within a reactive scope.
208
+ */
209
+ export function onBack(fn: (e: BackEvent) => void) {
210
+ backHandlers.add(fn)
211
+ let cleanup = () => backHandlers.delete(fn)
212
+ onCleanup(cleanup)
213
+ return cleanup
214
+ }
215
+
182
216
  // ------ Window ----------------
183
217
 
184
218
  export function attachWindow(_nodeId: number) {
@@ -191,6 +225,7 @@ export function attachWindow(_nodeId: number) {
191
225
  let unsubWheel: () => void = null!
192
226
  let unsubKeyDown: () => void = null!
193
227
  let unsubKeyUp: () => void = null!
228
+ let unsubBack: () => void = null!
194
229
  let unsubTextInput: () => void = null!
195
230
  let unsubKeyboardVisibility: () => void = null!
196
231
  let unsubRefreshRate: () => void = null!
@@ -304,6 +339,18 @@ export function attachWindow(_nodeId: number) {
304
339
  }
305
340
  })
306
341
 
342
+ unsubBack = on("back", () => {
343
+ let prevented = false
344
+ let e: BackEvent = {
345
+ preventDefault: () => {
346
+ prevented = true
347
+ },
348
+ }
349
+ // Copy first: a handler may unregister (itself or others) mid-dispatch.
350
+ for (let fn of [...backHandlers]) fn(e)
351
+ if (!prevented) exit()
352
+ })
353
+
307
354
  unsubTextInput = on("textInput", (e: any) => {
308
355
  let id = getFocusedNodeId()
309
356
  if (id != null) {
@@ -339,6 +386,7 @@ export function attachWindow(_nodeId: number) {
339
386
  if (unsubWheel) unsubWheel()
340
387
  if (unsubKeyDown) unsubKeyDown()
341
388
  if (unsubKeyUp) unsubKeyUp()
389
+ if (unsubBack) unsubBack()
342
390
  if (unsubTextInput) unsubTextInput()
343
391
  if (unsubKeyboardVisibility) unsubKeyboardVisibility()
344
392
  if (unsubRefreshRate) unsubRefreshRate()