@relyio/sdk 0.2.1 → 0.4.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.
Files changed (39) hide show
  1. package/CHANGELOG.md +116 -0
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/{chunk-RJBIJ2ZK.js → chunk-43VPZT2G.js} +496 -103
  4. package/dist/chunk-BBUB7C2Z.js +81 -0
  5. package/dist/{chunk-FJK7ZWKK.cjs → chunk-HAQELDZN.cjs} +156 -221
  6. package/dist/chunk-LSRPMNPT.cjs +89 -0
  7. package/dist/{chunk-7W4MJXQ4.cjs → chunk-XS32U2UP.cjs} +497 -102
  8. package/dist/{chunk-2QUK2ZGD.js → chunk-XY5KFEFY.js} +157 -219
  9. package/dist/client/index.cjs +4 -3
  10. package/dist/client/index.d.cts +4 -3
  11. package/dist/client/index.d.ts +4 -3
  12. package/dist/client/index.js +2 -1
  13. package/dist/define-content-type-CBfnTWSS.d.cts +716 -0
  14. package/dist/define-content-type-CBfnTWSS.d.ts +716 -0
  15. package/dist/{define-schema-DHvUCKwj.d.cts → define-schema-2xbHgtK-.d.cts} +63 -726
  16. package/dist/{define-schema-DHvUCKwj.d.ts → define-schema-DzYXk4HL.d.ts} +63 -726
  17. package/dist/dev-handshake/index.cjs +37 -0
  18. package/dist/dev-handshake/index.d.cts +144 -0
  19. package/dist/dev-handshake/index.d.ts +144 -0
  20. package/dist/dev-handshake/index.js +4 -0
  21. package/dist/{index-DGWaawHt.d.cts → index-BvO6HDtY.d.cts} +237 -12
  22. package/dist/{index-B-KiFHbx.d.ts → index-BzOFJJKS.d.ts} +237 -12
  23. package/dist/{index-BsUqCAu8.d.cts → index-DFehx5sI.d.cts} +749 -2160
  24. package/dist/{index-BsUqCAu8.d.ts → index-FDak5ofk.d.ts} +749 -2160
  25. package/dist/index.cjs +120 -70
  26. package/dist/index.d.cts +136 -55
  27. package/dist/index.d.ts +136 -55
  28. package/dist/index.js +45 -3
  29. package/dist/schema/index.cjs +35 -47
  30. package/dist/schema/index.d.cts +3 -2
  31. package/dist/schema/index.d.ts +3 -2
  32. package/dist/schema/index.js +1 -1
  33. package/dist/types/index.d.cts +2 -1
  34. package/dist/types/index.d.ts +2 -1
  35. package/package.json +15 -19
  36. package/dist/react/index.cjs +0 -4
  37. package/dist/react/index.d.cts +0 -2
  38. package/dist/react/index.d.ts +0 -2
  39. package/dist/react/index.js +0 -3
package/dist/index.d.cts CHANGED
@@ -1,9 +1,10 @@
1
- export { N as AdhocAggregateBlock, M as AdhocFetchBlock, L as AdhocQueryBuilder, K as AdhocQueryClient, W as AdhocQueryDefinition, X as AdhocQueryOptions, Z as AdhocQueryResult, P as AdhocSearchBlock, Q as AdhocSimilarBlock, O as AggregateMetric, _ as AssetClient, a8 as AssetEntryResponse, a5 as AssetFileBlock, $ as AssetFileBuilder, a6 as AssetFileExtracted, a0 as AssetUploadBuilder, a7 as AssetUrls, a2 as AssetVisibility, A as AutocompleteBuilder, t as AutocompleteResponse, s as AutocompleteSuggestion, y as BatchBuilder, B as BatchClient, z as BatchMethod, D as BatchOperation, G as BatchOperationResult, F as BatchOptions, J as BatchResponse, I as BatchSummary, j as ChildrenOptions, C as ClientSchema, b as ConditionalWriteOptions, ac as ConfirmInput, ad as ConfirmResult, i as ContentByIdBuilder, d as ContentClient, h as ContentQueryBuilder, ag as CreateAssetOptions, E as ExtendedQueryResult, a4 as FileBackend, am as FileErrorCode, a3 as FileStatus, an as FileUploadError, ap as FileValidationConstraints, ao as FileValidationError, U as FilterValue, V as FullTextConfig, H as HttpClient, ai as MultipartCreateResult, aj as MultipartPart, ak as MultipartTarget, a9 as PopulatedAssetReference, aa as PresignInput, ab as PresignResult, Y as QueryMetadata, ae as ResolveUrlInput, af as ResolveUrlResult, R as RetryableWriteOptions, n as SearchBuilder, m as SearchClient, x as SearchFields, w as SearchFilter, p as SearchMode, r as SearchResponse, q as SearchResultItem, S as SendOptions, g as SettingsClient, l as SettingsFetchOptions, o as SimilarBuilder, v as SimilarResponse, u as SimilarResult, f as SingletonClient, k as SingletonFetchOptions, a as TypedClientConfig, T as TypedRelyIOClient, al as UploadProgress, ah as WaitUntilReadyOptions, c as createClient, c as default, e as entityTagOf, a1 as isAssetEntry, aq as validateFile } from './index-DGWaawHt.cjs';
1
+ export { W as AdhocAggregateBlock, V as AdhocFetchBlock, U as AdhocQueryBuilder, Q as AdhocQueryClient, a0 as AdhocQueryDefinition, a1 as AdhocQueryOptions, a3 as AdhocQueryResult, Y as AdhocSearchBlock, Z as AdhocSimilarBlock, X as AggregateMetric, a4 as AssetClient, ae as AssetEntryResponse, ab as AssetFileBlock, a5 as AssetFileBuilder, ac as AssetFileExtracted, a6 as AssetUploadBuilder, ad as AssetUrls, a8 as AssetVisibility, A as AutocompleteBuilder, z as AutocompleteResponse, y as AutocompleteSuggestion, J as BatchBuilder, I as BatchClient, K as BatchMethod, L as BatchOperation, N as BatchOperationResult, M as BatchOptions, P as BatchResponse, O as BatchSummary, h as Change, g as ChangesExpiredError, j as ChangesExpiredReason, i as ChangesOptions, p as ChildrenOptions, C as ClientSchema, d as ConditionalWriteOptions, ai as ConfirmInput, aj as ConfirmResult, o as ContentByIdBuilder, k as ContentClient, n as ContentQueryBuilder, am as CreateAssetOptions, E as ExtendedQueryResult, aa as FileBackend, aw as FileErrorCode, a9 as FileStatus, ax as FileUploadError, az as FileValidationConstraints, ay as FileValidationError, _ as FilterValue, $ as FullTextConfig, H as HttpClient, ao as MultipartCreateResult, ap as MultipartPart, aq as MultipartTarget, af as PopulatedAssetReference, ag as PresignInput, ah as PresignResult, a2 as QueryMetadata, R as Register, b as RegisteredSchema, ak as ResolveUrlInput, al as ResolveUrlResult, at as ResourceConflictError, au as ResourceExpiredError, as as ResourceNotFoundError, f as RetryableWriteOptions, t as SearchBuilder, s as SearchClient, G as SearchFields, F as SearchFilter, v as SearchMode, x as SearchResponse, w as SearchResultItem, S as SendOptions, m as SettingsClient, r as SettingsFetchOptions, u as SimilarBuilder, D as SimilarResponse, B as SimilarResult, l as SingletonClient, q as SingletonFetchOptions, a as TypedClientConfig, T as TypedRelyIOClient, ar as UploadProgress, an as WaitUntilReadyOptions, c as createClient, c as default, e as entityTagOf, a7 as isAssetEntry, av as isResourceNotFound, aA as validateFile } from './index-BvO6HDtY.cjs';
2
2
  export { fields } from './schema/index.cjs';
