palbase 0.17.1 → 0.18.1

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 (63) hide show
  1. package/dist/ai/index.js +2 -2
  2. package/dist/backend/engine.js +2 -2
  3. package/dist/backend/env.js +1 -1
  4. package/dist/backend/index.js +11 -11
  5. package/dist/backend/stack.js +1 -1
  6. package/dist/backend/test.js +2 -2
  7. package/dist/chunks/{22M4UQVQ.js → 2235YZCU.js} +2 -2
  8. package/dist/chunks/{B2IIU37G.js → 2IQO655S.js} +1 -1
  9. package/dist/chunks/{E27BZ5SM.js → 3AWINO2F.js} +2 -2
  10. package/dist/chunks/{XT3I7PG3.js → 5RT5MMQZ.js} +2 -2
  11. package/dist/chunks/{3Y4K6F6T.js → 6KQLUU3H.js} +2 -2
  12. package/dist/chunks/{R7PRW7FG.js → B34MLQR7.js} +1 -1
  13. package/dist/chunks/{VXT46THA.js → BAI274LR.js} +2 -2
  14. package/dist/chunks/{3UVLEWTM.js → BDXJNCHK.js} +1 -1
  15. package/dist/chunks/{K23K6ZFG.js → D6EZT4FT.js} +2 -2
  16. package/dist/chunks/{NJFKRHS6.js → EFLH3KG7.js} +2 -2
  17. package/dist/chunks/{KBDCHYSD.js → HVZBXN5X.js} +1 -1
  18. package/dist/chunks/{Y6NZV7LU.js → I3Z7F2Q7.js} +1 -1
  19. package/dist/chunks/{2PIDGENK.js → KK6V5EI4.js} +2 -2
  20. package/dist/chunks/{ZSUSEU5H.js → LJP3LHLO.js} +2 -2
  21. package/dist/chunks/{6WGPEHCE.js → NTAJM7WR.js} +1 -1
  22. package/dist/chunks/{LAHIVWPV.js → PTZ7ZIVR.js} +1 -1
  23. package/dist/chunks/{DWRLUP7O.js → RH4K3QBY.js} +2 -2
  24. package/dist/chunks/RNDZZL4L.js +2 -0
  25. package/dist/chunks/S7MGNDUF.js +22 -0
  26. package/dist/chunks/{FWX3RGVS.js → TQFLWOSE.js} +2 -2
  27. package/dist/chunks/{7C7HACEZ.js → W6N2DVBO.js} +2 -2
  28. package/dist/chunks/WJ6WXWYV.js +21 -0
  29. package/dist/chunks/{LR5ONXTF.js → XW2UNA5Y.js} +2 -2
  30. package/dist/cli.js +117 -117
  31. package/dist/refuse/ai.js +1 -1
  32. package/dist/refuse/backend.js +1 -1
  33. package/dist/refuse/server.js +1 -1
  34. package/dist/server/index.js +2 -2
  35. package/dist/server/testing.js +2 -2
  36. package/dist/web/index.js +2 -2
  37. package/dist/web/message.js +2 -2
  38. package/dist/web/palbe.js +2 -2
  39. package/dist/web/paywall.js +2 -2
  40. package/dist/web/push-sw.js +1 -1
  41. package/dist/web/ssr.js +2 -2
  42. package/dist/web/vite.js +2 -2
  43. package/package.json +2 -2
  44. package/types/backend/src/attest.d.ts +59 -0
  45. package/types/backend/src/decorators.d.ts +10 -1
  46. package/types/backend/src/index.d.ts +1 -1
  47. package/types/internal/src/messaging/engine.d.ts +31 -0
  48. package/types/internal/src/messaging/files.d.ts +11 -0
  49. package/types/internal/src/messaging/index.d.ts +5 -0
  50. package/types/internal/src/messaging/local.d.ts +31 -0
  51. package/types/internal/src/messaging/outbox.d.ts +53 -0
  52. package/types/internal/src/messaging/store.d.ts +67 -0
  53. package/types/internal/src/modules/auth.d.ts +8 -0
  54. package/types/internal/src/modules/events.d.ts +2 -2
  55. package/types/internal/src/modules/purchases.d.ts +2 -2
  56. package/types/internal/src/modules/stores.d.ts +166 -0
  57. package/types/web/src/auth.d.ts +11 -1
  58. package/types/web/src/client.d.ts +5 -0
  59. package/types/web/src/index.d.ts +1 -0
  60. package/types/web/src/messaging.d.ts +280 -0
  61. package/dist/chunks/CYLNEHKQ.js +0 -2
  62. package/dist/chunks/LIKE2KDM.js +0 -22
  63. package/dist/chunks/OER3S5NN.js +0 -21
