@relyio/sdk 0.7.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +61 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/{chunk-GYHAVYND.js → chunk-LGNJIGHL.js} +884 -16
- package/dist/{chunk-VH2DE7HZ.cjs → chunk-SPFRDXAF.cjs} +889 -15
- package/dist/client/index.cjs +3 -3
- package/dist/client/index.d.cts +5 -4
- package/dist/client/index.d.ts +5 -4
- package/dist/client/index.js +1 -1
- package/dist/{define-content-type-DiVpbwNs.d.cts → define-content-type-cEGjIwT5.d.cts} +205 -10
- package/dist/{define-content-type-DiVpbwNs.d.ts → define-content-type-cEGjIwT5.d.ts} +205 -10
- package/dist/{define-schema-C-5an28C.d.ts → define-schema-BPj2srgh.d.ts} +1 -1
- package/dist/{define-schema-D7MButVt.d.cts → define-schema-DgbJ5Kwn.d.cts} +1 -1
- package/dist/{index-M0X45k7J.d.cts → index-B9axQW8s.d.cts} +265 -14
- package/dist/{index-DbsTUw3Q.d.cts → index-B_rIWO_l.d.cts} +47 -5
- package/dist/{index-BOQIHnsh.d.ts → index-Cv4tmcrw.d.ts} +47 -5
- package/dist/{index-1G97sNA8.d.ts → index-GIfaMlQ7.d.ts} +265 -14
- package/dist/index.cjs +119 -75
- package/dist/index.d.cts +152 -41
- package/dist/index.d.ts +152 -41
- package/dist/index.js +37 -12
- package/dist/schema/index.d.cts +3 -3
- package/dist/schema/index.d.ts +3 -3
- package/dist/types/index.d.cts +2 -2
- package/dist/types/index.d.ts +2 -2
- package/package.json +1 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { aK as components, aJ as paths, W as InferContentType, aa as InferAssetType, a3 as InferSingleton } from './define-content-type-
|
|
3
|
-
import { a as SchemaDefinition, b as SchemaContentTypeNames, j as SchemaEntryOf, ay as FilterOperator, h as SchemaAssetTypeNames, c as SchemaSingletonNames, g as SchemaSettingsGroupNames, I as InferSettingsGroup, e as SchemaQueryNames, f as SchemaLocaleCodes } from './define-schema-
|
|
1
|
+
import { K as MergedRelyIOConfig, A as ApiPath, c as ApiMethod, N as PathParamsOf, w as ApiResponse, W as Wire, v as RequestConfig, B as BaseContent, h as WhereClause, Q as QueryOptions, j as SortOptions, k as ContentQueryResult, C as CreateInput, U as UpdateInput, S as SDKError, H as BaseValidationError, G as ValidationViolation, R as RelyIOConfig, a as RelyIOConfigUpdate } from './index-Cv4tmcrw.js';
|
|
2
|
+
import { aK as components, aJ as paths, W as InferContentType, aa as InferAssetType, a3 as InferSingleton } from './define-content-type-cEGjIwT5.js';
|
|
3
|
+
import { a as SchemaDefinition, b as SchemaContentTypeNames, j as SchemaEntryOf, ay as FilterOperator, h as SchemaAssetTypeNames, c as SchemaSingletonNames, g as SchemaSettingsGroupNames, I as InferSettingsGroup, e as SchemaQueryNames, f as SchemaLocaleCodes } from './define-schema-BPj2srgh.js';
|
|
4
|
+
import { VisitorResyncReason } from './live-visitor.js';
|
|
4
5
|
import { DevUnreadableReason } from './dev-handshake/index.js';
|
|
5
6
|
|
|
6
7
|
/**
|
|
@@ -301,11 +302,20 @@ declare class ContentQueryBuilder<T extends BaseContent = BaseContent, F extends
|
|
|
301
302
|
private requestHeaders?;
|
|
302
303
|
/** The client's locale, asked when the query is sent rather than copied when it was built. */
|
|
303
304
|
private readonly clientLocale;
|
|
305
|
+
private freshValue?;
|
|
304
306
|
/**
|
|
305
307
|
* @param locale - The client's locale (`withLocale()`, `updateConfig({ locale })`), sent when the
|
|
306
308
|
* query names none: the function `TypedRelyIOClient` hands over, or a locale fixed for it
|
|
307
309
|
*/
|
|
308
310
|
constructor(httpClient: HttpClient, contentType: string, locale?: ClientLocale);
|
|
311
|
+
/**
|
|
312
|
+
* The feed position this read follows — a change's `fresh` (`FeedChange`), or a resync's. Sent as
|
|
313
|
+
* `?_fresh`, the one term the API declares for it: no cache — the Content API's edge or the
|
|
314
|
+
* browser's own — holds an answer for that position from before it, so the read is answered after
|
|
315
|
+
* the change, and every read naming the same position shares that answer. The answer is the
|
|
316
|
+
* read's own; omit it for a read no change prompted.
|
|
317
|
+
*/
|
|
318
|
+
fresh(position: string): this;
|
|
309
319
|
/**
|
|
310
320
|
* Headers this query adds to the client's own, e.g. `X-RelyIO-Dataset` to list another dataset
|
|
311
321
|
* the key can see. A name the client already sends is replaced for this query only; the client
|
|
@@ -516,11 +526,20 @@ declare class ContentByIdBuilder<T extends BaseContent = BaseContent> {
|
|
|
516
526
|
private requestHeaders?;
|
|
517
527
|
/** The client's locale, asked when the read is sent rather than copied when it was built. */
|
|
518
528
|
private readonly clientLocale;
|
|
529
|
+
private freshValue?;
|
|
519
530
|
/**
|
|
520
531
|
* @param locale - The client's locale (`withLocale()`, `updateConfig({ locale })`), sent when the
|
|
521
532
|
* read names none: the function `TypedRelyIOClient` hands over, or a locale fixed for it
|
|
522
533
|
*/
|
|
523
534
|
constructor(httpClient: HttpClient, contentType: string, id: string, locale?: ClientLocale);
|
|
535
|
+
/**
|
|
536
|
+
* The feed position this read follows — a change's `fresh` (`FeedChange`), or a resync's. Sent as
|
|
537
|
+
* `?_fresh`, the one term the API declares for it: no cache — the Content API's edge or the
|
|
538
|
+
* browser's own — holds an answer for that position from before it, so the read is answered after
|
|
539
|
+
* the change, and every read naming the same position shares that answer. The answer is the
|
|
540
|
+
* read's own; omit it for a read no change prompted.
|
|
541
|
+
*/
|
|
542
|
+
fresh(position: string): this;
|
|
524
543
|
/**
|
|
525
544
|
* Include related content in the response
|
|
526
545
|
*/
|
|
@@ -1352,6 +1371,12 @@ interface SingletonFetchOptions {
|
|
|
1352
1371
|
locale?: string;
|
|
1353
1372
|
/** Reference fields to populate */
|
|
1354
1373
|
include?: string[];
|
|
1374
|
+
/**
|
|
1375
|
+
* The feed position this read follows — a change's `fresh` (`FeedChange`), or a resync's. Sent as
|
|
1376
|
+
* `?_fresh`: no cache holds an answer for it from before that position, so the read is answered
|
|
1377
|
+
* after the change. The answer is the read's own; omit it for a read no change prompted.
|
|
1378
|
+
*/
|
|
1379
|
+
fresh?: string;
|
|
1355
1380
|
}
|
|
1356
1381
|
/**
|
|
1357
1382
|
* Singleton client for managing singleton content operations
|
|
@@ -1738,6 +1763,7 @@ declare class SearchBuilder<T extends BaseContent = BaseContent, S extends AnySc
|
|
|
1738
1763
|
private query;
|
|
1739
1764
|
private searchOptions;
|
|
1740
1765
|
private requestHeaders?;
|
|
1766
|
+
private freshValue?;
|
|
1741
1767
|
/** The client's locale, asked when the query is sent rather than copied when it was built. */
|
|
1742
1768
|
private readonly clientLocale;
|
|
1743
1769
|
/**
|
|
@@ -1750,6 +1776,12 @@ declare class SearchBuilder<T extends BaseContent = BaseContent, S extends AnySc
|
|
|
1750
1776
|
* dataset the key can see. A name the client already sends is replaced for this search only.
|
|
1751
1777
|
*/
|
|
1752
1778
|
headers(headers: Record<string, string>): this;
|
|
1779
|
+
/**
|
|
1780
|
+
* The feed position this search follows — a change's `fresh` (`FeedChange`), or a resync's. Sent
|
|
1781
|
+
* as `?_fresh` on the query string beside the body: the edge keys a search on both, so no answer
|
|
1782
|
+
* it holds from before that position can answer it. The answer is the search's own.
|
|
1783
|
+
*/
|
|
1784
|
+
fresh(position: string): this;
|
|
1753
1785
|
/**
|
|
1754
1786
|
* Search within a single content type. Where a schema types the client, the name is one of its
|
|
1755
1787
|
* content types and the results are that type's entries.
|
|
@@ -2833,8 +2865,34 @@ type ChangesPageBody = PollChanges['responses'][200]['content']['application/jso
|
|
|
2833
2865
|
* item, and fails if it is ever `unknown` again.
|
|
2834
2866
|
*/
|
|
2835
2867
|
type Change = ChangesPageBody['data'][number];
|
|
2836
|
-
/**
|
|
2837
|
-
|
|
2868
|
+
/**
|
|
2869
|
+
* A change as `relyio.changes()` and `relyio.liveChanges()` deliver it: the document's
|
|
2870
|
+
* {@link Change}, and `fresh`.
|
|
2871
|
+
*
|
|
2872
|
+
* `fresh` is the feed position a refetch for this change names, as the one query term the API
|
|
2873
|
+
* declares on every read its edge may keep (`?_fresh`, `sdk-surfaces-spec.md` decision 32): hand it
|
|
2874
|
+
* to the read — `.fresh(change.fresh)` on `findById()`, `query()` and `search()`, `{ fresh }` to a
|
|
2875
|
+
* singleton's `fetch()`. A position no request named before the change is a key no cache holds a
|
|
2876
|
+
* body under, so the read is answered after the change — at the edge and in the browser, whether
|
|
2877
|
+
* or not the change's purge has reached them — and every later read naming it shares that answer.
|
|
2878
|
+
*
|
|
2879
|
+
* It is at or after the change, never before: on `/v1/changes` the change's own cursor, the ledger
|
|
2880
|
+
* row it came from; at the live edge the cursor of the batch it arrived in. It is not always
|
|
2881
|
+
* `cursor`: at the edge an earlier change of a batch carries the position **before** the batch as
|
|
2882
|
+
* its `cursor`, so a failure part-way through replays the batch, and a refetch naming that position
|
|
2883
|
+
* would be answered from before the change.
|
|
2884
|
+
*/
|
|
2885
|
+
type FeedChange = Change & {
|
|
2886
|
+
/** The feed position a refetch for this change names (`?_fresh`); at or after the change. */
|
|
2887
|
+
readonly fresh: string;
|
|
2888
|
+
};
|
|
2889
|
+
/**
|
|
2890
|
+
* Why a cursor could no longer be replayed, or why everything must be refetched. `/v1/changes`
|
|
2891
|
+
* names `retention` and `dataset-replaced`; the live edge's `feed.resync` may name any reason its
|
|
2892
|
+
* wire declares (`VisitorResyncReason` in `@relyio/api-contract`, read from there rather than
|
|
2893
|
+
* restated). `unknown` when the message named none.
|
|
2894
|
+
*/
|
|
2895
|
+
type ChangesExpiredReason = VisitorResyncReason | 'unknown';
|
|
2838
2896
|
/**
|
|
2839
2897
|
* `RESOURCE_EXPIRED` from the changes feed: the cursor names a position the
|
|
2840
2898
|
* ledger can no longer replay from (`INV-SS-CURSOR-REPLAYS`). The consumer
|
|
@@ -2843,12 +2901,28 @@ type ChangesExpiredReason = 'retention' | 'dataset-replaced' | 'unknown';
|
|
|
2843
2901
|
* A `ResourceExpiredError`, so code that already catches that still does. The
|
|
2844
2902
|
* refusal declares no details, so `reason` is read from the message the api
|
|
2845
2903
|
* writes (`apps/services/api/src/changes/changes-request.ts` `refusalOf`).
|
|
2904
|
+
*
|
|
2905
|
+
* The live edge's `feed.resync` — a socket's frame or a poll's answer — is the
|
|
2906
|
+
* same instruction and arrives as the same error ({@link ChangesExpiredError.resync}),
|
|
2907
|
+
* so `onExpired` means one thing on both transports.
|
|
2846
2908
|
*/
|
|
2847
2909
|
declare class ChangesExpiredError extends ResourceExpiredError {
|
|
2848
2910
|
readonly reason: ChangesExpiredReason;
|
|
2849
|
-
/**
|
|
2850
|
-
|
|
2851
|
-
|
|
2911
|
+
/**
|
|
2912
|
+
* The position the feed resynced to, which a refetch of everything names as `?_fresh`, as a
|
|
2913
|
+
* change's {@link FeedChange.fresh} is named: the head a `/v1/changes` resync took, or the cursor
|
|
2914
|
+
* the edge's `feed.resync` sent. `undefined` when there was no resync to take one — the error was
|
|
2915
|
+
* thrown (`onExpired: 'throw'`) — and on an error a caller built itself.
|
|
2916
|
+
*/
|
|
2917
|
+
readonly fresh: string | undefined;
|
|
2918
|
+
/** The base class's signature, so `withContext` can rebuild one; then the position resynced to. */
|
|
2919
|
+
constructor(message: string, statusCode?: number, cause?: Error, context?: Record<string, unknown>, fresh?: string);
|
|
2920
|
+
/** The base class rebuilds from its four arguments, which would drop the position resynced to. */
|
|
2921
|
+
withContext(context: Record<string, unknown>): this;
|
|
2922
|
+
/** `/v1/changes`' refusal, with the head the feed resynced to when it did. */
|
|
2923
|
+
static of(expired: ResourceExpiredError, fresh?: string): ChangesExpiredError;
|
|
2924
|
+
/** The live edge's `feed.resync`: refetch everything, then continue from the cursor it sent. */
|
|
2925
|
+
static resync(reason: VisitorResyncReason, cursor: string): ChangesExpiredError;
|
|
2852
2926
|
}
|
|
2853
2927
|
interface ChangesOptions {
|
|
2854
2928
|
/**
|
|
@@ -2882,15 +2956,152 @@ interface ChangesOptions {
|
|
|
2882
2956
|
* - a function — resync, and call it with the error once the new position is
|
|
2883
2957
|
* taken and before any change after it is yielded. This is the observable
|
|
2884
2958
|
* form: whatever the consumer derived from the feed may be stale, so the
|
|
2885
|
-
* function is where it invalidates everything
|
|
2959
|
+
* function is where it invalidates everything — naming the error's `fresh`,
|
|
2960
|
+
* the new position, on every refetch. The iterator waits for it.
|
|
2886
2961
|
*/
|
|
2887
2962
|
onExpired?: 'throw' | 'resync' | ((expired: ChangesExpiredError) => void | Promise<void>);
|
|
2963
|
+
/**
|
|
2964
|
+
* Called once, when the feed was opened without `since`, with the position it starts from: the
|
|
2965
|
+
* first poll's answer, the dataset's head — before the next poll is sent. Read what you show
|
|
2966
|
+
* **after** it and a write your read did not see is after the position, so this feed delivers it,
|
|
2967
|
+
* with no second request to take the position first (`changesHead()` is that request) (REL-1513).
|
|
2968
|
+
*
|
|
2969
|
+
* `followChanges()` passes it (`ChangeSourceOptions.reached`), so a feed that drops before its first
|
|
2970
|
+
* change reopens from there rather than re-reading everything. Never called with a later empty
|
|
2971
|
+
* page's cursor: filtered, that cursor is past rows the filter hid, and a caller that widens the
|
|
2972
|
+
* filter must not reopen from it.
|
|
2973
|
+
*/
|
|
2974
|
+
reached?: (cursor: string) => void;
|
|
2888
2975
|
}
|
|
2889
2976
|
interface ChangesHeadOptions {
|
|
2890
2977
|
/** Cancels the request; the promise then rejects. */
|
|
2891
2978
|
signal?: AbortSignal;
|
|
2892
2979
|
}
|
|
2893
2980
|
|
|
2981
|
+
/**
|
|
2982
|
+
* `relyio.liveChanges()` — a dataset's published changes at RelyIO's live edge, for a publishable key
|
|
2983
|
+
* (`live-layer-spec.md` decision 20; LV5.2, REL-1158).
|
|
2984
|
+
*
|
|
2985
|
+
* The wire is `@relyio/api-contract`'s `live-visitor.ts`, read from there and never restated: the
|
|
2986
|
+
* path and query names, the frames and their reader, the keepalive, the poll's answer and its reader,
|
|
2987
|
+
* the poll interval, and what each close code and each refused poll means a client does next.
|
|
2988
|
+
*
|
|
2989
|
+
* **One open, two ways in.** A subscription opens a WebSocket to the edge. Where it cannot — the
|
|
2990
|
+
* runtime has no `WebSocket` (Node 18 and 20), constructing one throws, the socket fails before it
|
|
2991
|
+
* opens (a network that blocks sockets), or it has not opened and been caught up within
|
|
2992
|
+
* {@link LIVE_SOCKET_OPEN_TIMEOUT_MS} (a network that holds it) — it polls the edge instead, from the
|
|
2993
|
+
* same cursor, about every {@link VISITOR_POLL_INTERVAL_MS}, and tries a socket again about once a
|
|
2994
|
+
* minute. Both carry one cursor space, so a switch either way loses nothing.
|
|
2995
|
+
*
|
|
2996
|
+
* **Where it starts.** Without `since`, the edge answers the dataset's current position before
|
|
2997
|
+
* anything else — the socket's `feed.opened`, or the first poll's answer — and the subscription hands
|
|
2998
|
+
* it to `reached`. That call is the position, with no request of its own for it: a read sent after it
|
|
2999
|
+
* is answered at or after the position, and every change after it is delivered here, so a publish the
|
|
3000
|
+
* read did not see is announced (REL-1513). The edge counts the subscription as one live connection,
|
|
3001
|
+
* whichever way in it took (`INV-LV-LIVE-IS-METERED`).
|
|
3002
|
+
*
|
|
3003
|
+
* **It ends only when its signal aborts, and throws every other end** — a socket closed by a refusal
|
|
3004
|
+
* or a deploy, a refused poll, a keepalive nobody answered — as a `LiveEdgeError` saying what to do
|
|
3005
|
+
* next, so `followChanges()` reconnects, backs off or stops by the edge's own tables. That loop is
|
|
3006
|
+
* the one reconnect policy (`INV-SS-ONE-CORE`, REL-1215); this module keeps no back-off of its own.
|
|
3007
|
+
*
|
|
3008
|
+
* **Cursors.** The edge sends one cursor after a batch of changes. The last change of a batch carries
|
|
3009
|
+
* it; each earlier one carries the position before the batch, so a failure part-way through a batch
|
|
3010
|
+
* replays the whole batch rather than skipping its rest. Delivery is at-least-once: a replay and the
|
|
3011
|
+
* live frames after it may name one change twice, and a refetch makes a repeat cost a read, never a
|
|
3012
|
+
* wrong view (`INV-SS-CHANGE-IS-IDS`).
|
|
3013
|
+
*
|
|
3014
|
+
* **What a refetch names.** Every change of a batch carries the batch's own cursor as `fresh`
|
|
3015
|
+
* (`FeedChange`), the position its refetch names as `?_fresh` — not `cursor`, which for an earlier
|
|
3016
|
+
* change is the position before the batch: the previous batch's refetches were answered under that
|
|
3017
|
+
* one, before this batch, and a cache would hand the same answer back. A `feed.resync`'s error
|
|
3018
|
+
* carries the cursor it sent the same way.
|
|
3019
|
+
*/
|
|
3020
|
+
|
|
3021
|
+
/**
|
|
3022
|
+
* How often an open socket sends the keepalive, which the edge's runtime answers without waking the
|
|
3023
|
+
* feed — the Studio's dataset room sends its own on the same interval. A socket that has heard
|
|
3024
|
+
* nothing by the next one, not even the answer, is presumed dead and reconnected: a client that only
|
|
3025
|
+
* receives never learns otherwise that a network change dropped its connection.
|
|
3026
|
+
*/
|
|
3027
|
+
declare const LIVE_KEEPALIVE_INTERVAL_MS = 30000;
|
|
3028
|
+
/**
|
|
3029
|
+
* How long a socket has to open and be caught up — the feed's `feed.opened` — before the subscription
|
|
3030
|
+
* stops waiting on it, closes it and polls instead, as it does for a socket that fails before it opens
|
|
3031
|
+
* (REL-1513).
|
|
3032
|
+
*
|
|
3033
|
+
* The poll interval, because that is what a socket is for: telling the page sooner than a poll would.
|
|
3034
|
+
* A poll is answered at once and polled again within this interval, so a socket that has not caught
|
|
3035
|
+
* up by then has already served the page worse than polling would have. It is well past a healthy
|
|
3036
|
+
* open — the door's checks and one ledger read at the edge — and half the keepalive's verdict on an
|
|
3037
|
+
* open socket that has gone quiet ({@link LIVE_KEEPALIVE_INTERVAL_MS}, twice). It bounds how long
|
|
3038
|
+
* `<RelyIOProvider live>`'s first reads wait for a position on a network that neither opens a socket
|
|
3039
|
+
* nor refuses one — a proxy that holds the upgrade — which without it they would wait on for as long
|
|
3040
|
+
* as the page is open.
|
|
3041
|
+
*/
|
|
3042
|
+
declare const LIVE_SOCKET_OPEN_TIMEOUT_MS = 15000;
|
|
3043
|
+
interface LiveChangesOptions {
|
|
3044
|
+
/**
|
|
3045
|
+
* A change's cursor from an earlier subscription. Omitted, the edge answers the dataset's current
|
|
3046
|
+
* position first and replays nothing, and the subscription hands that position to `reached` before
|
|
3047
|
+
* anything after it. Read what you show **after** that first call — a read sent before it, from a
|
|
3048
|
+
* subscription opened afterwards without `since`, leaves a publish between the two that neither
|
|
3049
|
+
* sees (REL-1513). With `followChanges()`, which hands the source its own `reached`, call both —
|
|
3050
|
+
* and let the read go if the loop fails first, so content never waits on a feed that is down:
|
|
3051
|
+
*
|
|
3052
|
+
* ```ts
|
|
3053
|
+
* let positioned!: () => void
|
|
3054
|
+
* const position = new Promise<void>(resolve => (positioned = resolve))
|
|
3055
|
+
* const following = followChanges(
|
|
3056
|
+
* from =>
|
|
3057
|
+
* relyio.liveChanges({
|
|
3058
|
+
* ...from,
|
|
3059
|
+
* ids: [id],
|
|
3060
|
+
* reached: cursor => {
|
|
3061
|
+
* from.reached(cursor)
|
|
3062
|
+
* positioned()
|
|
3063
|
+
* },
|
|
3064
|
+
* }),
|
|
3065
|
+
* { signal, onChange, onResync, onState: state => state.kind !== 'following' && positioned() },
|
|
3066
|
+
* )
|
|
3067
|
+
* await position
|
|
3068
|
+
* const post = await relyio.content('post').findById(id).execute()
|
|
3069
|
+
* ```
|
|
3070
|
+
*
|
|
3071
|
+
* The wait is bounded: a socket that has not opened and been told its position within
|
|
3072
|
+
* {@link LIVE_SOCKET_OPEN_TIMEOUT_MS} is given up for a poll, answered at once.
|
|
3073
|
+
*/
|
|
3074
|
+
since?: string;
|
|
3075
|
+
/** Content types to keep. Omitted keeps every type; an empty list is refused. At most 50. */
|
|
3076
|
+
types?: readonly string[];
|
|
3077
|
+
/** Entry ids to keep. Omitted keeps every entry; an empty list is refused. At most 100. */
|
|
3078
|
+
ids?: readonly string[];
|
|
3079
|
+
/**
|
|
3080
|
+
* Ends the subscription. An abort — while connected, while polling, or between polls — makes the
|
|
3081
|
+
* `for await` **complete**, with the socket closed, no further request and nothing thrown.
|
|
3082
|
+
*/
|
|
3083
|
+
signal?: AbortSignal;
|
|
3084
|
+
/**
|
|
3085
|
+
* What to do when the edge says to refetch everything (`feed.resync`: the cursor is too old, was
|
|
3086
|
+
* never this dataset's, or the dataset was replaced) — as `relyio.changes()` takes it: `'throw'`
|
|
3087
|
+
* (default) throws a `ChangesExpiredError`, `'resync'` carries on from the edge's position, and a
|
|
3088
|
+
* function is awaited with the error before any change after that position is yielded.
|
|
3089
|
+
*/
|
|
3090
|
+
onExpired?: ChangesOptions['onExpired'];
|
|
3091
|
+
/**
|
|
3092
|
+
* Called when the edge has the subscription in hand — its `feed.opened` frame, or an answered
|
|
3093
|
+
* poll. `followChanges()` passes it to reset its back-off; see `ChangeSourceOptions.opened`.
|
|
3094
|
+
*/
|
|
3095
|
+
opened?: () => void;
|
|
3096
|
+
/**
|
|
3097
|
+
* Called with a position reached without a change to carry it. `followChanges()` passes it so a
|
|
3098
|
+
* connection dropped before its first change reconnects from there; see
|
|
3099
|
+
* `ChangeSourceOptions.reached`. Without `since`, its first call is the position the subscription
|
|
3100
|
+
* starts from (see `since`).
|
|
3101
|
+
*/
|
|
3102
|
+
reached?: (cursor: string) => void;
|
|
3103
|
+
}
|
|
3104
|
+
|
|
2894
3105
|
/**
|
|
2895
3106
|
* The key's project, as `GET /v1/project` describes it: organization, project, dataset and branch,
|
|
2896
3107
|
* each by id and name, and `studioUrl` — the Studio root the preview toolbar deep-links from
|
|
@@ -2952,6 +3163,8 @@ declare class TypedRelyIOClient<TSchema extends AnySchemaDefinition | undefined
|
|
|
2952
3163
|
* locale, or none after `locale: null` (REL-1453).
|
|
2953
3164
|
*/
|
|
2954
3165
|
private readonly currentLocale;
|
|
3166
|
+
/** The live edge's poll client id: chosen once, when first needed, and kept for this client's life. */
|
|
3167
|
+
private _liveClientId;
|
|
2955
3168
|
constructor(config: TypedClientConfig<TSchema>);
|
|
2956
3169
|
/**
|
|
2957
3170
|
* Get the schema definition
|
|
@@ -3114,13 +3327,15 @@ declare class TypedRelyIOClient<TSchema extends AnySchemaDefinition | undefined
|
|
|
3114
3327
|
* Lazy — nothing is requested until the first `next()`. It runs until
|
|
3115
3328
|
* `signal` aborts, which ends the `for await` cleanly rather than throwing.
|
|
3116
3329
|
* A change names what changed; refetch it through the ordinary read path
|
|
3117
|
-
* (`INV-SS-CHANGE-IS-IDS`)
|
|
3330
|
+
* (`INV-SS-CHANGE-IS-IDS`), naming its `fresh` so no cache answers with the
|
|
3331
|
+
* body from before it (`FeedChange`).
|
|
3118
3332
|
*
|
|
3119
3333
|
* @example
|
|
3120
3334
|
* ```typescript
|
|
3121
3335
|
* const controller = new AbortController()
|
|
3122
3336
|
* for await (const change of relyio.changes({ since: cursor, types: ['post'], signal: controller.signal })) {
|
|
3123
|
-
* // { entryId, contentType, locale, kind, cursor }
|
|
3337
|
+
* // { entryId, contentType, locale, kind, cursor, fresh }
|
|
3338
|
+
* await relyio.content(change.contentType).findById(change.entryId).fresh(change.fresh).execute()
|
|
3124
3339
|
* }
|
|
3125
3340
|
* ```
|
|
3126
3341
|
*
|
|
@@ -3128,11 +3343,47 @@ declare class TypedRelyIOClient<TSchema extends AnySchemaDefinition | undefined
|
|
|
3128
3343
|
* ```typescript
|
|
3129
3344
|
* for await (const change of relyio.changes({
|
|
3130
3345
|
* since: cursor,
|
|
3131
|
-
* onExpired: async
|
|
3346
|
+
* onExpired: async expired => refetchEverything(expired.fresh),
|
|
3132
3347
|
* })) { … }
|
|
3133
3348
|
* ```
|
|
3134
3349
|
*/
|
|
3135
|
-
changes(options?: ChangesOptions): AsyncIterable<
|
|
3350
|
+
changes(options?: ChangesOptions): AsyncIterable<FeedChange>;
|
|
3351
|
+
/**
|
|
3352
|
+
* Follow the dataset's **published** changes at RelyIO's live edge, with a publishable key
|
|
3353
|
+
* (`rly_pub_…`): each change as ids, in order — the transport a browser follows changes with.
|
|
3354
|
+
*
|
|
3355
|
+
* A WebSocket to the edge, from `since` or the dataset's current position; where a socket cannot
|
|
3356
|
+
* open — the runtime has none, the network refuses it, or it has not opened and been told its
|
|
3357
|
+
* position within `LIVE_SOCKET_OPEN_TIMEOUT_MS` — it polls the edge instead, about every fifteen
|
|
3358
|
+
* seconds, from the same cursor. The edge is `liveUrl`, or derived from the default `baseUrl`
|
|
3359
|
+
* (see `RelyIOConfig.liveUrl`).
|
|
3360
|
+
*
|
|
3361
|
+
* Without `since` it starts at the dataset's current position, which it hands `reached` before
|
|
3362
|
+
* anything after it: read what you show after that call, and a publish your read did not see is
|
|
3363
|
+
* one this subscription announces (see `LiveChangesOptions.since`).
|
|
3364
|
+
*
|
|
3365
|
+
* One subscription ends only when `signal` aborts, which ends the `for await` cleanly; every other
|
|
3366
|
+
* end — a socket a deploy dropped, a refusal, a refused poll — is thrown as a `LiveEdgeError`
|
|
3367
|
+
* that says whether to stop, retry or back off. Hand it to `followChanges()`, the one loop that
|
|
3368
|
+
* reconnects from the last cursor with jittered back-off and honours those answers:
|
|
3369
|
+
*
|
|
3370
|
+
* @example
|
|
3371
|
+
* ```typescript
|
|
3372
|
+
* const relyio = createClient({ apiKey: 'rly_pub_…' })
|
|
3373
|
+
* const controller = new AbortController()
|
|
3374
|
+
* await followChanges(from => relyio.liveChanges({ ...from, types: ['post'] }), {
|
|
3375
|
+
* signal: controller.signal,
|
|
3376
|
+
* // `fresh` names a position no cache holds a body for from before the change.
|
|
3377
|
+
* onChange: change =>
|
|
3378
|
+
* relyio.content(change.contentType).findById(change.entryId).fresh(change.fresh).execute(),
|
|
3379
|
+
* onResync: resync => refetchEverything(resync.cause === 'expired' ? resync.expired.fresh : undefined),
|
|
3380
|
+
* })
|
|
3381
|
+
* ```
|
|
3382
|
+
*
|
|
3383
|
+
* A client without a publishable key sends nothing: a secret or preview key is never put in the
|
|
3384
|
+
* edge's URL. On a server, follow `changes()` with it instead.
|
|
3385
|
+
*/
|
|
3386
|
+
liveChanges(options?: LiveChangesOptions): AsyncIterable<FeedChange>;
|
|
3136
3387
|
/**
|
|
3137
3388
|
* The dataset's current position in the changes feed, as a cursor to start
|
|
3138
3389
|
* `changes({ since })` or `followChanges(…, { since })` from. One
|
|
@@ -3414,4 +3665,4 @@ declare function createClient<TSchema extends AnySchemaDefinition>(config: Typed
|
|
|
3414
3665
|
*/
|
|
3415
3666
|
type ClientSchema<T extends TypedRelyIOClient<AnySchemaDefinition>> = T extends TypedRelyIOClient<infer TSchema> ? TSchema : never;
|
|
3416
3667
|
|
|
3417
|
-
export {
|
|
3668
|
+
export { type BatchOptions as $, type ActiveSandbox as A, type SearchMode as B, type Change as C, type SearchResultItem as D, type ExtendedQueryResult as E, type FeedChange as F, type SearchHitMetadata as G, HttpClient as H, type SearchResponse as I, type AutocompleteSuggestion as J, type AutocompleteResponse as K, LIVE_KEEPALIVE_INTERVAL_MS as L, type SimilarResult as M, type SimilarResponse as N, type SearchFilter as O, type Project as P, type SearchFields as Q, type Register as R, type SandboxState as S, TypedRelyIOClient as T, type SearchSort as U, type SearchTypeName as V, type SearchEntry as W, BatchClient as X, BatchBuilder as Y, type BatchMethod as Z, type BatchOperation as _, ChangesExpiredError as a, type BatchOperationResult as a0, type BatchSummary as a1, type BatchResponse as a2, AdhocQueryClient as a3, AdhocQueryBuilder as a4, type FetchBlock as a5, type AggregateBlock as a6, type AggregateMetric as a7, type SearchBlock as a8, type FilterValue as a9, type MultipartCreateResult as aA, type MultipartPart as aB, type MultipartTarget as aC, type UploadProgress as aD, ResourceNotFoundError as aE, ResourceConflictError as aF, ResourceExpiredError as aG, isResourceNotFound as aH, type FileErrorCode as aI, type FileUploadErrorCode as aJ, FileUploadError as aK, FileValidationError as aL, type FileValidationConstraints as aM, validateFile as aN, type FullTextConfig as aa, type AdhocQueryDefinition as ab, type AdhocQueryOptions as ac, type QueryMetadata as ad, type AdhocQueryResult as ae, AssetClient as af, AssetFileBuilder as ag, AssetUploadBuilder as ah, isAssetEntry as ai, type AssetVisibility as aj, type FileStatus as ak, type FileBackend as al, type AssetFileBlock as am, type AssetFileExtracted as an, type FileStatusResult as ao, type AssetUrls as ap, type AssetEntryResponse as aq, type PopulatedAssetReference as ar, type PresignInput as as, type PresignResult as at, type ConfirmInput as au, type ConfirmResult as av, type ResolveUrlInput as aw, type ResolveUrlResult as ax, type CreateAssetOptions as ay, type WaitUntilReadyOptions as az, type ChangesExpiredReason as b, createClient as c, type TypedClientConfig as d, type ClientSchema as e, type RegisteredSchema as f, type SendOptions as g, entityTagOf as h, type ConditionalWriteOptions as i, type RetryableWriteOptions as j, type ChangesHeadOptions as k, type ChangesOptions as l, LIVE_SOCKET_OPEN_TIMEOUT_MS as m, type LiveChangesOptions as n, ContentClient as o, SingletonClient as p, SettingsClient as q, ContentQueryBuilder as r, ContentByIdBuilder as s, type ChildrenOptions as t, type SingletonFetchOptions as u, type SettingsFetchOptions as v, SearchClient as w, SearchBuilder as x, AutocompleteBuilder as y, SimilarBuilder as z };
|