3
- import { S as SDKError } from './index-BsUqCAu8.cjs';
4
- export { a as ApiMethod, A as ApiPath, r as ApiResponse, b as ApiSuccessBody, B as BaseContent, v as BaseValidationError, o as CacheConfig, t as CacheStrategy, f as ContentQueryResult, j as ContentTypeSchema, C as CreateInput, i as CustomQuery, D as DebugConfig, E as Environment, k as FieldOptions, F as FieldTypeName, z as InvalidFieldTypeError, I as InvalidPayloadError, L as LogLevel, P as PerformanceMetrics, Q as QueryOptions, p as RealtimeConfig, m as RealtimeEvent, l as RealtimeEventType, R as RelyIOConfig, q as RequestConfig, y as RequiredFieldError, s as RetryConfig, x as SchemaValidationError, h as SettingsGroup, g as SingletonContent, e as SortOptions, n as SubscriptionOptions, U as UpdateInput, w as ValidationError, V as ValidationRule, u as ValidationViolation, c as WhereClause, d as WhereOperator, W as Wire } from './index-BsUqCAu8.cjs';
3
+ import { S as SDKError, B as BaseContent } from './index-DFehx5sI.cjs';
4
+ export { a as ApiMethod, A as ApiPath, t as ApiResponse, b as ApiSuccessBody, x as BaseValidationError, q as CacheConfig, v as CacheStrategy, g as ContentQueryResult, k as ContentTypeSchema, C as CreateInput, j as CustomQuery, D as DebugConfig, E as Environment, l as FieldOptions, F as FieldTypeName, H as InvalidFieldTypeError, I as InvalidPayloadError, L as LogLevel, M as MatchRouteOptions, P as PerformanceMetrics, Q as QueryOptions, r as RealtimeConfig, o as RealtimeEvent, n as RealtimeEventType, R as RelyIOConfig, s as RequestConfig, G as RequiredFieldError, u as RetryConfig, c as RouteMatch, z as SchemaValidationError, i as SettingsGroup, h as SingletonContent, f as SortOptions, p as SubscriptionOptions, U as UpdateInput, y as ValidationError, V as ValidationRule, w as ValidationViolation, d as WhereClause, e as WhereOperator, W as Wire, m as matchRoute } from './index-DFehx5sI.cjs';
5
5
  export { camelToSnake, createDeferred, debounce, deepClone, generateId, isBrowser, isNode, isPlainObject, isValidEmail, isValidUrl, mergeDeep, omit, pick, retry, sleep, snakeToCamel, throttle, toSafeString } from './utils/index.cjs';
6
- export { bv as AggregateBlock, ap as AssetTypeConfig, as as AssetTypeDefinition, n as BaseFieldConfig, ae as ComponentConfig, af as ComponentDefinition, ag as ComponentMetadata, a1 as ContentTypeConfig, a2 as ContentTypeConfigWithFields, a3 as ContentTypeConfigWithFieldsets, a4 as ContentTypeDefinition, a5 as EntryMetadata, bu as FetchBlock, c as FieldDefinition, b as FieldRule, o as FieldType, F as FieldUIConfig, a0 as Fieldset, aw as FileKindConfig, aK as FileScanConfig, aJ as FileUploadConfig, bF as FilterDefinition, aC as ImageExifConfig, au as ImageKindConfig, aB as ImageSourceConfig, aA as ImageUploadConfig, bD as IncludeDefinition, at as InferAssetType, a6 as InferContentType, bL as InferQueryParams, bK as InferQueryResponse, ac as InferSingleton, ab as InferSingletonContentType, L as LocalizationConfig, bs as QueryConfig, bt as QueryDefinition, K as SchemaAssetTypeNames, w as SchemaConfig, y as SchemaContentTypeNames, x as SchemaDefinition, H as SchemaLocaleCodes, G as SchemaQueryNames, J as SchemaSettingsGroupNames, z as SchemaSingletonNames, bw as SearchBlock, bE as SelectMapping, ak as SettingsGroupConfig, al as SettingsGroupDefinition, bx as SimilarBlock, a9 as SingletonContentTypeDefinition, aa as SingletonMetadata, bB as SortCondition, aD as VariantDefinition, aG as VideoCaptionsConfig, aH as VideoDownloadConfig, av as VideoKindConfig, aF as VideoPosterConfig, aE as VideoUploadConfig, aI as VideoWatermarkConfig, by as WhereCondition, ao as defineAssetType, ad as defineComponent, _ as defineContentType, br as defineQuery, u as defineSchema, aj as defineSettingsGroup, a8 as defineSingleton, a7 as defineSingletonContentType, $ as fieldset, v as schemaToJSON } from './define-schema-DHvUCKwj.cjs';
6
+ export { ax as AggregateBlock, G as AssetTypeConfig, K as AssetTypeDefinition, C as ComponentConfig, v as ComponentDefinition, w as ComponentMetadata, aw as FetchBlock, O as FileKindConfig, a3 as FileScanConfig, a2 as FileUploadConfig, aH as FilterDefinition, X as ImageExifConfig, N as ImageKindConfig, W as ImageSourceConfig, U as ImageUploadConfig, aF as IncludeDefinition, M as InferAssetType, aR as InferQueryParams, aQ as InferQueryResponse, t as InferSingleton, I as InferSingletonContentType, au as QueryConfig, av as QueryDefinition, h as SchemaAssetTypeNames, S as SchemaConfig, b as SchemaContentTypeNames, a as SchemaDefinition, f as SchemaLocaleCodes, e as SchemaQueryNames, g as SchemaSettingsGroupNames, c as SchemaSingletonNames, ay as SearchBlock, aG as SelectMapping, A as SettingsGroupConfig, B as SettingsGroupDefinition, az as SimilarBlock, r as SingletonContentTypeDefinition, s as SingletonMetadata, aD as SortCondition, Y as VariantDefinition, $ as VideoCaptionsConfig, a0 as VideoDownloadConfig, V as VideoKindConfig, _ as VideoPosterConfig, Z as VideoUploadConfig, a1 as VideoWatermarkConfig, aA as WhereCondition, F as defineAssetType, u as defineComponent, at as defineQuery, d as defineSchema, z as defineSettingsGroup, q as defineSingleton, p as defineSingletonContentType } from './define-schema-2xbHgtK-.cjs';
7
+ export { n as BaseFieldConfig, x as ContentTypeConfig, y as ContentTypeConfigWithFields, z as ContentTypeConfigWithFieldsets, G as ContentTypeDefinition, H as EntryMetadata, c as FieldDefinition, b as FieldRule, o as FieldType, F as FieldUIConfig, w as Fieldset, J as InferContentType, K as LocalePublicationFields, L as LocalizationConfig, u as defineContentType, v as fieldset } from './define-content-type-CBfnTWSS.cjs';
7
8
 
