Skip to content

Release Ember 6.4 (Data 5.4.1) #40

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
May 26, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
45 changes: 45 additions & 0 deletions json-docs/ember-data/5.4.1/classes/ember-data-5.4.1-<Await />.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{
"data": {
"id": "ember-data-5.4.1-<Await />",
"type": "class",
"attributes": {
"name": "<Await />",
"shortname": "<Await />",
"classitems": [],
"plugins": [],
"extensions": [],
"plugin_for": [],
"extension_for": [],
"module": "@warp-drive/ember",
"namespace": "",
"file": "../ember/src/-private/await.gts",
"line": 53,
"description": "The <Await /> component allow you to utilize reactive control flow\nfor asynchronous states in your application.\n\nAwait is ideal for handling \"boundaries\", outside which some state is\nstill allowed to be unresolved and within which it MUST be resolved.\n\n```gjs\nimport { Await } from '@warp-drive/ember';\n\n<template>\n <Await @promise={{@request}}>\n <:pending>\n <Spinner />\n </:pending>\n\n <:error as |error|>\n <ErrorForm @error={{error}} />\n </:error>\n\n <:success as |result|>\n <h1>{{result.title}}</h1>\n </:success>\n </Await>\n</template>\n```\n\nThe <Await /> component requires that error states are properly handled.\n\nIf no error block is provided and the promise rejects, the error will\nbe thrown.",
"access": "public",
"tagname": "",
"methods": [],
"events": [],
"properties": []
},
"relationships": {
"parent-class": {
"data": null
},
"descendants": {
"data": []
},
"module": {
"data": {
"id": "ember-data-5.4.1-@warp-drive/ember",
"type": "module"
}
},
"project-version": {
"data": {
"id": "ember-data-5.4.1",
"type": "project-version"
}
}
}
}
}

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
{
"data": {
"id": "ember-data-5.4.1-<Interface> CacheHandler",
"type": "class",
"attributes": {
"name": "<Interface> CacheHandler",
"shortname": "<Interface> CacheHandler",
"classitems": [],
"plugins": [],
"extensions": [],
"plugin_for": [],
"extension_for": [],
"module": "@ember-data/request",
"namespace": "",
"file": "../request/src/-private/types.ts",
"line": 232,
"description": "The CacheHandler is identical to other handlers ecxept that it\nis allowed to return a value synchronously. This is useful for\nfeatures like reducing microtask queueing when de-duping.\n\nA RequestManager may only have one CacheHandler, registered via\n`manager.useCache(CacheHandler)`.",
"access": "public",
"tagname": "",
"methods": [
{
"file": "../packages/request/src/-private/types.ts",
"line": 244,
"description": "Method to implement to handle requests. Receives the request\ncontext and a nextFn to call to pass-along the request to\nother handlers.",
"itemtype": "method",
"name": "request",
"access": "public",
"tagname": "",
"params": [
{
"name": "context",
"description": ""
},
{
"name": "next",
"description": ""
}
],
"class": "<Interface> CacheHandler",
"module": "@ember-data/request"
}
],
"events": [],
"properties": []
},
"relationships": {
"parent-class": {
"data": null
},
"descendants": {
"data": []
},
"module": {
"data": {
"id": "ember-data-5.4.1-@ember-data/request",
"type": "module"
}
},
"project-version": {
"data": {
"id": "ember-data-5.4.1",
"type": "project-version"
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
{
"data": {
"id": "ember-data-5.4.1-<Interface> CachePolicy",
"type": "class",
"attributes": {
"name": "<Interface> CachePolicy",
"shortname": "<Interface> CachePolicy",
"classitems": [],
"plugins": [],
"extensions": [],
"plugin_for": [],
"extension_for": [],
"module": "@ember-data/store",
"namespace": "",
"file": "../store/src/-private/cache-handler/types.ts",
"line": 6,
"description": "A service which an application may provide to the store via\nthe store's `lifetimes` property to configure the behavior\nof the CacheHandler.\n\nThe default behavior for request lifetimes is to never expire\nunless manually refreshed via `cacheOptions.reload` or `cacheOptions.backgroundReload`.\n\nImplementing this service allows you to programatically define\nwhen a request should be considered expired.",
"access": "public",
"tagname": "",
"methods": [
{
"file": "../packages/store/src/-private/cache-handler/types.ts",
"line": 21,
"description": "Invoked to determine if the request may be fulfilled from cache\nif possible.\n\nNote, this is only invoked if the request has a cache-key.\n\nIf no cache entry is found or the entry is hard expired,\nthe request will be fulfilled from the configured request handlers\nand the cache will be updated before returning the response.",
"itemtype": "method",
"name": "isHardExpired",
"access": "public",
"tagname": "",
"params": [
{
"name": "identifier",
"description": "",
"type": "StableDocumentIdentifier"
},
{
"name": "store",
"description": "",
"type": "Store"
}
],
"return": {
"description": "true if the request is considered hard expired",
"type": "Boolean"
},
"class": "<Interface> CachePolicy",
"module": "@ember-data/store"
},
{
"file": "../packages/store/src/-private/cache-handler/types.ts",
"line": 38,
"description": "Invoked if `isHardExpired` is false to determine if the request\nshould be update behind the scenes if cache data is already available.\n\nNote, this is only invoked if the request has a cache-key.\n\nIf true, the request will be fulfilled from cache while a backgrounded\nrequest is made to update the cache via the configured request handlers.",
"itemtype": "method",
"name": "isSoftExpired",
"access": "public",
"tagname": "",
"params": [
{
"name": "identifier",
"description": "",
"type": "StableDocumentIdentifier"
},
{
"name": "store",
"description": "",
"type": "Store"
}
],
"return": {
"description": "true if the request is considered soft expired",
"type": "Boolean"
},
"class": "<Interface> CachePolicy",
"module": "@ember-data/store"
},
{
"file": "../packages/store/src/-private/cache-handler/types.ts",
"line": 55,
"description": "Invoked when a request will be sent to the configured request handlers.\nThis is invoked for both foreground and background requests.\n\nNote, this is invoked regardless of whether the request has a cache-key.",
"itemtype": "method",
"name": "willRequest [Optional]",
"access": "public",
"tagname": "",
"params": [
{
"name": "request",
"description": "",
"type": "ImmutableRequestInfo"
},
{
"name": "identifier",
"description": "",
"type": "StableDocumentIdentifier | null"
},
{
"name": "store",
"description": "",
"type": "Store"
}
],
"return": {
"description": "",
"type": "Void"
},
"class": "<Interface> CachePolicy",
"module": "@ember-data/store"
},
{
"file": "../packages/store/src/-private/cache-handler/types.ts",
"line": 70,
"description": "Invoked when a request has been fulfilled from the configured request handlers.\nThis is invoked for both foreground and background requests once the cache has\nbeen updated.\n\nNote, this is invoked regardless of whether the request has a cache-key.\n\nIt is best practice to notify the store of any requests marked as invalidated\nso that request subscriptions can reload when needed.\n\n```ts\nstore.notifications.notify(identifier, 'invalidated');\n```\n\nThis allows anything subscribed to the request to be notified of the change\n\ne.g.\n\n```ts\nstore.notifications.subscribe(identifier, (_, type) => {\n if (type === 'invalidated') {\n // do update\n }\n});\n```\n\nNote,",
"itemtype": "method",
"name": "didRequest [Optional]",
"access": "public",
"tagname": "",
"params": [
{
"name": "request",
"description": "",
"type": "ImmutableRequestInfo"
},
{
"name": "response",
"description": "",
"type": "ImmutableResponse"
},
{
"name": "identifier",
"description": "",
"type": "StableDocumentIdentifier | null"
},
{
"name": "store",
"description": "",
"type": "Store"
}
],
"return": {
"description": "",
"type": "Void"
},
"class": "<Interface> CachePolicy",
"module": "@ember-data/store"
}
],
"events": [],
"properties": []
},
"relationships": {
"parent-class": {
"data": null
},
"descendants": {
"data": []
},
"module": {
"data": {
"id": "ember-data-5.4.1-@ember-data/store",
"type": "module"
}
},
"project-version": {
"data": {
"id": "ember-data-5.4.1",
"type": "project-version"
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
{
"data": {
"id": "ember-data-5.4.1-<Interface> Handler",
"type": "class",
"attributes": {
"name": "<Interface> Handler",
"shortname": "<Interface> Handler",
"classitems": [],
"plugins": [],
"extensions": [],
"plugin_for": [],
"extension_for": [],
"module": "@ember-data/request",
"namespace": "",
"file": "../request/src/-private/types.ts",
"line": 107,
"description": "Requests are fulfilled by handlers. A handler receives the request context\nas well as a `next` function with which to pass along a request to the next\nhandler if it so chooses.\n\nA handler may be any object with a `request` method. This allows both stateful and non-stateful\nhandlers to be utilized.\n\nIf a handler calls `next`, it receives a `Future` which resolves to a `StructuredDocument`\nthat it can then compose how it sees fit with its own response.\n\n```ts\ntype NextFn<P> = (req: RequestInfo) => Future<P>;\n\ninterface Handler {\n async request<T>(context: RequestContext, next: NextFn<P>): T;\n}\n```\n\n`RequestContext` contains a readonly version of the RequestInfo as well as a few methods for building up the `StructuredDocument` and `Future` that will be part of the response.\n\n```ts\ninterface RequestContext<T> {\n readonly request: RequestInfo;\n\n setStream(stream: ReadableStream | Promise<ReadableStream>): void;\n setResponse(response: Response | ResponseInfo): void;\n}\n```\n\nA basic `fetch` handler with support for streaming content updates while\nthe download is still underway might look like the following, where we use\n[`response.clone()`](https://developer.mozilla.org/en-US/docs/Web/API/Response/clone) to `tee` the `ReadableStream` into two streams.\n\nA more efficient handler might read from the response stream, building up the\nresponse content before passing along the chunk downstream.\n\n```ts\nconst FetchHandler = {\n async request(context) {\n const response = await fetch(context.request);\n context.setResponse(reponse);\n context.setStream(response.clone().body);\n\n return response.json();\n }\n}\n```\n\n### Stream Currying\n\n`RequestManager.request` and `next` differ from `fetch` in one **crucial detail** in that the outer Promise resolves only once the response stream has been processed.\n\nFor context, it helps to understand a few of the use-cases that RequestManager\nis intended to allow.\n\n- to manage and return streaming content (such as video files)\n- to fulfill a request from multiple sources or by splitting one request into multiple requests\n - for instance one API call for a user and another for the user's friends\n - or e.g. fulfilling part of the request from one source (one API, in-memory, localStorage, IndexedDB etc.) and the rest from another source (a different API, a WebWorker, etc.)\n- to coalesce multiple requests\n- to decorate a request with additional info\n - e.g. an Auth handler that ensures the correct tokens or headers or cookies are attached.\n\n----\n\n`await fetch(<req>)` resolves at the moment headers are received. This allows for the body of the request to be processed as a stream by application\ncode *while chunks are still being received by the browser*.\n\nWhen an app chooses to `await response.json()` what occurs is the browser reads the stream to completion and then returns the result. Additionally, this stream may only be read **once**.\n\nThe `RequestManager` preserves this ability to subscribe to and utilize the stream by either the application or the handler – thereby delivering the full power and flexibility of native APIs – without restricting developers in ways that lead to complicated workarounds.\n\nEach handler may call `setStream` only once, but may do so *at any time* until the promise that the handler returns has resolved. The associated promise returned by calling `future.getStream` will resolve with the stream set by `setStream` if that method is called, or `null` if that method\nhas not been called by the time that the handler's request method has resolved.\n\nHandlers that do not create a stream of their own, but which call `next`, should defensively pipe the stream forward. While this is not required (see automatic currying below) it is better to do so in most cases as otherwise the stream may not become available to downstream handlers or the application until the upstream handler has fully read it.\n\n```ts\ncontext.setStream(future.getStream());\n```\n\nHandlers that either call `next` multiple times or otherwise have reason to create multiple fetch requests should either choose to return no stream, meaningfully combine the streams, or select a single prioritized stream.\n\nOf course, any handler may choose to read and handle the stream, and return either no stream or a different stream in the process.\n\n### Automatic Currying of Stream and Response\n\nIn order to simplify the common case for handlers which decorate a request, if `next` is called only a single time and `setResponse` was never called by the handler, the response set by the next handler in the chain will be applied to that handler's outcome. For instance, this makes the following pattern possible `return (await next(<req>)).content;`.\n\nSimilarly, if `next` is called only a single time and neither `setStream` nor `getStream` was called, we automatically curry the stream from the future returned by `next` onto the future returned by the handler.\n\nFinally, if the return value of a handler is a `Future`, we curry `content` and `errors` as well, thus enabling the simplest form `return next(<req>)`.\n\nIn the case of the `Future` being returned, `Stream` proxying is automatic and immediate and does not wait for the `Future` to resolve.\n\n### Handler Order\n\nRequest handlers are registered by configuring the manager via `use`\n\n```ts\nconst manager = new RequestManager()\n .use([Handler1, Handler2]);\n```\n\nHandlers will be invoked in the order they are registered (\"fifo\", first-in first-out), and may only be registered up until the first request is made. It is recommended but not required to register all handlers at one time in order to ensure explicitly visible handler ordering.",
"access": "public",
"tagname": "",
"methods": [
{
"file": "../packages/request/src/-private/types.ts",
"line": 219,
"description": "Method to implement to handle requests. Receives the request\ncontext and a nextFn to call to pass-along the request to\nother handlers.",
"itemtype": "method",
"name": "request",
"access": "public",
"tagname": "",
"params": [
{
"name": "context",
"description": ""
},
{
"name": "next",
"description": ""
}
],
"class": "<Interface> Handler",
"module": "@ember-data/request"
}
],
"events": [],
"properties": []
},
"relationships": {
"parent-class": {
"data": null
},
"descendants": {
"data": []
},
"module": {
"data": {
"id": "ember-data-5.4.1-@ember-data/request",
"type": "module"
}
},
"project-version": {
"data": {
"id": "ember-data-5.4.1",
"type": "project-version"
}
}
}
}
}
Loading