@@ -467,6 +467,10 @@ export type AppleChangedEvent = {
467
467
  * What Apple said of the key (connected, checked).
468
468
  */
469
469
  status?: "active" | "agreement" | "refused";
470
+ /**
471
+ * The key was made at Apple by Palbase, with the environment's Apple ID session (connected).
472
+ */
473
+ made?: boolean;
470
474
  };
471
475
  /**
472
476
  * A one-time grant to connect an Apple key: the key goes from the person's browser (connect_url) or terminal (POST /stores/connect with the grant) straight to the module.
@@ -2532,6 +2536,7 @@ export type AppleSession = {
2532
2536
  */
2533
2537
  status?: "active" | "expired";
2534
2538
  team?: AppleTeam;
2539
+ shared_from?: SharedEnvironment;
2535
2540
  };
2536
2541
  /**
2537
2542
  * stores.apple.session.changed: an Apple ID was signed in for the project, or disconnected. Never the session.
@@ -2885,6 +2890,125 @@ export type AppleSessionEndedEvent = {
2885
2890
  */
2886
2891
  connected_by: string;
2887
2892
  };
2893
+ /**
2894
+ * A key Palbase made at Apple for the environment: never its .p8.
2895
+ */
2896
+ export type MadeKey = {
2897
+ /**
2898
+ * The apps it is for (APNs, In-App Purchase).
2899
+ */
2900
+ bundles?: string[];
2901
+ /**
2902
+ * An APNs key's environment.
2903
+ */
2904
+ environment?: "sandbox" | "prod";
2905
+ /**
2906
+ * The key's id at Apple.
2907
+ */
2908
+ key_id: string;
2909
+ /**
2910
+ * `asc` (App Store Connect API), `apns` or `iap` (In-App Purchase).
2911
+ */
2912
+ kind: "asc" | "apns" | "iap";
2913
+ /**
2914
+ * When it was made.
2915
+ */
2916
+ made_at: string;
2917
+ /**
2918
+ * Who asked for it: a developer's id, or the key's.
2919
+ */
2920
+ made_by: string;
2921
+ /**
2922
+ * The module it is for: notify (APNs), purchases (In-App Purchase).
2923
+ */
2924
+ module?: "notify" | "purchases";
2925
+ /**
2926
+ * What became of it, when it was not simply taken.
2927
+ */
2928
+ note?: string;
2929
+ /**
2930
+ * When its module took it, refused it, or it was revoked.
2931
+ */
2932
+ settled_at?: string;
2933
+ /**
2934
+ * `waiting` for its module to take it, `taken`, `refused` (its module keeps a key of its own and it could not be revoked at Apple), or `revoked`.
2935
+ */
2936
+ state: "waiting" | "taken" | "refused" | "revoked";
2937
+ };
2938
+ /**
2939
+ * Keys Palbase made at Apple for the environment.
2940
+ */
2941
+ export type MadeKeys = {
2942
+ keys: MadeKey[];
2943
+ };
2944
+ /**
2945
+ * The key to make at Apple.
2946
+ */
2947
+ export type MakeKeyRequest = {
2948
+ /**
2949
+ * The iOS app an In-App Purchase key is for; required when the environment has more than one.
2950
+ */
2951
+ bundle?: string;
2952
+ /**
2953
+ * `asc` (App Store Connect API), `apns` or `iap` (In-App Purchase).
2954
+ */
2955
+ kind: "asc" | "apns" | "iap";
2956
+ };
2957
+ /**
2958
+ * The environment of the organization whose Apple ID session the project uses, having none of its own: signed in to the project's App Store Connect team.
2959
+ */
2960
+ export type SharedEnvironment = {
2961
+ /**
2962
+ * Its project's name.
2963
+ */
2964
+ name?: string;
2965
+ /**
2966
+ * Its platform project's id.
2967
+ */
2968
+ project_id: string;
2969
+ /**
2970
+ * Its ref.
2971
+ */
2972
+ ref?: string;
2973
+ };
2974
+ /**
2975
+ * stores.apple.key.made: keys were made at Apple for another module of the environment (notify's APNs keys, purchases' In-App Purchase key), which takes them. Never a key.
2976
+ */
2977
+ export type AppleKeyMadeEvent = {
2978
+ /**
2979
+ * The keys' handover: what the module takes at once.
2980
+ */
2981
+ handover: string;
2982
+ /**
2983
+ * The keys' ids at Apple.
2984
+ */
2985
+ key_ids: string[];
2986
+ /**
2987
+ * `apns` or `iap`.
2988
+ */
2989
+ kind: "apns" | "iap";
2990
+ /**
2991
+ * The module the keys are for.
2992
+ */
2993
+ module: "notify" | "purchases";
2994
+ };
2995
+ /**
2996
+ * stores.apple.key.revoked: a key Palbase made at Apple for the environment was revoked there. Never the key.
2997
+ */
2998
+ export type AppleKeyRevokedEvent = {
2999
+ /**
3000
+ * The key's id at Apple.
3001
+ */
3002
+ key_id: string;
3003
+ /**
3004
+ * `apns` or `iap`.
3005
+ */
3006
+ kind: "asc" | "apns" | "iap";
3007
+ /**
3008
+ * The module it was for.
3009
+ */
3010
+ module?: string;
3011
+ };
2888
3012
  /** The events this module sends the project's webhooks (x-palbase-events), by type: each one's payload, the event's data. */