8
9
  /**
9
10
  * Network-related errors
@@ -56,47 +57,6 @@ declare class InvalidApiKeyError extends SDKError {
56
57
  getUserMessage(): string;
57
58
  }
58
59
 
59
- /**
60
- * Content and resource errors.
61
- *
62
- * `ContentTypeNotFoundError` and `ContentNotFoundError` were deleted at API5.
63
- * The mapper reached them by sniffing `CONTENT_TYPE_NOT_FOUND` and
64
- * `CONTENT_NOT_FOUND`, neither of which is in the closed vocabulary, so neither
65
- * class was reachable. Both cases are `RESOURCE_NOT_FOUND`, whose declared
66
- * `details` are `{ kind, id? }` — the same two facts, from the one code a route
67
- * can actually declare.
68
- */
69
- declare class ResourceNotFoundError extends SDKError {
70
- readonly code = "RESOURCE_NOT_FOUND";
71
- readonly retryable = false;
72
- constructor(message?: string, statusCode?: number, cause?: Error, context?: Record<string, unknown>);
73
- getUserMessage(): string;
74
- }
75
- declare class ResourceConflictError extends SDKError {
76
- readonly code = "RESOURCE_CONFLICT";
77
- readonly retryable = false;
78
- constructor(message?: string, statusCode?: number, cause?: Error, context?: Record<string, unknown>);
79
- getUserMessage(): string;
80
- }
81
- declare class ResourceExpiredError extends SDKError {
82
- readonly code = "RESOURCE_EXPIRED";
83
- readonly retryable = false;
84
- constructor(message?: string, statusCode?: number, cause?: Error, context?: Record<string, unknown>);
85
- getUserMessage(): string;
86
- }
87
- /**
88
- * "Did the service say this resource does not exist?"
89
- *
90
- * Reads the **code**, not the status. Four contract codes are 4xx on a read and
91
- * only one of them means "not there"; the incumbent checked `statusCode === 404`
92
- * on the thrown value, and a second arm duck-typed a plain object for the same
93
- * number so a hand-written test double would pass. Both are the branch
94
- * `INV-API-CLIENT-IS-DERIVED` forbids where a code exists — and the second one
95
- * only existed because the tests faked the boundary (rule 20). They now stub
96
- * `fetch`, so the double is gone with the branch.
97
- */
98
- declare function isResourceNotFound(error: unknown): boolean;
99
-
100
60
  /**
101
61
  * One class per contract code that had none.
102
62
  *
@@ -152,16 +112,23 @@ declare class UsageQuotaExceededError extends SDKError {
152
112
  /**
153
113
  * `RATE_LIMIT_EXCEEDED` — too many requests in the window.
154
114
  *
155
- * The one refusal the SDK's own retry loop acts on. `resetAt` and `limit` are
156
- * optional because the IP window can fill neither honestly, which is the same
157
- * decision the service made about its `X-RateLimit-*` headers at API0c.
115
+ * `resetAt` and `limit` are optional because the IP window can fill neither
116
+ * honestly, which is the same decision the service made about its
117
+ * `X-RateLimit-*` headers at API0c.
118
+ *
119
+ * `retryAfterMs` is the third and most direct of the three, and it comes from
120
+ * the response **headers** rather than the refusal body — which is why it has
121
+ * to be threaded in rather than read off `details`. The retry policy prefers it
122
+ * over `resetAt` and both over its own backoff.
158
123
  */
159
124
  declare class RateLimitError extends SDKError {
160
125
  readonly code = "RATE_LIMIT_EXCEEDED";
161
126
  readonly retryable = true;
162
127
  readonly limit?: number;
163
128
  readonly resetAt?: string;
164
- constructor(message?: string, limit?: number, resetAt?: string, context?: Record<string, unknown>);
129
+ /** `Retry-After`, in milliseconds, where the response carried a readable one. */
130
+ readonly retryAfterMs?: number;
131
+ constructor(message?: string, limit?: number, resetAt?: string, context?: Record<string, unknown>, retryAfterMs?: number);
165
132
  getUserMessage(): string;
166
133
  }
167
134
  /** `METHOD_NOT_ALLOWED` — the route exists and does not serve this verb. */
