@corva/chat-core 0.0.1 → 0.1.2

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/README.md CHANGED
@@ -10,13 +10,70 @@ It holds everything that is not UI: the Revolt/Stoat API and socket client, chat
10
10
  ## Rules
11
11
 
12
12
  - **No platform globals.** The type environment is `es2022` only, with no DOM or Node types. The only
13
- globals allowed are the timers and `console` declared in `src/platform.d.ts`. `fetch`, `WebSocket`,
13
+ globals allowed are the timers, `console` and `requestAnimationFrame` declared in
14
+ `src/platform.d.ts` and `src/raf.d.ts`. `fetch`, `WebSocket`,
14
15
  storage, notifications and app-state events are injected by the host app through adapters.
15
16
  - **No React.** Stores use `zustand/vanilla`; each app wraps them in its own hooks.
16
17
  - **No UI dependencies** (`@corva/ui`, MUI, React Native).
17
18
 
19
+ Hosts must provide a global `crypto.getRandomValues` for `uuid`: browsers have it, and the mobile
20
+ app installs it with `polyfillWebCrypto()` from `expo-standard-web-crypto` in its root layout.
21
+
18
22
  Lint and typecheck enforce these rules.
19
23
 
24
+ ## Setup
25
+
26
+ Call `configureChat(host)` once at app start, before touching any store, then `ensureChatSession(corvaUser)` to sign in:
27
+
28
+ ```ts
29
+ import { configureChat, ensureChatSession } from '@corva/chat-core';
30
+
31
+ configureChat({
32
+ apiUrl, // Revolt REST, e.g. https://stoat.corva.ai/api
33
+ wsUrl, // Revolt events, e.g. wss://stoat.corva.ai/ws
34
+ platform, // ChatPlatform, see below
35
+ storage, // KeyValueStorage: localStorage on web
36
+ corvaApi, // { get, post } against corva-api with the Corva JWT
37
+ appState, // { isHidden, isInactive, subscribe, onTerminate? }
38
+ dates, // { startOfTomorrowAt(hour, now) } in the user's timezone
39
+ notifier, // optional { showIncomingMessage, onMessageSent, onLogout }
40
+ });
41
+
42
+ await ensureChatSession(corvaUser);
43
+ ```
44
+
45
+ | Host member | Web | React Native |
46
+ | ----------- | ---------------------------------------------------------- | --------------------------------------- |
47
+ | `storage` | `localStorage` | MMKV, or a hydrated in-memory map |
48
+ | `corvaApi` | `apiCore` / `jsonApi` (`get` repeats array keys) | the app's `ApiClient` |
49
+ | `appState` | `visibilityState`, `hasFocus()`, `pagehide` | `AppState` (`background` counts hidden) |
50
+ | `dates` | `moment` with the user's timezone default | `date-fns` in the device timezone |
51
+ | `notifier` | browser notification + sound, notification prompt, favicon | push/local notification, badge |
52
+
53
+ Stores are `zustand/vanilla` stores (`roomStore`, `messageStore`, …). React apps wrap them:
54
+
55
+ ```ts
56
+ import { useStore } from 'zustand';
57
+ import { roomStore } from '@corva/chat-core';
58
+
59
+ export const useRoomStore = <T>(selector: (state: ReturnType<typeof roomStore.getState>) => T) =>
60
+ useStore(roomStore, selector);
61
+ ```
62
+
63
+ ## Platform adapter
64
+
65
+ `ChatPlatform` (`src/platform/types.ts`) is the transport part of the host, also taken directly by
66
+ `createRevoltAPI` and `createRevoltSocket`:
67
+
68
+ | Member | Web | React Native |
69
+ | ------------------------- | --------------------------------- | ------------------------------------- |
70
+ | `fetch` | `(url, init) => fetch(url, init)` | same |
71
+ | `createWebSocket` | `url => new WebSocket(url)` | same |
72
+ | `createUploadBody` | `FormData` with the `File` | `FormData` with `{ uri, name, type }` |
73
+ | `subscribeReconnectHints` | `online` + `visibilitychange` | NetInfo + `AppState` `active` |
74
+
75
+ `typecheck/browserPlatform.ts` is a compile-only reference web adapter (platform and app state) that proves the browser APIs fit.
76
+
20
77
  ## Development
21
78
 
22
79
  ```sh