2889
3013
  export interface Events {
2890
3014
  /**
@@ -2971,6 +3095,14 @@ export interface Events {
2971
3095
  * stores.apple.session.ended: Palbase's own project's copy of an Apple ID session Apple ended in a customer's project, whose Studio mails the person who connected it.
2972
3096
  */
2973
3097
  "stores.apple.session.ended": AppleSessionEndedEvent;
3098
+ /**
3099
+ * stores.apple.key.made: keys were made at Apple for another module of the environment (notify's APNs keys, purchases' In-App Purchase key), which takes them. Never a key.
3100
+ */
3101
+ "stores.apple.key.made": AppleKeyMadeEvent;
3102
+ /**
3103
+ * stores.apple.key.revoked: a key Palbase made at Apple for the environment was revoked there. Never the key.
3104
+ */
3105
+ "stores.apple.key.revoked": AppleKeyRevokedEvent;
2974
3106
  }
2975
3107
  /** Palbase Stores */
2976
3108
  export declare function client(t: Transport): {
@@ -3914,5 +4046,39 @@ export declare function client(t: Transport): {
3914
4046
  }; /** Stops the call: the request in flight, a wait before a retry, a proof-of-work being solved. */
3915
4047
  signal?: AbortSignal;
3916
4048
  }): Promise<Reply<204, undefined>>;
