@maravilla-labs/platform 0.2.1 → 0.2.4
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/dist/config.d.ts +236 -0
- package/dist/config.js +8 -0
- package/dist/config.js.map +1 -0
- package/dist/events.d.ts +182 -0
- package/dist/events.js +45 -0
- package/dist/events.js.map +1 -0
- package/dist/index.d.ts +470 -51
- package/dist/index.js +253 -2
- package/dist/index.js.map +1 -1
- package/dist/push.d.ts +67 -0
- package/dist/push.js +173 -0
- package/dist/push.js.map +1 -0
- package/dist/ren-D0DCQ0Fs.d.ts +48 -0
- package/package.json +13 -1
- package/src/config.ts +276 -0
- package/src/events.ts +283 -0
- package/src/index.ts +1 -0
- package/src/push.ts +280 -0
- package/src/remote-client.ts +101 -1
- package/src/types.ts +514 -1
- package/tsup.config.ts +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
export { a as RenClient, b as RenClientOptions, R as RenEvent, g as getOrCreateClientId, r as renFetch, s as storageDelete, c as storageUpload } from './ren-D0DCQ0Fs.js';
|
|
1
2
|
import { LocalParticipant } from 'livekit-client';
|
|
3
|
+
export { RegisterPushOptions, RegisterPushResult, offsetBefore, registerPush, unregisterPush } from './push.js';
|
|
2
4
|
|
|
3
5
|
/**
|
|
4
6
|
* Media service for video/audio room management.
|
|
@@ -299,6 +301,104 @@ interface Database {
|
|
|
299
301
|
deleteMany(collection: string, filter: any): Promise<{
|
|
300
302
|
deleted: number;
|
|
301
303
|
}>;
|
|
304
|
+
/**
|
|
305
|
+
* Register a vector index on a collection field. Inserts thereafter
|
|
306
|
+
* will have vectors in `spec.field` synced into an ANN-indexed `vec0`
|
|
307
|
+
* table inside the same SQLite transaction as the document write.
|
|
308
|
+
*
|
|
309
|
+
* Idempotent when the spec matches an existing index; errors on
|
|
310
|
+
* incompatible re-declaration.
|
|
311
|
+
*
|
|
312
|
+
* @example
|
|
313
|
+
* ```typescript
|
|
314
|
+
* await db.createVectorIndex('products', {
|
|
315
|
+
* field: 'embedding',
|
|
316
|
+
* dimensions: 1536,
|
|
317
|
+
* metric: 'cosine',
|
|
318
|
+
* storage: 'int8',
|
|
319
|
+
* });
|
|
320
|
+
* ```
|
|
321
|
+
*/
|
|
322
|
+
createVectorIndex(collection: string, spec: VectorIndexSpec): Promise<void>;
|
|
323
|
+
/**
|
|
324
|
+
* Drop a vector index. Returns `{ removed: true }` if the index existed
|
|
325
|
+
* and was removed; `{ removed: false }` otherwise. The underlying
|
|
326
|
+
* collection's documents are untouched.
|
|
327
|
+
*/
|
|
328
|
+
dropVectorIndex(collection: string, field: string): Promise<{
|
|
329
|
+
removed: boolean;
|
|
330
|
+
}>;
|
|
331
|
+
/** List every registered vector index on a collection. */
|
|
332
|
+
listVectorIndexes(collection: string): Promise<VectorIndexDescriptor[]>;
|
|
333
|
+
/**
|
|
334
|
+
* Pure vector search — convenience wrapper. For hybrid metadata +
|
|
335
|
+
* vector search, use `find()` with `options.vector`.
|
|
336
|
+
*/
|
|
337
|
+
findSimilar(collection: string, query: VectorQueryWithFilter): Promise<VectorSearchHit[]>;
|
|
338
|
+
/**
|
|
339
|
+
* Register a MongoDB-style secondary index on a collection. Speeds up
|
|
340
|
+
* `find()` / `findOne()` queries whose filter matches the indexed keys.
|
|
341
|
+
*
|
|
342
|
+
* Idempotent when the spec matches an existing index; errors on name
|
|
343
|
+
* collision with a different spec.
|
|
344
|
+
*
|
|
345
|
+
* @example
|
|
346
|
+
* ```typescript
|
|
347
|
+
* await db.createIndex('users', { keys: { email: 1 }, unique: true });
|
|
348
|
+
* await db.createIndex('posts', { keys: { authorId: 1, createdAt: -1 } });
|
|
349
|
+
* await db.createIndex('sessions', { keys: { createdAt: 1 }, expireAfterSeconds: 3600 });
|
|
350
|
+
* ```
|
|
351
|
+
*/
|
|
352
|
+
createIndex(collection: string, spec: IndexSpec): Promise<IndexDescriptor>;
|
|
353
|
+
/** Drop an index by name. Returns `true` if it existed and was removed. */
|
|
354
|
+
dropIndex(collection: string, name: string): Promise<{
|
|
355
|
+
removed: boolean;
|
|
356
|
+
}>;
|
|
357
|
+
/**
|
|
358
|
+
* List every index on a collection — both document indexes and
|
|
359
|
+
* vector indexes — in a unified response.
|
|
360
|
+
*/
|
|
361
|
+
listIndexes(collection: string): Promise<IndexDescriptor[]>;
|
|
362
|
+
}
|
|
363
|
+
/** MongoDB-style key direction: `1` = ascending, `-1` = descending. */
|
|
364
|
+
type IndexDirection = 1 | -1;
|
|
365
|
+
/** Whether an index is a regular document index or a vector index. */
|
|
366
|
+
type IndexKind = 'document' | 'vector';
|
|
367
|
+
interface IndexSpec {
|
|
368
|
+
/** Optional index name. Falls back to an auto-derived name. */
|
|
369
|
+
name?: string;
|
|
370
|
+
/**
|
|
371
|
+
* Key shape. Accepts an ordered array of `[field, direction]` tuples
|
|
372
|
+
* (recommended) OR a plain object — note that object key order is
|
|
373
|
+
* language-dependent, so tuples are safer for compound indexes.
|
|
374
|
+
*/
|
|
375
|
+
keys: Array<[string, IndexDirection]> | Record<string, IndexDirection>;
|
|
376
|
+
/** Enforce uniqueness across the indexed columns. */
|
|
377
|
+
unique?: boolean;
|
|
378
|
+
/**
|
|
379
|
+
* Partial-index predicate. Only matching documents are included in
|
|
380
|
+
* the index. Supports `$eq`, `$ne`, `$gt/$gte/$lt/$lte`, `$in/$nin`,
|
|
381
|
+
* `$exists`, `$and`, `$or`. Rejects `$regex`, `$where`, `$text`.
|
|
382
|
+
*/
|
|
383
|
+
partial?: Record<string, any>;
|
|
384
|
+
/** Shorthand for `partial: { <field>: { $exists: true } }`. */
|
|
385
|
+
sparse?: boolean;
|
|
386
|
+
/**
|
|
387
|
+
* TTL in seconds. Requires a single-field index on a Unix-epoch-seconds
|
|
388
|
+
* field. The platform runs a background sweeper that deletes documents
|
|
389
|
+
* older than this.
|
|
390
|
+
*/
|
|
391
|
+
expireAfterSeconds?: number;
|
|
392
|
+
}
|
|
393
|
+
interface IndexDescriptor {
|
|
394
|
+
collection: string;
|
|
395
|
+
name: string;
|
|
396
|
+
keys: Array<[string, IndexDirection]>;
|
|
397
|
+
unique: boolean;
|
|
398
|
+
sparse: boolean;
|
|
399
|
+
partial?: Record<string, any>;
|
|
400
|
+
expireAfterSeconds?: number;
|
|
401
|
+
kind: IndexKind;
|
|
302
402
|
}
|
|
303
403
|
/**
|
|
304
404
|
* Options for database find operations.
|
|
@@ -311,7 +411,81 @@ interface DbFindOptions {
|
|
|
311
411
|
skip?: number;
|
|
312
412
|
/** Sort order specification (MongoDB-style: { field: 1 } for ascending, { field: -1 } for descending) */
|
|
313
413
|
sort?: any;
|
|
414
|
+
/**
|
|
415
|
+
* Vector search clause. When set, `find()` performs a hybrid
|
|
416
|
+
* metadata + vector search using the collection's registered vector
|
|
417
|
+
* index on `vector.field`. The metadata filter in `filter` is applied
|
|
418
|
+
* after (or alongside, depending on the index type) the vector ranking.
|
|
419
|
+
*/
|
|
420
|
+
vector?: VectorQuery;
|
|
421
|
+
}
|
|
422
|
+
/** Distance metric used to compare vectors. */
|
|
423
|
+
type VectorMetric = 'cosine' | 'l2' | 'hamming';
|
|
424
|
+
/**
|
|
425
|
+
* On-disk storage precision for vectors.
|
|
426
|
+
* - `float32` (default): 4 bytes per dim, highest accuracy
|
|
427
|
+
* - `int8`: 1 byte per dim, 4× smaller, <2% accuracy loss for most embeddings
|
|
428
|
+
* - `bit`: 1 bit per dim, 32× smaller; requires metric='hamming'
|
|
429
|
+
*/
|
|
430
|
+
type VectorStorage = 'float32' | 'int8' | 'bit';
|
|
431
|
+
/** Query shape: single vector or an array of vectors (ColBERT-style). */
|
|
432
|
+
type VectorQueryMode = 'single' | 'late-interaction';
|
|
433
|
+
/** How multi-vector distances are aggregated per document. */
|
|
434
|
+
type VectorAggregation = 'max-sim' | 'sum';
|
|
435
|
+
interface VectorIndexSpec {
|
|
436
|
+
/** JSON path of the vector field inside each document (dotted syntax OK). */
|
|
437
|
+
field: string;
|
|
438
|
+
/** Stored vector dimensionality. */
|
|
439
|
+
dimensions: number;
|
|
440
|
+
/** Distance metric; defaults to `cosine`. */
|
|
441
|
+
metric?: VectorMetric;
|
|
442
|
+
/** Storage precision; defaults to `float32`. Int8/bit quantize automatically on insert. */
|
|
443
|
+
storage?: VectorStorage;
|
|
444
|
+
/** Allow queries with vectors shorter than `dimensions`. Requires matryoshka-trained embeddings. */
|
|
445
|
+
matryoshka?: boolean;
|
|
446
|
+
/** Each document holds an array of vectors (one per chunk/token). */
|
|
447
|
+
multiVector?: boolean;
|
|
448
|
+
}
|
|
449
|
+
interface VectorIndexDescriptor {
|
|
450
|
+
collection: string;
|
|
451
|
+
field: string;
|
|
452
|
+
dimensions: number;
|
|
453
|
+
metric: VectorMetric;
|
|
454
|
+
storage: VectorStorage;
|
|
455
|
+
matryoshka: boolean;
|
|
456
|
+
multiVector: boolean;
|
|
457
|
+
}
|
|
458
|
+
interface VectorQuery {
|
|
459
|
+
/** Must match a registered vector index field on the collection. */
|
|
460
|
+
field: string;
|
|
461
|
+
/**
|
|
462
|
+
* Query vector (`number[]` for `queryMode: 'single'`) or array of
|
|
463
|
+
* query vectors (`number[][]` for `queryMode: 'late-interaction'`).
|
|
464
|
+
*/
|
|
465
|
+
value: number[] | number[][];
|
|
466
|
+
/** Top-k result count. Must be > 0. */
|
|
467
|
+
k: number;
|
|
468
|
+
/** Per-query metric override. Defaults to the index's configured metric. */
|
|
469
|
+
metric?: VectorMetric;
|
|
470
|
+
/** Drop results below this normalized score (0–1, higher = more similar). */
|
|
471
|
+
minScore?: number;
|
|
472
|
+
/** Defaults to `single`. */
|
|
473
|
+
queryMode?: VectorQueryMode;
|
|
474
|
+
/** Defaults to `max-sim`. Only meaningful for multi-vector indexes. */
|
|
475
|
+
aggregation?: VectorAggregation;
|
|
314
476
|
}
|
|
477
|
+
/** Convenience shape for the pure-vector `findSimilar()` helper. */
|
|
478
|
+
interface VectorQueryWithFilter extends VectorQuery {
|
|
479
|
+
/** Optional metadata filter applied alongside the vector search. */
|
|
480
|
+
filter?: any;
|
|
481
|
+
/** Overall result cap (defaults to `k`). */
|
|
482
|
+
limit?: number;
|
|
483
|
+
}
|
|
484
|
+
/** Document returned from a vector search, with similarity metadata attached. */
|
|
485
|
+
type VectorSearchHit = Record<string, any> & {
|
|
486
|
+
_score: number;
|
|
487
|
+
_distance: number;
|
|
488
|
+
};
|
|
315
489
|
/**
|
|
316
490
|
* Storage interface for object/file storage operations.
|
|
317
491
|
* Provides S3-compatible API for storing and retrieving files.
|
|
@@ -343,7 +517,7 @@ interface DbFindOptions {
|
|
|
343
517
|
* Source types accepted by Storage.putStream for streaming uploads.
|
|
344
518
|
*/
|
|
345
519
|
type StoragePutStreamSource = Uint8Array | ArrayBuffer | string | Blob | ReadableStream<Uint8Array | ArrayBuffer | string | number[]> | Iterable<Uint8Array | ArrayBuffer | string | number[]> | AsyncIterable<Uint8Array | ArrayBuffer | string | number[]>;
|
|
346
|
-
interface Storage
|
|
520
|
+
interface Storage {
|
|
347
521
|
/**
|
|
348
522
|
* Generate a presigned URL for uploading a file directly from the browser.
|
|
349
523
|
*
|
|
@@ -555,7 +729,7 @@ interface PlatformEnv {
|
|
|
555
729
|
/** Database interface for document operations */
|
|
556
730
|
DB: Database;
|
|
557
731
|
/** Object/file storage interface */
|
|
558
|
-
STORAGE: Storage
|
|
732
|
+
STORAGE: Storage;
|
|
559
733
|
}
|
|
560
734
|
/**
|
|
561
735
|
* Main platform interface providing access to all Maravilla runtime services.
|
|
@@ -621,6 +795,25 @@ interface AuthUser {
|
|
|
621
795
|
/** Unix timestamp of last login (if any) */
|
|
622
796
|
last_login_at?: number;
|
|
623
797
|
}
|
|
798
|
+
/**
|
|
799
|
+
* Snapshot of whoever is currently bound to the request as the caller.
|
|
800
|
+
*
|
|
801
|
+
* Populated by {@link AuthService.login} (implicit), {@link AuthService.setCurrentUser}
|
|
802
|
+
* (explicit), or left anonymous if neither has run for this request.
|
|
803
|
+
* This is exactly what per-resource policies see as `auth.*` when they run.
|
|
804
|
+
*/
|
|
805
|
+
interface AuthCaller {
|
|
806
|
+
/** Caller's user id, or `""` if anonymous */
|
|
807
|
+
user_id: string;
|
|
808
|
+
/** Caller's email, or `""` if anonymous */
|
|
809
|
+
email: string;
|
|
810
|
+
/** Admin flag from the session */
|
|
811
|
+
is_admin: boolean;
|
|
812
|
+
/** Role names (project-scoped) */
|
|
813
|
+
roles: string[];
|
|
814
|
+
/** `true` when no identity is bound to this request */
|
|
815
|
+
is_anonymous: boolean;
|
|
816
|
+
}
|
|
624
817
|
/**
|
|
625
818
|
* Session returned after successful login or token refresh.
|
|
626
819
|
*/
|
|
@@ -869,6 +1062,270 @@ interface AuthService {
|
|
|
869
1062
|
withAuth<T extends (request: Request & {
|
|
870
1063
|
user: AuthUser;
|
|
871
1064
|
}) => Promise<Response>>(handler: T): (request: Request) => Promise<Response>;
|
|
1065
|
+
/**
|
|
1066
|
+
* Explicitly bind the caller for the remainder of this request.
|
|
1067
|
+
* Pass a JWT to validate + bind, or `null` / `""` to clear.
|
|
1068
|
+
*
|
|
1069
|
+
* `login()` already binds implicitly on success; reach for `setCurrentUser`
|
|
1070
|
+
* when you receive a JWT from an inbound `Authorization` header or cookie
|
|
1071
|
+
* and want subsequent KV/DB/realtime/media ops to run as that user.
|
|
1072
|
+
*
|
|
1073
|
+
* Not available on remote clients — throws.
|
|
1074
|
+
*/
|
|
1075
|
+
setCurrentUser(token: string | null): Promise<void>;
|
|
1076
|
+
/**
|
|
1077
|
+
* Snapshot of the currently bound caller. Returns an anonymous caller
|
|
1078
|
+
* (`is_anonymous: true`) when no identity has been bound.
|
|
1079
|
+
*
|
|
1080
|
+
* Not available on remote clients — throws.
|
|
1081
|
+
*/
|
|
1082
|
+
getCurrentUser(): AuthCaller;
|
|
1083
|
+
/**
|
|
1084
|
+
* Ask the policy engine whether the bound caller would be allowed to
|
|
1085
|
+
* perform `action` on `resourceId`, given the supplied `node` payload.
|
|
1086
|
+
* Returns a boolean — never throws on denial.
|
|
1087
|
+
*
|
|
1088
|
+
* The check runs the exact same evaluator that gates direct KV/DB/
|
|
1089
|
+
* realtime/media ops, so `can(...)` is authoritative.
|
|
1090
|
+
*
|
|
1091
|
+
* @example
|
|
1092
|
+
* ```typescript
|
|
1093
|
+
* const ok = await platform.auth.can("delete", "documents", {
|
|
1094
|
+
* owner: doc.owner,
|
|
1095
|
+
* status: doc.status,
|
|
1096
|
+
* });
|
|
1097
|
+
* if (!ok) return new Response("Forbidden", { status: 403 });
|
|
1098
|
+
* ```
|
|
1099
|
+
*
|
|
1100
|
+
* Not available on remote clients — throws.
|
|
1101
|
+
*/
|
|
1102
|
+
can(action: string, resourceId: string, node?: Record<string, unknown> | null): Promise<boolean>;
|
|
1103
|
+
}
|
|
1104
|
+
/**
|
|
1105
|
+
* Per-request opt-out toggle for the Layer 2 policy evaluator.
|
|
1106
|
+
*
|
|
1107
|
+
* Flipping `setEnabled(false)` disables **per-resource policies only** for
|
|
1108
|
+
* the remainder of the current request. Layer 1 (tenant + owner isolation)
|
|
1109
|
+
* is always enforced — no call can ever escape its tenant. Every flip is
|
|
1110
|
+
* audit-logged server-side with the caller's identity.
|
|
1111
|
+
*
|
|
1112
|
+
* Intended for trusted in-app flows (first-run seeders, admin jobs). Do not
|
|
1113
|
+
* toggle based on untrusted input.
|
|
1114
|
+
*
|
|
1115
|
+
* Not available on remote clients — throws.
|
|
1116
|
+
*/
|
|
1117
|
+
interface PolicyService {
|
|
1118
|
+
/** Disable or re-enable Layer 2 policy checks for this request. */
|
|
1119
|
+
setEnabled(enabled: boolean): void;
|
|
1120
|
+
/** `true` when Layer 2 is active for this request. */
|
|
1121
|
+
isEnabled(): boolean;
|
|
1122
|
+
}
|
|
1123
|
+
/**
|
|
1124
|
+
* Target selector for Web Push sends. Combine fields to narrow — all
|
|
1125
|
+
* specified conditions must match for a subscription to receive the push.
|
|
1126
|
+
*
|
|
1127
|
+
* @example
|
|
1128
|
+
* ```typescript
|
|
1129
|
+
* // Every subscription tagged with "waitlist"
|
|
1130
|
+
* await platform.push.send({ topic: 'waitlist' }, notification);
|
|
1131
|
+
*
|
|
1132
|
+
* // Every device belonging to one authenticated user
|
|
1133
|
+
* await platform.push.send({ userId: 'u_42' }, notification);
|
|
1134
|
+
*
|
|
1135
|
+
* // "This specific user's subscription for this specific invite"
|
|
1136
|
+
* await platform.push.send({ userId: 'u_42', topic: 'invite:abc:rsvp' }, notification);
|
|
1137
|
+
* ```
|
|
1138
|
+
*/
|
|
1139
|
+
interface PushTarget {
|
|
1140
|
+
userId?: string;
|
|
1141
|
+
visitorId?: string;
|
|
1142
|
+
topic?: string;
|
|
1143
|
+
userIds?: string[];
|
|
1144
|
+
topics?: string[];
|
|
1145
|
+
onlyActive?: boolean;
|
|
1146
|
+
}
|
|
1147
|
+
/** Shape of a Web Push notification payload. */
|
|
1148
|
+
interface NotificationPayload {
|
|
1149
|
+
/** Required — the notification headline shown on lock screens and the notification shade. */
|
|
1150
|
+
title: string;
|
|
1151
|
+
body?: string;
|
|
1152
|
+
icon?: string;
|
|
1153
|
+
badge?: string;
|
|
1154
|
+
image?: string;
|
|
1155
|
+
/** Browsers dedupe notifications sharing a tag. */
|
|
1156
|
+
tag?: string;
|
|
1157
|
+
/** Where to navigate when the notification is clicked. */
|
|
1158
|
+
url?: string;
|
|
1159
|
+
/** Arbitrary JSON delivered to the service worker alongside the notification. */
|
|
1160
|
+
data?: Record<string, unknown>;
|
|
1161
|
+
/** Seconds the push service holds the message if the device is offline. */
|
|
1162
|
+
ttl?: number;
|
|
1163
|
+
urgency?: 'very-low' | 'low' | 'normal' | 'high';
|
|
1164
|
+
}
|
|
1165
|
+
/**
|
|
1166
|
+
* Options for `platform.push.schedule(...)`.
|
|
1167
|
+
*
|
|
1168
|
+
* @example
|
|
1169
|
+
* ```typescript
|
|
1170
|
+
* // Remind every RSVP'd guest one hour before the event.
|
|
1171
|
+
* await platform.push.schedule(
|
|
1172
|
+
* { topic: `invite:${invite.id}` },
|
|
1173
|
+
* { title: invite.title, body: 'Your event is in one hour' },
|
|
1174
|
+
* {
|
|
1175
|
+
* at: offsetBefore(invite.event_date, '1h'),
|
|
1176
|
+
* key: `invite:${invite.id}:reminder-1h`,
|
|
1177
|
+
* }
|
|
1178
|
+
* );
|
|
1179
|
+
* ```
|
|
1180
|
+
*/
|
|
1181
|
+
interface ScheduleOptions {
|
|
1182
|
+
/**
|
|
1183
|
+
* When to send. Absolute `Date` or ISO-8601 string; the server treats
|
|
1184
|
+
* bare (no-offset) strings as UTC.
|
|
1185
|
+
*/
|
|
1186
|
+
at: Date | string;
|
|
1187
|
+
/**
|
|
1188
|
+
* Idempotency key scoped to your project. Re-calling `schedule` with the
|
|
1189
|
+
* same key atomically replaces the prior pending job — safe to call on
|
|
1190
|
+
* every save of an invite whose event date may change.
|
|
1191
|
+
*/
|
|
1192
|
+
key: string;
|
|
1193
|
+
/** Maximum delivery attempts before the job is marked failed. Defaults to 3. */
|
|
1194
|
+
maxAttempts?: number;
|
|
1195
|
+
/**
|
|
1196
|
+
* If set, the job re-queues after every successful send and fires again
|
|
1197
|
+
* this many seconds later. Use for daily digests (`86400`), weekly
|
|
1198
|
+
* updates (`604800`), or any fixed-interval loop. `cancelScheduled(key)`
|
|
1199
|
+
* stops the loop.
|
|
1200
|
+
*/
|
|
1201
|
+
everySeconds?: number;
|
|
1202
|
+
}
|
|
1203
|
+
/** A single scheduled push job as returned by `listScheduled` / `getScheduled`. */
|
|
1204
|
+
interface ScheduledJob {
|
|
1205
|
+
jobId: string;
|
|
1206
|
+
key?: string;
|
|
1207
|
+
/** Next fire time — unix seconds. Convert with `new Date(scheduledFor * 1000)`. */
|
|
1208
|
+
scheduledFor: number;
|
|
1209
|
+
status: 'pending' | 'running' | 'succeeded' | 'failed';
|
|
1210
|
+
attempts: number;
|
|
1211
|
+
maxAttempts: number;
|
|
1212
|
+
lastError?: string;
|
|
1213
|
+
createdAt: number;
|
|
1214
|
+
updatedAt: number;
|
|
1215
|
+
/** Populated once the job has fired at least once. */
|
|
1216
|
+
sentAt?: number;
|
|
1217
|
+
/** Set when the job recurs — `schedule()` was called with `everySeconds`. */
|
|
1218
|
+
recurringIntervalSecs?: number;
|
|
1219
|
+
}
|
|
1220
|
+
/** Filter passed to `listScheduled`. */
|
|
1221
|
+
interface ListScheduledFilter {
|
|
1222
|
+
status?: 'pending' | 'running' | 'succeeded' | 'failed';
|
|
1223
|
+
limit?: number;
|
|
1224
|
+
offset?: number;
|
|
1225
|
+
}
|
|
1226
|
+
/** Counts by status, as returned by `queueStats`. */
|
|
1227
|
+
interface QueueStats {
|
|
1228
|
+
pending: number;
|
|
1229
|
+
running: number;
|
|
1230
|
+
succeeded: number;
|
|
1231
|
+
failed: number;
|
|
1232
|
+
}
|
|
1233
|
+
/** Outcome of a single `platform.push.send(...)` fan-out. */
|
|
1234
|
+
interface SendReport {
|
|
1235
|
+
attempted: number;
|
|
1236
|
+
succeeded: number;
|
|
1237
|
+
gone: number;
|
|
1238
|
+
failed: number;
|
|
1239
|
+
errors?: Array<{
|
|
1240
|
+
subscriptionId: string;
|
|
1241
|
+
message: string;
|
|
1242
|
+
}>;
|
|
1243
|
+
}
|
|
1244
|
+
/** Shape of a stored Web Push subscription. */
|
|
1245
|
+
interface StoredPushSubscription {
|
|
1246
|
+
id: string;
|
|
1247
|
+
provider: 'web-push' | 'apns' | 'fcm';
|
|
1248
|
+
endpoint: string;
|
|
1249
|
+
p256dh?: string | null;
|
|
1250
|
+
auth?: string | null;
|
|
1251
|
+
userId?: string | null;
|
|
1252
|
+
visitorId?: string | null;
|
|
1253
|
+
userAgent?: string | null;
|
|
1254
|
+
topics: string[];
|
|
1255
|
+
createdAt: number;
|
|
1256
|
+
lastSeenAt?: number | null;
|
|
1257
|
+
expiresAt?: number | null;
|
|
1258
|
+
isActive: boolean;
|
|
1259
|
+
}
|
|
1260
|
+
/** Aggregate counts across every subscription in the project. */
|
|
1261
|
+
interface SubscriptionCounts {
|
|
1262
|
+
total: number;
|
|
1263
|
+
byTopic: Array<[string, number]>;
|
|
1264
|
+
byProvider: Array<[string, number]>;
|
|
1265
|
+
}
|
|
1266
|
+
/** Public VAPID config for the current project. */
|
|
1267
|
+
interface PublicPushConfig {
|
|
1268
|
+
vapidPublic: string;
|
|
1269
|
+
contactEmail: string;
|
|
1270
|
+
updatedAt: number;
|
|
1271
|
+
}
|
|
1272
|
+
/**
|
|
1273
|
+
* Server-side Web Push service. Access via `platform.push` inside your
|
|
1274
|
+
* runtime code.
|
|
1275
|
+
*/
|
|
1276
|
+
interface PushService {
|
|
1277
|
+
/**
|
|
1278
|
+
* Fan out a notification to every active subscription matching `target`.
|
|
1279
|
+
* Blocks until every device has been tried.
|
|
1280
|
+
*/
|
|
1281
|
+
send(target: PushTarget, notification: NotificationPayload): Promise<SendReport>;
|
|
1282
|
+
/**
|
|
1283
|
+
* Fire-and-forget variant. The request handler can return immediately;
|
|
1284
|
+
* the dispatch continues in the background. Best-effort — a delivery
|
|
1285
|
+
* restart mid-dispatch loses in-flight sends.
|
|
1286
|
+
*/
|
|
1287
|
+
sendBackground(target: PushTarget, notification: NotificationPayload): Promise<void>;
|
|
1288
|
+
/**
|
|
1289
|
+
* Queue a notification for a future time. Idempotent by `key` — repeated
|
|
1290
|
+
* calls with the same key replace the prior pending job. Set `everySeconds`
|
|
1291
|
+
* for recurring digests.
|
|
1292
|
+
*/
|
|
1293
|
+
schedule(target: PushTarget, notification: NotificationPayload, opts: ScheduleOptions): Promise<{
|
|
1294
|
+
jobId: string;
|
|
1295
|
+
}>;
|
|
1296
|
+
/** Cancel the pending scheduled job with this idempotency key. */
|
|
1297
|
+
cancelScheduled(key: string): Promise<{
|
|
1298
|
+
canceled: number;
|
|
1299
|
+
}>;
|
|
1300
|
+
/** List scheduled jobs for this project, optionally filtered by status. */
|
|
1301
|
+
listScheduled(filter?: ListScheduledFilter): Promise<ScheduledJob[]>;
|
|
1302
|
+
/** Look up a single scheduled job by idempotency key. */
|
|
1303
|
+
getScheduled(key: string): Promise<ScheduledJob | null>;
|
|
1304
|
+
/** Per-status counts for the scheduled queue. */
|
|
1305
|
+
queueStats(): Promise<QueueStats>;
|
|
1306
|
+
/** List subscriptions — useful for admin UIs and debugging. */
|
|
1307
|
+
list(filter?: {
|
|
1308
|
+
topic?: string;
|
|
1309
|
+
userId?: string;
|
|
1310
|
+
visitorId?: string;
|
|
1311
|
+
onlyActive?: boolean;
|
|
1312
|
+
limit?: number;
|
|
1313
|
+
offset?: number;
|
|
1314
|
+
}): Promise<StoredPushSubscription[]>;
|
|
1315
|
+
/** Aggregate counts grouped by topic and provider. */
|
|
1316
|
+
counts(): Promise<SubscriptionCounts>;
|
|
1317
|
+
/** Remove a subscription by id. */
|
|
1318
|
+
unsubscribe(subscriptionId: string): Promise<void>;
|
|
1319
|
+
/** Remove a subscription by its push service endpoint URL. */
|
|
1320
|
+
unsubscribeByEndpoint(endpoint: string): Promise<void>;
|
|
1321
|
+
/** Fetch the project's current VAPID public key + contact email. */
|
|
1322
|
+
getVapidConfig(): Promise<PublicPushConfig>;
|
|
1323
|
+
/**
|
|
1324
|
+
* Rotate the project's VAPID keypair. **Every existing subscription
|
|
1325
|
+
* silently stops working** — browsers bind subscriptions to the key they
|
|
1326
|
+
* saw at subscribe time. Confirm with your users before calling.
|
|
1327
|
+
*/
|
|
1328
|
+
rotateVapidKeys(): Promise<PublicPushConfig>;
|
|
872
1329
|
}
|
|
873
1330
|
interface Platform {
|
|
874
1331
|
/** Environment containing all available platform services */
|
|
@@ -877,57 +1334,19 @@ interface Platform {
|
|
|
877
1334
|
media?: MediaService;
|
|
878
1335
|
/** Realtime service for pub/sub channels and presence */
|
|
879
1336
|
realtime: RealtimeService;
|
|
880
|
-
/** Auth service for end-user authentication and
|
|
1337
|
+
/** Auth service for end-user authentication, identity binding, and authorization checks */
|
|
881
1338
|
auth: AuthService;
|
|
1339
|
+
/** Per-request Layer 2 policy toggle (Layer 1 isolation always applies) */
|
|
1340
|
+
policy: PolicyService;
|
|
1341
|
+
/**
|
|
1342
|
+
* Web Push — send, schedule, or query browser push notifications for
|
|
1343
|
+
* logged-in users and anonymous visitors. Available when Push is enabled
|
|
1344
|
+
* in project settings; `undefined` when running against the dev-server
|
|
1345
|
+
* fallback that doesn't proxy to delivery.
|
|
1346
|
+
*/
|
|
1347
|
+
push?: PushService;
|
|
882
1348
|
}
|
|
883
1349
|
|
|
884
|
-
interface RenEvent {
|
|
885
|
-
t: string;
|
|
886
|
-
r: string;
|
|
887
|
-
k?: string;
|
|
888
|
-
v?: string;
|
|
889
|
-
ts?: number;
|
|
890
|
-
src?: string;
|
|
891
|
-
ns?: string;
|
|
892
|
-
ch?: string;
|
|
893
|
-
data?: any;
|
|
894
|
-
uid?: string;
|
|
895
|
-
[extra: string]: any;
|
|
896
|
-
}
|
|
897
|
-
interface RenClientOptions {
|
|
898
|
-
endpoint?: string;
|
|
899
|
-
subscriptions?: string[];
|
|
900
|
-
clientId?: string;
|
|
901
|
-
autoReconnect?: boolean;
|
|
902
|
-
maxBackoffMs?: number;
|
|
903
|
-
debug?: boolean;
|
|
904
|
-
}
|
|
905
|
-
type Listener = (event: RenEvent) => void;
|
|
906
|
-
declare class RenClient {
|
|
907
|
-
private endpoint;
|
|
908
|
-
private subs;
|
|
909
|
-
private clientId;
|
|
910
|
-
private listeners;
|
|
911
|
-
private es;
|
|
912
|
-
private closed;
|
|
913
|
-
private attempt;
|
|
914
|
-
private autoReconnect;
|
|
915
|
-
private maxBackoff;
|
|
916
|
-
private debug;
|
|
917
|
-
constructor(opts?: RenClientOptions);
|
|
918
|
-
private detectEndpoint;
|
|
919
|
-
private log;
|
|
920
|
-
private buildUrl;
|
|
921
|
-
private connect;
|
|
922
|
-
on(listener: Listener): () => void;
|
|
923
|
-
getClientId(): string;
|
|
924
|
-
close(): void;
|
|
925
|
-
}
|
|
926
|
-
declare function getOrCreateClientId(storage?: Storage): string;
|
|
927
|
-
declare function renFetch(input: string | URL | Request, init?: RequestInit, clientId?: string): Promise<Response>;
|
|
928
|
-
declare function storageUpload(path: string, file: Blob | File, clientId?: string): Promise<any>;
|
|
929
|
-
declare function storageDelete(path: string, clientId?: string): Promise<any>;
|
|
930
|
-
|
|
931
1350
|
interface RealtimeEvent {
|
|
932
1351
|
event: string;
|
|
933
1352
|
channel: string;
|
|
@@ -1241,4 +1660,4 @@ declare function getPlatform(options?: {
|
|
|
1241
1660
|
*/
|
|
1242
1661
|
declare function clearPlatformCache(): void;
|
|
1243
1662
|
|
|
1244
|
-
export { type AuthField, type AuthService, type AuthSession, type AuthUser, type Database, type DbFindOptions, type KvListResult, type KvNamespace, type LoginOptions, MediaLocalParticipant, type MediaParticipant, type MediaParticipantInfo, MediaRoom, MediaRoomEvent, type MediaRoomInfo, type MediaRoomInfoSettings, type MediaRoomOptions, type MediaService, type MediaTokenResult, type MediaTrackPublication, type Platform, type PlatformEnv, type PresenceMember, type PresenceService, RealtimeClient, type RealtimeClientOptions, type RealtimeEvent, type RealtimeService, type RegisterOptions, RemoteMediaService,
|
|
1663
|
+
export { type AuthCaller, type AuthField, type AuthService, type AuthSession, type AuthUser, type Database, type DbFindOptions, type IndexDescriptor, type IndexDirection, type IndexKind, type IndexSpec, type KvListResult, type KvNamespace, type ListScheduledFilter, type LoginOptions, MediaLocalParticipant, type MediaParticipant, type MediaParticipantInfo, MediaRoom, MediaRoomEvent, type MediaRoomInfo, type MediaRoomInfoSettings, type MediaRoomOptions, type MediaService, type MediaTokenResult, type MediaTrackPublication, type NotificationPayload, type Platform, type PlatformEnv, type PolicyService, type PresenceMember, type PresenceService, type PublicPushConfig, type PushService, type PushTarget, type QueueStats, RealtimeClient, type RealtimeClientOptions, type RealtimeEvent, type RealtimeService, type RegisterOptions, RemoteMediaService, type ScheduleOptions, type ScheduledJob, type SendReport, type Storage, type StoragePutStreamSource, type StoredPushSubscription, type SubscriptionCounts, type TrackKind, type TrackSource, type UpdateUserOptions, type UserListFilter, type UserListResponse, type VectorAggregation, type VectorIndexDescriptor, type VectorIndexSpec, type VectorMetric, type VectorQuery, type VectorQueryMode, type VectorQueryWithFilter, type VectorSearchHit, type VectorStorage, type VideoResolution, attachTrack, clearPlatformCache, detachTrack, getPlatform };
|