@relyio/sdk 0.3.0 → 0.5.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 +109 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/{chunk-QIZOBT5F.js → chunk-5AZUUV5B.js} +349 -25
- package/dist/{chunk-54WP2PWG.cjs → chunk-CIRT6TVT.cjs} +350 -24
- package/dist/{chunk-HMVGXUGR.cjs → chunk-HAQELDZN.cjs} +2 -2
- package/dist/{chunk-LYRYCIX5.js → chunk-XY5KFEFY.js} +2 -2
- package/dist/client/index.cjs +3 -3
- package/dist/client/index.d.cts +4 -3
- package/dist/client/index.d.ts +4 -3
- package/dist/client/index.js +1 -1
- package/dist/{define-schema-BfXeR6K8.d.cts → define-schema-2xbHgtK-.d.cts} +8 -4
- package/dist/{define-schema-BD6HSPnG.d.ts → define-schema-DzYXk4HL.d.ts} +8 -4
- package/dist/{index-BDpar3FO.d.cts → index-BozPz4n1.d.cts} +320 -8
- package/dist/{index-ulOrcfPa.d.cts → index-C5mRBb6t.d.cts} +368 -11
- package/dist/{index-Dx01iwaf.d.ts → index-Dzo-upNS.d.ts} +320 -8
- package/dist/{index-DuEhsGdE.d.ts → index-mXUx2H99.d.ts} +368 -11
- package/dist/index.cjs +119 -66
- package/dist/index.d.cts +131 -46
- package/dist/index.d.ts +131 -46
- package/dist/index.js +44 -3
- package/dist/schema/index.cjs +35 -35
- package/dist/schema/index.d.cts +1 -1
- package/dist/schema/index.d.ts +1 -1
- package/dist/schema/index.js +1 -1
- package/dist/types/index.d.cts +1 -1
- package/dist/types/index.d.ts +1 -1
- package/package.json +3 -13
- package/dist/react/index.cjs +0 -4
- package/dist/react/index.d.cts +0 -2
- package/dist/react/index.d.ts +0 -2
- package/dist/react/index.js +0 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,114 @@
|
|
|
1
1
|
# @relyio/sdk
|
|
2
2
|
|
|
3
|
+
## 0.5.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- c59912d: `client.sandbox` reports the `relyio dev` sandbox the client resolved, `client.project()` describes the project your key belongs to, and `@relyio/sdk` exports the `SandboxState`, `Project` and `RelyIOChangeDetail` types.
|
|
8
|
+
|
|
9
|
+
`client.project()` calls `GET /v1/project` and returns the organization, project, dataset and branch, each with its `id` and `name`, plus `studioUrl`, the address of the project's Studio. `dataset` is the one your requests read, which may be a sandbox rather than the project's default, so add it to a Studio link as `?dataset=`. `studioUrl` is `null` when the service has no Dashboard address configured.
|
|
10
|
+
|
|
11
|
+
`client.sandbox` is one of five states:
|
|
12
|
+
|
|
13
|
+
- `{ state: 'active', datasetId, branchId, expiresAt, source }` — the client is reading the sandbox. `source` is `'env'` under `relyio dev -- <command>` and `'file'` when it read `.relyio/dev.json`. `branchId` is `null` from the environment, which names no branch. `expiresAt` is `null` for a sandbox with no deadline.
|
|
14
|
+
- `{ state: 'expired', expiredAt }` or `{ state: 'unreadable', reason }` — a sandbox was found and ignored, so the client reads the dataset and key you configured. The console says so, as before.
|
|
15
|
+
- `{ state: 'absent' }` — no sandbox was found. A client created in the browser always reports this, because the browser cannot see the environment or the file.
|
|
16
|
+
- `{ state: 'disabled' }` — the client did not look, because you passed `dev: false`, or `NODE_ENV` is `production` and you did not pass `dev: true`.
|
|
17
|
+
|
|
18
|
+
It is plain JSON with no API key in it, so a Next.js server component can pass it to a client component as a prop:
|
|
19
|
+
|
|
20
|
+
```tsx
|
|
21
|
+
<SandboxBadge sandbox={relyio.sandbox} />
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
`RelyIOChangeDetail` is the `detail` a `RELYIO_CHANGE_EVENT` dispatch carries: the same `{ entryId, contentType, locale, kind, cursor }` as a `Change` from `relyio.changes()`.
|
|
25
|
+
|
|
26
|
+
## 0.4.0
|
|
27
|
+
|
|
28
|
+
### Minor Changes
|
|
29
|
+
|
|
30
|
+
- 06baad9: `relyio.changes()` follows the content changes feed (`GET /v1/changes`) as an async iterable.
|
|
31
|
+
|
|
32
|
+
```ts
|
|
33
|
+
const controller = new AbortController()
|
|
34
|
+
|
|
35
|
+
for await (const change of relyio.changes({ types: ['post'], signal: controller.signal })) {
|
|
36
|
+
// { entryId, contentType, locale, kind: 'published' | 'updated' | 'unpublished' | 'deleted', cursor }
|
|
37
|
+
await revalidate(change.contentType, change.entryId)
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
- A change carries ids only. Refetch the entry through the ordinary read methods to see it.
|
|
42
|
+
- The API key decides what arrives: a published key sees publication changes, a preview key sees draft saves as well.
|
|
43
|
+
- Each request long-polls, so an idle feed costs one request every 25 seconds or so. When the service or your key is at its limit of held connections, the iterator waits for the `Retry-After` the service sends before asking again.
|
|
44
|
+
- Pass `since` (a change's `cursor`) to resume where you stopped. Without it, the feed starts at the present.
|
|
45
|
+
- A cursor too old to replay throws `ChangesExpiredError` (with a `reason`). Pass `onExpired: 'resync'` to start again from the present instead, or a function to be called when that happens — the place to refetch everything you hold.
|
|
46
|
+
- Aborting the `signal` ends the loop without throwing.
|
|
47
|
+
|
|
48
|
+
Also fixed: a request given its own `signal` no longer loses the client's timeout, and aborting it is no longer retried or reported as a `TimeoutError`.
|
|
49
|
+
|
|
50
|
+
- f21099b: `createClient()` takes a `fetch` option, and `@relyio/sdk` exports `matchRoute`, `IMAGE_LADDER`, `snapToLadder` and `RELYIO_CHANGE_EVENT`.
|
|
51
|
+
|
|
52
|
+
`fetch` is the function every request to the RelyIO API is sent through. The client still builds each request and passes your function the same `RequestInit` it would pass the runtime's `fetch`, including on a retry, so a write's `Idempotency-Key` does not change between attempts. Use it to add what your framework reads off the request, such as Next.js cache tags:
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
import { createClient } from '@relyio/sdk'
|
|
56
|
+
|
|
57
|
+
const relyio = createClient({
|
|
58
|
+
apiKey: process.env.RELYIO_API_KEY!,
|
|
59
|
+
fetch: (input, init) => fetch(input, { ...init, next: { tags: ['posts'] } }),
|
|
60
|
+
})
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Leave it out and the client uses the global `fetch`, as before. File bytes that an asset upload sends straight to a presigned storage URL do not go through it.
|
|
64
|
+
|
|
65
|
+
`matchRoute(url)` is the reverse of what the client does when it builds a URL. It returns the API route the URL names (`'/v1/{contentType}/{id}'`), its decoded path parameters and its query, or `null` for a URL that is not a RelyIO API route. If your `baseUrl` has a path of its own, pass it as `matchRoute(url, { baseUrl })`.
|
|
66
|
+
|
|
67
|
+
`snapToLadder(width)` rounds an image dimension to the sizes the RelyIO CDN renders: the nearest multiple of `IMAGE_LADDER.bucket` (100), from 100 up to `IMAGE_LADDER.maxDimension` (5000). The CDN snaps every requested width the same way, so snapping first means two widths that render the same image also share one URL and one cache entry.
|
|
68
|
+
|
|
69
|
+
`RELYIO_CHANGE_EVENT` (`'relyio:change'`) is the name of the DOM event a RelyIO preview surface dispatches on `window` when content on the page has changed. Listen for it by this constant rather than by the string: `@relyio/next`'s `<RelyIORefresh />` does.
|
|
70
|
+
|
|
71
|
+
The `cache` option still configures nothing: the client keeps no response cache of its own, so every call reaches `fetch`.
|
|
72
|
+
|
|
73
|
+
- 745103e: `createClient()` is typed by your schema without a generic or a `schema:` option, once `relyio generate-types` has run.
|
|
74
|
+
|
|
75
|
+
`@relyio/sdk` now exports an empty `Register` interface. The `schema.ts` that `relyio generate-types` writes fills it in, and from then on:
|
|
76
|
+
|
|
77
|
+
```ts
|
|
78
|
+
import { createClient } from '@relyio/sdk'
|
|
79
|
+
|
|
80
|
+
const relyio = createClient({ apiKey: process.env.RELYIO_API_KEY! })
|
|
81
|
+
|
|
82
|
+
relyio.content('article') // content type, singleton, settings group and query names autocomplete
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
`schema.ts` only has to be part of your TypeScript program, which it is if your `tsconfig.json` includes it or anything imports from it. Passing `schema:` or an explicit generic works exactly as before, and either one takes precedence over the registered schema.
|
|
86
|
+
|
|
87
|
+
**If you have not run the generator,** `createClient({ apiKey })` returns `TypedRelyIOClient<undefined>`, the untyped client: every name is accepted and entries are typed as `BaseContent`. Previously the call resolved to `TypedRelyIOClient<SchemaDefinition<any, …>>`, a client that claimed a schema it did not have. Code that named that type explicitly needs to name `TypedRelyIOClient<undefined>` instead.
|
|
88
|
+
|
|
89
|
+
**Also fixed:** on a client typed by a schema, `settings()`, `asset()` and `withLocale()` accepted no argument at all, because the settings groups, asset types and locales are optional parts of a schema and their names resolved to `never`. They now accept the schema's names.
|
|
90
|
+
|
|
91
|
+
- cf979dd: **Breaking:** `@relyio/sdk/react` is removed, and the package no longer declares `react` as a peer dependency. `relyioField` is added to `@relyio/sdk`.
|
|
92
|
+
|
|
93
|
+
The `@relyio/sdk/react` subpath exported nothing. It existed so that an import of it would resolve, and it carried an optional `react` peer and a React type dependency for that alone. It now fails to resolve with `ERR_PACKAGE_PATH_NOT_EXPORTED`.
|
|
94
|
+
|
|
95
|
+
**If you imported it:** delete the import. Nothing was exported from it, so nothing that used it needs a replacement. React hooks for RelyIO will ship as their own package, `@relyio/react`.
|
|
96
|
+
|
|
97
|
+
`relyioField(entry, field)` returns the attributes that tie a rendered element to the entry field it shows. Spread them onto that element:
|
|
98
|
+
|
|
99
|
+
```tsx
|
|
100
|
+
import { relyioField } from '@relyio/sdk'
|
|
101
|
+
|
|
102
|
+
// `post` is an entry the client returned, e.g. from `relyio.content('post').fetchOne(id)`
|
|
103
|
+
;<h1 {...relyioField(post, 'title')}>{post.title}</h1>
|
|
104
|
+
// → data-relyio-entry="6710f…" data-relyio-type="post" data-relyio-field="title"
|
|
105
|
+
// data-relyio-locale="en-US" data-relyio-v="1"
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
The entry id, content type and locale all come from the entry itself, so the element is tied to the locale its value was actually served in. With a typed schema, `field` autocompletes to the content type's field names and a misspelt name does not compile. Without one, any field name is accepted. The helper throws a `TypeError` when the entry has no `_metadata.id`, `_metadata.type` or `_metadata.locale`. Every entry the API returns has all three, so that only happens with an object that did not come from RelyIO.
|
|
109
|
+
|
|
110
|
+
The attribute set is fixed at these five. `data-relyio-v` is the version of the set, and any future change to the attributes will bump it.
|
|
111
|
+
|
|
3
112
|
## 0.3.0
|
|
4
113
|
|
|
5
114
|
### Minor Changes
|