4049
+ /**
4050
+ * Keys made at Apple
4051
+ *
4052
+ * The keys Palbase made at Apple for the environment with its Apple ID session (`POST /stores/apple/keys`), the newest first — never a key itself: its App Store Connect API key, its APNs keys (notify's) and its In-App Purchase key (purchases'), and where each stands.
4053
+ */
4054
+ listMadeAppleKeys(input?: {
4055
+ signal?: AbortSignal;
4056
+ }): Promise<Reply<200, MadeKeys>>;
4057
+ /**
4058
+ * Make a key at Apple
4059
+ *
4060
+ * Makes one key at Apple with the Apple ID session the environment uses, and connects it: no one downloads a .p8. `asc` — the environment's App Store Connect API key (Admin, every app), connected as `POST /stores/connect` connects one (409 `key_connected` when one is). `apns` — two APNs keys, one for each APNs environment (Apple makes a key scoped to apps for one environment), scoped to the environment's iOS apps, which the notify module takes as its APNs provider. `iap` — an In-App Purchase key for one of its iOS apps (`bundle`, required with more than one), which the purchases module connects. A module that keeps a key the environment connected itself refuses the one made, and it is revoked at Apple. One a request (each well inside the edge's time); 409 `key_made` for a kind Palbase made already. The Apple ID must be an Admin or the Account Holder (409 `apple_role_insufficient`). An owner's or an admin's, or the project's secret key's (403 `admin_required` for a member); never an environment's token's (403 `token_out_of_scope`): a key outlives it. Emits `stores.apple.changed` (asc) or `stores.apple.key.made` (apns, iap).
4061
+ */
4062
+ makeAppleKey(input: {
4063
+ headers?: {
4064
+ "Idempotency-Key"?: string;
4065
+ };
4066
+ body: MakeKeyRequest; /** Stops the call: the request in flight, a wait before a retry, a proof-of-work being solved. */
4067
+ signal?: AbortSignal;
4068
+ }): Promise<Reply<201, MadeKeys>>;
4069
+ /**
4070
+ * Revoke a key made at Apple
4071
+ *
4072
+ * Revokes at Apple an APNs or In-App Purchase key Palbase made for the environment: its module keeps it, and it no longer works. The App Store Connect key is revoked as it is disconnected (`DELETE /stores/apple`; 409 `key_connected` here). An owner's or an admin's, or the project's secret key's. Emits `stores.apple.key.revoked`.
4073
+ */
4074
+ revokeMadeAppleKey(input: {
4075
+ path: {
4076
+ key_id: string;
4077
+ };
4078
+ headers?: {
4079
+ "Idempotency-Key"?: string;
4080
+ }; /** Stops the call: the request in flight, a wait before a retry, a proof-of-work being solved. */
4081
+ signal?: AbortSignal;
4082
+ }): Promise<Reply<200, MadeKey>>;
3917
4083
  };
3918
4084
  export type Client = ReturnType<typeof client>;
@@ -1,6 +1,6 @@
1
1
  import { auth as authModule } from '../../internal/src/modules/index.js';
2
2
  import type { Transport } from '../../internal/src/transport.js';
3
- import type { AuthEvent, Session, SessionEndReason, SessionManager } from './session.js';
3
+ import { type AuthEvent, type Session, type SessionEndReason, type SessionManager } from './session.js';
4
4
  type A = typeof authModule;
5
5
  export type User = authModule.User;
6
6
  export type SignupRequest = authModule.SignupRequest;
@@ -62,6 +62,13 @@ export declare class Auth {
62
62
  /** Removes a factor; the account's password confirms it. */
63
63
  removeFactor: (id: string, currentPassword: string) => Promise<void>;
64
64
  regenerateRecoveryCodes: () => Promise<authModule.MFARecoveryCodesResponse>;
65
+ /**
66
+ * Raises the signed-in session to aal2 with a code the authenticator app
67
+ * shows — what a route marked auth { aal: 'aal2' } asks for (401
68
+ * insufficient_user_authentication). The session holds the new token from
69
+ * here on; its refreshes stay at aal2.
70
+ */
71
+ stepUp: (code: string) => Promise<Session>;
65
72
  };
66
73
  readonly passkey: {
67
74
  /** Adds a passkey to the signed-in user. */
@@ -79,6 +86,8 @@ export declare class Auth {
79
86
  * it (the sign-up answers no tokens). The identifier is the user's email.
80
87
  */
81
88
  signUp: (identifier: string, userName?: string) => Promise<User>;
89
+ /** Raises the signed-in session to aal2 with one of the user's passkeys (as mfa.stepUp does with a code). */
90
+ stepUp: () => Promise<Session>;
82
91
  list: () => Promise<authModule.WebAuthnCredentialList>;
83
92
  remove: (id: string) => Promise<void>;
84
93
  };
@@ -156,6 +165,7 @@ export declare class Auth {
156
165
  }): Promise<User>;
157
166
  /** Starts the session from a token pair; the user is the answer's, or read once when it carries none. */
158
167
  private signedIn;
168
+ private steppedUp;
159
169
  private authenticator;
160
170
  }
161
171
  type Json = Record<string, unknown>;
@@ -10,6 +10,7 @@ import { Notify } from './notify.js';
10
10
  import { Purchases } from './purchases.js';
