@fkn/lib 0.9.29 → 0.9.31

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.
@@ -1,8 +1,8 @@
1
- import { t as cloudFetch } from "./proxy-YNFaF0dC.js";
1
+ import { t as cloudFetch } from "./proxy-AooDS--C.js";
2
2
  import { i as Frame, r as AttachFrameOptions } from "./index-DH3_12nU.js";
3
3
  import { t as dns_d_exports } from "./dns.js";
4
- import { n as fs_d_exports } from "./fs-CBVaShOR.js";
5
- import { s as net_d_exports } from "./net-DOkodxE3.js";
4
+ import { n as fs_d_exports } from "./fs-CYcErwc4.js";
5
+ import { s as net_d_exports } from "./net-DtRM2eKo.js";
6
6
  import { t as dgram_d_exports } from "./dgram.js";
7
7
  import { t as http_d_exports } from "./http.js";
8
8
  //#region src/cloud/frame.d.ts
package/cloud.d.ts CHANGED
@@ -1,8 +1,8 @@
1
- import { t as cloudFetch } from "./proxy-YNFaF0dC.js";
2
- import { a as attachFrame, i as quota, r as QuotaStatus, t as available } from "./cloud-BpruQ4I2.js";
1
+ import { t as cloudFetch } from "./proxy-AooDS--C.js";
2
+ import { a as attachFrame, i as quota, r as QuotaStatus, t as available } from "./cloud-BYw0XBF4.js";
3
3
  import { t as dns_d_exports } from "./dns.js";
4
- import { n as fs_d_exports } from "./fs-CBVaShOR.js";
5
- import { s as net_d_exports } from "./net-DOkodxE3.js";
4
+ import { n as fs_d_exports } from "./fs-CYcErwc4.js";
5
+ import { s as net_d_exports } from "./net-DtRM2eKo.js";
6
6
  import { t as dgram_d_exports } from "./dgram.js";
7
7
  import { t as http_d_exports } from "./http.js";
8
8
  export { type QuotaStatus, attachFrame, available, dgram_d_exports as dgram, dns_d_exports as dns, cloudFetch as fetch, fs_d_exports as fs, http_d_exports as http, net_d_exports as net, quota };
@@ -181,14 +181,17 @@ type MountDescriptor = {
181
181
  };
182
182
  type RoomPermission = 'send' | 'receive' | 'remove' | 'block';
183
183
  type RoomPermissions = Readonly<Record<RoomPermission, boolean>>;
184
+ /** What a member gets unless an override says otherwise. `maxMessageBytes` is measured on the wire: nonce plus ciphertext, base64url. */
184
185
  type RoomDefaults = Readonly<{
185
186
  send: boolean;
186
187
  receive: boolean;
188
+ maxMessageBytes: number;
187
189
  }>;
188
190
  /** A participant as this room sees them. The id is fresh in every room. */
189
191
  type RoomMember = {
190
192
  id: string;
191
193
  permissions: RoomPermissions;
194
+ maxMessageBytes: number;
192
195
  };
