@glassly/engine 0.3.5-beta.760 → 0.3.5-beta.775

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 (47) hide show
  1. package/build/engine.d.ts +3 -0
  2. package/build/engine.d.ts.map +1 -1
  3. package/build/facades/memory.d.ts +10 -2
  4. package/build/facades/memory.d.ts.map +1 -1
  5. package/build/facades/memory.js +10 -0
  6. package/build/facades/memory.js.map +1 -1
  7. package/build/generated/releaseMetadata.js +3 -3
  8. package/build/generated/releaseMetadata.js.map +1 -1
  9. package/build/services/BlobStore.js +3 -3
  10. package/build/services/BlobStore.js.map +1 -1
  11. package/build/services/ForegroundLocationPermission.d.ts +1 -1
  12. package/build/services/ForegroundLocationPermission.d.ts.map +1 -1
  13. package/build/services/ForegroundLocationPermission.js.map +1 -1
  14. package/build/services/LocalMiniappRuntime.d.ts +4 -2
  15. package/build/services/LocalMiniappRuntime.d.ts.map +1 -1
  16. package/build/services/LocalMiniappRuntime.js +51 -11
  17. package/build/services/LocalMiniappRuntime.js.map +1 -1
  18. package/build/services/MemoryStore.d.ts +13 -1
  19. package/build/services/MemoryStore.d.ts.map +1 -1
  20. package/build/services/MemoryStore.js +98 -1
  21. package/build/services/MemoryStore.js.map +1 -1
  22. package/build/services/manifestActions.d.ts +1 -1
  23. package/build/services/manifestActions.d.ts.map +1 -1
  24. package/build/services/manifestActions.js +3 -2
  25. package/build/services/manifestActions.js.map +1 -1
  26. package/build/services/memoryBackupFile.d.ts +9 -0
  27. package/build/services/memoryBackupFile.d.ts.map +1 -0
  28. package/build/services/memoryBackupFile.js +47 -0
  29. package/build/services/memoryBackupFile.js.map +1 -0
  30. package/build/services/widgetPlacements.d.ts +8 -7
  31. package/build/services/widgetPlacements.d.ts.map +1 -1
  32. package/build/services/widgetPlacements.js +7 -6
  33. package/build/services/widgetPlacements.js.map +1 -1
  34. package/build/types/applet.d.ts +3 -1
  35. package/build/types/applet.d.ts.map +1 -1
  36. package/build/types/applet.js.map +1 -1
  37. package/package.json +9 -9
  38. package/src/facades/memory.ts +11 -2
  39. package/src/generated/releaseMetadata.ts +3 -3
  40. package/src/services/BlobStore.ts +3 -3
  41. package/src/services/ForegroundLocationPermission.ts +1 -1
  42. package/src/services/LocalMiniappRuntime.ts +56 -11
  43. package/src/services/MemoryStore.ts +111 -2
  44. package/src/services/manifestActions.ts +10 -3
  45. package/src/services/memoryBackupFile.ts +50 -0
  46. package/src/services/widgetPlacements.ts +23 -9
  47. package/src/types/applet.ts +3 -1
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Memory backup files: the share-sheet export and file-picker import behind
3
+ * Settings > Memory and session.memory.exportFile/importFile.
4
+ */
5
+
6
+ import type {MemoryExportResult, MemoryImportResult} from "@glassly/miniapp"
7
+ import {File, Paths} from "expo-file-system"
8
+ import {Platform} from "react-native"
9
+ import Share from "react-native-share"
10
+
11
+ import {MemoryBackupError} from "./MemoryStore"
12
+ import {memoryStore} from "./memoryStoreInstance"
13
+
14
+ // Some Android document providers report .json files as octet-stream.
15
+ const PICK_MIME_TYPES =
16
+ Platform.OS === "android" ? ["application/json", "application/octet-stream"] : ["application/json"]
17
+
18
+ export async function exportMemoryFile(): Promise<MemoryExportResult> {
19
+ const backup = await memoryStore.exportBackup()
20
+ const filename = `glassly-memory-${localDate(backup.exportedAt)}.json`
21
+ const file = new File(Paths.cache, filename)
22
+ file.writeSync(JSON.stringify(backup))
23
+ try {
24
+ await Share.open({url: file.uri, type: "application/json", filename, title: "Glassly memory"})
25
+ return {success: true}
26
+ } catch (error: any) {
27
+ // react-native-share rejects when the user dismisses the sheet.
28
+ if (error?.message?.includes("User did not share")) return {success: false, cancelled: true}
29
+ throw error
30
+ }
31
+ }
32
+
33
+ /** Resolves null when the user cancels the picker. */
34
+ export async function importMemoryFile(): Promise<MemoryImportResult | null> {
35
+ const picked = await File.pickFileAsync({mimeTypes: PICK_MIME_TYPES})
36
+ if (picked.canceled) return null
37
+ let data: unknown
38
+ try {
39
+ data = JSON.parse(await picked.result.text())
40
+ } catch {
41
+ throw new MemoryBackupError("Not a Glassly memory backup")
42
+ }
43
+ return memoryStore.importBackup(data)
44
+ }
45
+
46
+ function localDate(ms: number): string {
47
+ const d = new Date(ms)
48
+ const pad = (n: number) => String(n).padStart(2, "0")
49
+ return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`
50
+ }
@@ -2,12 +2,14 @@
2
2
  * Who placed which widget where: the pure bookkeeping behind the runtime's
3
3
  * widget routing. A placement is one host's box for one provider widget;
4
4
  * a provider is placed while any host holds one of its widgets. Frames are
5
- * kept per widget so a host that places one again gets the last frame
6
- * at once.
5
+ * kept per widget and view so a host that places one again gets the last
6
+ * card and expanded frames at once.
7
7
  */
8
8
 
9
+ export type WidgetView = "card" | "expanded"
10
+
9
11
  export interface WidgetBox {
10
- size: "XS" | "SM" | "MD" | "LG"
12
+ size: "XS" | "XSM" | "SM" | "MD" | "LG"
11
13
  width: number
12
14
  height: number
13
15
  }
@@ -22,8 +24,8 @@ export interface Placement {
22
24
  export interface WidgetPlacements {
23
25
  /** Keyed by `${host}|${provider}/${widgetId}`. */
24
26
  placements: ReadonlyMap<string, Placement>
25
- /** The latest frame per `${provider}/${widgetId}`. */
26
- frames: ReadonlyMap<string, unknown[]>
27
+ /** The latest frame per `${provider}/${widgetId}` and view. */
28
+ frames: ReadonlyMap<string, Readonly<Partial<Record<WidgetView, unknown[]>>>>
27
29
  }
28
30
 
29
31
  export const widgetKey = (providerPackageName: string, widgetId: string): string => `${providerPackageName}/${widgetId}`
@@ -71,14 +73,26 @@ export function dropProvider(state: WidgetPlacements, providerPackageName: strin
71
73
  return placements.size === state.placements.size ? state : {...state, placements}
72
74
  }
73
75
 
74
- export function setFrame(state: WidgetPlacements, providerPackageName: string, widgetId: string, elements: unknown[]): WidgetPlacements {
76
+ export function setFrame(
77
+ state: WidgetPlacements,
78
+ providerPackageName: string,
79
+ widgetId: string,
80
+ elements: unknown[],
81
+ view: WidgetView = "card",
82
+ ): WidgetPlacements {
83
+ const key = widgetKey(providerPackageName, widgetId)
75
84
  const frames = new Map(state.frames)
76
- frames.set(widgetKey(providerPackageName, widgetId), elements)
85
+ frames.set(key, {...state.frames.get(key), [view]: elements})
77
86
  return {...state, frames}
78
87
  }
79
88
 
80
- export function frameOf(state: WidgetPlacements, providerPackageName: string, widgetId: string): unknown[] | null {
81
- return state.frames.get(widgetKey(providerPackageName, widgetId)) ?? null
89
+ export function frameOf(
90
+ state: WidgetPlacements,
91
+ providerPackageName: string,
92
+ widgetId: string,
93
+ view: WidgetView = "card",
94
+ ): unknown[] | null {
95
+ return state.frames.get(widgetKey(providerPackageName, widgetId))?.[view] ?? null
82
96
  }
83
97
 
84
98
  export function placementOf(
@@ -89,7 +89,7 @@ export interface DeclaredAction {
89
89
  visibility?: "public" | "system"
90
90
  }
91
91
 
92
- export type DeclaredWidgetSize = "XS" | "SM" | "MD" | "LG"
92
+ export type DeclaredWidgetSize = "XS" | "XSM" | "SM" | "MD" | "LG"
93
93
 
94
94
  /** A dashboard widget a miniapp declares in `miniapp.json` and serves through `session.widgets`. */
95
95
  export interface DeclaredWidget {
@@ -97,6 +97,8 @@ export interface DeclaredWidget {
97
97
  name: string
98
98
  sizes: DeclaredWidgetSize[]
99
99
  defaultSize: DeclaredWidgetSize
100
+ /** A tap on the selected widget expands it to the full screen instead of activating the card. */
101
+ expandable: boolean
100
102
  }
101
103
 
102
104
  export interface ClientApp extends AppletInterface {