11
11
  import { type ChatToolCall } from './chat.js';
12
12
  import { Flags } from './flags.js';
13
+ import { Messaging, type MessagingOptions } from './messaging.js';
13
14
  export interface ClientOptions {
14
15
  /** The project's address: https://<ref>.<domain> */
15
16
  url: string;
@@ -68,6 +69,8 @@ export interface ClientOptions {
68
69
  * pb.setLanguage changes it.
69
70
  */
70
71
  language?: string | readonly string[];
72
+ /** What the device keeps of the signed-in person's conversations (pb.messaging): dropped on sign-out unless keepOnSignOut. */
73
+ messaging?: MessagingOptions;
71
74
  }
72
75
  /**
73
76
  * The app's client. A backend's generated Palbe module (palbase apps:sync)
@@ -93,6 +96,8 @@ export interface PalbaseClient {
93
96
  notify: Notify;
94
97
  /** The project's feature flags and remote configuration, resolved for this app and its reader, kept current as they change. */
95
98
  flags: Flags;
99
+ /** The signed-in person's conversations — direct ones and groups — kept up to date, on the device and live. */
100
+ messaging: Messaging;
96
101
  /** The language every request says from now on (ClientOptions.language); null for the browser's own. */
97
102
  setLanguage(language: string | readonly string[] | null): void;
98
103
  /**
@@ -10,6 +10,7 @@ export { connectVoice, type StartedVoice, type VoiceConnection, type VoiceOption
10
10
  export { Purchases, redemptionToken, type CheckoutSource, type CustomerInfo, type CustomerInfoListener, type GrantInfo, type MergeGrant, type OfferView, type Offerings, type Redeemed, type RedemptionLink, } from './purchases.js';
11
11
  export { Notify, WebPush, type PushPermission, type PushSubscribeOptions } from './notify.js';
12
12
  export { Flags, type FlagSource, type FlagsListener } from './flags.js';
13
+ export { ConversationList, ConversationView, indexedDBKeyValue, Messaging, ScheduledList, ThreadView, type Conversation, type ConversationViewState, type ConversationListState, type Entry, type Member, type Message, type MessagingOptions, type MyProfile, type Observed, type OpenedFile, type OutboxItem, type OutgoingFile, type Profile, type ScheduledMessage, type SendOptions, type ThreadState, type ThreadViewState, } from './messaging.js';
13
14
  export { Inbox, type InboxItem, type InboxListOptions, type InboxPage, type InboxView, type InboxViewOptions } from './inbox.js';
14
15
  export { InApp, SESSION_START, type InAppOptions } from './inapp.js';
15
16
  export type { Paywall, PaywallRenderOptions } from './paywall/placement.js';
@@ -0,0 +1,280 @@
1
+ import { messaging as api } from '../../internal/src/modules/index.js';
2
+ import { Engine, type Entry, type KeyValue, type OutboxItem, type Touched } from '../../internal/src/messaging/index.js';
3
+ import { type Fetch, type Transport } from '../../internal/src/transport.js';
4
+ import { type SessionManager } from './session.js';
5
+ import type { RealtimeSocket } from './socket.js';
6
+ export type Conversation = api.Conversation;
7
+ export type Message = api.Message;
8
+ export type Member = api.Member;
9
+ export type MyProfile = api.MyProfile;
10
+ export type Profile = api.Profile;
11
+ export type ScheduledMessage = api.ScheduledMessage;
12
+ export type ThreadState = api.ThreadState;
13
+ export type { Entry, OutboxItem } from '../../internal/src/messaging/index.js';
14
+ export interface MessagingOptions {
15
+ /**
16
+ * What the device keeps of a person's conversations when they sign out:
17
+ * dropped unless true — then it is theirs again when they come back, and
18
+ * no one else who signs in on the device reads it.
19
+ */
20
+ keepOnSignOut?: boolean;
21
+ /** Where the device keeps it: IndexedDB in a browser, memory where there is none, unless given. */
22
+ storage?: KeyValue;
23
+ }
24
+ /** A file to send: its bytes are encrypted on the device before they are uploaded. */
25
+ export interface OutgoingFile {
26
+ data: Blob | Uint8Array;
27
+ contentType: string;
28
+ name?: string;
29
+ width?: number;
30
+ height?: number;
31
+ durationMs?: number;
32
+ /** A small preview the app makes (a blurhash, a tiny data URL): sealed in the message, as the file's key is. */
33
+ thumbnail?: string;
34
+ }
35
+ export interface SendOptions {
36
+ text?: string;
37
+ mentions?: api.Mention[];
38
+ /** The message it answers inline. */
39
+ replyTo?: string;
40
+ /** The message whose thread it answers in. */
41
+ threadId?: string;
42
+ /** A thread's answer the conversation's timeline shows too. */
43
+ alsoInConversation?: boolean;
44
+ files?: OutgoingFile[];
45
+ /** Seconds it lives: from when it is sent, or (expiresFrom 'read') from when everyone it was for read it. */
46
+ expiresIn?: number;
47
+ expiresFrom?: 'send' | 'read';
48
+ /** Its files are seen a limited number of times: once (1) or once more (2), each for seconds at most. */
49
+ viewOnce?: {
50
+ limit: 1 | 2;
51
+ seconds?: number;
52
+ };
53
+ /** Sent then, by the server, the person's device off or not. */
54
+ sendAt?: Date;
55
+ }
56
+ /** A file opened: its bytes, decrypted on the device. */
57
+ export interface OpenedFile {
58
+ id: string;
59
+ name: string | null;
60
+ contentType: string;
61
+ bytes: Uint8Array;
62
+ }
63
+ type Listener = () => void;
64
+ /** Something that keeps itself up to date: state, and a way to hear it change. */
65
+ export interface Observed<S> {
66
+ readonly state: S;
67
+ subscribe(listener: Listener): () => void;
68
+ }
69
+ export interface ConversationListState {
70
+ /** The person's conversations, the latest first. */
71
+ items: Conversation[];
72
+ /** How many messages they have not read, across them. */
73
+ unread: number;
74
+ /** The device's copy was drawn and the sync has caught up. */
75
+ synced: boolean;
76
+ }
77
+ export interface ConversationViewState {
78
+ conversation: Conversation | null;
79
+ /** Its timeline: its messages, the oldest first, then what is on its way. */
80
+ entries: Entry[];
81
+ members: Member[];
82
+ /** Who is typing now, by user id. */
83
+ typing: string[];
84
+ /** Older messages are there to read (loadEarlier). */
85
+ hasEarlier: boolean;
86
+ }
87
+ export interface ThreadViewState {
88
+ root: Message | null;
89
+ entries: Entry[];
90
+ thread: ThreadState | null;
91
+ }
92
+ /** Where a browser keeps it: IndexedDB, one object store of each person's state. */
93
+ export declare function indexedDBKeyValue(name?: string): KeyValue | null;
94
+ type Client = ReturnType<typeof api.client>;
95
+ export declare class Messaging {
96
+ /** The module's API with whoever is signed in now: everything the views do not. */
97
+ readonly api: Client;
98
+ private readonly local;
99
+ private readonly transportFor;
100
+ /** Each person's API: what is done for one — what they wrote, what they read — never goes with another's token. */
101
+ private readonly clients;
102
+ private user;
103
+ private engine;
104
+ private starting;
105
+ private channel;
106
+ private off;
107
+ private readonly heard;
108
+ private synced;
109
+ private syncing;
110
+ private resync;
111
+ private flushing;
112
+ private reflush;
113
+ private retries;
114
+ private timers;
115
+ private readonly delivered;
116
+ private readonly expiring;
117
+ private readonly typingBy;
118
+ private readonly typedAt;
119
+ private readonly loaded;
120
+ private readonly earlier;
121
+ private saving;
122
+ private readonly reopeners;
123
+ private readonly incoming;
124
+ private readonly session;
125
+ private readonly socket;
126
+ private readonly ref;
127
+ private readonly fetchFn;
128
+ private readonly opts;
129
+ constructor(transport: Transport, transportFor: (user: string) => Transport, session: SessionManager, socket: RealtimeSocket, ref: string, fetchFn: Fetch, opts?: MessagingOptions);
130
+ /**
131
+ * Starts following the signed-in person's conversations — the views do it
132
+ * themselves: the device's copy first, then the person's channel and the
133
+ * sync. Rejects when no one is signed in.
134
+ */
135
+ ready(): Promise<Engine>;
136
+ /** The person signed out (or another signed in): what the device keeps is dropped unless kept, and nothing of theirs is followed. */
137
+ private end;
138
+ private unfollow;
139
+ private follow;
140
+ /** The app is back (online, in view): catch up and send what waits. */
141
+ private wake;
142
+ /** Reads what changed since the cursor the device holds, until nothing is left. */
143
+ sync(): Promise<void>;
144
+ /**
145
+ * Tells the app of a message someone else wrote, as it comes live — what an app shows a banner of while it is in
146
+ * front (its pushes are not shown then): once, never what a sync or a page reads, an edit, a removal or the
147
+ * person's own. Returns the unsubscribe.
148
+ */
149
+ onIncoming(listener: (m: Message) => void): () => void;
150
+ private heardLive;
151
+ /** Applies what changed to the person's conversations — to e's alone: what came for one who is gone goes nowhere. */
152
+ private changed;
153
+ /** What follows a change: timers to take messages away, deliveries told, the device's copy saved. */
154
+ private after;
155
+ /** A message whose time is up goes from the device at once: the server says so too, a moment after. */
156
+ private expireAt;
157
+ private deliver;
158
+ private save;
159
+ /** Sends what waits, in each conversation's order; tries again later while the network or the server is away. */
160
+ flush(): Promise<void>;
161
+ /** Sends one message with its writer's token — none other: signed out meanwhile, it waits for them. */
162
+ private post;
163
+ private presence;
164
+ private as;
165
+ /** The signed-in person's place: what is done for them goes with their token, and comes back to them alone. */
166
+ private seat;
167
+ private typed;
168
+ private tell;
169
+ /** The person's conversations, the latest first, kept up to date. */
170
+ conversations(): ConversationList;
171
+ /** A conversation of the person's, kept up to date: its timeline, its members, who is typing. */
172
+ conversation(conversationId: string): ConversationView;
173
+ /** The direct conversation with someone — the one there is, or a new one. */
174
+ direct(userId: string): Promise<ConversationView>;
175
+ /** A new group, the person its owner. */
176
+ group(input: {
177
+ title: string;
178
+ memberIds?: string[];
179
+ description?: string;
180
+ photo?: string;
181
+ settings?: api.GroupSettings;
182
+ }): Promise<{
183
+ conversation: ConversationView;
184
+ notAdded: api.NotAdded[];
185
+ }>;
186
+ /** A thread: a message's answers, kept up to date. */
187
+ thread(conversationId: string, rootId: string): ThreadView;
188
+ /** The person's messages scheduled for later, kept up to date. */
189
+ scheduled(): ScheduledList;
190
+ /** The threads the person follows, the latest answered first. */
191
+ threads(): Promise<api.ThreadItem[]>;
192
+ /** Writes a message: drawn at once, sent now or once the network is back — once. A message for later is in scheduled(). */
193
+ send(conversationId: string, input: string | SendOptions): Promise<OutboxItem>;
194
+ /** Each file encrypted with a key of its own, uploaded: what a message carries of them. */
195
+ private upload;
196
+ /** A file of a message, downloaded and decrypted on the device. A message seen once gives its files by viewOnce alone. */
197
+ open(message: Message, attachmentId: string): Promise<OpenedFile>;
198
+ /** Opens a message seen a limited number of times: its files, decrypted — held by the app, never by the device. */
199
+ viewOnce(message: Message): Promise<OpenedFile[]>;
200
+ private bytes;
201
+ edit(conversationId: string, messageId: string, text: string, mentions?: api.Mention[]): Promise<Message>;
202
+ /** Removes a message: for everyone (its writer, within 48 hours; a group's admin) or for the person alone. */
203
+ remove(conversationId: string, messageId: string, scope?: 'everyone' | 'me'): Promise<void>;
204
+ /** Reacts with an emoji, beside the person's other reactions (replace: in their place). */
205
+ react(conversationId: string, messageId: string, emoji: string, opts?: {
206
+ replace?: boolean;
207
+ }): Promise<Message>;
208
+ unreact(conversationId: string, messageId: string, emoji: string): Promise<Message>;
209
+ /** The person read a conversation up to seq (its last message unless given): their unread count goes, and the others see it unless reads are hidden. */
210
+ markRead(conversationId: string, seq?: number, threadId?: string): Promise<void>;
211
+ /** The person is typing: told to the others, at most every two seconds. */
212
+ typing(conversationId: string, threadId?: string): Promise<void>;
213
+ /** Changes a conversation: its title, picture, timer, vanish mode, policies. */
214
+ update(conversationId: string, change: api.UpdateConversation): Promise<Conversation>;
215
+ /** The person leaves a conversation in vanish mode: what they read in it goes. */
216
+ close(conversationId: string): Promise<void>;
217
+ /** The person took a screenshot of a conversation: the others are told (an app on a phone knows it; a browser does not). */
218
+ screenshot(conversationId: string): Promise<Message>;
219
+ leave(conversationId: string): Promise<void>;
220
+ deleteConversation(conversationId: string): Promise<void>;
221
+ notifications(conversationId: string, change: api.NotificationsRequest): Promise<void>;
222
+ cancelScheduled(id: string): Promise<void>;
223
+ editScheduled(id: string, change: api.UpdateScheduled): Promise<ScheduledMessage>;
224
+ me(): Promise<MyProfile>;
225
+ /** Changes the person's profile and settings: name, picture, last seen, read receipts, the timer of conversations they open. */
226
+ updateMe(change: api.UpdateProfile): Promise<MyProfile>;
227
+ profiles(userIds: string[]): Promise<Profile[]>;
228
+ block(userId: string): Promise<void>;
229
+ unblock(userId: string): Promise<void>;
230
+ report(input: api.ReportRequest): Promise<api.ReportCreated>;
231
+ }
232
+ declare abstract class View<S> implements Observed<S> {
233
+ protected listeners: Set<Listener>;
234
+ private unlisten;
235
+ private unperson;
236
+ private cached;
237
+ protected readonly m: Messaging;
238
+ constructor(m: Messaging);
239
+ /** What it is now: kept while it is subscribed, read again each time when not. */
240
+ get state(): S;
241
+ subscribe(listener: Listener): () => void;
242
+ protected opened(): void;
243
+ protected abstract touches(t: Touched): boolean;
244
+ protected abstract read(): S;
245
+ }
246
+ export declare class ConversationList extends View<ConversationListState> {
247
+ protected touches(t: Touched): boolean;
248
+ protected read(): ConversationListState;
249
+ }
250
+ export declare class ConversationView extends View<ConversationViewState> {
251
+ readonly id: string;
252
+ constructor(m: Messaging, id: string);
253
+ protected opened(): void;
254
+ protected touches(t: Touched): boolean;
255
+ protected read(): ConversationViewState;
256
+ /** Reads the conversation's newest page now (opening it does). */
257
+ refresh(): Promise<boolean>;
258
+ /** Reads the page of messages before the oldest one drawn; answers whether there are more. */
259
+ loadEarlier(): Promise<boolean>;
260
+ send(input: string | SendOptions): Promise<OutboxItem>;
261
+ markRead(seq?: number): Promise<void>;
262
+ typing(): Promise<void>;
263
+ thread(rootId: string): ThreadView;
264
+ }
265
+ export declare class ThreadView extends View<ThreadViewState> {
266
+ readonly conversationId: string;
267
+ readonly rootId: string;
268
+ constructor(m: Messaging, conversationId: string, rootId: string);
269
+ protected opened(): void;
270
+ protected touches(t: Touched): boolean;
271
+ protected read(): ThreadViewState;
272
+ /** Answers in the thread (alsoInConversation: the conversation's timeline shows it too). */
273
+ send(input: string | Omit<SendOptions, 'threadId'>): Promise<OutboxItem>;
274
+ markRead(): Promise<void>;
275
+ }
276
+ export declare class ScheduledList extends View<ScheduledMessage[]> {
277
+ protected opened(): void;
278
+ protected touches(t: Touched): boolean;
279
+ protected read(): ScheduledMessage[];
280
+ }