@@ -195,12 +162,23 @@ declare class TransactionRolledBackError extends SDKError {
195
162
  * `SERVICE_INDETERMINATE` — a dependency the service needed to decide was
196
163
  * unreachable, so it answered "I could not tell" rather than "no"
197
164
  * (`INV-AC-INDETERMINATE-IS-AN-OUTAGE`). Retryable: it is an outage.
165
+ *
166
+ * **Retryable is not the same as replayable.** "Could not decide" means the
167
+ * write may already have landed, so the retry policy sends this one again only
168
+ * where the request was replay-safe to begin with — an idempotent verb, or a
169
+ * request carrying `Idempotency-Key`.
170
+ *
171
+ * `refuse()` in `@relyio/api-contract` will not serialize this code without a
172
+ * `Retry-After` header, so `retryAfterMs` is populated on every one of these
173
+ * that reaches the SDK through a RelyIO service.
198
174
  */
199
175
  declare class ServiceIndeterminateError extends SDKError {
200
176
  readonly code = "SERVICE_INDETERMINATE";
201
177
  readonly retryable = true;
202
178
  readonly missing?: string;
203
- constructor(message?: string, missing?: string, context?: Record<string, unknown>);
179
+ /** `Retry-After`, in milliseconds. The contract requires the header on this code. */
180
+ readonly retryAfterMs?: number;
181
+ constructor(message?: string, missing?: string, context?: Record<string, unknown>, retryAfterMs?: number);
204
182
  getUserMessage(): string;
205
183
  }
206
184
  /** `INTERNAL_ERROR` — everything a client can only log (Decision 3). */
@@ -267,10 +245,6 @@ declare class ErrorMapper {
267
245
  * Check if an error is retryable
268
246
  */
269
247
  static isRetryable(error: Error): boolean;
270
- /**
271
- * Extract retry delay from error
272
- */
273
- static getRetryDelay(_error: Error): number;
274
248
  }
275
249
 
276
250
  /**
@@ -484,6 +458,113 @@ declare const localeHelpers: {
484
458
  getAllLocalizedValues: typeof getAllLocalizedValues;
485
459
  };
486
460
 
461
+ /**
462
+ * The DOM↔field binding contract, as the one pure helper that emits it.
463
+ *
464
+ * Spread onto the element that renders a field, it stamps which entry, content type, field and
465
+ * locale produced that element, so an editing surface can find the field by scanning the DOM
466
+ * rather than by guessing (`INV-TB-BINDING`). The contract is `toolbar-spec.md` §DOM↔field; this
467
+ * file is its only implementation.
468
+ *
469
+ * **Frozen** (`INV-SS-BINDING-FROZEN`). The attribute set is exactly the five below. Adding,
470
+ * renaming or dropping one is a new contract, and a new contract is a bump of `data-relyio-v` — a
471
+ * page built against version 1 keeps being read as version 1 by any surface that scans it.
472
+ *
473
+ * **Pure** (`INV-TB-SDK-PURE`). It reads the entry it is handed and returns attributes. It imports
474
+ * nothing but the SDK's own types: no realtime, no AI, no first-party code, no framework. That is
475
+ * what lets it live in the customer SDK and run on a server render as happily as in a browser.
476
+ *
477
+ * **Every value comes from the entry.** The id, the content type and the locale are the ones the
478
+ * API reported in `_metadata` — the locale is the one the payload's field values were composed
479
+ * for. There is deliberately no `locale` argument: a caller-supplied locale could bind a node to a
480
+ * locale whose value it is not rendering, which is the silently inferred binding `INV-TB-BINDING`
481
+ * forbids.
482
+ */
483
+
484
+ /** The version of the binding contract this helper emits. */
485
+ declare const BINDING_VERSION = "1";
486
+ /** The attributes `relyioField` returns — the whole of binding contract version 1. */
487
+ interface RelyIOFieldAttributes {
488
+ /** The entry's id (`_metadata.id`). */
489
+ readonly 'data-relyio-entry': string;
490
+ /** The entry's content type (`_metadata.type`); every customer read is keyed by it. */
491
+ readonly 'data-relyio-type': string;
492
+ /** The field the element renders. */
493
+ readonly 'data-relyio-field': string;
494
+ /** The locale the entry's field values were composed for (`_metadata.locale`). */
495
+ readonly 'data-relyio-locale': string;
496
+ /** The binding contract's version. */
497
+ readonly 'data-relyio-v': typeof BINDING_VERSION;
498
+ }
499
+ /**
500
+ * The field names `relyioField` accepts for an entry of type `T`.
501
+ *
502
+ * A schema-typed entry narrows to its declared field names, so they autocomplete and a misspelt
503
+ * one does not compile. An entry with no declared fields — `BaseContent`, which is what an
504
+ * un-generated client returns — has none to narrow to, and `keyof` of it is `never`; that would
505
+ * make the helper uncallable for every untyped customer, so it accepts any field name instead.
506
+ */
507
+ type RelyIOFieldName<T extends BaseContent> = [Exclude<keyof T, '_metadata'>] extends [never] ? string : string & Exclude<keyof T, '_metadata'>;
508
+ /**
509
+ * Binding attributes for one field of one entry.
510
+ *
511
+ * @example
512
+ * ```tsx
513
+ * import { relyioField } from '@relyio/sdk'
514
+ *
515
+ * <h1 {...relyioField(post, 'title')}>{post.title}</h1>
516
+ * // → data-relyio-entry="6710f…" data-relyio-type="post" data-relyio-field="title"
517
+ * // data-relyio-locale="en-US" data-relyio-v="1"
518
+ * ```
519
+ *
520
+ * @throws {TypeError} when the entry's `_metadata` lacks its id, content type or locale. Every
521
+ * entry the API returns carries all three, so this is reached only by a value that was not read
522
+ * from RelyIO. It throws rather than emitting a partial binding: a node stamped with no locale, or
523
+ * none at all, is a binding a surface would have to guess the rest of.
524
+ */
525
+ declare function relyioField<T extends BaseContent>(entry: T, field: RelyIOFieldName<T>): RelyIOFieldAttributes;
526
+
527
+ /**
528
+ * The DOM event a preview surface dispatches when content on the page has changed, and the one
529
+ * spelling of its name (`sdk-surfaces-spec.md` decision 23: the toolbar emits, the framework
530
+ * listens).
531
+ *
532
+ * It is the same kind of seam as the binding attributes beside it: a string both sides read from the
533
+ * core, so the preview toolbar needs no Next dependency and `@relyio/next`'s `<RelyIORefresh />`
534
+ * needs no toolbar dependency. Neither restates the name.
535
+ *
536
+ * **Dispatched on `window`.** Listeners subscribe with
537
+ * `window.addEventListener(RELYIO_CHANGE_EVENT, …)`; the toolbar renders inside a shadow root, and
538
+ * `window` is the one target both sides reach without knowing where the other is mounted.
539
+ *
540
+ * **The name is a wire contract.** A page can run a toolbar and a framework package released at
541
+ * different times, so renaming it silently disconnects them. The `detail` a dispatch carries is
542
+ * the preview toolbar's to declare (SS4); a listener that only refreshes reads none of it.
543
+ */
544
+ declare const RELYIO_CHANGE_EVENT = "relyio:change";
545
+
546
+ /**
547
+ * The width ladder the delivery Worker snaps every rendered dimension to
548
+ * (`INV-SS-ONE-LADDER`, sdk-surfaces-spec decision 14).
549
+ *
550
+ * A dimension is clamped to a ceiling and snapped to a bucket, so "any width"
551
+ * cannot become "unboundedly many distinct transforms". A client that asks the
552
+ * Worker for `w=749` is served the `w=700` render anyway; snapping on this side
553
+ * first means an image loader emits the URL the edge cache already holds.
554
+ *
555
+ * This is a **copy**, and deliberately so: the core cannot import
556
+ * `@relyio/storage` or the Worker. `apps/edge/cdn/src/__tests__/ladder-parity.test.ts`
557
+ * holds the two equal — the constants, and what the Worker actually renders for
558
+ * a sweep of requested widths — so a divergence fails the gate rather than a
559
+ * cache.
560
+ */
561
+ declare const IMAGE_LADDER: {
562
+ readonly maxDimension: 5000;
563
+ readonly bucket: 100;
564
+ };
565
+ /** Clamp to the ceiling, then snap to the nearest bucket — never below one bucket. */
566
+ declare function snapToLadder(value: number): number;
567
+
487
568
  /**
488
569
  * RelyIO SDK - Main Entry Point
489
570
  *
@@ -520,4 +601,4 @@ declare const localeHelpers: {
520
601
 
521
602
  declare const VERSION = "__VERSION__";
522
603
 
523
- export { AuthenticationError, AuthorizationError, ConnectionError, ErrorMapper, InvalidApiKeyError, type LanguageSwitcherOption, type LanguageSwitcherOptions, type LocaleMetadata, type LocaleStatus, type LocalizedEntry, MethodNotAllowedError, MissingApiKeyError, NetworkError, PayloadTooLargeError, PlanFeatureUnavailableError, RateLimitError, ReadOnlyKeyError, ResourceConflictError, ResourceExpiredError, ResourceNotFoundError, SDKError, ServerError, ServiceIndeterminateError, TimeoutError, TransactionRolledBackError, type TranslationCompleteness, UnknownContractError, UsageQuotaExceededError, VERSION, buildLanguageSwitcher, estimateTranslationCompleteness, getAllLocalizedValues, getAvailableLocaleCodes, getDefaultLocale, getFallbackFields, getFieldFallbackLocale, getLocalizedField, getPublishedLocaleCodes, getRequestedLocale, hasLocale, isFieldFallback, isPublishedInLocale, isResourceNotFound, localeHelpers, needsTranslation };
604
+ export { AuthenticationError, AuthorizationError, BaseContent, ConnectionError, ErrorMapper, IMAGE_LADDER, InvalidApiKeyError, type LanguageSwitcherOption, type LanguageSwitcherOptions, type LocaleMetadata, type LocaleStatus, type LocalizedEntry, MethodNotAllowedError, MissingApiKeyError, NetworkError, PayloadTooLargeError, PlanFeatureUnavailableError, RELYIO_CHANGE_EVENT, RateLimitError, ReadOnlyKeyError, type RelyIOFieldAttributes, type RelyIOFieldName, SDKError, ServerError, ServiceIndeterminateError, TimeoutError, TransactionRolledBackError, type TranslationCompleteness, UnknownContractError, UsageQuotaExceededError, VERSION, buildLanguageSwitcher, estimateTranslationCompleteness, getAllLocalizedValues, getAvailableLocaleCodes, getDefaultLocale, getFallbackFields, getFieldFallbackLocale, getLocalizedField, getPublishedLocaleCodes, getRequestedLocale, hasLocale, isFieldFallback, isPublishedInLocale, localeHelpers, needsTranslation, relyioField, snapToLadder };
package/dist/index.d.ts CHANGED
@@ -1,9 +1,10 @@
1
- export { N as AdhocAggregateBlock, M as AdhocFetchBlock, L as AdhocQueryBuilder, K as AdhocQueryClient, W as AdhocQueryDefinition, X as AdhocQueryOptions, Z as AdhocQueryResult, P as AdhocSearchBlock, Q as AdhocSimilarBlock, O as AggregateMetric, _ as AssetClient, a8 as AssetEntryResponse, a5 as AssetFileBlock, $ as AssetFileBuilder, a6 as AssetFileExtracted, a0 as AssetUploadBuilder, a7 as AssetUrls, a2 as AssetVisibility, A as AutocompleteBuilder, t as AutocompleteResponse, s as AutocompleteSuggestion, y as BatchBuilder, B as BatchClient, z as BatchMethod, D as BatchOperation, G as BatchOperationResult, F as BatchOptions, J as BatchResponse, I as BatchSummary, j as ChildrenOptions, C as ClientSchema, b as ConditionalWriteOptions, ac as ConfirmInput, ad as ConfirmResult, i as ContentByIdBuilder, d as ContentClient, h as ContentQueryBuilder, ag as CreateAssetOptions, E as ExtendedQueryResult, a4 as FileBackend, am as FileErrorCode, a3 as FileStatus, an as FileUploadError, ap as FileValidationConstraints, ao as FileValidationError, U as FilterValue, V as FullTextConfig, H as HttpClient, ai as MultipartCreateResult, aj as MultipartPart, ak as MultipartTarget, a9 as PopulatedAssetReference, aa as PresignInput, ab as PresignResult, Y as QueryMetadata, ae as ResolveUrlInput, af as ResolveUrlResult, R as RetryableWriteOptions, n as SearchBuilder, m as SearchClient, x as SearchFields, w as SearchFilter, p as SearchMode, r as SearchResponse, q as SearchResultItem, S as SendOptions, g as SettingsClient, l as SettingsFetchOptions, o as SimilarBuilder, v as SimilarResponse, u as SimilarResult, f as SingletonClient, k as SingletonFetchOptions, a as TypedClientConfig, T as TypedRelyIOClient, al as UploadProgress, ah as WaitUntilReadyOptions, c as createClient, c as default, e as entityTagOf, a1 as isAssetEntry, aq as validateFile } from './index-B-KiFHbx.js';
1
+ export { W as AdhocAggregateBlock, V as AdhocFetchBlock, U as AdhocQueryBuilder, Q as AdhocQueryClient, a0 as AdhocQueryDefinition, a1 as AdhocQueryOptions, a3 as AdhocQueryResult, Y as AdhocSearchBlock, Z as AdhocSimilarBlock, X as AggregateMetric, a4 as AssetClient, ae as AssetEntryResponse, ab as AssetFileBlock, a5 as AssetFileBuilder, ac as AssetFileExtracted, a6 as AssetUploadBuilder, ad as AssetUrls, a8 as AssetVisibility, A as AutocompleteBuilder, z as AutocompleteResponse, y as AutocompleteSuggestion, J as BatchBuilder, I as BatchClient, K as BatchMethod, L as BatchOperation, N as BatchOperationResult, M as BatchOptions, P as BatchResponse, O as BatchSummary, h as Change, g as ChangesExpiredError, j as ChangesExpiredReason, i as ChangesOptions, p as ChildrenOptions, C as ClientSchema, d as ConditionalWriteOptions, ai as ConfirmInput, aj as ConfirmResult, o as ContentByIdBuilder, k as ContentClient, n as ContentQueryBuilder, am as CreateAssetOptions, E as ExtendedQueryResult, aa as FileBackend, aw as FileErrorCode, a9 as FileStatus, ax as FileUploadError, az as FileValidationConstraints, ay as FileValidationError, _ as FilterValue, $ as FullTextConfig, H as HttpClient, ao as MultipartCreateResult, ap as MultipartPart, aq as MultipartTarget, af as PopulatedAssetReference, ag as PresignInput, ah as PresignResult, a2 as QueryMetadata, R as Register, b as RegisteredSchema, ak as ResolveUrlInput, al as ResolveUrlResult, at as ResourceConflictError, au as ResourceExpiredError, as as ResourceNotFoundError, f as RetryableWriteOptions, t as SearchBuilder, s as SearchClient, G as SearchFields, F as SearchFilter, v as SearchMode, x as SearchResponse, w as SearchResultItem, S as SendOptions, m as SettingsClient, r as SettingsFetchOptions, u as SimilarBuilder, D as SimilarResponse, B as SimilarResult, l as SingletonClient, q as SingletonFetchOptions, a as TypedClientConfig, T as TypedRelyIOClient, ar as UploadProgress, an as WaitUntilReadyOptions, c as createClient, c as default, e as entityTagOf, a7 as isAssetEntry, av as isResourceNotFound, aA as validateFile } from './index-BzOFJJKS.js';
2
2
  export { fields } from './schema/index.js';
3
- import { S as SDKError } from './index-BsUqCAu8.js';
4
- export { a as ApiMethod, A as ApiPath, r as ApiResponse, b as ApiSuccessBody, B as BaseContent, v as BaseValidationError, o as CacheConfig, t as CacheStrategy, f as ContentQueryResult, j as ContentTypeSchema, C as CreateInput, i as CustomQuery, D as DebugConfig, E as Environment, k as FieldOptions, F as FieldTypeName, z as InvalidFieldTypeError, I as InvalidPayloadError, L as LogLevel, P as PerformanceMetrics, Q as QueryOptions, p as RealtimeConfig, m as RealtimeEvent, l as RealtimeEventType, R as RelyIOConfig, q as RequestConfig, y as RequiredFieldError, s as RetryConfig, x as SchemaValidationError, h as SettingsGroup, g as SingletonContent, e as SortOptions, n as SubscriptionOptions, U as UpdateInput, w as ValidationError, V as ValidationRule, u as ValidationViolation, c as WhereClause, d as WhereOperator, W as Wire } from './index-BsUqCAu8.js';
3
+ import { S as SDKError, B as BaseContent } from './index-FDak5ofk.js';
4
+ export { a as ApiMethod, A as ApiPath, t as ApiResponse, b as ApiSuccessBody, x as BaseValidationError, q as CacheConfig, v as CacheStrategy, g as ContentQueryResult, k as ContentTypeSchema, C as CreateInput, j as CustomQuery, D as DebugConfig, E as Environment, l as FieldOptions, F as FieldTypeName, H as InvalidFieldTypeError, I as InvalidPayloadError, L as LogLevel, M as MatchRouteOptions, P as PerformanceMetrics, Q as QueryOptions, r as RealtimeConfig, o as RealtimeEvent, n as RealtimeEventType, R as RelyIOConfig, s as RequestConfig, G as RequiredFieldError, u as RetryConfig, c as RouteMatch, z as SchemaValidationError, i as SettingsGroup, h as SingletonContent, f as SortOptions, p as SubscriptionOptions, U as UpdateInput, y as ValidationError, V as ValidationRule, w as ValidationViolation, d as WhereClause, e as WhereOperator, W as Wire, m as matchRoute } from './index-FDak5ofk.js';
5
5
  export { camelToSnake, createDeferred, debounce, deepClone, generateId, isBrowser, isNode, isPlainObject, isValidEmail, isValidUrl, mergeDeep, omit, pick, retry, sleep, snakeToCamel, throttle, toSafeString } from './utils/index.js';
6
- export { bv as AggregateBlock, ap as AssetTypeConfig, as as AssetTypeDefinition, n as BaseFieldConfig, ae as ComponentConfig, af as ComponentDefinition, ag as ComponentMetadata, a1 as ContentTypeConfig, a2 as ContentTypeConfigWithFields, a3 as ContentTypeConfigWithFieldsets, a4 as ContentTypeDefinition, a5 as EntryMetadata, bu as FetchBlock, c as FieldDefinition, b as FieldRule, o as FieldType, F as FieldUIConfig, a0 as Fieldset, aw as FileKindConfig, aK as FileScanConfig, aJ as FileUploadConfig, bF as FilterDefinition, aC as ImageExifConfig, au as ImageKindConfig, aB as ImageSourceConfig, aA as ImageUploadConfig, bD as IncludeDefinition, at as InferAssetType, a6 as InferContentType, bL as InferQueryParams, bK as InferQueryResponse, ac as InferSingleton, ab as InferSingletonContentType, L as LocalizationConfig, bs as QueryConfig, bt as QueryDefinition, K as SchemaAssetTypeNames, w as SchemaConfig, y as SchemaContentTypeNames, x as SchemaDefinition, H as SchemaLocaleCodes, G as SchemaQueryNames, J as SchemaSettingsGroupNames, z as SchemaSingletonNames, bw as SearchBlock, bE as SelectMapping, ak as SettingsGroupConfig, al as SettingsGroupDefinition, bx as SimilarBlock, a9 as SingletonContentTypeDefinition, aa as SingletonMetadata, bB as SortCondition, aD as VariantDefinition, aG as VideoCaptionsConfig, aH as VideoDownloadConfig, av as VideoKindConfig, aF as VideoPosterConfig, aE as VideoUploadConfig, aI as VideoWatermarkConfig, by as WhereCondition, ao as defineAssetType, ad as defineComponent, _ as defineContentType, br as defineQuery, u as defineSchema, aj as defineSettingsGroup, a8 as defineSingleton, a7 as defineSingletonContentType, $ as fieldset, v as schemaToJSON } from './define-schema-DHvUCKwj.js';
6
+ export { ax as AggregateBlock, G as AssetTypeConfig, K as AssetTypeDefinition, C as ComponentConfig, v as ComponentDefinition, w as ComponentMetadata, aw as FetchBlock, O as FileKindConfig, a3 as FileScanConfig, a2 as FileUploadConfig, aH as FilterDefinition, X as ImageExifConfig, N as ImageKindConfig, W as ImageSourceConfig, U as ImageUploadConfig, aF as IncludeDefinition, M as InferAssetType, aR as InferQueryParams, aQ as InferQueryResponse, t as InferSingleton, I as InferSingletonContentType, au as QueryConfig, av as QueryDefinition, h as SchemaAssetTypeNames, S as SchemaConfig, b as SchemaContentTypeNames, a as SchemaDefinition, f as SchemaLocaleCodes, e as SchemaQueryNames, g as SchemaSettingsGroupNames, c as SchemaSingletonNames, ay as SearchBlock, aG as SelectMapping, A as SettingsGroupConfig, B as SettingsGroupDefinition, az as SimilarBlock, r as SingletonContentTypeDefinition, s as SingletonMetadata, aD as SortCondition, Y as VariantDefinition, $ as VideoCaptionsConfig, a0 as VideoDownloadConfig, V as VideoKindConfig, _ as VideoPosterConfig, Z as VideoUploadConfig, a1 as VideoWatermarkConfig, aA as WhereCondition, F as defineAssetType, u as defineComponent, at as defineQuery, d as defineSchema, z as defineSettingsGroup, q as defineSingleton, p as defineSingletonContentType } from './define-schema-DzYXk4HL.js';
7
+ export { n as BaseFieldConfig, x as ContentTypeConfig, y as ContentTypeConfigWithFields, z as ContentTypeConfigWithFieldsets, G as ContentTypeDefinition, H as EntryMetadata, c as FieldDefinition, b as FieldRule, o as FieldType, F as FieldUIConfig, w as Fieldset, J as InferContentType, K as LocalePublicationFields, L as LocalizationConfig, u as defineContentType, v as fieldset } from './define-content-type-CBfnTWSS.js';
7
8
 
8
9
  /**
9
10
  * Network-related errors
@@ -56,47 +57,6 @@ declare class InvalidApiKeyError extends SDKError {
56
57
  getUserMessage(): string;
57
58
  }
58
59
 
59
- /**
60
- * Content and resource errors.
61
- *
62
- * `ContentTypeNotFoundError` and `ContentNotFoundError` were deleted at API5.
63
- * The mapper reached them by sniffing `CONTENT_TYPE_NOT_FOUND` and
64
- * `CONTENT_NOT_FOUND`, neither of which is in the closed vocabulary, so neither
65
- * class was reachable. Both cases are `RESOURCE_NOT_FOUND`, whose declared
66
- * `details` are `{ kind, id? }` — the same two facts, from the one code a route
67
- * can actually declare.
68
- */
69
- declare class ResourceNotFoundError extends SDKError {
70
- readonly code = "RESOURCE_NOT_FOUND";
71
- readonly retryable = false;
72
- constructor(message?: string, statusCode?: number, cause?: Error, context?: Record<string, unknown>);
73
- getUserMessage(): string;
74
- }
75
- declare class ResourceConflictError extends SDKError {
76
- readonly code = "RESOURCE_CONFLICT";
77
- readonly retryable = false;
78
- constructor(message?: string, statusCode?: number, cause?: Error, context?: Record<string, unknown>);
79
- getUserMessage(): string;
80
- }
81
- declare class ResourceExpiredError extends SDKError {
82
- readonly code = "RESOURCE_EXPIRED";
83
- readonly retryable = false;
84
- constructor(message?: string, statusCode?: number, cause?: Error, context?: Record<string, unknown>);
85
- getUserMessage(): string;
86
- }
87
- /**
88
- * "Did the service say this resource does not exist?"
89
- *
90
- * Reads the **code**, not the status. Four contract codes are 4xx on a read and
91
- * only one of them means "not there"; the incumbent checked `statusCode === 404`
92
- * on the thrown value, and a second arm duck-typed a plain object for the same
93
- * number so a hand-written test double would pass. Both are the branch
94
- * `INV-API-CLIENT-IS-DERIVED` forbids where a code exists — and the second one
95
- * only existed because the tests faked the boundary (rule 20). They now stub
96
- * `fetch`, so the double is gone with the branch.
97
- */
98
- declare function isResourceNotFound(error: unknown): boolean;
99
-
100
60
  /**
101
61
  * One class per contract code that had none.
102
62
  *
@@ -152,16 +112,23 @@ declare class UsageQuotaExceededError extends SDKError {
152
112
  /**
153
113
  * `RATE_LIMIT_EXCEEDED` — too many requests in the window.
154
114
  *
155
- * The one refusal the SDK's own retry loop acts on. `resetAt` and `limit` are
156
- * optional because the IP window can fill neither honestly, which is the same
157
- * decision the service made about its `X-RateLimit-*` headers at API0c.
115
+ * `resetAt` and `limit` are optional because the IP window can fill neither
116
+ * honestly, which is the same decision the service made about its
117
+ * `X-RateLimit-*` headers at API0c.
118
+ *
119
+ * `retryAfterMs` is the third and most direct of the three, and it comes from
120
+ * the response **headers** rather than the refusal body — which is why it has
121
+ * to be threaded in rather than read off `details`. The retry policy prefers it
122
+ * over `resetAt` and both over its own backoff.
158
123
  */
159
124
  declare class RateLimitError extends SDKError {
160
125
  readonly code = "RATE_LIMIT_EXCEEDED";
161
126
  readonly retryable = true;
162
127
  readonly limit?: number;
163
128
  readonly resetAt?: string;
164
- constructor(message?: string, limit?: number, resetAt?: string, context?: Record<string, unknown>);
129
+ /** `Retry-After`, in milliseconds, where the response carried a readable one. */
130
+ readonly retryAfterMs?: number;
131
+ constructor(message?: string, limit?: number, resetAt?: string, context?: Record<string, unknown>, retryAfterMs?: number);
165
132
  getUserMessage(): string;
166
133
  }
167
134
  /** `METHOD_NOT_ALLOWED` — the route exists and does not serve this verb. */
@@ -195,12 +162,23 @@ declare class TransactionRolledBackError extends SDKError {
195
162
  * `SERVICE_INDETERMINATE` — a dependency the service needed to decide was
196
163
  * unreachable, so it answered "I could not tell" rather than "no"
197
164
  * (`INV-AC-INDETERMINATE-IS-AN-OUTAGE`). Retryable: it is an outage.
165
+ *
166
+ * **Retryable is not the same as replayable.** "Could not decide" means the
167
+ * write may already have landed, so the retry policy sends this one again only
168
+ * where the request was replay-safe to begin with — an idempotent verb, or a
169
+ * request carrying `Idempotency-Key`.
170
+ *
171
+ * `refuse()` in `@relyio/api-contract` will not serialize this code without a
172
+ * `Retry-After` header, so `retryAfterMs` is populated on every one of these
173
+ * that reaches the SDK through a RelyIO service.
198
174
  */
199
175
  declare class ServiceIndeterminateError extends SDKError {
200
176
  readonly code = "SERVICE_INDETERMINATE";
201
177
  readonly retryable = true;
202
178
  readonly missing?: string;
203
- constructor(message?: string, missing?: string, context?: Record<string, unknown>);
179
+ /** `Retry-After`, in milliseconds. The contract requires the header on this code. */
180
+ readonly retryAfterMs?: number;
181
+ constructor(message?: string, missing?: string, context?: Record<string, unknown>, retryAfterMs?: number);
204
182
  getUserMessage(): string;
205
183
  }
206
184
  /** `INTERNAL_ERROR` — everything a client can only log (Decision 3). */
@@ -267,10 +245,6 @@ declare class ErrorMapper {
267
245
  * Check if an error is retryable
268
246
  */
269
247
  static isRetryable(error: Error): boolean;
270
- /**
271
- * Extract retry delay from error
272
- */
273
- static getRetryDelay(_error: Error): number;
274
248
  }
275
249
 
276
250
  /**
@@ -484,6 +458,113 @@ declare const localeHelpers: {
484
458
  getAllLocalizedValues: typeof getAllLocalizedValues;
485
459
  };
486
460
 
461
+ /**
462
+ * The DOM↔field binding contract, as the one pure helper that emits it.
463
+ *
464
+ * Spread onto the element that renders a field, it stamps which entry, content type, field and
465
+ * locale produced that element, so an editing surface can find the field by scanning the DOM
466
+ * rather than by guessing (`INV-TB-BINDING`). The contract is `toolbar-spec.md` §DOM↔field; this
467
+ * file is its only implementation.
468
+ *
469
+ * **Frozen** (`INV-SS-BINDING-FROZEN`). The attribute set is exactly the five below. Adding,
470
+ * renaming or dropping one is a new contract, and a new contract is a bump of `data-relyio-v` — a
471
+ * page built against version 1 keeps being read as version 1 by any surface that scans it.
472
+ *
473
+ * **Pure** (`INV-TB-SDK-PURE`). It reads the entry it is handed and returns attributes. It imports
474
+ * nothing but the SDK's own types: no realtime, no AI, no first-party code, no framework. That is
475
+ * what lets it live in the customer SDK and run on a server render as happily as in a browser.
476
+ *
477
+ * **Every value comes from the entry.** The id, the content type and the locale are the ones the
478
+ * API reported in `_metadata` — the locale is the one the payload's field values were composed
479
+ * for. There is deliberately no `locale` argument: a caller-supplied locale could bind a node to a
480
+ * locale whose value it is not rendering, which is the silently inferred binding `INV-TB-BINDING`
481
+ * forbids.
482
+ */
483
+
484
+ /** The version of the binding contract this helper emits. */
485
+ declare const BINDING_VERSION = "1";
486
+ /** The attributes `relyioField` returns — the whole of binding contract version 1. */
487
+ interface RelyIOFieldAttributes {
488
+ /** The entry's id (`_metadata.id`). */
489
+ readonly 'data-relyio-entry': string;
490
+ /** The entry's content type (`_metadata.type`); every customer read is keyed by it. */
491
+ readonly 'data-relyio-type': string;
492
+ /** The field the element renders. */
493
+ readonly 'data-relyio-field': string;
494
+ /** The locale the entry's field values were composed for (`_metadata.locale`). */
495
+ readonly 'data-relyio-locale': string;
496
+ /** The binding contract's version. */
497
+ readonly 'data-relyio-v': typeof BINDING_VERSION;
498
+ }
499
+ /**
500
+ * The field names `relyioField` accepts for an entry of type `T`.
501
+ *
502
+ * A schema-typed entry narrows to its declared field names, so they autocomplete and a misspelt
503
+ * one does not compile. An entry with no declared fields — `BaseContent`, which is what an
504
+ * un-generated client returns — has none to narrow to, and `keyof` of it is `never`; that would
505
+ * make the helper uncallable for every untyped customer, so it accepts any field name instead.
506
+ */
507
+ type RelyIOFieldName<T extends BaseContent> = [Exclude<keyof T, '_metadata'>] extends [never] ? string : string & Exclude<keyof T, '_metadata'>;
508
+ /**
509
+ * Binding attributes for one field of one entry.
510
+ *
511
+ * @example
512
+ * ```tsx
513
+ * import { relyioField } from '@relyio/sdk'
514
+ *
515
+ * <h1 {...relyioField(post, 'title')}>{post.title}</h1>
516
+ * // → data-relyio-entry="6710f…" data-relyio-type="post" data-relyio-field="title"
517
+ * // data-relyio-locale="en-US" data-relyio-v="1"
518
+ * ```
519
+ *
520
+ * @throws {TypeError} when the entry's `_metadata` lacks its id, content type or locale. Every
521
+ * entry the API returns carries all three, so this is reached only by a value that was not read
522
+ * from RelyIO. It throws rather than emitting a partial binding: a node stamped with no locale, or
523
+ * none at all, is a binding a surface would have to guess the rest of.
524
+ */
525
+ declare function relyioField<T extends BaseContent>(entry: T, field: RelyIOFieldName<T>): RelyIOFieldAttributes;
526
+
527
+ /**
528
+ * The DOM event a preview surface dispatches when content on the page has changed, and the one
529
+ * spelling of its name (`sdk-surfaces-spec.md` decision 23: the toolbar emits, the framework
530
+ * listens).
531
+ *
532
+ * It is the same kind of seam as the binding attributes beside it: a string both sides read from the
533
+ * core, so the preview toolbar needs no Next dependency and `@relyio/next`'s `<RelyIORefresh />`
534
+ * needs no toolbar dependency. Neither restates the name.
535
+ *
536
+ * **Dispatched on `window`.** Listeners subscribe with
537
+ * `window.addEventListener(RELYIO_CHANGE_EVENT, …)`; the toolbar renders inside a shadow root, and
538
+ * `window` is the one target both sides reach without knowing where the other is mounted.
539
+ *
540
+ * **The name is a wire contract.** A page can run a toolbar and a framework package released at
541
+ * different times, so renaming it silently disconnects them. The `detail` a dispatch carries is
542
+ * the preview toolbar's to declare (SS4); a listener that only refreshes reads none of it.
543
+ */
544
+ declare const RELYIO_CHANGE_EVENT = "relyio:change";
545
+
546
+ /**
547
+ * The width ladder the delivery Worker snaps every rendered dimension to
548
+ * (`INV-SS-ONE-LADDER`, sdk-surfaces-spec decision 14).
549
+ *
550
+ * A dimension is clamped to a ceiling and snapped to a bucket, so "any width"
551
+ * cannot become "unboundedly many distinct transforms". A client that asks the
552
+ * Worker for `w=749` is served the `w=700` render anyway; snapping on this side
553
+ * first means an image loader emits the URL the edge cache already holds.
554
+ *
555
+ * This is a **copy**, and deliberately so: the core cannot import
556
+ * `@relyio/storage` or the Worker. `apps/edge/cdn/src/__tests__/ladder-parity.test.ts`
557
+ * holds the two equal — the constants, and what the Worker actually renders for
558
+ * a sweep of requested widths — so a divergence fails the gate rather than a
559
+ * cache.
560
+ */
561
+ declare const IMAGE_LADDER: {
562
+ readonly maxDimension: 5000;
563
+ readonly bucket: 100;
564
+ };
565
+ /** Clamp to the ceiling, then snap to the nearest bucket — never below one bucket. */
566
+ declare function snapToLadder(value: number): number;
567
+
487
568
  /**
488
569
  * RelyIO SDK - Main Entry Point
489
570
  *
@@ -520,4 +601,4 @@ declare const localeHelpers: {
520
601
 
521
602
  declare const VERSION = "__VERSION__";
522
603
 
523
- export { AuthenticationError, AuthorizationError, ConnectionError, ErrorMapper, InvalidApiKeyError, type LanguageSwitcherOption, type LanguageSwitcherOptions, type LocaleMetadata, type LocaleStatus, type LocalizedEntry, MethodNotAllowedError, MissingApiKeyError, NetworkError, PayloadTooLargeError, PlanFeatureUnavailableError, RateLimitError, ReadOnlyKeyError, ResourceConflictError, ResourceExpiredError, ResourceNotFoundError, SDKError, ServerError, ServiceIndeterminateError, TimeoutError, TransactionRolledBackError, type TranslationCompleteness, UnknownContractError, UsageQuotaExceededError, VERSION, buildLanguageSwitcher, estimateTranslationCompleteness, getAllLocalizedValues, getAvailableLocaleCodes, getDefaultLocale, getFallbackFields, getFieldFallbackLocale, getLocalizedField, getPublishedLocaleCodes, getRequestedLocale, hasLocale, isFieldFallback, isPublishedInLocale, isResourceNotFound, localeHelpers, needsTranslation };
604
+ export { AuthenticationError, AuthorizationError, BaseContent, ConnectionError, ErrorMapper, IMAGE_LADDER, InvalidApiKeyError, type LanguageSwitcherOption, type LanguageSwitcherOptions, type LocaleMetadata, type LocaleStatus, type LocalizedEntry, MethodNotAllowedError, MissingApiKeyError, NetworkError, PayloadTooLargeError, PlanFeatureUnavailableError, RELYIO_CHANGE_EVENT, RateLimitError, ReadOnlyKeyError, type RelyIOFieldAttributes, type RelyIOFieldName, SDKError, ServerError, ServiceIndeterminateError, TimeoutError, TransactionRolledBackError, type TranslationCompleteness, UnknownContractError, UsageQuotaExceededError, VERSION, buildLanguageSwitcher, estimateTranslationCompleteness, getAllLocalizedValues, getAvailableLocaleCodes, getDefaultLocale, getFallbackFields, getFieldFallbackLocale, getLocalizedField, getPublishedLocaleCodes, getRequestedLocale, hasLocale, isFieldFallback, isPublishedInLocale, localeHelpers, needsTranslation, relyioField, snapToLadder };
package/dist/index.js CHANGED
@@ -1,5 +1,6 @@
1
- export { defineAssetType, defineComponent, defineContentType, defineQuery, defineSchema, defineSettingsGroup, defineSingleton, defineSingletonContentType, fields, fieldset, schemaToJSON } from './chunk-2QUK2ZGD.js';
2
- export { AdhocQueryBuilder, AdhocQueryClient, AssetClient, AssetFileBuilder, AssetUploadBuilder, AuthenticationError, AuthorizationError, AutocompleteBuilder, BaseValidationError, BatchBuilder, BatchClient, ConnectionError, ContentByIdBuilder, ContentClient, ContentQueryBuilder, ErrorMapper, FileUploadError, FileValidationError, HttpClient, InvalidApiKeyError, InvalidFieldTypeError, InvalidPayloadError, MethodNotAllowedError, MissingApiKeyError, NetworkError, PayloadTooLargeError, PlanFeatureUnavailableError, RateLimitError, ReadOnlyKeyError, RequiredFieldError, ResourceConflictError, ResourceExpiredError, ResourceNotFoundError, SDKError, SchemaValidationError, SearchBuilder, SearchClient, ServerError, ServiceIndeterminateError, SettingsClient, SimilarBuilder, SingletonClient, TimeoutError, TransactionRolledBackError, TypedRelyIOClient, UnknownContractError, UsageQuotaExceededError, ValidationError, createClient, createClient as default, entityTagOf, isAssetEntry, isResourceNotFound, validateFile } from './chunk-RJBIJ2ZK.js';
1
+ export { defineAssetType, defineComponent, defineContentType, defineQuery, defineSchema, defineSettingsGroup, defineSingleton, defineSingletonContentType, fields, fieldset } from './chunk-XY5KFEFY.js';
2
+ export { AdhocQueryBuilder, AdhocQueryClient, AssetClient, AssetFileBuilder, AssetUploadBuilder, AuthenticationError, AuthorizationError, AutocompleteBuilder, BaseValidationError, BatchBuilder, BatchClient, ChangesExpiredError, ConnectionError, ContentByIdBuilder, ContentClient, ContentQueryBuilder, ErrorMapper, FileUploadError, FileValidationError, HttpClient, InvalidApiKeyError, InvalidFieldTypeError, InvalidPayloadError, MethodNotAllowedError, MissingApiKeyError, NetworkError, PayloadTooLargeError, PlanFeatureUnavailableError, RateLimitError, ReadOnlyKeyError, RequiredFieldError, ResourceConflictError, ResourceExpiredError, ResourceNotFoundError, SDKError, SchemaValidationError, SearchBuilder, SearchClient, ServerError, ServiceIndeterminateError, SettingsClient, SimilarBuilder, SingletonClient, TimeoutError, TransactionRolledBackError, TypedRelyIOClient, UnknownContractError, UsageQuotaExceededError, ValidationError, createClient, createClient as default, entityTagOf, isAssetEntry, isResourceNotFound, matchRoute, validateFile } from './chunk-43VPZT2G.js';
3
+ import './chunk-BBUB7C2Z.js';
3
4
  import './chunk-IY5LSKXU.js';
4
5
  export { camelToSnake, createDeferred, debounce, deepClone, generateId, isBrowser, isNode, isPlainObject, isValidEmail, isValidUrl, mergeDeep, omit, pick, retry, sleep, snakeToCamel, throttle, toSafeString } from './chunk-I3ESNANB.js';
5
6
  import { __name } from './chunk-XQ4QHWZE.js';
@@ -140,9 +141,50 @@ var localeHelpers = {
140
141
  getAllLocalizedValues
141
142
  };
142
143
 
144
+ // src/binding/relyio-field.ts
145
+ var BINDING_VERSION = "1";
146
+ function relyioField(entry, field) {
147
+ const metadata = entry._metadata;
148
+ return {
149
+ "data-relyio-entry": requireMetadata(metadata, "id", field),
150
+ "data-relyio-type": requireMetadata(metadata, "type", field),
151
+ "data-relyio-field": field,
152
+ "data-relyio-locale": requireMetadata(metadata, "locale", field),
153
+ "data-relyio-v": BINDING_VERSION
154
+ };
155
+ }
156
+ __name(relyioField, "relyioField");
157
+ function requireMetadata(metadata, key, field) {
158
+ const value = metadata?.[key];
159
+ if (typeof value !== "string" || value.length === 0) {
160
+ throw new TypeError(
161
+ `relyioField(entry, '${field}'): the entry has no _metadata.${key}, so the field cannot be bound. Pass an entry as the RelyIO API returned it.`
162
+ );
163
+ }
164
+ return value;
165
+ }
166
+ __name(requireMetadata, "requireMetadata");
167
+
168
+ // src/binding/change-event.ts
169
+ var RELYIO_CHANGE_EVENT = "relyio:change";
170
+
171
+ // src/image/ladder.ts
172
+ var IMAGE_LADDER = {
173
+ maxDimension: 5e3,
174
+ bucket: 100
175
+ };
176
+ function snapToLadder(value) {
177
+ const clamped = Math.min(Math.max(value, 1), IMAGE_LADDER.maxDimension);
178
+ return Math.max(
179
+ IMAGE_LADDER.bucket,
180
+ Math.round(clamped / IMAGE_LADDER.bucket) * IMAGE_LADDER.bucket
181
+ );
182
+ }
183
+ __name(snapToLadder, "snapToLadder");
184
+
143
185
  // src/index.ts
144
186
  var VERSION = "__VERSION__";
145
187
 
146
- export { VERSION, buildLanguageSwitcher, estimateTranslationCompleteness, getAllLocalizedValues, getAvailableLocaleCodes, getDefaultLocale, getFallbackFields, getFieldFallbackLocale, getLocalizedField, getPublishedLocaleCodes, getRequestedLocale, hasLocale, isFieldFallback, isPublishedInLocale, localeHelpers, needsTranslation };
188
+ export { IMAGE_LADDER, RELYIO_CHANGE_EVENT, VERSION, buildLanguageSwitcher, estimateTranslationCompleteness, getAllLocalizedValues, getAvailableLocaleCodes, getDefaultLocale, getFallbackFields, getFieldFallbackLocale, getLocalizedField, getPublishedLocaleCodes, getRequestedLocale, hasLocale, isFieldFallback, isPublishedInLocale, localeHelpers, needsTranslation, relyioField, snapToLadder };
147
189
  //# sourceMappingURL=index.js.map
148
190
  //# sourceMappingURL=index.js.map