@glassly/engine 0.4.0-dev.1039 → 0.4.0-dev.1042
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/build/generated/releaseMetadata.js +3 -3
- package/build/generated/releaseMetadata.js.map +1 -1
- package/build/services/CloudClientService.d.ts +4 -4
- package/build/services/CloudClientService.d.ts.map +1 -1
- package/build/services/CloudClientService.js +6 -6
- package/build/services/CloudClientService.js.map +1 -1
- package/build/services/HotspotOtaTransport.d.ts.map +1 -1
- package/build/services/HotspotOtaTransport.js +0 -1
- package/build/services/HotspotOtaTransport.js.map +1 -1
- package/build/stores/settings.js +1 -1
- package/build/stores/settings.js.map +1 -1
- package/build/utils/display/index.d.ts.map +1 -1
- package/build/utils/display/index.js +1 -2
- package/build/utils/display/index.js.map +1 -1
- package/package.json +7 -7
- package/src/generated/releaseMetadata.ts +3 -3
- package/src/services/CloudClientService.ts +7 -6
- package/src/services/HotspotOtaTransport.ts +0 -1
- package/src/stores/settings.ts +1 -1
- package/src/utils/display/index.ts +1 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/utils/display/index.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @glassly/display-utils\n *\n * Glasses-agnostic, pixel-accurate text measurement and wrapping library\n * for smart glasses displays.\n *\n * Key features:\n * - Pixel-perfect measurement (no abstract units or averages)\n * - Multiple break modes (character, word, strict-word)\n * - Full script support (Latin, CJK, Korean, Cyrillic)\n * - Configurable display profiles for different glasses hardware\n *\n * @example\n * ```typescript\n * import {\n * TextMeasurer,\n * TextWrapper,\n * DisplayHelpers,\n * G1_PROFILE\n * } from '@glassly/display-utils'\n *\n * // Create measurer and wrapper for G1 glasses\n * const measurer = new TextMeasurer(G1_PROFILE)\n * const wrapper = new TextWrapper(measurer, { breakMode: 'character' })\n * const helpers = new DisplayHelpers(measurer, wrapper)\n *\n * // Wrap text for display\n * const result = wrapper.wrap(\"Hello, world! This is a long text.\")\n * console.log(result.lines)\n * // [\"Hello, world! This is a long text th-\", \"at needs wrapping.\"]\n * ```\n */\n\n// =============================================================================\n// Profiles - Hardware configurations for different glasses\n// =============================================================================\n\n// Import for factory functions\nimport {G1_PROFILE_LEGACY, G2_PROFILE, Z100_PROFILE, NEX_PROFILE} from \"./profiles\"\n\n// =============================================================================\n// Convenience factory functions\n// =============================================================================\n\nimport {TextMeasurer} from \"./measurer\"\nimport {TextWrapper} from \"./wrapper\"\nimport {DisplayHelpers} from \"./helpers\"\nimport {ColumnComposer} from \"./composer\"\nimport {G1_PROFILE} from \"./profiles\"\nimport type {DisplayProfile} from \"./profiles\"\nimport type {WrapOptions} from \"./wrapper\"\n\nexport type {\n DisplayProfile,\n FontMetrics,\n UniformScriptWidths,\n FallbackConfig,\n DisplayConstraints,\n ScriptType,\n} from \"./profiles\"\n\nexport {G1_PROFILE, G1_PROFILE_LEGACY, G1_HYPHEN_WIDTH_PX, G1_SPACE_WIDTH_PX} from \"./profiles\"\n\n// G2 Profile\nexport {G2_PROFILE, G2_HYPHEN_WIDTH_PX, G2_SPACE_WIDTH_PX} from \"./profiles\"\n\n// Z100 Profile\nexport {Z100_PROFILE, Z100_HYPHEN_WIDTH_PX, Z100_SPACE_WIDTH_PX} from \"./profiles\"\n\n// Mentra Nex Profile (a.k.a. Mentra Display)\nexport {NEX_PROFILE, NEX_HYPHEN_WIDTH_PX, NEX_SPACE_WIDTH_PX} from \"./profiles\"\n\n// RayNeo iO Profiles (stock subtitle page, Glassly CFW scene page)\nexport {RAYNEO_IO_PROFILE, RAYNEO_IO_CFW_PROFILE, RAYNEO_IO_HYPHEN_WIDTH_PX, RAYNEO_IO_SPACE_WIDTH_PX} from \"./profiles\"\n\n// =============================================================================\n// Measurer - Pixel-accurate text measurement\n// =============================================================================\n\nexport {TextMeasurer} from \"./measurer\"\nexport type {CharMeasurement, TextMeasurement} from \"./measurer\"\n\n// Script detection utilities\nexport {\n detectScript,\n isCJKCharacter,\n isKoreanCharacter,\n isUniformWidthScript,\n isUnsupportedScript,\n needsHyphenForBreak,\n SCRIPT_RANGES,\n} from \"./measurer\"\n\n// =============================================================================\n// Wrapper - Text wrapping with multiple break modes\n// =============================================================================\n\nexport {TextWrapper} from \"./wrapper\"\nexport type {WrapOptions, WrapResult, LineMetrics, BreakMode} from \"./wrapper\"\nexport {DEFAULT_WRAP_OPTIONS} from \"./wrapper\"\n\n// =============================================================================\n// Helpers - Optional convenience utilities\n// =============================================================================\n\nexport {DisplayHelpers, ScrollView} from \"./helpers\"\nexport type {TruncateResult, Page, Chunk, ScrollPosition, ScrollViewport} from \"./helpers\"\n\n// =============================================================================\n// Composer - Multi-column layout composition\n// =============================================================================\n\nexport {ColumnComposer, createColumnComposer} from \"./composer\"\nexport type {ColumnConfig, ComposeOptions, ComposeResult} from \"./composer\"\n\n/**\n * Create a complete display toolkit for a given profile.\n *\n * @param profile - Display profile (defaults to G1)\n * @param wrapOptions - Default wrap options\n * @returns Object with measurer, wrapper, and helpers\n *\n * @example\n * ```typescript\n * const { measurer, wrapper, helpers } = createDisplayToolkit()\n * const lines = wrapper.wrapToLines(\"Hello, world!\")\n * ```\n */\nexport function createDisplayToolkit(\n profile: DisplayProfile = G1_PROFILE,\n wrapOptions?: WrapOptions,\n): {\n measurer: TextMeasurer\n wrapper: TextWrapper\n helpers: DisplayHelpers\n composer: ColumnComposer\n profile: DisplayProfile\n} {\n const measurer = new TextMeasurer(profile)\n const wrapper = new TextWrapper(measurer, wrapOptions)\n const helpers = new DisplayHelpers(measurer, wrapper)\n const composer = new ColumnComposer(profile, wrapOptions?.breakMode || \"word\")\n\n return {\n measurer,\n wrapper,\n helpers,\n composer,\n profile,\n }\n}\n\n/**\n * Create a G1-configured display toolkit with character breaking.\n * This is the recommended setup for captions and similar high-utilization use cases.\n *\n * @returns Object with measurer, wrapper, and helpers configured for G1\n *\n * @example\n * ```typescript\n * const { wrapper, composer } = createG1Toolkit()\n * const result = wrapper.wrap(\"Your text here\")\n * const columns = composer.composeDoubleTextWall(\"Left\", \"Right\")\n * ```\n */\nexport function createG1Toolkit(): {\n measurer: TextMeasurer\n wrapper: TextWrapper\n helpers: DisplayHelpers\n composer: ColumnComposer\n profile: DisplayProfile\n} {\n return createDisplayToolkit(G1_PROFILE, {\n breakMode: \"character-no-hyphen\",\n })\n}\n\n/**\n * Create a G1-configured display toolkit for LEGACY mobile clients.\n *\n * Use this when the mobile client has old wrapping logic that re-wraps\n * text received from the cloud. This profile uses a reduced display width\n * (~522px instead of 576px) to prevent double-wrapping overflow.\n *\n * @returns Object with measurer, wrapper, and helpers configured for legacy G1 clients\n *\n * @example\n * ```typescript\n * // For old mobile clients that double-wrap\n * const { wrapper } = createG1LegacyToolkit()\n * const result = wrapper.wrap(\"Your text here\")\n * // Lines will be shorter to account for mobile re-wrapping\n * ```\n */\nexport function createG1LegacyToolkit(): {\n measurer: TextMeasurer\n wrapper: TextWrapper\n helpers: DisplayHelpers\n composer: ColumnComposer\n profile: DisplayProfile\n} {\n return createDisplayToolkit(G1_PROFILE_LEGACY, {\n breakMode: \"character-no-hyphen\",\n })\n}\n\n/**\n * Create a G2-configured display toolkit with character breaking.\n * G2 uses EvenHub protocol with the same display hardware as G1.\n *\n * @returns Object with measurer, wrapper, and helpers configured for Even G2\n *\n * @example\n * ```typescript\n * const { wrapper } = createG2Toolkit()\n * const result = wrapper.wrap(\"Your text here\")\n * ```\n */\nexport function createG2Toolkit(): {\n measurer: TextMeasurer\n wrapper: TextWrapper\n helpers: DisplayHelpers\n composer: ColumnComposer\n profile: DisplayProfile\n} {\n return createDisplayToolkit(G2_PROFILE, {\n breakMode: \"character-no-hyphen\",\n })\n}\n\n/**\n * Create a Z100-configured display toolkit with character breaking.\n *\n * @returns Object with measurer, wrapper, and helpers configured for Vuzix Z100\n *\n * @example\n * ```typescript\n * const { wrapper } = createZ100Toolkit()\n * const result = wrapper.wrap(\"Your text here\")\n * ```\n */\nexport function createZ100Toolkit(): {\n measurer: TextMeasurer\n wrapper: TextWrapper\n helpers: DisplayHelpers\n composer: ColumnComposer\n profile: DisplayProfile\n} {\n return createDisplayToolkit(Z100_PROFILE, {\n breakMode: \"character-no-hyphen\",\n })\n}\n\n/**\n * Create a Mentra Nex-configured display toolkit with character breaking.\n * Also known as \"Mentra Display\".\n *\n * @returns Object with measurer, wrapper, and helpers configured for Mentra Nex\n *\n * @example\n * ```typescript\n * const { wrapper } = createNexToolkit()\n * const result = wrapper.wrap(\"Your text here\")\n * ```\n */\nexport function createNexToolkit(): {\n measurer: TextMeasurer\n wrapper: TextWrapper\n helpers: DisplayHelpers\n composer: ColumnComposer\n profile: DisplayProfile\n} {\n return createDisplayToolkit(NEX_PROFILE, {\n breakMode: \"character-no-hyphen\",\n })\n}\n\nexport {MEMOMIND_ONE_PROFILE} from \"./profiles\"\nexport {NIMO_PROFILE} from \"./profiles\"\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/utils/display/index.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @glassly/display-utils\n *\n * Glasses-agnostic, pixel-accurate text measurement and wrapping library\n * for smart glasses displays.\n *\n * Key features:\n * - Pixel-perfect measurement (no abstract units or averages)\n * - Multiple break modes (character, word, strict-word)\n * - Full script support (Latin, CJK, Korean, Cyrillic)\n * - Configurable display profiles for different glasses hardware\n *\n * @example\n * ```typescript\n * import {\n * TextMeasurer,\n * TextWrapper,\n * DisplayHelpers,\n * G1_PROFILE\n * } from '@glassly/display-utils'\n *\n * // Create measurer and wrapper for G1 glasses\n * const measurer = new TextMeasurer(G1_PROFILE)\n * const wrapper = new TextWrapper(measurer, { breakMode: 'character' })\n * const helpers = new DisplayHelpers(measurer, wrapper)\n *\n * // Wrap text for display\n * const result = wrapper.wrap(\"Hello, world! This is a long text.\")\n * console.log(result.lines)\n * // [\"Hello, world! This is a long text th-\", \"at needs wrapping.\"]\n * ```\n */\n\n// =============================================================================\n// Profiles - Hardware configurations for different glasses\n// =============================================================================\n\n// Import for factory functions\nimport {G1_PROFILE_LEGACY, G2_PROFILE, Z100_PROFILE, NEX_PROFILE, G1_PROFILE} from \"./profiles\"\n\n// =============================================================================\n// Convenience factory functions\n// =============================================================================\n\nimport {TextMeasurer} from \"./measurer\"\nimport {TextWrapper} from \"./wrapper\"\nimport {DisplayHelpers} from \"./helpers\"\nimport {ColumnComposer} from \"./composer\"\nimport type {DisplayProfile} from \"./profiles\"\nimport type {WrapOptions} from \"./wrapper\"\n\nexport type {\n DisplayProfile,\n FontMetrics,\n UniformScriptWidths,\n FallbackConfig,\n DisplayConstraints,\n ScriptType,\n} from \"./profiles\"\n\nexport {G1_PROFILE, G1_PROFILE_LEGACY, G1_HYPHEN_WIDTH_PX, G1_SPACE_WIDTH_PX} from \"./profiles\"\n\n// G2 Profile\nexport {G2_PROFILE, G2_HYPHEN_WIDTH_PX, G2_SPACE_WIDTH_PX} from \"./profiles\"\n\n// Z100 Profile\nexport {Z100_PROFILE, Z100_HYPHEN_WIDTH_PX, Z100_SPACE_WIDTH_PX} from \"./profiles\"\n\n// Mentra Nex Profile (a.k.a. Mentra Display)\nexport {NEX_PROFILE, NEX_HYPHEN_WIDTH_PX, NEX_SPACE_WIDTH_PX} from \"./profiles\"\n\n// RayNeo iO Profiles (stock subtitle page, Glassly CFW scene page)\nexport {RAYNEO_IO_PROFILE, RAYNEO_IO_CFW_PROFILE, RAYNEO_IO_HYPHEN_WIDTH_PX, RAYNEO_IO_SPACE_WIDTH_PX} from \"./profiles\"\n\n// =============================================================================\n// Measurer - Pixel-accurate text measurement\n// =============================================================================\n\nexport {TextMeasurer} from \"./measurer\"\nexport type {CharMeasurement, TextMeasurement} from \"./measurer\"\n\n// Script detection utilities\nexport {\n detectScript,\n isCJKCharacter,\n isKoreanCharacter,\n isUniformWidthScript,\n isUnsupportedScript,\n needsHyphenForBreak,\n SCRIPT_RANGES,\n} from \"./measurer\"\n\n// =============================================================================\n// Wrapper - Text wrapping with multiple break modes\n// =============================================================================\n\nexport {TextWrapper} from \"./wrapper\"\nexport type {WrapOptions, WrapResult, LineMetrics, BreakMode} from \"./wrapper\"\nexport {DEFAULT_WRAP_OPTIONS} from \"./wrapper\"\n\n// =============================================================================\n// Helpers - Optional convenience utilities\n// =============================================================================\n\nexport {DisplayHelpers, ScrollView} from \"./helpers\"\nexport type {TruncateResult, Page, Chunk, ScrollPosition, ScrollViewport} from \"./helpers\"\n\n// =============================================================================\n// Composer - Multi-column layout composition\n// =============================================================================\n\nexport {ColumnComposer, createColumnComposer} from \"./composer\"\nexport type {ColumnConfig, ComposeOptions, ComposeResult} from \"./composer\"\n\n/**\n * Create a complete display toolkit for a given profile.\n *\n * @param profile - Display profile (defaults to G1)\n * @param wrapOptions - Default wrap options\n * @returns Object with measurer, wrapper, and helpers\n *\n * @example\n * ```typescript\n * const { measurer, wrapper, helpers } = createDisplayToolkit()\n * const lines = wrapper.wrapToLines(\"Hello, world!\")\n * ```\n */\nexport function createDisplayToolkit(\n profile: DisplayProfile = G1_PROFILE,\n wrapOptions?: WrapOptions,\n): {\n measurer: TextMeasurer\n wrapper: TextWrapper\n helpers: DisplayHelpers\n composer: ColumnComposer\n profile: DisplayProfile\n} {\n const measurer = new TextMeasurer(profile)\n const wrapper = new TextWrapper(measurer, wrapOptions)\n const helpers = new DisplayHelpers(measurer, wrapper)\n const composer = new ColumnComposer(profile, wrapOptions?.breakMode || \"word\")\n\n return {\n measurer,\n wrapper,\n helpers,\n composer,\n profile,\n }\n}\n\n/**\n * Create a G1-configured display toolkit with character breaking.\n * This is the recommended setup for captions and similar high-utilization use cases.\n *\n * @returns Object with measurer, wrapper, and helpers configured for G1\n *\n * @example\n * ```typescript\n * const { wrapper, composer } = createG1Toolkit()\n * const result = wrapper.wrap(\"Your text here\")\n * const columns = composer.composeDoubleTextWall(\"Left\", \"Right\")\n * ```\n */\nexport function createG1Toolkit(): {\n measurer: TextMeasurer\n wrapper: TextWrapper\n helpers: DisplayHelpers\n composer: ColumnComposer\n profile: DisplayProfile\n} {\n return createDisplayToolkit(G1_PROFILE, {\n breakMode: \"character-no-hyphen\",\n })\n}\n\n/**\n * Create a G1-configured display toolkit for LEGACY mobile clients.\n *\n * Use this when the mobile client has old wrapping logic that re-wraps\n * text received from the cloud. This profile uses a reduced display width\n * (~522px instead of 576px) to prevent double-wrapping overflow.\n *\n * @returns Object with measurer, wrapper, and helpers configured for legacy G1 clients\n *\n * @example\n * ```typescript\n * // For old mobile clients that double-wrap\n * const { wrapper } = createG1LegacyToolkit()\n * const result = wrapper.wrap(\"Your text here\")\n * // Lines will be shorter to account for mobile re-wrapping\n * ```\n */\nexport function createG1LegacyToolkit(): {\n measurer: TextMeasurer\n wrapper: TextWrapper\n helpers: DisplayHelpers\n composer: ColumnComposer\n profile: DisplayProfile\n} {\n return createDisplayToolkit(G1_PROFILE_LEGACY, {\n breakMode: \"character-no-hyphen\",\n })\n}\n\n/**\n * Create a G2-configured display toolkit with character breaking.\n * G2 uses EvenHub protocol with the same display hardware as G1.\n *\n * @returns Object with measurer, wrapper, and helpers configured for Even G2\n *\n * @example\n * ```typescript\n * const { wrapper } = createG2Toolkit()\n * const result = wrapper.wrap(\"Your text here\")\n * ```\n */\nexport function createG2Toolkit(): {\n measurer: TextMeasurer\n wrapper: TextWrapper\n helpers: DisplayHelpers\n composer: ColumnComposer\n profile: DisplayProfile\n} {\n return createDisplayToolkit(G2_PROFILE, {\n breakMode: \"character-no-hyphen\",\n })\n}\n\n/**\n * Create a Z100-configured display toolkit with character breaking.\n *\n * @returns Object with measurer, wrapper, and helpers configured for Vuzix Z100\n *\n * @example\n * ```typescript\n * const { wrapper } = createZ100Toolkit()\n * const result = wrapper.wrap(\"Your text here\")\n * ```\n */\nexport function createZ100Toolkit(): {\n measurer: TextMeasurer\n wrapper: TextWrapper\n helpers: DisplayHelpers\n composer: ColumnComposer\n profile: DisplayProfile\n} {\n return createDisplayToolkit(Z100_PROFILE, {\n breakMode: \"character-no-hyphen\",\n })\n}\n\n/**\n * Create a Mentra Nex-configured display toolkit with character breaking.\n * Also known as \"Mentra Display\".\n *\n * @returns Object with measurer, wrapper, and helpers configured for Mentra Nex\n *\n * @example\n * ```typescript\n * const { wrapper } = createNexToolkit()\n * const result = wrapper.wrap(\"Your text here\")\n * ```\n */\nexport function createNexToolkit(): {\n measurer: TextMeasurer\n wrapper: TextWrapper\n helpers: DisplayHelpers\n composer: ColumnComposer\n profile: DisplayProfile\n} {\n return createDisplayToolkit(NEX_PROFILE, {\n breakMode: \"character-no-hyphen\",\n })\n}\n\nexport {MEMOMIND_ONE_PROFILE} from \"./profiles\"\nexport {NIMO_PROFILE} from \"./profiles\"\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@glassly/engine",
|
|
3
|
-
"version": "0.4.0-dev.
|
|
3
|
+
"version": "0.4.0-dev.1042",
|
|
4
4
|
"description": "Glassly Engine — miniapp registry, WebView bridge, and miniapp store",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"react-native": "src/index.ts",
|
|
@@ -97,17 +97,17 @@
|
|
|
97
97
|
"registry": "https://registry.npmjs.org/"
|
|
98
98
|
},
|
|
99
99
|
"dependencies": {
|
|
100
|
-
"@glassly/bluetooth-sdk": "0.4.0-dev.
|
|
101
|
-
"@glassly/cloud-client": "0.4.0-dev.
|
|
102
|
-
"@glassly/cloud-protocol": "0.4.0-dev.
|
|
103
|
-
"@glassly/crust": "0.4.0-dev.
|
|
104
|
-
"@glassly/miniapp": "0.4.0-dev.
|
|
100
|
+
"@glassly/bluetooth-sdk": "0.4.0-dev.1042",
|
|
101
|
+
"@glassly/cloud-client": "0.4.0-dev.1042",
|
|
102
|
+
"@glassly/cloud-protocol": "0.4.0-dev.1042",
|
|
103
|
+
"@glassly/crust": "0.4.0-dev.1042",
|
|
104
|
+
"@glassly/miniapp": "0.4.0-dev.1042",
|
|
105
105
|
"buffer": "^6.0.3",
|
|
106
106
|
"events": "^3.3.0",
|
|
107
107
|
"react-native-marked": "8.3.2",
|
|
108
108
|
"semver": "^7.7.4",
|
|
109
109
|
"typesafe-ts": "^1.7.1",
|
|
110
|
-
"@glassly/llm-providers": "0.4.0-dev.
|
|
110
|
+
"@glassly/llm-providers": "0.4.0-dev.1042",
|
|
111
111
|
"@huggingface/jinja": "^0.5.9",
|
|
112
112
|
"jsonrepair": "^3.12.0"
|
|
113
113
|
},
|
|
@@ -12,9 +12,9 @@ export interface EngineReleaseMetadata {
|
|
|
12
12
|
export const ENGINE_RELEASE_METADATA: Readonly<EngineReleaseMetadata> = Object.freeze({
|
|
13
13
|
"schemaVersion": 1,
|
|
14
14
|
"familyBaseVersion": "0.4.0",
|
|
15
|
-
"releaseIdentity": "0.4.0-dev.
|
|
16
|
-
"releaseSetId": "glassly-0.4.0-dev.
|
|
17
|
-
"sourceCommit": "
|
|
15
|
+
"releaseIdentity": "0.4.0-dev.1042",
|
|
16
|
+
"releaseSetId": "glassly-0.4.0-dev.1042",
|
|
17
|
+
"sourceCommit": "efd69f62018117af77c4270370674256802dc597",
|
|
18
18
|
"otaManifestUrl": null,
|
|
19
19
|
"otaManifestSha256": null
|
|
20
20
|
})
|
|
@@ -20,6 +20,7 @@ import type {
|
|
|
20
20
|
StoreCatalogResponse,
|
|
21
21
|
StoreListing,
|
|
22
22
|
StoreReleasesResponse,
|
|
23
|
+
StoreHostOptions,
|
|
23
24
|
} from "@glassly/cloud-client/react-native"
|
|
24
25
|
import type {SubjectTokenType} from "@glassly/cloud-client"
|
|
25
26
|
import {AppState, Platform} from "react-native"
|
|
@@ -770,25 +771,25 @@ export const cloudClientService = {
|
|
|
770
771
|
return c.core.miniapps.getRegistry()
|
|
771
772
|
},
|
|
772
773
|
|
|
773
|
-
async getStoreCatalog(): Promise<StoreCatalogResponse> {
|
|
774
|
+
async getStoreCatalog(opts?: StoreHostOptions): Promise<StoreCatalogResponse> {
|
|
774
775
|
if (!client) this.init()
|
|
775
776
|
const c = client
|
|
776
777
|
if (!c?.core) throw new Error("cloud client core is unavailable")
|
|
777
|
-
return c.core.store.list()
|
|
778
|
+
return c.core.store.list(opts)
|
|
778
779
|
},
|
|
779
780
|
|
|
780
|
-
async getStoreListing(packageName: string): Promise<StoreListing> {
|
|
781
|
+
async getStoreListing(packageName: string, opts?: StoreHostOptions): Promise<StoreListing> {
|
|
781
782
|
if (!client) this.init()
|
|
782
783
|
const c = client
|
|
783
784
|
if (!c?.core) throw new Error("cloud client core is unavailable")
|
|
784
|
-
return c.core.store.get(packageName)
|
|
785
|
+
return c.core.store.get(packageName, opts)
|
|
785
786
|
},
|
|
786
787
|
|
|
787
|
-
async getStoreReleases(packageName: string): Promise<StoreReleasesResponse> {
|
|
788
|
+
async getStoreReleases(packageName: string, opts?: StoreHostOptions): Promise<StoreReleasesResponse> {
|
|
788
789
|
if (!client) this.init()
|
|
789
790
|
const c = client
|
|
790
791
|
if (!c?.core) throw new Error("cloud client core is unavailable")
|
|
791
|
-
return c.core.store.releases(packageName)
|
|
792
|
+
return c.core.store.releases(packageName, opts)
|
|
792
793
|
},
|
|
793
794
|
|
|
794
795
|
/** Bytes of a store icon or screenshot; these routes need the user Bearer. */
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import BluetoothSdk, {isEnabledHotspotStatus} from "@glassly/bluetooth-sdk"
|
|
2
2
|
import {otaServer} from "@glassly/bluetooth-sdk/ota-transport"
|
|
3
3
|
// One coordinator selects the native Android or iOS staging implementation at runtime.
|
|
4
|
-
// eslint-disable-next-line react-native/split-platform-components
|
|
5
4
|
import {PermissionsAndroid, Platform} from "react-native"
|
|
6
5
|
import type {OtaCheckCurrentGlassesResult} from "./OtaUpdateCheckService"
|
|
7
6
|
import {
|
package/src/stores/settings.ts
CHANGED
|
@@ -134,7 +134,7 @@ export const SETTINGS: Record<string, Setting> = {
|
|
|
134
134
|
},
|
|
135
135
|
memomind_accessory_picker: {
|
|
136
136
|
key: "memomind_accessory_picker",
|
|
137
|
-
defaultValue: () =>
|
|
137
|
+
defaultValue: () => true,
|
|
138
138
|
writable: true,
|
|
139
139
|
saveOnServer: false,
|
|
140
140
|
persist: true,
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
// =============================================================================
|
|
37
37
|
|
|
38
38
|
// Import for factory functions
|
|
39
|
-
import {G1_PROFILE_LEGACY, G2_PROFILE, Z100_PROFILE, NEX_PROFILE} from "./profiles"
|
|
39
|
+
import {G1_PROFILE_LEGACY, G2_PROFILE, Z100_PROFILE, NEX_PROFILE, G1_PROFILE} from "./profiles"
|
|
40
40
|
|
|
41
41
|
// =============================================================================
|
|
42
42
|
// Convenience factory functions
|
|
@@ -46,7 +46,6 @@ import {TextMeasurer} from "./measurer"
|
|
|
46
46
|
import {TextWrapper} from "./wrapper"
|
|
47
47
|
import {DisplayHelpers} from "./helpers"
|
|
48
48
|
import {ColumnComposer} from "./composer"
|
|
49
|
-
import {G1_PROFILE} from "./profiles"
|
|
50
49
|
import type {DisplayProfile} from "./profiles"
|
|
51
50
|
import type {WrapOptions} from "./wrapper"
|
|
52
51
|
|