193
196
  type RoomMessage = {
194
197
  seq: number;
@@ -196,9 +199,26 @@ type RoomMessage = {
196
199
  at: number;
197
200
  text: string;
198
201
  };
199
- type RoomEvent = {
202
+ /** What a claimed room's mailbox holds, as the room last said. Null for a room nobody has claimed. */
203
+ type RoomMailbox = {
204
+ messages: number;
205
+ bytes: number;
206
+ cap: number;
207
+ archived: boolean;
208
+ };
209
+ type RoomEvent =
210
+ /** `replayed` when the message predates this connection: a backlog page, never a live send */
211
+ {
200
212
  type: 'message';
201
213
  message: RoomMessage;
214
+ replayed: boolean;
215
+ } | {
216
+ type: 'edited';
217
+ message: RoomMessage;
218
+ } | {
219
+ type: 'deleted';
220
+ from: number;
221
+ to: number;
202
222
  } | {
203
223
  type: 'joined';
204
224
  member: RoomMember;
@@ -210,11 +230,18 @@ type RoomEvent = {
210
230
  type: 'permissions';
211
231
  id: string;
212
232
  permissions: RoomPermissions;
233
+ maxMessageBytes: number;
213
234
  } | {
214
235
  type: 'defaults';
215
236
  defaults: RoomDefaults;
237
+ } |
238
+ /** the room was claimed, released or dissolved; `owner` is the owner's member id, or '' while a claimed room's owner has never joined */
239
+ {
240
+ type: 'claim';
241
+ claimed: boolean;
242
+ owner: string;
216
243
  };
217
- type RoomsErrorCode = 'invalid' | 'not-found' | 'bad-key' | 'full' | 'blocked' | 'denied' | 'rate-limited' | 'too-large' | 'unavailable' | 'closed';
244
+ type RoomsErrorCode = 'invalid' | 'not-found' | 'bad-key' | 'full' | 'blocked' | 'denied' | 'rate-limited' | 'too-large' | 'storage' | 'quota' | 'unavailable' | 'closed';
218
245
  /** A refusal, as data. `packages` crosses the hop the same way, and for the same reason. */
219
246
  type RoomsFail = {
220
247
  error: RoomsErrorCode;
@@ -224,15 +251,24 @@ type RoomsFail = {
224
251
  type RoomEnd = {
225
252
  reason: 'left' | 'removed' | 'blocked' | 'ended' | 'unavailable';
226
253
  };
227
- type RoomCreateOptions = {
254
+ type RoomOpenOptions = {
228
255
  /** aborting it leaves the room; it never bounds the wait for the broker */
229
256
  signal?: AbortSignal;
257
+ /** honoured only by the join that brings the room into being */
230
258
  members?: number;
231
259
  defaults?: Partial<RoomDefaults>;
260
+ /** the room key, 32 bytes base64url, minted when absent. Deriving one from something people already share is how a name becomes a rendezvous. */
261
+ key?: string;
232
262
  };
263
+ type RoomCreateOptions = RoomOpenOptions;
233
264
  type RoomJoinOptions = {
234
265
  signal?: AbortSignal;
235
266
  };
267
+ /** What a backlog page answered: the highest seq it sent, and whether another page follows. */
268
+ type RoomBacklog = {
269
+ last: number;
270
+ more: boolean;
271
+ };
236
272
  /**
237
273
  * A joined room, held by the broker: it owns the socket, the room key and the derived message key,
238
274
  * and hands the app plaintext and member ids only.
@@ -241,23 +277,40 @@ type RoomJoinOptions = {
241
277
  * survives the osra hop as data. `leave` and `on` cannot be refused.
242
278
  */
243
279
  type RoomHandle = {
244
- /** the room's uuid */
280
+ /** `<scope>/<name>`: the name under the app's own scope, or under `global` */
245
281
  id: string;
246
- /** the room key, base64url. The api never sees it. Anyone holding it and the id can join. */
282
+ name: string;
283
+ /** the room key, base64url. The server never sees it. Anyone holding it and the id can join. */
247
284
  key: string;
248
- /** `id` and `key` as one string, the thing to put in a link */
285
+ /** `<key>.<id>` as one string, the thing to put in a link */
249
286
  invite: string;
250
287
  self: RoomMember;
251
288
  owner: string;
289
+ claimed: boolean;
290
+ mailbox: RoomMailbox | null;
252
291
  defaults: () => Promise<RoomDefaults>;
253
292
  members: () => Promise<RoomMember[]>;
254
- /** at most 4,096 bytes of UTF-8, sealed before it leaves the browser; never truncated */
293
+ /** sealed before it leaves the browser and refused, never truncated, past this member's `maxMessageBytes` on the wire */
255
294
  send: (text: string) => Promise<RoomsFail | {
256
295
  ok: true;
257
296
  }>;
297
+ /** a stored message's text, replaced: the sender's own, or any as the owner */
298
+ edit: (seq: number, text: string) => Promise<RoomsFail | {
299
+ ok: true;
300
+ }>;
301
+ /** stored messages dropped: one of the sender's own, or any range as the owner */
302
+ delete: (from: number, to?: number) => Promise<RoomsFail | {
303
+ ok: true;
304
+ }>;
305
+ /** replays stored messages above `after` as `message` events marked `replayed`, one page at a time */
306
+ backlog: (after: number, limit?: number) => Promise<RoomsFail | RoomBacklog>;
258
307
  setDefault: (permission: 'send' | 'receive', value: boolean) => Promise<RoomsFail | {
259
308
  ok: true;
260
309
  }>;
310
+ /** the message size cap: the room default when no member is named, that member's override otherwise, cleared by null */
311
+ limit: (maxMessageBytes: number | null, id?: string) => Promise<RoomsFail | {
312
+ ok: true;
313
+ }>;
261
314
  grant: (id: string, permission: RoomPermission) => Promise<RoomsFail | {
262
315
  ok: true;
263
316
  }>;
@@ -273,6 +326,14 @@ type RoomHandle = {
273
326
  unblock: (id: string) => Promise<RoomsFail | {
274
327
  ok: true;
275
328
  }>;
329
+ /** keeps the name and a mailbox for the signed-in premium account; the only thing in rooms that premium buys */
330
+ claim: () => Promise<RoomsFail | {
331
+ ok: true;
332
+ }>;
333
+ release: () => Promise<RoomsFail | {
334
+ ok: true;
335
+ }>;
336
+ usage: () => Promise<RoomsFail | RoomMailbox | null>;
276
337
  /** the `account.onChange` shape: one broker-side registration, unsubscribed by the returned function */
277
338
  on: (listener: (event: RoomEvent) => void) => (() => void);
278
339
  leave: () => Promise<void>;
@@ -500,6 +561,9 @@ type Resolvers = {
500
561
  };
501
562
  rooms: {
502
563
  available: () => Promise<boolean>;
564
+ /** a name under the calling app's scope, or `global/<name>`; the room comes into being when nothing is there */
565
+ open: (name: string, options?: RoomOpenOptions) => Promise<RoomsFail | RoomHandle>;
566
+ /** `open` under a random name */
503
567
  create: (options?: RoomCreateOptions) => Promise<RoomsFail | RoomHandle>;
504
568
  join: (invite: string, options?: RoomJoinOptions) => Promise<RoomsFail | RoomHandle>;
505
569
  };
@@ -525,4 +589,4 @@ type Resolvers = {
525
589
  hideInstallPrompt: () => void;
526
590
  };
527
591
  //#endregion
528
- export { TcpSocketOptions as $, ProxyFetchInit as A, RoomJoinOptions as B, PackageQuery as C, PickOptions as D, PackagesFail as E, RoomCreateOptions as F, RoomsErrorCode as G, RoomMessage as H, RoomDefaults as I, StorageEntry as J, RoomsFail as K, RoomEnd as L, Quota as M, Radii as N, Placement as O, Resolvers as P, TcpSocketListenerResult as Q, RoomEvent as R, OverlayState as S, PackagesErrorCode as T, RoomPermission as U, RoomMember as V, RoomPermissions as W, SurfaceRect as X, StorageQuota as Y, TcpSocketListenerOptions as Z, InstallOptions as _, ConflictChoice as a, MountDescriptor as b, ConnectAvailability as c, DisplayLevel as d, TcpSocketResult as et, DnsLookup as f, HiddenSurface as g, FrameFetchScope as h, AdoptState as i, WriteData as it, ProxyFetchInput as j, ProxyFetch as k, ConnectOptions as l, FrameConsentRequest as m, AddressLookupResult as n, UdpSocketOptions as nt, ConflictRequest as o, EncryptionState as p, SetOverlayHost as q, AdoptRequest as r, UdpSocketResult as rt, ConflictSide as s, Account as t, UdpDatagram as tt, DisplayCause as u, InstalledPackage as v, PackageResult as w, OverlayRect as x, IpFamily as y, RoomHandle as z };
592
+ export { SurfaceRect as $, ProxyFetchInit as A, RoomHandle as B, PackageQuery as C, PickOptions as D, PackagesFail as E, RoomBacklog as F, RoomOpenOptions as G, RoomMailbox as H, RoomCreateOptions as I, RoomsErrorCode as J, RoomPermission as K, RoomDefaults as L, Quota as M, Radii as N, Placement as O, Resolvers as P, StorageQuota as Q, RoomEnd as R, OverlayState as S, PackagesErrorCode as T, RoomMember as U, RoomJoinOptions as V, RoomMessage as W, SetOverlayHost as X, RoomsFail as Y, StorageEntry as Z, InstallOptions as _, ConflictChoice as a, UdpSocketOptions as at, MountDescriptor as b, ConnectAvailability as c, DisplayLevel as d, TcpSocketListenerOptions as et, DnsLookup as f, HiddenSurface as g, FrameFetchScope as h, AdoptState as i, UdpDatagram as it, ProxyFetchInput as j, ProxyFetch as k, ConnectOptions as l, FrameConsentRequest as m, AddressLookupResult as n, TcpSocketOptions as nt, ConflictRequest as o, UdpSocketResult as ot, EncryptionState as p, RoomPermissions as q, AdoptRequest as r, TcpSocketResult as rt, ConflictSide as s, WriteData as st, Account as t, TcpSocketListenerResult as tt, DisplayCause as u, InstalledPackage as v, PackageResult as w, OverlayRect as x, IpFamily as y, RoomEvent as z };
package/contract.d.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  import { o as TcpSocketOption, v as UdpSocketOption } from "./wire-Gbo-D74t.js";
2
- import { $ as TcpSocketOptions, A as ProxyFetchInit, B as RoomJoinOptions, C as PackageQuery, D as PickOptions, E as PackagesFail, F as RoomCreateOptions, G as RoomsErrorCode, H as RoomMessage, I as RoomDefaults, J as StorageEntry, K as RoomsFail, L as RoomEnd, M as Quota, N as Radii, O as Placement, P as Resolvers, Q as TcpSocketListenerResult, R as RoomEvent, S as OverlayState, T as PackagesErrorCode, U as RoomPermission, V as RoomMember, W as RoomPermissions, X as SurfaceRect, Y as StorageQuota, Z as TcpSocketListenerOptions, _ as InstallOptions, a as ConflictChoice, b as MountDescriptor, c as ConnectAvailability, d as DisplayLevel, et as TcpSocketResult, f as DnsLookup, g as HiddenSurface, h as FrameFetchScope, i as AdoptState, it as WriteData, j as ProxyFetchInput, k as ProxyFetch, l as ConnectOptions, m as FrameConsentRequest, n as AddressLookupResult, nt as UdpSocketOptions, o as ConflictRequest, p as EncryptionState, q as SetOverlayHost, r as AdoptRequest, rt as UdpSocketResult, s as ConflictSide, t as Account, tt as UdpDatagram, u as DisplayCause, v as InstalledPackage, w as PackageResult, x as OverlayRect, y as IpFamily, z as RoomHandle } from "./contract-DLyjkumA.js";
3
- export { Account, AddressLookupResult, AdoptRequest, AdoptState, ConflictChoice, ConflictRequest, ConflictSide, ConnectAvailability, ConnectOptions, DisplayCause, DisplayLevel, DnsLookup, EncryptionState, FrameConsentRequest, FrameFetchScope, HiddenSurface, InstallOptions, InstalledPackage, IpFamily, MountDescriptor, OverlayRect, OverlayState, PackageQuery, PackageResult, PackagesErrorCode, PackagesFail, PickOptions, Placement, ProxyFetch, ProxyFetchInit, ProxyFetchInput, Quota, Radii, Resolvers, RoomCreateOptions, RoomDefaults, RoomEnd, RoomEvent, RoomHandle, RoomJoinOptions, RoomMember, RoomMessage, RoomPermission, RoomPermissions, RoomsErrorCode, RoomsFail, SetOverlayHost, StorageEntry, StorageQuota, SurfaceRect, TcpSocketListenerOptions, TcpSocketListenerResult, type TcpSocketOption, TcpSocketOptions, TcpSocketResult, UdpDatagram, type UdpSocketOption, UdpSocketOptions, UdpSocketResult, WriteData };
2
+ import { $ as SurfaceRect, A as ProxyFetchInit, B as RoomHandle, C as PackageQuery, D as PickOptions, E as PackagesFail, F as RoomBacklog, G as RoomOpenOptions, H as RoomMailbox, I as RoomCreateOptions, J as RoomsErrorCode, K as RoomPermission, L as RoomDefaults, M as Quota, N as Radii, O as Placement, P as Resolvers, Q as StorageQuota, R as RoomEnd, S as OverlayState, T as PackagesErrorCode, U as RoomMember, V as RoomJoinOptions, W as RoomMessage, X as SetOverlayHost, Y as RoomsFail, Z as StorageEntry, _ as InstallOptions, a as ConflictChoice, at as UdpSocketOptions, b as MountDescriptor, c as ConnectAvailability, d as DisplayLevel, et as TcpSocketListenerOptions, f as DnsLookup, g as HiddenSurface, h as FrameFetchScope, i as AdoptState, it as UdpDatagram, j as ProxyFetchInput, k as ProxyFetch, l as ConnectOptions, m as FrameConsentRequest, n as AddressLookupResult, nt as TcpSocketOptions, o as ConflictRequest, ot as UdpSocketResult, p as EncryptionState, q as RoomPermissions, r as AdoptRequest, rt as TcpSocketResult, s as ConflictSide, st as WriteData, t as Account, tt as TcpSocketListenerResult, u as DisplayCause, v as InstalledPackage, w as PackageResult, x as OverlayRect, y as IpFamily, z as RoomEvent } from "./contract-CSdeTq_Y.js";
3
+ export { Account, AddressLookupResult, AdoptRequest, AdoptState, ConflictChoice, ConflictRequest, ConflictSide, ConnectAvailability, ConnectOptions, DisplayCause, DisplayLevel, DnsLookup, EncryptionState, FrameConsentRequest, FrameFetchScope, HiddenSurface, InstallOptions, InstalledPackage, IpFamily, MountDescriptor, OverlayRect, OverlayState, PackageQuery, PackageResult, PackagesErrorCode, PackagesFail, PickOptions, Placement, ProxyFetch, ProxyFetchInit, ProxyFetchInput, Quota, Radii, Resolvers, RoomBacklog, RoomCreateOptions, RoomDefaults, RoomEnd, RoomEvent, RoomHandle, RoomJoinOptions, RoomMailbox, RoomMember, RoomMessage, RoomOpenOptions, RoomPermission, RoomPermissions, RoomsErrorCode, RoomsFail, SetOverlayHost, StorageEntry, StorageQuota, SurfaceRect, TcpSocketListenerOptions, TcpSocketListenerResult, type TcpSocketOption, TcpSocketOptions, TcpSocketResult, UdpDatagram, type UdpSocketOption, UdpSocketOptions, UdpSocketResult, WriteData };
package/dgram.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { v as UdpSocketOption } from "./wire-Gbo-D74t.js";
2
- import { P as Resolvers, rt as UdpSocketResult } from "./contract-DLyjkumA.js";
3
- import "./api-CxrIIOW8.js";
2
+ import { P as Resolvers, ot as UdpSocketResult } from "./contract-CSdeTq_Y.js";
3
+ import "./api-LKxHamsI.js";
4
4
  import { Buffer } from "buffer";
5
5
  import { AddressInfo } from "net";
6
6
  import { EventEmitter } from "events";
package/dns.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { n as AddressLookupResult } from "./contract-DLyjkumA.js";
1
+ import { n as AddressLookupResult } from "./contract-CSdeTq_Y.js";
2
2
  declare namespace dns_d_exports {
3
3
  export { AddressLookupResult, lookup };
4
4
  }
@@ -1,6 +1,6 @@
1
1
  import { a as WriteData, i as Stats, n as MakeOptions, o as WriteOptions, r as ReadOptions, t as Callback } from "./index-BQgZVQl7.js";
2
2
  import { a as StorageNotFoundError, c as isNotFound, d as unlock, i as StorageLockedError, l as quota, n as FileEntry, o as StorageQuota, r as SealedRead, s as encryption, t as EncryptionStatus, u as readFileSealed } from "./storage-WZEvw3KN.js";
3
- import { i as STORAGE_NOT_FOUND } from "./messages-DvpKMTsY.js";
3
+ import { a as STORAGE_NOT_FOUND } from "./messages-C66ghz_A.js";
4
4
  declare namespace fs_d_exports {
5
5
  export { EncryptionStatus, FileEntry, STORAGE_NOT_FOUND, SealedRead, Stats, StorageLockedError, StorageNotFoundError, StorageQuota, available, encryption, isNotFound, mkdir, promises, quota, readFile, readFileSealed, readdir, rename, rm, stat, unlink, unlock, writeFile };
6
6
  }
package/http.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { n as Socket, t as Server$1 } from "./net-DOkodxE3.js";
1
+ import { n as Socket, t as Server$1 } from "./net-DtRM2eKo.js";
2
2
  import { Buffer } from "buffer";
3
3
  import { Stream } from "stream";
4
4
  import { IncomingHttpHeaders, OutgoingHttpHeaders, RequestOptions } from "http";
package/index.d.ts CHANGED
@@ -1,10 +1,10 @@
1
1
  import { t as account_d_exports } from "./account.js";
2
2
  import { A as modifyRequestHeadersPermission, C as LOCATOR_ERROR, D as isTerminalError, E as isLocatorUnsupported, F as cookies, G as isLocalNetworkUrl, H as fetchLocalPermission, I as readCookiePermission, J as assertOneCookieIdentity, K as FORGEABLE_HEADERS, L as FetchInit, M as setRequestHeaderRule, N as CookieDetails, O as HeaderOperation, P as SiteCookie, R as ProxyFetchRequest, S as LOCATOR_DENIED, T as isLocatorDenied, U as fetchPermission, V as fetchCredentialedPermission, W as isBlockedFetchUrl, Y as hasForgedCookie, _ as PermissionRequest, b as assertLockdownApplicable, c as setMissingExtensionHandler, d as ExtensionHandshake, f as ExtensionOperationUnsupportedError, g as PermissionGrant, h as supportsOperation, i as promptInstall, j as removeRequestHeaderRule, k as RequestHeaderRule, l as waitForExtensionExposure, m as REQUIRED_EXTENSION_ABI, n as fetch, o as isExtensionExposed, p as ExtensionOutdatedError, q as assertForgeableHeaders, s as readExtensionHandshake, t as extension_d_exports, u as EXTENSION_ABI, v as permissions, w as LOCATOR_UNSUPPORTED, x as isBlockedFrameUrl, y as assertAttachableFrameUrl, z as assertFetchableUrl } from "./extension-DNkuFy1Y.js";
3
3
  import { C as OperationRequest, S as GateTools, _ as isType, a as FrameBackend, b as Executor, c as attachFramePermission, d as handleRevivableModules, f as BoxedVideoElement, g as createVideoElementHandle, h as box, i as Frame, l as createFrame, m as VideoElementState, o as GotoOptions, p as RemoteVideoElement, r as AttachFrameOptions, s as Locator, t as ATTACH_FRAME_EVENT_KEY, u as gotoPermission, v as revive, w as SelectorPart, x as Gate, y as type } from "./index-DH3_12nU.js";
4
- import { n as cloud_d_exports } from "./cloud-BpruQ4I2.js";
4
+ import { n as cloud_d_exports } from "./cloud-BYw0XBF4.js";
5
5
  import { t as dns_d_exports } from "./dns.js";
6
6
  import { u as index_d_exports } from "./index-Cg6y_FTi.js";
7
- import { s as net_d_exports } from "./net-DOkodxE3.js";
7
+ import { s as net_d_exports } from "./net-DtRM2eKo.js";
8
8
  import { t as dgram_d_exports } from "./dgram.js";
9
9
  import { t as http_d_exports } from "./http.js";
10
10
  import { t as desktop_d_exports } from "./desktop.js";
@@ -2,6 +2,8 @@
2
2
  declare const E2E_LOCKED_MESSAGE = "fkn:e2e-locked";
3
3
  declare const E2E_STALE_EPOCH_MESSAGE = "fkn:e2e-stale-epoch: this file is encrypted under a previous key you reset";
4
4
  declare const E2E_INTEGRITY_MESSAGE = "fkn:e2e-integrity: stored data failed its integrity check";
5
+ /** the row is sealed in a format this version no longer opens (an envelope older than v3); distinct from integrity, since the bytes are intact */
6
+ declare const E2E_RETIRED_FORMAT_MESSAGE = "fkn:e2e-retired-format: stored data is in a format this version no longer opens";
5
7
  /**
6
8
  * "There is no object at this path", as a thing a caller can TEST rather than parse.
7
9
  *
@@ -25,4 +27,4 @@ declare const STORAGE_NOT_FOUND = "FKN_STORAGE_NOT_FOUND";
25
27
  */
26
28
  declare const STORAGE_UNREACHABLE = "FKN_API_UNREACHABLE";
27
29
  //#endregion
28
- export { STORAGE_UNREACHABLE as a, STORAGE_NOT_FOUND as i, E2E_LOCKED_MESSAGE as n, E2E_STALE_EPOCH_MESSAGE as r, E2E_INTEGRITY_MESSAGE as t };
30
+ export { STORAGE_NOT_FOUND as a, E2E_STALE_EPOCH_MESSAGE as i, E2E_LOCKED_MESSAGE as n, STORAGE_UNREACHABLE as o, E2E_RETIRED_FORMAT_MESSAGE as r, E2E_INTEGRITY_MESSAGE as t };
package/messages.cjs CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=`fkn:e2e-locked`,t=`fkn:e2e-stale-epoch: this file is encrypted under a previous key you reset`,n=`fkn:e2e-integrity: stored data failed its integrity check`,r=`FKN_STORAGE_NOT_FOUND`,i=`FKN_API_UNREACHABLE`;exports.E2E_INTEGRITY_MESSAGE=n,exports.E2E_LOCKED_MESSAGE=e,exports.E2E_STALE_EPOCH_MESSAGE=t,exports.STORAGE_NOT_FOUND=r,exports.STORAGE_UNREACHABLE=i;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=`fkn:e2e-locked`,t=`fkn:e2e-stale-epoch: this file is encrypted under a previous key you reset`,n=`fkn:e2e-integrity: stored data failed its integrity check`,r=`fkn:e2e-retired-format: stored data is in a format this version no longer opens`,i=`FKN_STORAGE_NOT_FOUND`,a=`FKN_API_UNREACHABLE`;exports.E2E_INTEGRITY_MESSAGE=n,exports.E2E_LOCKED_MESSAGE=e,exports.E2E_RETIRED_FORMAT_MESSAGE=r,exports.E2E_STALE_EPOCH_MESSAGE=t,exports.STORAGE_NOT_FOUND=i,exports.STORAGE_UNREACHABLE=a;
package/messages.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import { a as STORAGE_UNREACHABLE, i as STORAGE_NOT_FOUND, n as E2E_LOCKED_MESSAGE, r as E2E_STALE_EPOCH_MESSAGE, t as E2E_INTEGRITY_MESSAGE } from "./messages-DvpKMTsY.js";
2
- export { E2E_INTEGRITY_MESSAGE, E2E_LOCKED_MESSAGE, E2E_STALE_EPOCH_MESSAGE, STORAGE_NOT_FOUND, STORAGE_UNREACHABLE };
1
+ import { a as STORAGE_NOT_FOUND, i as E2E_STALE_EPOCH_MESSAGE, n as E2E_LOCKED_MESSAGE, o as STORAGE_UNREACHABLE, r as E2E_RETIRED_FORMAT_MESSAGE, t as E2E_INTEGRITY_MESSAGE } from "./messages-C66ghz_A.js";
2
+ export { E2E_INTEGRITY_MESSAGE, E2E_LOCKED_MESSAGE, E2E_RETIRED_FORMAT_MESSAGE, E2E_STALE_EPOCH_MESSAGE, STORAGE_NOT_FOUND, STORAGE_UNREACHABLE };
package/messages.js CHANGED
@@ -1,4 +1,4 @@
1
1
  //#region src/messages.ts
2
- var e = "fkn:e2e-locked", t = "fkn:e2e-stale-epoch: this file is encrypted under a previous key you reset", n = "fkn:e2e-integrity: stored data failed its integrity check", r = "FKN_STORAGE_NOT_FOUND", i = "FKN_API_UNREACHABLE";
2
+ var e = "fkn:e2e-locked", t = "fkn:e2e-stale-epoch: this file is encrypted under a previous key you reset", n = "fkn:e2e-integrity: stored data failed its integrity check", r = "fkn:e2e-retired-format: stored data is in a format this version no longer opens", i = "FKN_STORAGE_NOT_FOUND", a = "FKN_API_UNREACHABLE";
3
3
  //#endregion
4
- export { n as E2E_INTEGRITY_MESSAGE, e as E2E_LOCKED_MESSAGE, t as E2E_STALE_EPOCH_MESSAGE, r as STORAGE_NOT_FOUND, i as STORAGE_UNREACHABLE };
4
+ export { n as E2E_INTEGRITY_MESSAGE, e as E2E_LOCKED_MESSAGE, r as E2E_RETIRED_FORMAT_MESSAGE, t as E2E_STALE_EPOCH_MESSAGE, i as STORAGE_NOT_FOUND, a as STORAGE_UNREACHABLE };
@@ -1,6 +1,6 @@
1
1
  import { o as TcpSocketOption } from "./wire-Gbo-D74t.js";
2
- import { P as Resolvers, Q as TcpSocketListenerResult, et as TcpSocketResult } from "./contract-DLyjkumA.js";
3
- import "./api-CxrIIOW8.js";
2
+ import { P as Resolvers, rt as TcpSocketResult, tt as TcpSocketListenerResult } from "./contract-CSdeTq_Y.js";
3
+ import "./api-LKxHamsI.js";
4
4
  import { AddressInfo, ListenOptions, Server, ServerOpts, Socket, SocketConnectOpts, SocketConstructorOpts } from "net";
5
5
  import { DuplexOptions, Stream } from "stream";
6
6
  import { EventEmitter } from "events";
package/net.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import { a as createConnection, c as isIP, i as connect, l as isIPv4, n as Socket, o as createServer, r as _default, t as Server, u as isIPv6 } from "./net-DOkodxE3.js";
1
+ import { a as createConnection, c as isIP, i as connect, l as isIPv4, n as Socket, o as createServer, r as _default, t as Server, u as isIPv6 } from "./net-DtRM2eKo.js";
2
2
  export { Server, Socket, _default, _default as default, connect, createConnection, createServer, isIP, isIPv4, isIPv6 };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fkn/lib",
3
- "version": "0.9.29",
3
+ "version": "0.9.31",
4
4
  "main": "index.js",
5
5
  "types": "index.d.ts",
6
6
  "type": "module",
package/packages.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { C as PackageQuery, D as PickOptions, N as Radii, O as Placement, T as PackagesErrorCode, X as SurfaceRect, _ as InstallOptions, l as ConnectOptions, v as InstalledPackage, w as PackageResult } from "./contract-DLyjkumA.js";
1
+ import { $ as SurfaceRect, C as PackageQuery, D as PickOptions, N as Radii, O as Placement, T as PackagesErrorCode, _ as InstallOptions, l as ConnectOptions, v as InstalledPackage, w as PackageResult } from "./contract-CSdeTq_Y.js";
2
2
  import { Remote } from "osra";
3
3
  declare namespace packages_d_exports {
4
4
  export { AppConnectOptions, Connect, ConnectOptions, ConnectPayload, IncomingConnection, IncomingConnectionInfo, InstallOptions, InstalledPackage, MountOptions, MountedPackage, PackageConnection, PackageQuery, PackageResult, PackageView, PackagesError, PackagesErrorCode, PickOptions, Placement, Radii, RawPackageConnection, ShowOptions, SurfaceRect, attach, connect, hide, install, isVisible, list, mount, onConnect, onVisibilityChange, pick, search, show, uninstall };
@@ -1,5 +1,5 @@
1
- import { P as Resolvers } from "./contract-DLyjkumA.js";
2
- import "./api-CxrIIOW8.js";
1
+ import { P as Resolvers } from "./contract-CSdeTq_Y.js";
2
+ import "./api-LKxHamsI.js";
3
3
  //#region src/proxy.d.ts
4
4
  type ProxyFetch = Resolvers['cloud']['fetch'];
5
5
  type FetchParameters = Parameters<ProxyFetch>;
package/rooms.cjs CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./rolldown-runtime-BIInC43l.cjs"),t=require("./api-BCJO3EWi.cjs"),n=require("./busy-Dv8wzE5M.cjs");var r=e.t({available:()=>d,create:()=>f,join:()=>p}),i={noSuchRoom:`rooms: no such room`,wrongKey:`rooms: wrong room key`,inviteNoKey:`rooms: the invite carries no key`,noSuchMember:`rooms: no such member`,roomFull:`rooms: the room is full`,tooManyRooms:`rooms: too many rooms`,tooManyConnections:`rooms: too many connections`,tooManyBlocks:`rooms: too many blocks`,blocked:`rooms: you are blocked from this room`,cannotSend:`rooms: you cannot send here`,permissionDenied:`rooms: permission denied`,notOwner:`rooms: not the room owner`,ownerNotRemovable:`rooms: the owner cannot be removed`,ownerKeepsEvery:`rooms: the owner keeps every permission`,removeYourself:`rooms: you cannot remove yourself`,tooFast:`rooms: sending too fast`,tooLarge:`rooms: the message is too large`,unavailable:`rooms: rooms are unavailable`,notEnabled:`rooms: rooms are not available`,alreadyJoined:`rooms: already joined`,malformed:`rooms: malformed frame`,ended:`rooms: the room has ended`},a=(e,t)=>Object.assign(Error(t),{code:e}),o=e=>e instanceof Error&&typeof e.code==`string`,s=async()=>{if(!t.c)return;let e=(await t.o(`a room`).catch(()=>void 0))?.rooms;return typeof e?.create==`function`?e:void 0},c=()=>{throw a(`unavailable`,i.unavailable)},l=e=>e===`blocked`?`blocked`:e===`not-found`?`ended`:`unavailable`,u=async e=>{let r=e.invite,s=e,c=0,u=e.self,d=await e.defaults().catch(()=>({send:!0,receive:!0})),f=!1,p=new Set,m=new Set,h=n.t(`room`),g=()=>{},_=()=>{},v=new Promise(e=>{_=e}),y=e=>{let t=[...m];m.clear();for(let n of t)try{n(e)}catch{}},b=e=>{f||(f=!0,g(),p.clear(),h(),y(a(`closed`,i.ended)),_({reason:e}))},x=e=>{if(!f){e.type===`defaults`&&(d=e.defaults),e.type===`permissions`&&e.id===u.id&&(u={id:u.id,permissions:e.permissions});for(let t of[...p])try{t(e)}catch{}}},S=(e,t)=>{Promise.resolve(e.on(x)).catch(()=>{}),Promise.resolve(e.closed).then(e=>{t===c&&b(e.reason)},()=>{})},C=async(e,t)=>{if(typeof e?.join!=`function`)return b(`unavailable`);let n=await e.join(r).catch(()=>void 0);if(f||t!==c)return;if(!n)return b(`unavailable`);if(`error`in n)return b(l(n.error));if(n.self.id!==u.id)return Promise.resolve(n.leave()).catch(()=>{}),b(`unavailable`);s=n,u=n.self,S(n,t);let i=await n.defaults().catch(()=>void 0);i&&!f&&t===c&&(d=i)};g=t.l((e,t)=>{let n=c;c=t,!(f||n===0||n===t)&&(y(a(`unavailable`,i.unavailable)),C(e.rooms,t))}),S(e,c);let w=async e=>{if(f)throw a(`closed`,i.ended);let t=()=>{},n=new Promise((e,n)=>{t=n});m.add(t);try{return await Promise.race([Promise.resolve(e(s)),n])}catch(e){throw o(e)?e:a(`unavailable`,i.unavailable)}finally{m.delete(t)}},T=async e=>{let t=await w(e);if(`error`in t)throw a(t.error,t.message)};return{id:e.id,key:e.key,invite:r,get self(){return u},owner:e.owner,defaults:()=>d,members:()=>w(e=>e.members()),send:e=>T(t=>t.send(e)),setDefault:(e,t)=>T(n=>n.setDefault(e,t)),grant:(e,t)=>T(n=>n.grant(e,t)),revoke:(e,t)=>T(n=>n.revoke(e,t)),remove:e=>T(t=>t.remove(e)),block:e=>T(t=>t.block(e)),unblock:e=>T(t=>t.unblock(e)),on:async e=>f?()=>{}:(p.add(e),()=>{p.delete(e)}),leave:async()=>{await Promise.resolve(s.leave()).catch(()=>{}),b(`left`)},closed:v}},d=async()=>{let e=await s();return e?e.available().catch(()=>!1):!1},f=async e=>{let t=await s();if(!t)throw a(`unavailable`,i.unavailable);let n=await t.create(e).catch(c);if(`error`in n)throw a(n.error,n.message);return u(n)},p=async(e,t)=>{let n=typeof e==`string`?e.indexOf(`.`):-1;if(n<=0||n===e.length-1)throw a(`invalid`,i.inviteNoKey);let r=await s();if(!r)throw a(`unavailable`,i.unavailable);let o=await r.join(e,t).catch(c);if(`error`in o)throw a(o.error,o.message);return u(o)};exports.available=d,exports.create=f,exports.join=p,Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return r}});
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./rolldown-runtime-BIInC43l.cjs"),t=require("./api-BCJO3EWi.cjs"),n=require("./busy-Dv8wzE5M.cjs");var r=e.t({available:()=>f,create:()=>m,join:()=>h,open:()=>p}),i={wrongKey:`rooms: wrong room key`,inviteNoKey:`rooms: the invite carries no key`,badName:`rooms: the name is not one a room can have`,badKeyOption:`rooms: the key is not 32 bytes base64url`,noSuchMember:`rooms: no such member`,noSuchMessage:`rooms: no such message`,roomFull:`rooms: the room is full`,tooManyConnections:`rooms: too many connections`,tooManyBlocks:`rooms: too many blocks`,tooManyClaims:`rooms: too many claims`,mailboxFull:`rooms: the mailbox is full`,outOfStorage:`rooms: the owner is out of storage`,outOfQuota:`rooms: out of daily bandwidth`,blocked:`rooms: you are blocked from this room`,cannotSend:`rooms: you cannot send here`,permissionDenied:`rooms: permission denied`,notOwner:`rooms: not the room owner`,ownerNotRemovable:`rooms: the owner cannot be removed`,ownerKeepsEvery:`rooms: the owner keeps every permission`,removeYourself:`rooms: you cannot remove yourself`,needsAccount:`rooms: claiming needs an account`,needsPremium:`rooms: claiming needs premium`,nameClaimed:`rooms: the name is claimed`,notClaimed:`rooms: the room is not claimed`,noMailbox:`rooms: the room keeps no messages`,badLimit:`rooms: the limit is out of range`,tooFast:`rooms: sending too fast`,tooLarge:`rooms: the message is too large`,unavailable:`rooms: rooms are unavailable`,notEnabled:`rooms: rooms are not available`,alreadyJoined:`rooms: already joined`,notJoined:`rooms: not joined`,malformed:`rooms: malformed frame`,ended:`rooms: the room has ended`},a=(e,t)=>Object.assign(Error(t),{code:e}),o=e=>e instanceof Error&&typeof e.code==`string`,s={send:!0,receive:!0,maxMessageBytes:262144},c=async()=>{if(!t.c)return;let e=(await t.o(`a room`).catch(()=>void 0))?.rooms;return typeof e?.open==`function`?e:void 0},l=()=>{throw a(`unavailable`,i.unavailable)},u=e=>e===`blocked`?`blocked`:e===`not-found`?`ended`:`unavailable`,d=async e=>{let r=e.invite,c=e,l=0,d=e.self,f=e.owner,p=e.claimed,m=e.mailbox,h=await e.defaults().catch(()=>s),g=!1,_=new Set,v=new Set,y=n.t(`room`),b=()=>{},x=()=>{},S=new Promise(e=>{x=e}),C=e=>{let t=[...v];v.clear();for(let n of t)try{n(e)}catch{}},w=e=>{g||(g=!0,b(),_.clear(),y(),C(a(`closed`,i.ended)),x({reason:e}))},T=e=>{if(!g){e.type===`defaults`&&(h=e.defaults),e.type===`permissions`&&e.id===d.id&&(d={id:d.id,permissions:e.permissions,maxMessageBytes:e.maxMessageBytes}),e.type===`claim`&&(p=e.claimed,f=e.owner,p||(m=null));for(let t of[..._])try{t(e)}catch{}}},E=(e,t)=>{Promise.resolve(e.on(T)).catch(()=>{}),Promise.resolve(e.closed).then(e=>{t===l&&w(e.reason)},()=>{})},D=async(e,t)=>{if(typeof e?.join!=`function`)return w(`unavailable`);let n=await e.join(r).catch(()=>void 0);if(g||t!==l)return;if(!n)return w(`unavailable`);if(`error`in n)return w(u(n.error));if(n.self.id!==d.id)return Promise.resolve(n.leave()).catch(()=>{}),w(`unavailable`);c=n,d=n.self,f=n.owner,p=n.claimed,m=n.mailbox,E(n,t);let i=await n.defaults().catch(()=>void 0);i&&!g&&t===l&&(h=i)};b=t.l((e,t)=>{let n=l;l=t,!(g||n===0||n===t)&&(C(a(`unavailable`,i.unavailable)),D(e.rooms,t))}),E(e,l);let O=async e=>{if(g)throw a(`closed`,i.ended);let t=()=>{},n=new Promise((e,n)=>{t=n});v.add(t);try{return await Promise.race([Promise.resolve(e(c)),n])}catch(e){throw o(e)?e:a(`unavailable`,i.unavailable)}finally{v.delete(t)}},k=async e=>{let t=await O(e);if(`error`in t)throw a(t.error,t.message)},A=async e=>{let t=await O(e);if(typeof t==`object`&&t&&`error`in t)throw a(t.error,t.message);return t};return{id:e.id,name:e.name,key:e.key,invite:r,get self(){return d},get owner(){return f},get claimed(){return p},get mailbox(){return m},defaults:()=>h,members:()=>O(e=>e.members()),send:e=>k(t=>t.send(e)),edit:(e,t)=>k(n=>n.edit(e,t)),delete:(e,t)=>k(n=>n.delete(e,t)),backlog:(e,t)=>A(n=>n.backlog(e,t)),setDefault:(e,t)=>k(n=>n.setDefault(e,t)),limit:(e,t)=>k(n=>n.limit(e,t)),grant:(e,t)=>k(n=>n.grant(e,t)),revoke:(e,t)=>k(n=>n.revoke(e,t)),remove:e=>k(t=>t.remove(e)),block:e=>k(t=>t.block(e)),unblock:e=>k(t=>t.unblock(e)),claim:()=>k(e=>e.claim()),release:()=>k(e=>e.release()),usage:async()=>{let e=await A(e=>e.usage());return m=e,e},on:async e=>g?()=>{}:(_.add(e),()=>{_.delete(e)}),leave:async()=>{await Promise.resolve(c.leave()).catch(()=>{}),w(`left`)},closed:S}},f=async()=>{let e=await c();return e?e.available().catch(()=>!1):!1},p=async(e,t)=>{if(typeof e!=`string`||e.length===0||e.length>72)throw a(`invalid`,i.badName);let n=await c();if(!n)throw a(`unavailable`,i.unavailable);let r=await n.open(e,t).catch(l);if(`error`in r)throw a(r.error,r.message);return d(r)},m=async e=>{let t=await c();if(!t)throw a(`unavailable`,i.unavailable);let n=await t.create(e).catch(l);if(`error`in n)throw a(n.error,n.message);return d(n)},h=async(e,t)=>{let n=typeof e==`string`?e.indexOf(`.`):-1;if(n<=0||n===e.length-1)throw a(`invalid`,i.inviteNoKey);let r=await c();if(!r)throw a(`unavailable`,i.unavailable);let o=await r.join(e,t).catch(l);if(`error`in o)throw a(o.error,o.message);return d(o)};exports.available=f,exports.create=m,exports.join=h,exports.open=p,Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return r}});
package/rooms.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- import { B as RoomJoinOptions, F as RoomCreateOptions, G as RoomsErrorCode, H as RoomMessage, I as RoomDefaults, L as RoomEnd, R as RoomEvent, U as RoomPermission, V as RoomMember, W as RoomPermissions } from "./contract-DLyjkumA.js";
1
+ import { F as RoomBacklog, G as RoomOpenOptions, H as RoomMailbox, I as RoomCreateOptions, J as RoomsErrorCode, K as RoomPermission, L as RoomDefaults, R as RoomEnd, U as RoomMember, V as RoomJoinOptions, W as RoomMessage, q as RoomPermissions, z as RoomEvent } from "./contract-CSdeTq_Y.js";
2
2
  declare namespace rooms_d_exports {
3
- export { RoomCreateOptions as CreateOptions, RoomJoinOptions as JoinOptions, Room, RoomDefaults, RoomEnd, RoomEvent, RoomMember, RoomMessage, RoomPermission, RoomPermissions, RoomsError, RoomsErrorCode, available, create, join };
3
+ export { RoomCreateOptions as CreateOptions, RoomJoinOptions as JoinOptions, RoomOpenOptions as OpenOptions, Room, RoomBacklog, RoomDefaults, RoomEnd, RoomEvent, RoomMailbox, RoomMember, RoomMessage, RoomPermission, RoomPermissions, RoomsError, RoomsErrorCode, available, create, join, open };
4
4
  }
5
5
  /** Thrown by every member of this namespace. Match on `code`, never on the message. */
6
6
  type RoomsError = Error & {
@@ -11,36 +11,60 @@ type RoomsError = Error & {
11
11
  * as the chat lasts.
12
12
  */
13
13
  type Room = {
14
- /** the room's uuid */
14
+ /** `<scope>/<name>`: the name under this app's own scope, or under `global` */
15
15
  readonly id: string;
16
+ readonly name: string;
16
17
  /** the room key, base64url. The server never sees it. Anyone holding it and the id can join. */
17
18
  readonly key: string;
18
- /** `id` and `key` as one string, the thing to put in a link */
19
+ /** `key` and `id` as one string, the thing to put in a link */
19
20
  readonly invite: string;
20
21
  /** this app's member record, as this room sees it. The id is fresh in every room. */
21
22
  readonly self: RoomMember;
23
+ /** the owner's member id, or '' while a claimed room's owner has never joined */
22
24
  readonly owner: string;
25
+ /** whether a premium account keeps this name and its messages */
26
+ readonly claimed: boolean;
27
+ /** what the mailbox holds, as the room last said. Null for a room nobody has claimed. */
28
+ readonly mailbox: RoomMailbox | null;
23
29
  defaults: () => RoomDefaults;
24
30
  members: () => Promise<RoomMember[]>;
25
- /** at most 4,096 bytes of UTF-8, sealed before it leaves the browser. Rejects `too-large`, never truncates. */
31
+ /** sealed before it leaves the browser. Rejects `too-large` past `self.maxMessageBytes` on the wire, never truncates. */
26
32
  send: (text: string) => Promise<void>;
33
+ /** replaces a stored message's text: one of your own, or any as the owner */
34
+ edit: (seq: number, text: string) => Promise<void>;
35
+ /** drops stored messages: one of your own, or any range as the owner */
36
+ delete: (from: number, to?: number) => Promise<void>;
37
+ /** replays stored messages above `after` as `message` events marked `replayed`, one page at a time */
38
+ backlog: (after: number, limit?: number) => Promise<RoomBacklog>;
27
39
  setDefault: (permission: 'send' | 'receive', value: boolean) => Promise<void>;
40
+ /** the message size cap: the room default when no member is named, that member's override otherwise, cleared by null */
41
+ limit: (maxMessageBytes: number | null, id?: string) => Promise<void>;
28
42
  grant: (id: string, permission: RoomPermission) => Promise<void>;
29
43
  revoke: (id: string, permission: RoomPermission) => Promise<void>;
30
44
  remove: (id: string) => Promise<void>;
31
45
  block: (id: string) => Promise<void>;
32
46
  unblock: (id: string) => Promise<void>;
47
+ /** keeps the name and a mailbox for the signed-in premium account. The only thing in rooms that premium buys. */
48
+ claim: () => Promise<void>;
49
+ release: () => Promise<void>;
50
+ usage: () => Promise<RoomMailbox | null>;
33
51
  /** Await the returned unsubscribe in cleanup, the `account.onChange` shape. */
34
52
  on: (listener: (event: RoomEvent) => void) => Promise<() => void>;
35
53
  leave: () => Promise<void>;
36
54
  /** Settles once, when the room ends for this app. Never rejects. */
37
55
  readonly closed: Promise<RoomEnd>;
38
56
  };
39
- /** Whether this realm can join a room: false in Node, false in a worker nothing bridged, false against a shell older than rooms. Answers rather than rejecting. */
57
+ /** Whether this realm can join a room: false in Node, false in a worker nothing bridged, false against a shell older than named rooms. Answers rather than rejecting. */
40
58
  declare const available: () => Promise<boolean>;
41
- /** Open a room and become its owner. Share `room.invite` to let anyone else in. */
59
+ /**
60
+ * Open a room by name: a name under this app's own scope, or `global/<name>` for the shared one.
61
+ * Nobody there means the room comes into being with you as its owner; somebody there means you join
62
+ * them, and the key has to match theirs. Share `room.invite` to let anyone else in.
63
+ */
64
+ declare const open: (name: string, options?: RoomOpenOptions) => Promise<Room>;
65
+ /** Open a room under a random name and become its owner. Share `room.invite` to let anyone else in. */
42
66
  declare const create: (options?: RoomCreateOptions) => Promise<Room>;
43
- /** `invite` is `room.invite`, or an id and a key joined by a dot. */
67
+ /** `invite` is `room.invite`: a key and a room id joined by a dot. */
44
68
  declare const join: (invite: string, options?: RoomJoinOptions) => Promise<Room>;
45
69
  //#endregion
46
- export { type RoomCreateOptions as CreateOptions, type RoomJoinOptions as JoinOptions, Room, type RoomDefaults, type RoomEnd, type RoomEvent, type RoomMember, type RoomMessage, type RoomPermission, type RoomPermissions, RoomsError, type RoomsErrorCode, available, create, join, rooms_d_exports as t };
70
+ export { type RoomCreateOptions as CreateOptions, type RoomJoinOptions as JoinOptions, type RoomOpenOptions as OpenOptions, Room, type RoomBacklog, type RoomDefaults, type RoomEnd, type RoomEvent, type RoomMailbox, type RoomMember, type RoomMessage, type RoomPermission, type RoomPermissions, RoomsError, type RoomsErrorCode, available, create, join, open, rooms_d_exports as t };