@condorinst/mobile-bridge 0.8.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.
- package/CHANGELOG.md +350 -0
- package/LICENSE +14 -0
- package/README.md +396 -0
- package/dist/cli.cjs +194 -0
- package/dist/cli.cjs.map +1 -0
- package/dist/cli.js +193 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.cjs +1045 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +624 -0
- package/dist/index.d.ts +624 -0
- package/dist/index.js +1005 -0
- package/dist/index.js.map +1 -0
- package/package.json +65 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [0.8.0] — 2026-06-23
|
|
11
|
+
|
|
12
|
+
First **public** release. Runtime is identical to `0.7.0`; this version
|
|
13
|
+
packages the SDK for external White Label partners.
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
- **Package renamed `condor-mobile-bridge` → `@condorinst/mobile-bridge`**
|
|
18
|
+
(scoped, published to the public npm registry). Update imports accordingly.
|
|
19
|
+
This is the breaking change behind the minor bump (pre-1.0 semver).
|
|
20
|
+
- `README.md` and `CHANGELOG.md` rewritten in English; internal monorepo
|
|
21
|
+
references removed.
|
|
22
|
+
- `license` field set to `SEE LICENSE IN LICENSE` (proprietary EULA, unchanged
|
|
23
|
+
in spirit). `publishConfig.access: public`, `prepublishOnly` (build + test).
|
|
24
|
+
|
|
25
|
+
### Added
|
|
26
|
+
|
|
27
|
+
- `docs/client-guide.md` — _"Build your White Label Home"_ onboarding guide.
|
|
28
|
+
- `examples/minimal-home/` — runnable standalone client example.
|
|
29
|
+
- `RELEASING.md` — dev-private → npm + public-repo release flow.
|
|
30
|
+
|
|
31
|
+
## [0.7.0] — 2026-06-23
|
|
32
|
+
|
|
33
|
+
### Added
|
|
34
|
+
|
|
35
|
+
- **`sensorLog` key** in the `BRIDGE_KEYS` catalog (10th key) — read command
|
|
36
|
+
for the sensor log history. Since `subscribe`/`event` are validated against
|
|
37
|
+
`picklist(Object.values(BRIDGE_KEYS))`, the key must exist here for the shell
|
|
38
|
+
to relay the response to the sandboxed iframe (otherwise the message is
|
|
39
|
+
dropped at `safeParse`).
|
|
40
|
+
- **`SensorLogPayload`** in `payloads.ts` + an entry in `KeyPayloads` →
|
|
41
|
+
typed `PayloadOf<'sensorLog'>`. Envelope with an echoed `requestId`
|
|
42
|
+
(correlation of concurrent keyset pagination) + `success`/`error`; on success
|
|
43
|
+
it carries `logs[]` (ASC, °C, naive UTC timestamps) + opaque cursors +
|
|
44
|
+
`hasMore`/`hasPrevious`; on error, an `error` with the contract code (e.g.
|
|
45
|
+
`CONFLICTING_CURSORS`).
|
|
46
|
+
- `tests/messages.test.ts` — catalog updated (9→10), `sensorLog` wire string
|
|
47
|
+
and `PayloadOf<'sensorLog'>`. Total: **116/116**.
|
|
48
|
+
|
|
49
|
+
### Notes
|
|
50
|
+
|
|
51
|
+
- `sensorLog` is **read-only** for the client (it only receives the page/error);
|
|
52
|
+
sending the command uses the permissive `send` path (`command: v.string()`).
|
|
53
|
+
|
|
54
|
+
## [0.6.0] — 2026-06-22
|
|
55
|
+
|
|
56
|
+
### Added
|
|
57
|
+
|
|
58
|
+
- **Build CLI `condor-mobile-bridge build`** (`bin`) — generates the
|
|
59
|
+
self-contained white-label `.zip` bundle from the client's `dist/`. Inlines
|
|
60
|
+
`<script src>` (escaping `</script>`) and `<link rel=stylesheet>`, resolves
|
|
61
|
+
CSS `url()` and local `<img>`/icons to `data:` URIs, and packs a single
|
|
62
|
+
`index.html` at the root. Prints `bundleSize` (bytes) and `bundleHash`
|
|
63
|
+
(`sha256-<hex>`, **deterministic** via fixed mtime) for backend manifest
|
|
64
|
+
registration; **warns** (does not block) above the 2 MB limit. Flags:
|
|
65
|
+
`-i/--html`, `-o/--out`, `--max-bytes`.
|
|
66
|
+
- Production deps `node-html-parser` (a real HTML parser, not regex) and
|
|
67
|
+
`fflate` (100% JS zip, cross-platform — no system `zip` binary). Used **only**
|
|
68
|
+
by the CLI; they do not enter the iframe runtime bundle.
|
|
69
|
+
- `tests/cli.test.ts` — 18 tests (inliner, recursive `url()`, escaping,
|
|
70
|
+
preserved external refs, root zip, deterministic hash). Total: **115/115**.
|
|
71
|
+
|
|
72
|
+
### Notes
|
|
73
|
+
|
|
74
|
+
- The post-build inliner assumes a **single-chunk** `dist` (one JS + one CSS +
|
|
75
|
+
assets). Builds with code-splitting / ES modules require a single-file config
|
|
76
|
+
on the client side (Vite: `vite-plugin-singlefile`; CRA: no split). See README.
|
|
77
|
+
|
|
78
|
+
## [0.5.1] — 2026-06-09
|
|
79
|
+
|
|
80
|
+
### Added
|
|
81
|
+
|
|
82
|
+
- **`BridgeShell.bootstrapClientIframeWithHtml(clientHtml: string)`** — new
|
|
83
|
+
public method that accepts an HTML string directly instead of fetching it.
|
|
84
|
+
Required where `fetch` does not work (asset bundled at `file://` in Android
|
|
85
|
+
WebView, build-time inlined bundle via `esbuild.define`, etc.).
|
|
86
|
+
- 4 new tests covering the new API + the legacy `bootstrapClientIframe` error
|
|
87
|
+
flow. Total: **98/98 green**.
|
|
88
|
+
|
|
89
|
+
### Changed
|
|
90
|
+
|
|
91
|
+
- **`OVERRIDE_PREFIX` fixed** — `value/writable: false` replaced by a **no-op
|
|
92
|
+
getter/setter** + `configurable: false`. Reason: modern ESM bundles run in
|
|
93
|
+
strict mode; any `window.X = …` on a non-writable property **throws**,
|
|
94
|
+
breaking the bootstrap of legacy modules (including this package's own
|
|
95
|
+
`Bridge`, which sets `window.CondorBridge = {emit}` as a module-load
|
|
96
|
+
side effect). With a getter/setter, assignment passes silently; the getter
|
|
97
|
+
always returns undefined; native bridges stay unreachable in the iframe
|
|
98
|
+
without breaking legitimate JS flows. Validated empirically via an offensive
|
|
99
|
+
pen test on a physical device.
|
|
100
|
+
- `BridgeShell.bootstrapClientIframe(clientPath)` refactored to delegate
|
|
101
|
+
internally to `bootstrapClientIframeWithHtml` after the `fetch`. **No
|
|
102
|
+
observable behavior change**; the legacy API is preserved.
|
|
103
|
+
- `OVERRIDE_PREFIX` extracted as a module constant (was inline in the method).
|
|
104
|
+
|
|
105
|
+
### Notes
|
|
106
|
+
|
|
107
|
+
- **No breaking change.** `bootstrapClientIframe(clientPath)` keeps the same
|
|
108
|
+
signature and behavior as v0.5.0 (modulo the override-prefix fix). A client
|
|
109
|
+
importing only `BridgeClient` or other APIs is unaffected.
|
|
110
|
+
- The shell version (`shellVersion` in the handshake-ack) now reports `0.5.1`.
|
|
111
|
+
|
|
112
|
+
## [0.5.0] — 2026-06-09
|
|
113
|
+
|
|
114
|
+
### Added
|
|
115
|
+
|
|
116
|
+
- **`BridgeClient`** — API for external client code running inside an
|
|
117
|
+
`<iframe sandbox="allow-scripts">`. Surface identical to the legacy `Bridge`
|
|
118
|
+
(`on`/`send`/`openSettings`/`handshake`); internally every call becomes a
|
|
119
|
+
`window.parent.postMessage`. The client imports `BridgeClient` instead of
|
|
120
|
+
`Bridge` and never notices it is sandboxed.
|
|
121
|
+
- **`BridgeShell`** — API for the Condor-controlled shell that wraps the
|
|
122
|
+
iframe. Responsibilities: iframe bootstrap with the override prefix
|
|
123
|
+
(`bootstrapClientIframe`), iframe attestation (`verifySandbox`),
|
|
124
|
+
`postMessage` ↔ legacy `Bridge` routing with a default-deny policy, and
|
|
125
|
+
gating of sensitive commands via the `onConfirmationRequest` callback.
|
|
126
|
+
- **Valibot schemas** (`ClientToShellMessage` / `ShellToClientMessage`) —
|
|
127
|
+
strict validation of every `postMessage`. Malformed messages are dropped
|
|
128
|
+
silently. Types: `subscribe`, `unsubscribe`, `send`, `handshake`, `jsError`,
|
|
129
|
+
`sandbox-verify-response` (client→shell) + `event`, `handshake-ack`, `nack`,
|
|
130
|
+
`verify-sandbox` (shell→client).
|
|
131
|
+
- **`ShellPolicy`** — declarative interface for gating: `readOnlyKeys`,
|
|
132
|
+
`allowedCommands`, `requiresConfirmation`, `deniedCommands`. The policy is
|
|
133
|
+
data provided by the shell (not embedded in the package).
|
|
134
|
+
- 33 new tests (`tests/bridge-client.test.ts` 14 + `tests/bridge-shell.test.ts` 19).
|
|
135
|
+
Total: **94/94 green** (61 from v0.4.0 + 33 new).
|
|
136
|
+
- New dependency: `valibot` (~3 KB minified, tree-shakeable).
|
|
137
|
+
|
|
138
|
+
### Layered defense against `window.flutter_inappwebview` propagation to the iframe
|
|
139
|
+
|
|
140
|
+
Implemented in this release:
|
|
141
|
+
|
|
142
|
+
- **Layer 1** — `BridgeShell.bootstrapClientIframe(clientPath)`: fetches the
|
|
143
|
+
client HTML, prepends an override script that `delete`s
|
|
144
|
+
`window.flutter_inappwebview` and `window.CondorBridge` +
|
|
145
|
+
`Object.defineProperty(..., configurable: false)`, and sets it as `srcdoc`.
|
|
146
|
+
The override runs at parse-time, before any client script.
|
|
147
|
+
- **Layer 2** — `BridgeShell.verifySandbox()`: a `verify-sandbox` →
|
|
148
|
+
`sandbox-verify-response` `postMessage` round-trip. `BridgeClient` answers
|
|
149
|
+
authoritatively about the state of the bridges in the iframe. The shell
|
|
150
|
+
aborts the boot if it receives `ok: false`.
|
|
151
|
+
|
|
152
|
+
Layers 3 (native-validated shell nonce) and 4 (dual-WebView fallback) live on
|
|
153
|
+
the native Flutter side.
|
|
154
|
+
|
|
155
|
+
### Notes
|
|
156
|
+
|
|
157
|
+
- The legacy `Bridge` is unchanged — v0.4.0 clients importing `Bridge` keep
|
|
158
|
+
working identically. Migrating to the sandbox model is optional (but
|
|
159
|
+
recommended for an external-client audience).
|
|
160
|
+
- `BridgeClient` does **not** expose `installDevPanel`, `mockEmit`, `isMock`,
|
|
161
|
+
`getMockState` — those APIs are the shell's responsibility.
|
|
162
|
+
- Bundle: `dist/index.js` 29 KB (was 19 KB in v0.4.0; +10 KB for Valibot +
|
|
163
|
+
BridgeClient + BridgeShell + schemas).
|
|
164
|
+
- No runtime or build-time breaking changes for legacy `Bridge` users.
|
|
165
|
+
|
|
166
|
+
## [0.4.0] — 2026-06-04
|
|
167
|
+
|
|
168
|
+
### Added
|
|
169
|
+
|
|
170
|
+
- **Per-key strict types** in `PayloadOf<K>`. `Bridge.on<K>` now infers the
|
|
171
|
+
typed payload for a cataloged key. Unknown keys fall back to the permissive
|
|
172
|
+
`Record<string, unknown>`.
|
|
173
|
+
- **8 per-key DTOs**, derived authoritatively from the native source (services
|
|
174
|
+
+ entities):
|
|
175
|
+
- `PingPongPayload = { data: 'ping' | 'pong' }`
|
|
176
|
+
- `UserDevicePayload = { lastUpdate, devicesConfig[], devicesTelemetry[], devicesUserConfig[] }`
|
|
177
|
+
- `DeviceLightSensorsPayload = { serialNo, type, data: Record<string, unknown> }`
|
|
178
|
+
- `SyncTimeAckPayload = { serialNo, success }`
|
|
179
|
+
- `RealTimeAckPayload = { serialNo, success, value }`
|
|
180
|
+
- `DeleteMemoryAckPayload = { serialNo, success }`
|
|
181
|
+
- `DeviceNotificationPayload = { serialNo, isConnect, message: string | null, messageCode: string | null, isError }`
|
|
182
|
+
- `DeviceConnectionPayload = { serialNo, isConnect }`
|
|
183
|
+
- **`KeyPayloads`** mapped type discriminated by key. `PayloadOf<K>` is now
|
|
184
|
+
`K extends keyof KeyPayloads ? KeyPayloads[K] : Record<string, unknown>`.
|
|
185
|
+
- 9 new tests in `tests/messages.test.ts` using `expectTypeOf` (Vitest) to
|
|
186
|
+
validate compile-time inference + runtime sanity per key. Total: **61/61
|
|
187
|
+
green** (52 from v0.3.0 + 9 new).
|
|
188
|
+
|
|
189
|
+
### Notes
|
|
190
|
+
|
|
191
|
+
- `dfu` keeps the permissive fallback — reserved.
|
|
192
|
+
- `Bridge.send(type, payload?)` stays permissive in v0.4.0 (JS→BG commands are
|
|
193
|
+
heterogeneous: `realTime` `{serialNo, value}`, `userDevice` `{getFromServer}`,
|
|
194
|
+
`deviceConnection` `{type, serialNo}`, etc.). Typing a `send` overload is left
|
|
195
|
+
for a future release.
|
|
196
|
+
- **Runtime-compatible**, but technically a build-time break for v0.3.0 clients
|
|
197
|
+
that relied on an `unknown` payload in `Bridge.on`. A client that needs the
|
|
198
|
+
permissive shape can declare `(payload: Record<string, unknown>) => ...`
|
|
199
|
+
explicitly.
|
|
200
|
+
- `dist/` grew from ~17 KB to ~17.7 KB (minimal type overhead).
|
|
201
|
+
|
|
202
|
+
### Migration from v0.3.0 → v0.4.0 (client)
|
|
203
|
+
|
|
204
|
+
A client that had:
|
|
205
|
+
```typescript
|
|
206
|
+
Bridge.on(BRIDGE_KEYS.realTime, (payload) => {
|
|
207
|
+
// payload: Record<string, unknown> in v0.3.0
|
|
208
|
+
});
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
Still compiles. The gain: `payload` is now `RealTimeAckPayload` — accessing
|
|
212
|
+
`payload.serialNo`/`payload.success`/`payload.value` is type-safe without a cast.
|
|
213
|
+
|
|
214
|
+
## [0.3.0] — 2026-06-04
|
|
215
|
+
|
|
216
|
+
### Added
|
|
217
|
+
|
|
218
|
+
- **Auto-respond toggle** in the dev panel — an optional checkbox that, when
|
|
219
|
+
on, programmatically fires `mockEmit` in response to each `Bridge.send`
|
|
220
|
+
(closed loop in mock mode without manual intervention). Conditional render:
|
|
221
|
+
appears only when the client provides the policy in
|
|
222
|
+
`DevPanelOptions.onSendForAutoRespond`.
|
|
223
|
+
- **`DevPanelOptions.onSendForAutoRespond`** — synchronous callback
|
|
224
|
+
`(msg: MockMessage) => { key, payload } | null`. The client provides the
|
|
225
|
+
policy (send → emit mapping); the package provides the mechanism.
|
|
226
|
+
- **`DevPanelOptions.startAutoRespondEnabled`** — initial toggle state.
|
|
227
|
+
Default: `false` (manual stays default; v0.2.0 semantics preserved). The
|
|
228
|
+
client can override to `true` to auto-loop from boot.
|
|
229
|
+
- **`DevPanelOptions.autoRespondDelayMs`** — delay between the `send` and the
|
|
230
|
+
auto-response `mockEmit`. Default: `50` (approximates real native-bridge IPC
|
|
231
|
+
latency).
|
|
232
|
+
- **`AutoRespondResponse`** type exported: `{ key: string; payload: unknown }`.
|
|
233
|
+
- **`MockAdapter.onCallHandler(listener)`** — registers a listener invoked on
|
|
234
|
+
each `callHandler`. Returns an unsubscribe function. Errors in listeners are
|
|
235
|
+
caught + logged (they do not affect other listeners or the bridge pipeline).
|
|
236
|
+
Useful for runtime-inspection integrations (client tests, dev tooling).
|
|
237
|
+
|
|
238
|
+
### Behavior
|
|
239
|
+
|
|
240
|
+
- The "Auto-respond" toggle persists in memory for the panel's lifetime.
|
|
241
|
+
Re-installing the panel resets it to the declared `startAutoRespondEnabled`.
|
|
242
|
+
- The listener registered by the dev panel is cleaned up automatically on
|
|
243
|
+
`uninstall()` (no leak between re-installs).
|
|
244
|
+
- Errors in the client policy are caught via try/catch + `console.error` —
|
|
245
|
+
they do not destabilize `callHandler`.
|
|
246
|
+
|
|
247
|
+
### Tests
|
|
248
|
+
|
|
249
|
+
- 52/52 green (40 from v0.2.0 + 12 new: 4 `onCallHandler` + 8 auto-respond).
|
|
250
|
+
|
|
251
|
+
### Notes
|
|
252
|
+
|
|
253
|
+
- The Layer 1 API (`handshake`, `on`, `send`, `openSettings`) and the initial
|
|
254
|
+
Layer 2 API (`isMock`, `mockEmit`, `getMockState`, `installDevPanel`) are
|
|
255
|
+
**unchanged**. Auto-respond is purely opt-in: a client without a policy sees
|
|
256
|
+
no change in the panel.
|
|
257
|
+
- `dist/` grew from ~14 KB (v0.2.0) to ~17 KB (v0.3.0) — acceptable overhead.
|
|
258
|
+
- Minor bump (`0.2.0 → 0.3.0`): backward-compatible feature, no breaking
|
|
259
|
+
changes in API or behavior.
|
|
260
|
+
|
|
261
|
+
## [0.2.0] — 2026-06-03
|
|
262
|
+
|
|
263
|
+
### Added
|
|
264
|
+
|
|
265
|
+
- **Mock mode** — when `window.flutter_inappwebview` is not detected (regular
|
|
266
|
+
browser, Storybook, Vite dev server), the adapter activates automatically.
|
|
267
|
+
Unblocks client development in the browser without building the APK.
|
|
268
|
+
- **`Bridge.isMock`** (readonly getter) — `true` when the mock adapter is active.
|
|
269
|
+
- **`Bridge.mockEmit(key, payload?)`** — dispatches `window.CondorBridge.emit`
|
|
270
|
+
programmatically to simulate native events. Throws outside mock mode.
|
|
271
|
+
- **`Bridge.getMockState()`** — returns `{ isMock, messages, subscriberKeys }`.
|
|
272
|
+
A snapshot of the mock adapter state for asserts in client tests. Throws
|
|
273
|
+
outside mock mode.
|
|
274
|
+
- **`Bridge.installDevPanel(options?)`** — injects a floating HTML panel into
|
|
275
|
+
`document.body` to inspect the bridge in the browser:
|
|
276
|
+
- Header with a "MOCK" badge, sent counter, minimize/maximize button.
|
|
277
|
+
- Sent log — last N (default 20) messages (timestamp, type, payload).
|
|
278
|
+
- Trigger emit — dropdown of `BRIDGE_KEYS` + `handshake-ack` + JSON payload
|
|
279
|
+
textarea + "Emit" button + "Clear sent" button.
|
|
280
|
+
- Auto-refresh via `setInterval(500ms)`.
|
|
281
|
+
- Idempotent — re-install replaces the previous one.
|
|
282
|
+
- Inline styles + `condor-mock-panel-*` classes (reduces CSS conflicts).
|
|
283
|
+
- Options: `position`/`maxMessages`/`theme`/`startCollapsed`.
|
|
284
|
+
|
|
285
|
+
### Behavior
|
|
286
|
+
|
|
287
|
+
- **Handshake in mock mode is EXPLICIT.** `Bridge.handshake()` does NOT
|
|
288
|
+
auto-resolve in mock. The client/test must call
|
|
289
|
+
`Bridge.mockEmit('handshake-ack', {nativeVersion, accepted})` to unblock the
|
|
290
|
+
Promise. A design decision to force intentional tests.
|
|
291
|
+
- **`Bridge.send` in mock** records `{handlerName, payload, timestamp}` in a
|
|
292
|
+
FIFO buffer (cap 100) + `console.debug`. The buffer is accessible via
|
|
293
|
+
`getMockState().messages`.
|
|
294
|
+
|
|
295
|
+
### Refactor (non-breaking)
|
|
296
|
+
|
|
297
|
+
- `src/internal/native.ts` refactored to an adapter pattern. `NativeAdapter` is
|
|
298
|
+
a `RealAdapter | MockAdapter` union discriminated by `readonly isMock`.
|
|
299
|
+
`getActiveAdapter()` caches detection; `__resetAdapterForTests()` resets it.
|
|
300
|
+
|
|
301
|
+
### Tests
|
|
302
|
+
|
|
303
|
+
- 40/40 green (21 from v0.1.0 + 19 new):
|
|
304
|
+
- `tests/mock.test.ts`: 12 tests (isMock, send, mockEmit, explicit handshake,
|
|
305
|
+
getMockState, buffer cap).
|
|
306
|
+
- `tests/dev-panel.test.ts`: 7 tests (DOM injection, interaction, idempotency).
|
|
307
|
+
|
|
308
|
+
### Notes
|
|
309
|
+
|
|
310
|
+
- The Layer 1 API (`handshake`, `on`, `send`, `openSettings`) is **unchanged**.
|
|
311
|
+
- The `v0.1.0 → v0.2.0` migration is **automatic** — nothing to adjust in client
|
|
312
|
+
code; mock mode only activates when running outside the WebView.
|
|
313
|
+
- `dist/` grew from ~3 KB to ~14 KB (ESM) because of the inline dev panel.
|
|
314
|
+
Considered acceptable for the feature.
|
|
315
|
+
|
|
316
|
+
## [0.1.0] — 2026-06-03
|
|
317
|
+
|
|
318
|
+
### Added
|
|
319
|
+
|
|
320
|
+
- **Layer 1 of the bridge schema/runtime:**
|
|
321
|
+
- `Bridge.handshake({clientVersion})` — versioned handshake with native.
|
|
322
|
+
Returns `Promise<HandshakeAck>`. Rejects parallel calls.
|
|
323
|
+
- `Bridge.on(key, cb)` — typed subscribe to observable keys. Returns
|
|
324
|
+
`unsubscribe`. An error in one subscriber does not affect others.
|
|
325
|
+
- `Bridge.send(type, payload?)` — generic command to native via
|
|
326
|
+
`window.flutter_inappwebview.callHandler`.
|
|
327
|
+
- `Bridge.openSettings()` — sugar over `send('openSettings')`.
|
|
328
|
+
- **`BRIDGE_KEYS` catalog** — 9 keys in camelCase JS API mirroring the native
|
|
329
|
+
foreground com keys: `pingPong`, `userDevice`, `deviceLightSensors`,
|
|
330
|
+
`syncTime`, `realTime`, `deleteMemory`, `deviceNotification`,
|
|
331
|
+
`deviceConnection`, `dfu`.
|
|
332
|
+
- **Types:** `BridgeKey`, `BridgeIncomingMessage`, `BridgeOutgoingEvent`,
|
|
333
|
+
`HandshakeAck`, `HandshakeOptions`, `PayloadOf<K>` (permissive in the MVP).
|
|
334
|
+
- **Automatic bootstrap** of `window.CondorBridge.emit` at module load.
|
|
335
|
+
- **Native host detection** — `flutter_inappwebview` cross-platform (Android +
|
|
336
|
+
iOS). Clear error outside a Flutter WebView (mock mode in v0.2.0).
|
|
337
|
+
- **Tooling:** TypeScript strict + Biome (lint+format) + tsup (dual ESM+CJS
|
|
338
|
+
build + types) + Vitest (jsdom env) + CI.
|
|
339
|
+
- **21 tests** covering handshake, on/emit, send, openSettings, missing host,
|
|
340
|
+
and the key catalog.
|
|
341
|
+
|
|
342
|
+
### Notes
|
|
343
|
+
|
|
344
|
+
- Payloads use `Record<string, unknown>` in the MVP. Per-key strict types
|
|
345
|
+
landed once the native shapes crystallized.
|
|
346
|
+
- Only `pingPong` was actually emitted by native in the initial release. The
|
|
347
|
+
other 8 keys were reserved as a forward-looking contract.
|
|
348
|
+
- Protocol version (`PROTOCOL_VERSION`) = `'0.1.0'`, sent in the `version` of
|
|
349
|
+
each `BridgeIncomingMessage`. Native accepts any `clientVersion` in the MVP —
|
|
350
|
+
real semver validation lands once there are 2+ versions in the field.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
Proprietary — Condor Instruments
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Condor Instruments. All rights reserved.
|
|
4
|
+
|
|
5
|
+
This package is the canonical TypeScript SDK of the JS↔Native bridge of the
|
|
6
|
+
Condor white-label mobile app (`sleep_whitelabel`). It is distributed under a
|
|
7
|
+
proprietary license to authorized partners of Condor Instruments.
|
|
8
|
+
|
|
9
|
+
Unauthorized copying, redistribution, modification, reverse engineering, or
|
|
10
|
+
use of this package or any portion of it, by any medium, is strictly
|
|
11
|
+
prohibited without prior written consent from Condor Instruments.
|
|
12
|
+
|
|
13
|
+
For licensing inquiries, contact Condor Instruments through the official
|
|
14
|
+
support channels.
|