@apollion-dsi/relay 0.27.2 → 0.28.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/README.md +146 -0
- package/lib/chunks/chunk-54QV6DFY.esm.js +1 -0
- package/lib/chunks/chunk-FYOI5Q5V.esm.js +0 -0
- package/lib/chunks/chunk-GZONWSRB.esm.js +1 -0
- package/lib/chunks/chunk-KIA6YWO5.esm.js +1 -0
- package/lib/chunks/chunk-RMYDTZUF.esm.js +1 -0
- package/lib/chunks/chunk-XJA2SRQY.esm.js +1 -0
- package/lib/commitMutation/commitMutation.d.ts +15 -15
- package/lib/commitMutation/index.d.ts +4 -4
- package/lib/commitMutation/index.esm.js +1 -0
- package/lib/index.d.ts +10 -10
- package/lib/index.esm.js +1 -1
- package/lib/index.js +1 -1
- package/lib/mutationUtils/index.d.ts +5 -5
- package/lib/mutationUtils/index.esm.js +1 -0
- package/lib/mutationUtils/mutationUtils.d.ts +60 -60
- package/lib/relayArgsInterface/index.d.ts +3 -3
- package/lib/relayArgsInterface/index.esm.js +1 -0
- package/lib/relayArgsInterface/relayArgsInterface.d.ts +106 -79
- package/lib/setupRelayEnvironment/executeEnvironment.d.ts +13 -13
- package/lib/setupRelayEnvironment/fetchQuery.d.ts +19 -19
- package/lib/setupRelayEnvironment/fetchWithRetries.d.ts +20 -20
- package/lib/setupRelayEnvironment/index.d.ts +11 -0
- package/lib/setupRelayEnvironment/index.esm.js +1 -0
- package/lib/setupRelayEnvironment/setupRelayEnvironment.d.ts +74 -57
- package/lib/setupRelayEnvironment/setupRelayEnvironment.helpers.d.ts +64 -56
- package/lib/setupRelayEnvironment/storage.d.ts +17 -17
- package/lib/setupRelayEnvironment/subscriptionHandler.d.ts +26 -20
- package/lib/useEnvironment/index.d.ts +5 -5
- package/lib/useEnvironment/index.esm.js +1 -0
- package/lib/useEnvironment/useEnvironment.d.ts +16 -16
- package/package.json +33 -6
- package/README.MD +0 -119
package/README.md
ADDED
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
# @apollion-dsi/relay
|
|
2
|
+
|
|
3
|
+
Configure and use **Relay** (`react-relay` / `relay-runtime`) the Apollion DS
|
|
4
|
+
way — Environment creation with auth, multipart uploads, WebSocket
|
|
5
|
+
subscriptions, and httpOnly-cookie sessions, without the boilerplate.
|
|
6
|
+
|
|
7
|
+
[](https://www.npmjs.com/package/@apollion-dsi/relay)
|
|
8
|
+
[](https://www.npmjs.com/package/@apollion-dsi/relay)
|
|
9
|
+
[](https://www.npmjs.com/package/@apollion-dsi/relay)
|
|
10
|
+
|
|
11
|
+
- **Environment in one call.** `CreateRelayEnvironment` wires the network layer,
|
|
12
|
+
auth, and error handling from a single config object.
|
|
13
|
+
- **Two auth models.** `Bearer` tokens or secure **httpOnly cookies** — switch
|
|
14
|
+
with one flag (see below).
|
|
15
|
+
- **Persisted queries.** Ship only build-time hashes over the wire — the server
|
|
16
|
+
executes nothing outside its allowlist (see below).
|
|
17
|
+
- **Batteries included.** Multipart file uploads, `graphql-ws` subscriptions,
|
|
18
|
+
and pluggable network retry / refresh ship with the package.
|
|
19
|
+
- **Typed.** Ships its own types for every option.
|
|
20
|
+
|
|
21
|
+
## Installation
|
|
22
|
+
|
|
23
|
+
`react` is a **peer dependency** (`^19.0.0`); the Relay stack (`react-relay` /
|
|
24
|
+
`relay-runtime` 21.x, `graphql` 16.x, `graphql-ws`, `fetch-multipart-graphql`,
|
|
25
|
+
`js-cookie`) ships with the package:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
yarn add @apollion-dsi/relay react
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
> To generate Relay artifacts, also add `relay-compiler` as a dev dependency and
|
|
32
|
+
> a `relay.config.js`.
|
|
33
|
+
|
|
34
|
+
## Documentation
|
|
35
|
+
|
|
36
|
+
- **Docs & API reference:** <https://www.apollion.com.br>
|
|
37
|
+
- **Changelog:** <https://www.apollion.com.br/changelog>
|
|
38
|
+
|
|
39
|
+
## Quick start
|
|
40
|
+
|
|
41
|
+
Create the Environment and provide it to your tree:
|
|
42
|
+
|
|
43
|
+
```tsx
|
|
44
|
+
import { CreateRelayEnvironment } from '@apollion-dsi/relay';
|
|
45
|
+
import { RelayEnvironmentProvider } from 'react-relay';
|
|
46
|
+
import { App } from './app';
|
|
47
|
+
|
|
48
|
+
const { Environment } = new CreateRelayEnvironment({
|
|
49
|
+
url: 'https://api.example.com/graphql',
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
<RelayEnvironmentProvider environment={Environment}>
|
|
53
|
+
<App />
|
|
54
|
+
</RelayEnvironmentProvider>;
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Authentication: Bearer vs. httpOnly cookie
|
|
58
|
+
|
|
59
|
+
The Environment supports two auth models via `authMode`.
|
|
60
|
+
|
|
61
|
+
### `authMode: 'bearer'` (default)
|
|
62
|
+
|
|
63
|
+
Reads the `sessionToken` from storage (`localStorage` or a JS-readable cookie)
|
|
64
|
+
and injects `Authorization: Bearer <token>` into every request; session
|
|
65
|
+
verification uses the `${authUrl}user/me` probe.
|
|
66
|
+
|
|
67
|
+
```ts
|
|
68
|
+
new CreateRelayEnvironment({
|
|
69
|
+
url: 'https://api.example.com/graphql/',
|
|
70
|
+
authUrl: 'https://api.example.com/auth/',
|
|
71
|
+
useAuthorization: true,
|
|
72
|
+
storageType: 'cookie', // JS-readable cookie, or 'localStorage'
|
|
73
|
+
});
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### `authMode: 'cookie'` (httpOnly session — recommended for SPAs)
|
|
77
|
+
|
|
78
|
+
The session token lives in an **httpOnly + SameSite** cookie, invisible to JS
|
|
79
|
+
and immune to XSS. The Environment never reads the token or sets
|
|
80
|
+
`Authorization` — `credentials: 'include'` makes the browser attach the cookie
|
|
81
|
+
automatically. On an auth error (e.g. 401), a refresh `POST` is fired to
|
|
82
|
+
`authUrl` with credentials, without probing `user/me`.
|
|
83
|
+
|
|
84
|
+
```ts
|
|
85
|
+
new CreateRelayEnvironment({
|
|
86
|
+
url: 'https://api.example.com/graphql/',
|
|
87
|
+
authUrl: 'https://api.example.com/auth/refresh/',
|
|
88
|
+
authMode: 'cookie',
|
|
89
|
+
redirectOnError: true,
|
|
90
|
+
loginRoute: '/login',
|
|
91
|
+
});
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
| Option | Default | What it does |
|
|
95
|
+
| ----------------- | ---------------------------------- | ----------------------------------------------------------------------------------------- |
|
|
96
|
+
| `authMode` | `'bearer'` | `'bearer'` (token + header) or `'cookie'` (httpOnly). |
|
|
97
|
+
| `credentials` | cookie→`'include'`; bearer→omitted | `RequestCredentials` forwarded to the GraphQL and refresh fetches. Works in both modes. |
|
|
98
|
+
| `sessionCheckUrl` | mode-dependent | Overrides the probe URL; `false` disables it (auth error → direct logout, no extra call). |
|
|
99
|
+
|
|
100
|
+
## Persisted queries
|
|
101
|
+
|
|
102
|
+
With `usePersistedQueries: true`, every operation ships as a **build-time
|
|
103
|
+
hash** instead of GraphQL text. The server keeps the matching query map and
|
|
104
|
+
executes only hashes it knows — a tampered client query is refused, and the
|
|
105
|
+
server can cache aggressively by hash.
|
|
106
|
+
|
|
107
|
+
1. Enable `persistConfig` in your `relay.config.json` so `relay-compiler`
|
|
108
|
+
writes the query map and stamps each artifact's `id`:
|
|
109
|
+
|
|
110
|
+
```json
|
|
111
|
+
{
|
|
112
|
+
"src": "./src",
|
|
113
|
+
"schema": "./schema.graphql",
|
|
114
|
+
"language": "typescript",
|
|
115
|
+
"persistConfig": { "file": "./persisted/queryMap.json", "algorithm": "MD5" }
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
2. Ship `queryMap.json` to your GraphQL server as the allowlist.
|
|
120
|
+
|
|
121
|
+
3. Turn the flag on:
|
|
122
|
+
|
|
123
|
+
```ts
|
|
124
|
+
new CreateRelayEnvironment({
|
|
125
|
+
url: 'https://api.example.com/graphql/',
|
|
126
|
+
usePersistedQueries: true,
|
|
127
|
+
});
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
The request body becomes `{ name, doc_id, variables }` — no `query` key.
|
|
131
|
+
Uploads carry the hash inside the multipart `operations` field, and
|
|
132
|
+
subscriptions send it in `payload.extensions.doc_id` over `graphql-ws`.
|
|
133
|
+
|
|
134
|
+
| Option | Default | What it does |
|
|
135
|
+
| ------------------------- | ---------- | ------------------------------------------------------------------------------ |
|
|
136
|
+
| `usePersistedQueries` | `false` | Sends only the persisted hash; the GraphQL text never leaves the build. |
|
|
137
|
+
| `persistedOperationField` | `'doc_id'` | Renames the hash field to whatever your server's allowlist middleware expects. |
|
|
138
|
+
|
|
139
|
+
> **Server contract:** resolve the hash against the query map; refuse raw text
|
|
140
|
+
> and unknown hashes replying `200` + `{ "errors": [...] }` with
|
|
141
|
+
> `Content-Type: application/json` — a `4xx` is treated as a transport failure
|
|
142
|
+
> by the client's retry layer instead of surfacing the GraphQL error.
|
|
143
|
+
|
|
144
|
+
## License
|
|
145
|
+
|
|
146
|
+
MIT.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a as e}from"./chunk-GZONWSRB.esm.js";import r from"react";var t=r.createContext(void 0);function m({children:n,environment:o}){return r.createElement(t.Provider,{value:{environment:o}},n)}e(m,"EnvironmentProvider");function v(){let n=r.useContext(t);if(n===void 0)throw new Error("useEnvironment must be used within a EnvironmentProvider");if(n.environment===null||n.environment===void 0)throw new Error("You should provide a Relay Environment to EnvironmentProvider component");return n}e(v,"useEnvironment");export{m as a,v as b};
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var c=Object.defineProperty;var d=(a,b)=>c(a,"name",{value:b,configurable:!0});export{d as a};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a as s}from"./chunk-GZONWSRB.esm.js";import{Environment as ae,Network as ue,RecordSource as le,Store as ce}from"relay-runtime";import{Observable as te,QueryResponseCache as re}from"relay-runtime";var E=!!(typeof window!="undefined"&&window.document&&window.document.createElement),f={canUseDOM:E,canUseWorkers:typeof Worker!="undefined",canUseEventListeners:E&&!!(window.addEventListener||window.attachEvent),canUseViewport:E&&!!window.screen,isInWorker:!E};function $(e){return async t=>{let r=e.timeout,o=e.retries,a=0,i=0;return new Promise((u,l)=>{let c={};c.sendTimedRequest=()=>{a++,i=Date.now();let n=!0,p=new AbortController,m=setTimeout(()=>{if(n=!1,p.abort(),c.shouldRetry(a))e.useDebug&&console.log("fetchWithRetries: HTTP timeout, retrying."),c.retryRequest();else{let h=new Error(`fetchWithRetries(): Failed to get response from server, tried ${a} times.`);h.name="TimeOutError",l(h)}},r);fetch(e.url,{...t,signal:p.signal}).then(async h=>{if(clearTimeout(m),n)if(h.status>=200&&h.status<300)u(h);else if(c.shouldRetry(a)&&e.retryWhen.includes(h.status))e.useDebug&&console.log("fetchWithRetries: HTTP error, retrying..."),c.retryRequest();else{let d=new Error(`fetchWithRetries(): Still no successful response after ${a} retries, giving up.`);d.response=h,l(d)}}).catch(h=>{clearTimeout(m),h.name!=="AbortError"&&l(h)})},c.retryRequest=()=>{let n=o[a-1],p=i+n;setTimeout(c.sendTimedRequest,p-Date.now())},c.shouldRetry=n=>f.canUseDOM&&e.useRetries&&n<=o.length,c.sendTimedRequest()})}}s($,"fetchWithRetries");import{PatchResolver as X}from"fetch-multipart-graphql";var x=s(e=>e.operationKind==="mutation","isMutation"),O=s(e=>e.operationKind==="query","isQuery"),V=s(e=>!!(e&&e.force),"forceFetch"),Y=s(()=>f.canUseDOM?window.location.search.startsWith("?")?"&":"?":"","getParamsDelimiter"),C=s(()=>f.canUseDOM?window.location.pathname:"","getBrowserLocation"),R=s((e,t,r)=>{let o=e;(e!==t||r.loginRoute!==t)&&(o=`${t}${Y()}redirect=${e}`),window.location.href=o},"redirectUser");function L(e){if(!e.id)throw new Error(`[usePersistedQueries] Operation "${e.name}" has no persisted id \u2014 run relay-compiler with "persistConfig" set in relay.config.json.`);return e.id}s(L,"getPersistedOperationId");function Z(e,t,r,o){let a=new FormData,i=o!=null&&o.usePersistedQueries?{[o.persistedOperationField||"doc_id"]:L(e),variables:t,operationName:e.name}:{query:e.text,variables:t,operationName:e.name};a.append("operations",JSON.stringify(i));let u={};for(let l=0;l<r.files.length;l++)a.append(`${l}`,r.files[l]),u[`${l}`]=[r.path(l)];return a.append("map",JSON.stringify(u)),a}s(Z,"getRequestBodyWithUploadables");function ee(e,t,r){return r!=null&&r.usePersistedQueries?JSON.stringify({name:e.name,[r.persistedOperationField||"doc_id"]:L(e),variables:t}):JSON.stringify({name:e.name,query:e.text,variables:t})}s(ee,"getRequestBodyWithoutUplodables");function B(e,t,r,o){return r?Z(e,t,r,o):ee(e,t,o)}s(B,"getRequestBody");var U=s(e=>{if(e.credentials)return e.credentials;if(e.authMode==="cookie")return"include"},"resolveCredentials"),_=s((e,t)=>{let r=new Headers;if(t?r.append("Accept","*/*"):(r.append("Accept","application/json"),r.append("Content-type","application/json")),e.useAuthorization&&e.authMode!=="cookie"){let{sessionToken:o}=e.StorageHandler.getTokens();o&&C()!==e.loginRoute&&r.append("Authorization",`Bearer ${o}`)}return e.partner&&r.append("X-Partner",e.partner),r},"getHeaders"),j=s((e,t,r)=>{if(e.status<300&&e.headers&&e.headers.get("Content-Type")&&e.headers.get("Content-Type").indexOf("multipart/mixed")>=0){let o=e.body.getReader(),a=new TextDecoder,i=new X({onResponse:s(u=>t.next(u),"onResponse")});o.read().then(s(function u({value:l,done:c}){if(c)t.complete();else{let n;try{n=a.decode(l),i.handleChunk(n)}catch(p){let m=p;m.response=e,m.statusCode=e.status,m.bodyText=n,t.error(m)}o.read().then(u)}},"sendNext"))}else e.headers&&e.headers.get("Content-Type")&&e.headers.get("Content-Type").indexOf("application/json")>=0?e.json().then(r):e.text().then(o=>{t.next([o]),t.complete()})},"handleData"),b=1e3,v=b*60;var J=s(e=>{let t=new re({ttl:e.cacheTime,size:e.cacheSize}),r=$(e);async function o(){if(e.sessionCheckUrl===!1)return!1;let i=U(e);try{if(e.authMode==="cookie"){let n=e.sessionCheckUrl||e.authUrl;return(await fetch(n,{method:"POST",credentials:i||"include"})).status===200}let{sessionToken:u}=e.StorageHandler.getTokens(),l=e.sessionCheckUrl||`${e.authUrl}user/me`;return(await fetch(l,{headers:{"Content-Type":"application/json",Authorization:u},...i?{credentials:i}:{}})).status===200}catch(u){return console.warn(`[Auth] ${u.message}`),!1}}s(o,"checkSession");async function a(i,u,l,c,n){try{let p=i.id||("cacheID"in i?i.cacheID:null)||String(i.text);if(e.useCache&&O(i)&&!V(l)){let d=t.get(p,u);if(d){n.next(d),n.complete();return}}e.useCache&&x(i)&&t.clear();let m=U(e),h=await r({method:"POST",headers:_(e,c),body:B(i,u,c,e),...m?{credentials:m}:{}});j(h,n,async d=>{if(e.useCache&&O(i)&&t.set(p,u,d),!n.closed){if(x(i)&&d.errors&&n.error(d.errors),d.errors){if(await o()||(e.StorageHandler.clear(),R("/",e.loginRoute,e)),e.redirectOnError){let z=[];Array.isArray(d.errors)&&(z=d.errors.map(({status_code:P})=>P));let Q=C();z.some(P=>e.authenticationErrors.includes(P))&&Q!==e.loginRoute&&(e.StorageHandler.clear(),R(Q,e.loginRoute,e))}n.error(d.errors)}else d.data?n.next(d):n.error(d);n.complete()}})}catch(p){if(f.canUseDOM&&!["AbortError","TimeOutError"].includes(p.name)&&e.StorageHandler.clear(),e.redirectOnError){let h=C();h!==e.loginRoute&&R(h,e.loginRoute,e)}await o()||(e.StorageHandler.clear(),R("/",e.loginRoute,e)),n.error(p)}}return s(a,"fetchFn"),(i,u,l,c)=>te.create(n=>{a(i,u,l,c,n)})},"createFetchFunction");import se from"js-cookie";var A=class A{get(t){throw new Error('Must implement a "GET" method')}set(t,r){throw new Error('Must implement a "SET" method')}delete(t){throw new Error('Must implement a "DELETE" method')}};s(A,"DefaultStrategy");var k=A,I=class I extends k{constructor(){super(),this.strategy=localStorage}get(t){return this.strategy.getItem(t)}set(t,r){this.strategy.setItem(t,r)}delete(t){this.strategy.removeItem(t)}};s(I,"LocalStorageStrategy");var D=I,F=class F extends k{constructor(){super(),this.strategy=se}get(t){return this.strategy.get(t)}set(t,r){this.strategy.set(t,r)}delete(t){this.strategy.remove(t)}};s(F,"CookieStrategy");var M=F,y=Symbol("storage-handler"),g=Symbol("prop-session"),w=Symbol("prop-refresh"),H=class H{constructor(t){this[g]=t.sessionStorageProp,this[w]=t.refreshStorageProp,t.storageType==="cookie"?this[y]=new M:this[y]=new D}getTokens(){return{refreshToken:this[y].get(this[w]),sessionToken:this[y].get(this[g])}}setTokens(t){this[y].set(this[w],t.refreshToken),this[y].set(this[g],t.sessionToken)}clear(){this[y].delete(this[w]),this[y].delete(this[g])}hasChangedSession({sessionToken:t}){let{sessionToken:r}=this.getTokens();return t!==r}};s(H,"StorageClass");var S=H;import{createClient as oe}from"graphql-ws";import{Observable as ie}from"relay-runtime";function ne(e,t,r){if(e.usePersistedQueries){if(!t.id)throw new Error(`[usePersistedQueries] Operation "${t.name}" has no persisted id \u2014 run relay-compiler with "persistConfig" set in relay.config.json.`);return{operationName:t.name,query:"",variables:r,extensions:{[e.persistedOperationField||"doc_id"]:t.id}}}return{operationName:t.name,query:t.text||"",variables:r}}s(ne,"getSubscribePayload");function K(e){return()=>{let t;return(r,o)=>ie.create(a=>(t||(t=oe({url:e.socket})),t.subscribe(ne(e,r,o),{next:s(i=>a.next(i),"next"),error:s(i=>a.error(i),"error"),complete:s(()=>a.complete(),"complete")})))}}s(K,"setupSubscription");var G=Symbol("mount-environment"),N=Symbol("handler-fetch"),q=Symbol("handler-subscription"),W=class W{constructor(t){if(this.url=t.url,this.authUrl=t.authUrl,this.socket=t.socket,this.storageType=t.storageType||"localStorage",this.cacheSize=t.cacheSize||250,this.cacheTime=t.cacheTime||v*8,this.timeout=t.timeout||v*15,this.sessionStorageProp=t.sessionStorageProp||"USER_SESSION_TOKEN",this.refreshStorageProp=t.refreshStorageProp||"USER_REFRESH_TOKEN",this.loginRoute=t.loginRoute||"/",this.useCache=t.useCache||!1,this.useDebug=t.useDebug||!1,this.useAuthorization=t.useAuthorization||!1,this.authMode=t.authMode||"bearer",this.credentials=t.credentials,this.sessionCheckUrl=t.sessionCheckUrl,this.useRetries=t.useRetries||!1,this.useSubscription=t.useSubscription||!1,this.redirectOnError=t.redirectOnError||!1,this.retryWhen=t.retryWhen||[503,504,521,522,524],this.authenticationErrors=t.authenticationErrors||[401,403],this.retries=t.retries||[b,b*2,b*3,b*5,b*8,b*13,b*21,b*34],this.partner=t.partner||void 0,this.usePersistedQueries=t.usePersistedQueries||!1,this.persistedOperationField=t.persistedOperationField||"doc_id",!this.url)throw new Error("[HTTPFetchEndpoint] You must at least set url parameter.");if(this.useAuthorization&&!this.authUrl)throw new Error('[useAuthorization] Authorization is set but no "authUrl" was provided.');if(this.authMode==="cookie"&&this.sessionCheckUrl!==!1&&!this.authUrl)throw new Error('[authMode:cookie] Cookie auth refreshes against "authUrl" \u2014 provide it or set "sessionCheckUrl: false" to disable the probe.');if(this.StorageHandler=new S(this),this.useSubscription){if(!this.socket)throw new Error("[useSubscription] If you choose to use WebSocket you must set a socket endpoint.");this[q]=K(this)()}this[N]=J(this),this[G]()}[(N,q,G)](){let t=ue.create(this[N],this[q]||null),r=new le,o=new ce(r);this.Environment=new ae({network:t,store:o})}};s(W,"RelayEnvironment");var T=W;export{T as a};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a as o}from"./chunk-GZONWSRB.esm.js";import{commitMutation as m}from"relay-runtime";var p=o((t,r)=>new Promise((n,e)=>{m(t,{...r,onError:e,onCompleted:n})}),"commitMutation");export{p as a};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a as d}from"./chunk-GZONWSRB.esm.js";import{nanoid as g}from"nanoid";import{ConnectionHandler as p}from"relay-runtime";function y(e){return e!==null&&typeof e=="object"}d(y,"isObject");var O=g();function P({parentId:e,itemId:t,parentFieldName:o,store:n}){let r=n.get(e),i=r.getLinkedRecords(o);r.setLinkedRecords(i.filter(c=>c.dataID!==t),o)}d(P,"listRecordRemoveUpdater");function S({parentId:e,item:t,type:o,parentFieldName:n,store:r}){let i=r.create(t.id,o);Object.keys(t).forEach(s=>{i.setValue(t[s],s)});let c=r.get(e),a=c.getLinkedRecords(n);c.setLinkedRecords([...a,i],n)}d(S,"listRecordAddUpdater");function l(e,t,o,n,r=!1){if(n){let i=e.get(t),c=p.getConnection(i,o);if(!c)return;r?p.insertEdgeBefore(c,n):p.insertEdgeAfter(c,n)}}d(l,"connectionUpdater");function m({parentId:e,store:t,connectionName:o,item:n,customNode:r,itemType:i}){let c=r||t.create(n.id,i);!r&&Object.keys(n).forEach(s=>{c.setValue(n[s],s)});let a=t.create(`client:newEdge:${String(c.getDataID).match(/[^:]+$/)[0]}`,`${i}Edge`);a.setLinkedRecord(c,"node"),l(t,e,o,a)}d(m,"optimisticConnectionUpdater");function U({parentId:e,connectionName:t,nodeId:o,store:n}){let r=n.get(e),i=p.getConnection(r,t);if(!i){console.warn(`Connection ${t} not found on ${e}`);return}p.deleteNode(i,o)}d(U,"connectionDeleteEdgeUpdater");function C({object:e,proxy:t}){Object.keys(e).forEach(o=>{y(e[o])||Array.isArray(e[o])||t.setValue(e[o],o)})}d(C,"copyObjScalarsToProxy");export{y as a,O as b,P as c,S as d,l as e,m as f,U as g,C as h};
|
|
@@ -1,27 +1,27 @@
|
|
|
1
1
|
import { MutationConfig, MutationParameters } from 'relay-runtime';
|
|
2
2
|
import { Environment } from 'relay-runtime/lib/store/RelayStoreTypes';
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
4
|
+
* Promise-based wrapper around `relay-runtime`'s `commitMutation`.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* `optimisticResponse`, `updater`, `cacheConfig` etc.,
|
|
11
|
-
*
|
|
6
|
+
* Relay's original `commitMutation` exposes mutation completion via the
|
|
7
|
+
* `onCompleted` and `onError` callbacks. This function encapsulates those
|
|
8
|
+
* callbacks in a `Promise`, allowing natural `async/await` usage in the
|
|
9
|
+
* consumer — which typically covers 95% of the cases. For flows that need
|
|
10
|
+
* `optimisticResponse`, `updater`, `cacheConfig` etc., all the remaining
|
|
11
|
+
* `MutationConfig` options are still accepted via `config`.
|
|
12
12
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
13
|
+
* The `onCompleted` and `onError` fields are omitted from `config` on purpose:
|
|
14
|
+
* they are managed internally to feed the Promise's resolve/reject.
|
|
15
15
|
*
|
|
16
|
-
* @typeParam T -
|
|
17
|
-
* tagged) —
|
|
16
|
+
* @typeParam T - Type generated by the Relay Compiler for the mutation
|
|
17
|
+
* (`graphql` tagged) — provides the shape of `variables` and `response`.
|
|
18
18
|
*
|
|
19
|
-
* @param environment -
|
|
19
|
+
* @param environment - Relay environment (usually the one exposed by
|
|
20
20
|
* `CreateRelayEnvironment`).
|
|
21
|
-
* @param config -
|
|
21
|
+
* @param config - Mutation configuration, without `onCompleted` and `onError`.
|
|
22
22
|
*
|
|
23
|
-
* @returns Promise
|
|
24
|
-
*
|
|
23
|
+
* @returns Promise that resolves with `T['response']` or rejects with the
|
|
24
|
+
* error returned by Relay.
|
|
25
25
|
*
|
|
26
26
|
* @example
|
|
27
27
|
* ```tsx
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Public barrel for the `commitMutation` module.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* via `@apollion-dsi/relay/commitMutation` (
|
|
6
|
-
*
|
|
4
|
+
* Re-exports the `commitMutation` function so consumers can import it
|
|
5
|
+
* via `@apollion-dsi/relay/commitMutation` (granular import, avoiding
|
|
6
|
+
* loading the rest of the package) or via `@apollion-dsi/relay` (root barrel).
|
|
7
7
|
*/
|
|
8
8
|
export * from './commitMutation';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a}from"../chunks/chunk-RMYDTZUF.esm.js";import"../chunks/chunk-GZONWSRB.esm.js";export{a as commitMutation};
|
package/lib/index.d.ts
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Public barrel for the `@apollion-dsi/relay` package.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* (`CreateRelayEnvironment`),
|
|
6
|
-
* `useEnvironment`),
|
|
7
|
-
* `Sink`),
|
|
8
|
-
*
|
|
4
|
+
* Re-exports the package's public surface: the Environment factory
|
|
5
|
+
* (`CreateRelayEnvironment`), the Context/hook (`EnvironmentProvider` /
|
|
6
|
+
* `useEnvironment`), the configuration types (`RelayArgsInterface`,
|
|
7
|
+
* `Sink`), the mutation updater utilities and the Promise-based
|
|
8
|
+
* `commitMutation` wrapper.
|
|
9
9
|
*
|
|
10
|
-
*
|
|
11
|
-
* `@apollion-dsi/relay/<
|
|
12
|
-
*
|
|
10
|
+
* Each module can also be imported granularly via
|
|
11
|
+
* `@apollion-dsi/relay/<name>` when the consumer wants to load
|
|
12
|
+
* less code.
|
|
13
13
|
*/
|
|
14
|
-
export {
|
|
14
|
+
export { CreateRelayEnvironment } from './setupRelayEnvironment';
|
|
15
15
|
export * from './useEnvironment';
|
|
16
16
|
export * from './relayArgsInterface';
|
|
17
17
|
export * from './mutationUtils';
|
package/lib/index.esm.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var Z=Object.defineProperty;var o=(e,t)=>Z(e,"name",{value:t,configurable:!0});import{Environment as ue,Network as le,RecordSource as de,Store as pe}from"relay-runtime";import{Observable as ne,QueryResponseCache as se}from"relay-runtime";var S=!!(typeof window!="undefined"&&window.document&&window.document.createElement),b={canUseDOM:S,canUseWorkers:typeof Worker!="undefined",canUseEventListeners:S&&!!(window.addEventListener||window.attachEvent),canUseViewport:S&&!!window.screen,isInWorker:!S};function j(e){return async t=>{let r=e.timeout,n=e.retries,i=0,s=0;return new Promise((a,l)=>{let u={};u.sendTimedRequest=()=>{i++,s=Date.now();let c=!0,h=new AbortController,m=setTimeout(()=>{if(c=!1,h.abort(),u.shouldRetry(i))e.useDebug&&console.log("fetchWithRetries: HTTP timeout, retrying."),u.retryRequest();else{let d=new Error(`fetchWithRetries(): Failed to get response from server, tried ${i} times.`);d.name="TimeOutError",l(d)}},r);fetch(e.url,{...t,signal:h.signal}).then(async d=>{if(clearTimeout(m),c)if(d.status>=200&&d.status<300)a(d);else if(u.shouldRetry(i)&&e.retryWhen.includes(d.status))e.useDebug&&console.log("fetchWithRetries: HTTP error, retrying..."),u.retryRequest();else{let p=new Error(`fetchWithRetries(): Still no successful response after ${i} retries, giving up.`);p.response=d,l(p)}}).catch(d=>{clearTimeout(m),d.name!=="AbortError"&&l(d)})},u.retryRequest=()=>{let c=n[i-1],h=s+c;setTimeout(u.sendTimedRequest,h-Date.now())},u.shouldRetry=c=>b.canUseDOM&&e.useRetries&&c<=n.length,u.sendTimedRequest()})}}o(j,"fetchWithRetries");import{PatchResolver as ee}from"fetch-multipart-graphql";var k=o(e=>e.operationKind==="mutation","isMutation"),U=o(e=>e.operationKind==="query","isQuery"),B=o(e=>!!(e&&e.force),"forceFetch"),te=o(()=>b.canUseDOM?window.location.search.startsWith("?")?"&":"?":"","getParamsDelimiter"),T=o(()=>b.canUseDOM?window.location.pathname:"","getBrowserLocation"),g=o((e,t,r)=>{let n=e;(e!==t||r.loginRoute!==t)&&(n=`${t}${te()}redirect=${e}`),window.location.href=n},"redirectUser");function re(e,t,r){let n=new FormData;n.append("operations",JSON.stringify({query:e.text,variables:t,operationName:e.name}));let i={};for(let s=0;s<r.files.length;s++)n.append(`${s}`,r.files[s]),i[`${s}`]=[r.path(s)];return n.append("map",JSON.stringify(i)),n}o(re,"getRequestBodyWithUploadables");function oe(e,t){return JSON.stringify({name:e.name,query:e.text,variables:t})}o(oe,"getRequestBodyWithoutUplodables");function K(e,t,r){return r?re(e,t,r):oe(e,t)}o(K,"getRequestBody");var O=o(e=>{if(e.credentials)return e.credentials;if(e.authMode==="cookie")return"include"},"resolveCredentials"),_=o((e,t)=>{let r=new Headers;if(t?r.append("Accept","*/*"):(r.append("Accept","application/json"),r.append("Content-type","application/json")),e.useAuthorization&&e.authMode!=="cookie"){let{sessionToken:n}=e.StorageHandler.getTokens();n&&T()!==e.loginRoute&&r.append("Authorization",`Bearer ${n}`)}return e.partner&&r.append("X-Partner",e.partner),r},"getHeaders"),J=o((e,t,r)=>{if(e.status<300&&e.headers&&e.headers.get("Content-Type")&&e.headers.get("Content-Type").indexOf("multipart/mixed")>=0){let n=e.body.getReader(),i=new TextDecoder,s=new ee({onResponse:o(a=>t.next(a),"onResponse")});n.read().then(o(function a({value:l,done:u}){if(u)t.complete();else{let c;try{c=i.decode(l),s.handleChunk(c)}catch(h){let m=h;m.response=e,m.statusCode=e.status,m.bodyText=c,t.error(m)}n.read().then(a)}},"sendNext"))}else e.headers&&e.headers.get("Content-Type")&&e.headers.get("Content-Type").indexOf("application/json")>=0?e.json().then(r):e.text().then(n=>{t.next([n]),t.complete()})},"handleData"),f=1e3,M=f*60;var Q=o(e=>{let t=new se({ttl:e.cacheTime,size:e.cacheSize}),r=j(e);async function n(){if(e.sessionCheckUrl===!1)return!1;let s=O(e);try{if(e.authMode==="cookie"){let c=e.sessionCheckUrl||e.authUrl;return(await fetch(c,{method:"POST",credentials:s||"include"})).status===200}let{sessionToken:a}=e.StorageHandler.getTokens(),l=e.sessionCheckUrl||`${e.authUrl}user/me`;return(await fetch(l,{headers:{"Content-Type":"application/json",Authorization:a},...s?{credentials:s}:{}})).status===200}catch(a){return console.warn(`[Auth] ${a.message}`),!1}}o(n,"checkSession");async function i(s,a,l,u,c){try{let h=String(s.text);if(e.useCache&&U(s)&&!B(l)){let p=t.get(h,a);if(p){c.next(p),c.complete();return}}e.useCache&&k(s)&&t.clear();let m=O(e),d=await r({method:"POST",headers:_(e,u),body:K(s,a,u),...m?{credentials:m}:{}});J(d,c,async p=>{if(e.useCache&&U(s)&&t.set(h,a,p),!c.closed){if(k(s)&&p.errors&&c.error(p.errors),p.errors){if(await n()||(e.StorageHandler.clear(),g("/",e.loginRoute,e)),e.redirectOnError){let F=[];Array.isArray(p.errors)&&(F=p.errors.map(({status_code:P})=>P));let V=T();F.some(P=>e.authenticationErrors.includes(P))&&V!==e.loginRoute&&(e.StorageHandler.clear(),g(V,e.loginRoute,e))}c.error(p.errors)}else p.data?c.next(p):c.error(p);c.complete()}})}catch(h){if(b.canUseDOM&&!["AbortError","TimeOutError"].includes(h.name)&&e.StorageHandler.clear(),e.redirectOnError){let d=T();d!==e.loginRoute&&g(d,e.loginRoute,e)}await n()||(e.StorageHandler.clear(),g("/",e.loginRoute,e)),c.error(h)}}return o(i,"fetchFn"),(s,a,l,u)=>ne.create(c=>{i(s,a,l,u,c)})},"createFetchFunction");import ie from"js-cookie";var A=class A{get(t){throw new Error('Must implement a "GET" method')}set(t,r){throw new Error('Must implement a "SET" method')}delete(t){throw new Error('Must implement a "DELETE" method')}};o(A,"DefaultStrategy");var w=A,q=class q extends w{constructor(){super(),this.strategy=localStorage}get(t){return this.strategy.getItem(t)}set(t,r){this.strategy.setItem(t,r)}delete(t){this.strategy.removeItem(t)}};o(q,"LocalStorageStrategy");var D=q,H=class H extends w{constructor(){super(),this.strategy=ie}get(t){return this.strategy.get(t)}set(t,r){this.strategy.set(t,r)}delete(t){this.strategy.remove(t)}};o(H,"CookieStrategy");var I=H,y=Symbol("storage-handler"),R=Symbol("prop-session"),E=Symbol("prop-refresh"),N=class N{constructor(t){this[R]=t.sessionStorageProp,this[E]=t.refreshStorageProp,t.storageType==="cookie"?this[y]=new I:this[y]=new D}getTokens(){return{refreshToken:this[y].get(this[E]),sessionToken:this[y].get(this[R])}}setTokens(t){this[y].set(this[E],t.refreshToken),this[y].set(this[R],t.sessionToken)}clear(){this[y].delete(this[E]),this[y].delete(this[R])}hasChangedSession({sessionToken:t}){let{sessionToken:r}=this.getTokens();return t!==r}};o(N,"StorageClass");var x=N;import{createClient as ae}from"graphql-ws";import{Observable as ce}from"relay-runtime";function Y(e){return()=>{let t=ae({url:e.socket});return(r,n)=>ce.create(i=>t.subscribe({operationName:r.name,query:r.text||"",variables:n},{next:o(s=>i.next(s),"next"),error:o(s=>i.error(s),"error"),complete:o(()=>i.complete(),"complete")}))}}o(Y,"setupSubscription");var G=Symbol("mount-environment"),W=Symbol("handler-fetch"),L=Symbol("handler-subscription"),$=class ${constructor(t){if(this.url=t.url,this.authUrl=t.authUrl,this.socket=t.socket,this.storageType=t.storageType||"localStorage",this.cacheSize=t.cacheSize||250,this.cacheTime=t.cacheTime||M*8,this.timeout=t.timeout||M*15,this.sessionStorageProp=t.sessionStorageProp||"USER_SESSION_TOKEN",this.refreshStorageProp=t.refreshStorageProp||"USER_REFRESH_TOKEN",this.loginRoute=t.loginRoute||"/",this.useCache=t.useCache||!1,this.useDebug=t.useDebug||!1,this.useAuthorization=t.useAuthorization||!1,this.authMode=t.authMode||"bearer",this.credentials=t.credentials,this.sessionCheckUrl=t.sessionCheckUrl,this.useRetries=t.useRetries||!1,this.useSubscription=t.useSubscription||!1,this.redirectOnError=t.redirectOnError||!1,this.retryWhen=t.retryWhen||[503,504,521,522,524],this.authenticationErrors=t.authenticationErrors||[401,403],this.retries=t.retries||[f,f*2,f*3,f*5,f*8,f*13,f*21,f*34],this.partner=t.partner||void 0,!this.url)throw new Error("[HTTPFetchEndpoint] You must at least set url parameter.");if(this.useAuthorization&&!this.authUrl)throw new Error('[useAuthorization] Authorization is set but no "authUrl" was provided.');if(this.authMode==="cookie"&&this.sessionCheckUrl!==!1&&!this.authUrl)throw new Error('[authMode:cookie] Cookie auth refreshes against "authUrl" \u2014 provide it or set "sessionCheckUrl: false" to disable the probe.');if(this.StorageHandler=new x(this),this.useSubscription){if(!this.socket)throw new Error("[useSubscription] If you choose to use WebSocket you must set a socket endpoint.");this[L]=Y(this)}this[W]=Q(this),this[G]()}[(W,L,G)](){let t=le.create(this[W],this[L]||null),r=new de,n=new pe(r);this.Environment=new ue({network:t,store:n})}};o($,"RelayEnvironment");var C=$;import z from"react";var X=z.createContext(void 0);function et({children:e,environment:t}){return z.createElement(X.Provider,{value:{environment:t}},e)}o(et,"EnvironmentProvider");function tt(){let e=z.useContext(X);if(e===void 0)throw new Error("useEnvironment must be used within a EnvironmentProvider");if(e.environment===null||e.environment===void 0)throw new Error("You should provide a Relay Environment to EnvironmentProvider component");return e}o(tt,"useEnvironment");import{nanoid as he}from"nanoid";import{ConnectionHandler as v}from"relay-runtime";function me(e){return e!==null&&typeof e=="object"}o(me,"isObject");var dt=he();function pt({parentId:e,itemId:t,parentFieldName:r,store:n}){let i=n.get(e),s=i.getLinkedRecords(r);i.setLinkedRecords(s.filter(a=>a.dataID!==t),r)}o(pt,"listRecordRemoveUpdater");function ht({parentId:e,item:t,type:r,parentFieldName:n,store:i}){let s=i.create(t.id,r);Object.keys(t).forEach(u=>{s.setValue(t[u],u)});let a=i.get(e),l=a.getLinkedRecords(n);a.setLinkedRecords([...l,s],n)}o(ht,"listRecordAddUpdater");function fe(e,t,r,n,i=!1){if(n){let s=e.get(t),a=v.getConnection(s,r);if(!a)return;i?v.insertEdgeBefore(a,n):v.insertEdgeAfter(a,n)}}o(fe,"connectionUpdater");function mt({parentId:e,store:t,connectionName:r,item:n,customNode:i,itemType:s}){let a=i||t.create(n.id,s);!i&&Object.keys(n).forEach(u=>{a.setValue(n[u],u)});let l=t.create(`client:newEdge:${String(a.getDataID).match(/[^:]+$/)[0]}`,`${s}Edge`);l.setLinkedRecord(a,"node"),fe(t,e,r,l)}o(mt,"optimisticConnectionUpdater");function ft({parentId:e,connectionName:t,nodeId:r,store:n}){let i=n.get(e),s=v.getConnection(i,t);if(!s){console.warn(`Connection ${t} not found on ${e}`);return}v.deleteNode(s,r)}o(ft,"connectionDeleteEdgeUpdater");function yt({object:e,proxy:t}){Object.keys(e).forEach(r=>{me(e[r])||Array.isArray(e[r])||t.setValue(e[r],r)})}o(yt,"copyObjScalarsToProxy");import{commitMutation as ye}from"relay-runtime";var Tt=o((e,t)=>new Promise((r,n)=>{ye(e,{...t,onError:n,onCompleted:r})}),"commitMutation");export{dt as ClientMutationID,C as CreateRelayEnvironment,et as EnvironmentProvider,Tt as commitMutation,ft as connectionDeleteEdgeUpdater,fe as connectionUpdater,yt as copyObjScalarsToProxy,me as isObject,ht as listRecordAddUpdater,pt as listRecordRemoveUpdater,mt as optimisticConnectionUpdater,tt as useEnvironment};
|
|
1
|
+
import{a as o}from"./chunks/chunk-RMYDTZUF.esm.js";import{a as m,b as f,c as p,d as x,e as n,f as a,g as i,h as l}from"./chunks/chunk-XJA2SRQY.esm.js";import"./chunks/chunk-FYOI5Q5V.esm.js";import{a as r}from"./chunks/chunk-KIA6YWO5.esm.js";import{a as e,b as t}from"./chunks/chunk-54QV6DFY.esm.js";import"./chunks/chunk-GZONWSRB.esm.js";export{f as ClientMutationID,r as CreateRelayEnvironment,e as EnvironmentProvider,o as commitMutation,i as connectionDeleteEdgeUpdater,n as connectionUpdater,l as copyObjScalarsToProxy,m as isObject,x as listRecordAddUpdater,p as listRecordRemoveUpdater,a as optimisticConnectionUpdater,t as useEnvironment};
|
package/lib/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var pe=Object.create;var E=Object.defineProperty;var he=Object.getOwnPropertyDescriptor;var me=Object.getOwnPropertyNames;var fe=Object.getPrototypeOf,ye=Object.prototype.hasOwnProperty;var o=(e,t)=>E(e,"name",{value:t,configurable:!0});var be=(e,t)=>{for(var r in t)E(e,r,{get:t[r],enumerable:!0})},_=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of me(t))!ye.call(e,i)&&i!==r&&E(e,i,{get:()=>t[i],enumerable:!(n=he(t,i))||n.enumerable});return e};var J=(e,t,r)=>(r=e!=null?pe(fe(e)):{},_(t||!e||!e.__esModule?E(r,"default",{value:e,enumerable:!0}):r,e)),ge=e=>_(E({},"__esModule",{value:!0}),e);var Me={};be(Me,{ClientMutationID:()=>Te,CreateRelayEnvironment:()=>w,EnvironmentProvider:()=>ve,commitMutation:()=>Oe,connectionDeleteEdgeUpdater:()=>ke,connectionUpdater:()=>le,copyObjScalarsToProxy:()=>Ue,isObject:()=>ue,listRecordAddUpdater:()=>Ce,listRecordRemoveUpdater:()=>we,optimisticConnectionUpdater:()=>Pe,useEnvironment:()=>Se});module.exports=ge(Me);var b=require("relay-runtime");var k=require("relay-runtime");var C=!!(typeof window!="undefined"&&window.document&&window.document.createElement),g={canUseDOM:C,canUseWorkers:typeof Worker!="undefined",canUseEventListeners:C&&!!(window.addEventListener||window.attachEvent),canUseViewport:C&&!!window.screen,isInWorker:!C};function Q(e){return async t=>{let r=e.timeout,n=e.retries,i=0,s=0;return new Promise((a,l)=>{let u={};u.sendTimedRequest=()=>{i++,s=Date.now();let c=!0,h=new AbortController,m=setTimeout(()=>{if(c=!1,h.abort(),u.shouldRetry(i))e.useDebug&&console.log("fetchWithRetries: HTTP timeout, retrying."),u.retryRequest();else{let d=new Error(`fetchWithRetries(): Failed to get response from server, tried ${i} times.`);d.name="TimeOutError",l(d)}},r);fetch(e.url,{...t,signal:h.signal}).then(async d=>{if(clearTimeout(m),c)if(d.status>=200&&d.status<300)a(d);else if(u.shouldRetry(i)&&e.retryWhen.includes(d.status))e.useDebug&&console.log("fetchWithRetries: HTTP error, retrying..."),u.retryRequest();else{let p=new Error(`fetchWithRetries(): Still no successful response after ${i} retries, giving up.`);p.response=d,l(p)}}).catch(d=>{clearTimeout(m),d.name!=="AbortError"&&l(d)})},u.retryRequest=()=>{let c=n[i-1],h=s+c;setTimeout(u.sendTimedRequest,h-Date.now())},u.shouldRetry=c=>g.canUseDOM&&e.useRetries&&c<=n.length,u.sendTimedRequest()})}}o(Q,"fetchWithRetries");var Y=require("fetch-multipart-graphql");var D=o(e=>e.operationKind==="mutation","isMutation"),I=o(e=>e.operationKind==="query","isQuery"),G=o(e=>!!(e&&e.force),"forceFetch"),Re=o(()=>g.canUseDOM?window.location.search.startsWith("?")?"&":"?":"","getParamsDelimiter"),P=o(()=>g.canUseDOM?window.location.pathname:"","getBrowserLocation"),x=o((e,t,r)=>{let n=e;(e!==t||r.loginRoute!==t)&&(n=`${t}${Re()}redirect=${e}`),window.location.href=n},"redirectUser");function Ee(e,t,r){let n=new FormData;n.append("operations",JSON.stringify({query:e.text,variables:t,operationName:e.name}));let i={};for(let s=0;s<r.files.length;s++)n.append(`${s}`,r.files[s]),i[`${s}`]=[r.path(s)];return n.append("map",JSON.stringify(i)),n}o(Ee,"getRequestBodyWithUploadables");function xe(e,t){return JSON.stringify({name:e.name,query:e.text,variables:t})}o(xe,"getRequestBodyWithoutUplodables");function X(e,t,r){return r?Ee(e,t,r):xe(e,t)}o(X,"getRequestBody");var A=o(e=>{if(e.credentials)return e.credentials;if(e.authMode==="cookie")return"include"},"resolveCredentials"),Z=o((e,t)=>{let r=new Headers;if(t?r.append("Accept","*/*"):(r.append("Accept","application/json"),r.append("Content-type","application/json")),e.useAuthorization&&e.authMode!=="cookie"){let{sessionToken:n}=e.StorageHandler.getTokens();n&&P()!==e.loginRoute&&r.append("Authorization",`Bearer ${n}`)}return e.partner&&r.append("X-Partner",e.partner),r},"getHeaders"),ee=o((e,t,r)=>{if(e.status<300&&e.headers&&e.headers.get("Content-Type")&&e.headers.get("Content-Type").indexOf("multipart/mixed")>=0){let n=e.body.getReader(),i=new TextDecoder,s=new Y.PatchResolver({onResponse:o(a=>t.next(a),"onResponse")});n.read().then(o(function a({value:l,done:u}){if(u)t.complete();else{let c;try{c=i.decode(l),s.handleChunk(c)}catch(h){let m=h;m.response=e,m.statusCode=e.status,m.bodyText=c,t.error(m)}n.read().then(a)}},"sendNext"))}else e.headers&&e.headers.get("Content-Type")&&e.headers.get("Content-Type").indexOf("application/json")>=0?e.json().then(r):e.text().then(n=>{t.next([n]),t.complete()})},"handleData"),f=1e3,q=f*60;var te=o(e=>{let t=new k.QueryResponseCache({ttl:e.cacheTime,size:e.cacheSize}),r=Q(e);async function n(){if(e.sessionCheckUrl===!1)return!1;let s=A(e);try{if(e.authMode==="cookie"){let c=e.sessionCheckUrl||e.authUrl;return(await fetch(c,{method:"POST",credentials:s||"include"})).status===200}let{sessionToken:a}=e.StorageHandler.getTokens(),l=e.sessionCheckUrl||`${e.authUrl}user/me`;return(await fetch(l,{headers:{"Content-Type":"application/json",Authorization:a},...s?{credentials:s}:{}})).status===200}catch(a){return console.warn(`[Auth] ${a.message}`),!1}}o(n,"checkSession");async function i(s,a,l,u,c){try{let h=String(s.text);if(e.useCache&&I(s)&&!G(l)){let p=t.get(h,a);if(p){c.next(p),c.complete();return}}e.useCache&&D(s)&&t.clear();let m=A(e),d=await r({method:"POST",headers:Z(e,u),body:X(s,a,u),...m?{credentials:m}:{}});ee(d,c,async p=>{if(e.useCache&&I(s)&&t.set(h,a,p),!c.closed){if(D(s)&&p.errors&&c.error(p.errors),p.errors){if(await n()||(e.StorageHandler.clear(),x("/",e.loginRoute,e)),e.redirectOnError){let B=[];Array.isArray(p.errors)&&(B=p.errors.map(({status_code:M})=>M));let K=P();B.some(M=>e.authenticationErrors.includes(M))&&K!==e.loginRoute&&(e.StorageHandler.clear(),x(K,e.loginRoute,e))}c.error(p.errors)}else p.data?c.next(p):c.error(p);c.complete()}})}catch(h){if(g.canUseDOM&&!["AbortError","TimeOutError"].includes(h.name)&&e.StorageHandler.clear(),e.redirectOnError){let d=P();d!==e.loginRoute&&x(d,e.loginRoute,e)}await n()||(e.StorageHandler.clear(),x("/",e.loginRoute,e)),c.error(h)}}return o(i,"fetchFn"),(s,a,l,u)=>k.Observable.create(c=>{i(s,a,l,u,c)})},"createFetchFunction");var re=J(require("js-cookie"));var W=class W{get(t){throw new Error('Must implement a "GET" method')}set(t,r){throw new Error('Must implement a "SET" method')}delete(t){throw new Error('Must implement a "DELETE" method')}};o(W,"DefaultStrategy");var U=W,L=class L extends U{constructor(){super(),this.strategy=localStorage}get(t){return this.strategy.getItem(t)}set(t,r){this.strategy.setItem(t,r)}delete(t){this.strategy.removeItem(t)}};o(L,"LocalStorageStrategy");var H=L,$=class $ extends U{constructor(){super(),this.strategy=re.default}get(t){return this.strategy.get(t)}set(t,r){this.strategy.set(t,r)}delete(t){this.strategy.remove(t)}};o($,"CookieStrategy");var N=$,y=Symbol("storage-handler"),v=Symbol("prop-session"),S=Symbol("prop-refresh"),z=class z{constructor(t){this[v]=t.sessionStorageProp,this[S]=t.refreshStorageProp,t.storageType==="cookie"?this[y]=new N:this[y]=new H}getTokens(){return{refreshToken:this[y].get(this[S]),sessionToken:this[y].get(this[v])}}setTokens(t){this[y].set(this[S],t.refreshToken),this[y].set(this[v],t.sessionToken)}clear(){this[y].delete(this[S]),this[y].delete(this[v])}hasChangedSession({sessionToken:t}){let{sessionToken:r}=this.getTokens();return t!==r}};o(z,"StorageClass");var T=z;var oe=require("graphql-ws"),ne=require("relay-runtime");function se(e){return()=>{let t=(0,oe.createClient)({url:e.socket});return(r,n)=>ne.Observable.create(i=>t.subscribe({operationName:r.name,query:r.text||"",variables:n},{next:o(s=>i.next(s),"next"),error:o(s=>i.error(s),"error"),complete:o(()=>i.complete(),"complete")}))}}o(se,"setupSubscription");var ie=Symbol("mount-environment"),F=Symbol("handler-fetch"),V=Symbol("handler-subscription"),j=class j{constructor(t){if(this.url=t.url,this.authUrl=t.authUrl,this.socket=t.socket,this.storageType=t.storageType||"localStorage",this.cacheSize=t.cacheSize||250,this.cacheTime=t.cacheTime||q*8,this.timeout=t.timeout||q*15,this.sessionStorageProp=t.sessionStorageProp||"USER_SESSION_TOKEN",this.refreshStorageProp=t.refreshStorageProp||"USER_REFRESH_TOKEN",this.loginRoute=t.loginRoute||"/",this.useCache=t.useCache||!1,this.useDebug=t.useDebug||!1,this.useAuthorization=t.useAuthorization||!1,this.authMode=t.authMode||"bearer",this.credentials=t.credentials,this.sessionCheckUrl=t.sessionCheckUrl,this.useRetries=t.useRetries||!1,this.useSubscription=t.useSubscription||!1,this.redirectOnError=t.redirectOnError||!1,this.retryWhen=t.retryWhen||[503,504,521,522,524],this.authenticationErrors=t.authenticationErrors||[401,403],this.retries=t.retries||[f,f*2,f*3,f*5,f*8,f*13,f*21,f*34],this.partner=t.partner||void 0,!this.url)throw new Error("[HTTPFetchEndpoint] You must at least set url parameter.");if(this.useAuthorization&&!this.authUrl)throw new Error('[useAuthorization] Authorization is set but no "authUrl" was provided.');if(this.authMode==="cookie"&&this.sessionCheckUrl!==!1&&!this.authUrl)throw new Error('[authMode:cookie] Cookie auth refreshes against "authUrl" \u2014 provide it or set "sessionCheckUrl: false" to disable the probe.');if(this.StorageHandler=new T(this),this.useSubscription){if(!this.socket)throw new Error("[useSubscription] If you choose to use WebSocket you must set a socket endpoint.");this[V]=se(this)}this[F]=te(this),this[ie]()}[(F,V,ie)](){let t=b.Network.create(this[F],this[V]||null),r=new b.RecordSource,n=new b.Store(r);this.Environment=new b.Environment({network:t,store:n})}};o(j,"RelayEnvironment");var w=j;var O=J(require("react"));var ae=O.default.createContext(void 0);function ve({children:e,environment:t}){return O.default.createElement(ae.Provider,{value:{environment:t}},e)}o(ve,"EnvironmentProvider");function Se(){let e=O.default.useContext(ae);if(e===void 0)throw new Error("useEnvironment must be used within a EnvironmentProvider");if(e.environment===null||e.environment===void 0)throw new Error("You should provide a Relay Environment to EnvironmentProvider component");return e}o(Se,"useEnvironment");var ce=require("nanoid"),R=require("relay-runtime");function ue(e){return e!==null&&typeof e=="object"}o(ue,"isObject");var Te=(0,ce.nanoid)();function we({parentId:e,itemId:t,parentFieldName:r,store:n}){let i=n.get(e),s=i.getLinkedRecords(r);i.setLinkedRecords(s.filter(a=>a.dataID!==t),r)}o(we,"listRecordRemoveUpdater");function Ce({parentId:e,item:t,type:r,parentFieldName:n,store:i}){let s=i.create(t.id,r);Object.keys(t).forEach(u=>{s.setValue(t[u],u)});let a=i.get(e),l=a.getLinkedRecords(n);a.setLinkedRecords([...l,s],n)}o(Ce,"listRecordAddUpdater");function le(e,t,r,n,i=!1){if(n){let s=e.get(t),a=R.ConnectionHandler.getConnection(s,r);if(!a)return;i?R.ConnectionHandler.insertEdgeBefore(a,n):R.ConnectionHandler.insertEdgeAfter(a,n)}}o(le,"connectionUpdater");function Pe({parentId:e,store:t,connectionName:r,item:n,customNode:i,itemType:s}){let a=i||t.create(n.id,s);!i&&Object.keys(n).forEach(u=>{a.setValue(n[u],u)});let l=t.create(`client:newEdge:${String(a.getDataID).match(/[^:]+$/)[0]}`,`${s}Edge`);l.setLinkedRecord(a,"node"),le(t,e,r,l)}o(Pe,"optimisticConnectionUpdater");function ke({parentId:e,connectionName:t,nodeId:r,store:n}){let i=n.get(e),s=R.ConnectionHandler.getConnection(i,t);if(!s){console.warn(`Connection ${t} not found on ${e}`);return}R.ConnectionHandler.deleteNode(s,r)}o(ke,"connectionDeleteEdgeUpdater");function Ue({object:e,proxy:t}){Object.keys(e).forEach(r=>{ue(e[r])||Array.isArray(e[r])||t.setValue(e[r],r)})}o(Ue,"copyObjScalarsToProxy");var de=require("relay-runtime");var Oe=o((e,t)=>new Promise((r,n)=>{(0,de.commitMutation)(e,{...t,onError:n,onCompleted:r})}),"commitMutation");0&&(module.exports={ClientMutationID,CreateRelayEnvironment,EnvironmentProvider,commitMutation,connectionDeleteEdgeUpdater,connectionUpdater,copyObjScalarsToProxy,isObject,listRecordAddUpdater,listRecordRemoveUpdater,optimisticConnectionUpdater,useEnvironment});
|
|
1
|
+
var ge=Object.create;var S=Object.defineProperty;var be=Object.getOwnPropertyDescriptor;var Re=Object.getOwnPropertyNames;var xe=Object.getPrototypeOf,Ee=Object.prototype.hasOwnProperty;var o=(e,t)=>S(e,"name",{value:t,configurable:!0});var we=(e,t)=>{for(var r in t)S(e,r,{get:t[r],enumerable:!0})},Y=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of Re(t))!Ee.call(e,i)&&i!==r&&S(e,i,{get:()=>t[i],enumerable:!(n=be(t,i))||n.enumerable});return e};var G=(e,t,r)=>(r=e!=null?ge(xe(e)):{},Y(t||!e||!e.__esModule?S(r,"default",{value:e,enumerable:!0}):r,e)),Se=e=>Y(S({},"__esModule",{value:!0}),e);var We={};we(We,{ClientMutationID:()=>Ie,CreateRelayEnvironment:()=>x,EnvironmentProvider:()=>Oe,commitMutation:()=>Le,connectionDeleteEdgeUpdater:()=>Fe,connectionUpdater:()=>fe,copyObjScalarsToProxy:()=>He,isObject:()=>me,listRecordAddUpdater:()=>De,listRecordRemoveUpdater:()=>Ae,optimisticConnectionUpdater:()=>Ne,useEnvironment:()=>ke});module.exports=Se(We);var g=require("relay-runtime");var U=require("relay-runtime");var O=!!(typeof window!="undefined"&&window.document&&window.document.createElement),R={canUseDOM:O,canUseWorkers:typeof Worker!="undefined",canUseEventListeners:O&&!!(window.addEventListener||window.attachEvent),canUseViewport:O&&!!window.screen,isInWorker:!O};function X(e){return async t=>{let r=e.timeout,n=e.retries,i=0,s=0;return new Promise((a,u)=>{let l={};l.sendTimedRequest=()=>{i++,s=Date.now();let c=!0,h=new AbortController,m=setTimeout(()=>{if(c=!1,h.abort(),l.shouldRetry(i))e.useDebug&&console.log("fetchWithRetries: HTTP timeout, retrying."),l.retryRequest();else{let d=new Error(`fetchWithRetries(): Failed to get response from server, tried ${i} times.`);d.name="TimeOutError",u(d)}},r);fetch(e.url,{...t,signal:h.signal}).then(async d=>{if(clearTimeout(m),c)if(d.status>=200&&d.status<300)a(d);else if(l.shouldRetry(i)&&e.retryWhen.includes(d.status))e.useDebug&&console.log("fetchWithRetries: HTTP error, retrying..."),l.retryRequest();else{let p=new Error(`fetchWithRetries(): Still no successful response after ${i} retries, giving up.`);p.response=d,u(p)}}).catch(d=>{clearTimeout(m),d.name!=="AbortError"&&u(d)})},l.retryRequest=()=>{let c=n[i-1],h=s+c;setTimeout(l.sendTimedRequest,h-Date.now())},l.shouldRetry=c=>R.canUseDOM&&e.useRetries&&c<=n.length,l.sendTimedRequest()})}}o(X,"fetchWithRetries");var Z=require("fetch-multipart-graphql");var D=o(e=>e.operationKind==="mutation","isMutation"),N=o(e=>e.operationKind==="query","isQuery"),ee=o(e=>!!(e&&e.force),"forceFetch"),Pe=o(()=>R.canUseDOM?window.location.search.startsWith("?")?"&":"?":"","getParamsDelimiter"),k=o(()=>R.canUseDOM?window.location.pathname:"","getBrowserLocation"),P=o((e,t,r)=>{let n=e;(e!==t||r.loginRoute!==t)&&(n=`${t}${Pe()}redirect=${e}`),window.location.href=n},"redirectUser");function te(e){if(!e.id)throw new Error(`[usePersistedQueries] Operation "${e.name}" has no persisted id \u2014 run relay-compiler with "persistConfig" set in relay.config.json.`);return e.id}o(te,"getPersistedOperationId");function Ce(e,t,r,n){let i=new FormData,s=n!=null&&n.usePersistedQueries?{[n.persistedOperationField||"doc_id"]:te(e),variables:t,operationName:e.name}:{query:e.text,variables:t,operationName:e.name};i.append("operations",JSON.stringify(s));let a={};for(let u=0;u<r.files.length;u++)i.append(`${u}`,r.files[u]),a[`${u}`]=[r.path(u)];return i.append("map",JSON.stringify(a)),i}o(Ce,"getRequestBodyWithUploadables");function ve(e,t,r){return r!=null&&r.usePersistedQueries?JSON.stringify({name:e.name,[r.persistedOperationField||"doc_id"]:te(e),variables:t}):JSON.stringify({name:e.name,query:e.text,variables:t})}o(ve,"getRequestBodyWithoutUplodables");function re(e,t,r,n){return r?Ce(e,t,r,n):ve(e,t,n)}o(re,"getRequestBody");var F=o(e=>{if(e.credentials)return e.credentials;if(e.authMode==="cookie")return"include"},"resolveCredentials"),oe=o((e,t)=>{let r=new Headers;if(t?r.append("Accept","*/*"):(r.append("Accept","application/json"),r.append("Content-type","application/json")),e.useAuthorization&&e.authMode!=="cookie"){let{sessionToken:n}=e.StorageHandler.getTokens();n&&k()!==e.loginRoute&&r.append("Authorization",`Bearer ${n}`)}return e.partner&&r.append("X-Partner",e.partner),r},"getHeaders"),ne=o((e,t,r)=>{if(e.status<300&&e.headers&&e.headers.get("Content-Type")&&e.headers.get("Content-Type").indexOf("multipart/mixed")>=0){let n=e.body.getReader(),i=new TextDecoder,s=new Z.PatchResolver({onResponse:o(a=>t.next(a),"onResponse")});n.read().then(o(function a({value:u,done:l}){if(l)t.complete();else{let c;try{c=i.decode(u),s.handleChunk(c)}catch(h){let m=h;m.response=e,m.statusCode=e.status,m.bodyText=c,t.error(m)}n.read().then(a)}},"sendNext"))}else e.headers&&e.headers.get("Content-Type")&&e.headers.get("Content-Type").indexOf("application/json")>=0?e.json().then(r):e.text().then(n=>{t.next([n]),t.complete()})},"handleData"),f=1e3,H=f*60;var se=o(e=>{let t=new U.QueryResponseCache({ttl:e.cacheTime,size:e.cacheSize}),r=X(e);async function n(){if(e.sessionCheckUrl===!1)return!1;let s=F(e);try{if(e.authMode==="cookie"){let c=e.sessionCheckUrl||e.authUrl;return(await fetch(c,{method:"POST",credentials:s||"include"})).status===200}let{sessionToken:a}=e.StorageHandler.getTokens(),u=e.sessionCheckUrl||`${e.authUrl}user/me`;return(await fetch(u,{headers:{"Content-Type":"application/json",Authorization:a},...s?{credentials:s}:{}})).status===200}catch(a){return console.warn(`[Auth] ${a.message}`),!1}}o(n,"checkSession");async function i(s,a,u,l,c){try{let h=s.id||("cacheID"in s?s.cacheID:null)||String(s.text);if(e.useCache&&N(s)&&!ee(u)){let p=t.get(h,a);if(p){c.next(p),c.complete();return}}e.useCache&&D(s)&&t.clear();let m=F(e),d=await r({method:"POST",headers:oe(e,l),body:re(s,a,l,e),...m?{credentials:m}:{}});ne(d,c,async p=>{if(e.useCache&&N(s)&&t.set(h,a,p),!c.closed){if(D(s)&&p.errors&&c.error(p.errors),p.errors){if(await n()||(e.StorageHandler.clear(),P("/",e.loginRoute,e)),e.redirectOnError){let J=[];Array.isArray(p.errors)&&(J=p.errors.map(({status_code:A})=>A));let K=k();J.some(A=>e.authenticationErrors.includes(A))&&K!==e.loginRoute&&(e.StorageHandler.clear(),P(K,e.loginRoute,e))}c.error(p.errors)}else p.data?c.next(p):c.error(p);c.complete()}})}catch(h){if(R.canUseDOM&&!["AbortError","TimeOutError"].includes(h.name)&&e.StorageHandler.clear(),e.redirectOnError){let d=k();d!==e.loginRoute&&P(d,e.loginRoute,e)}await n()||(e.StorageHandler.clear(),P("/",e.loginRoute,e)),c.error(h)}}return o(i,"fetchFn"),(s,a,u,l)=>U.Observable.create(c=>{i(s,a,u,l,c)})},"createFetchFunction");var ie=G(require("js-cookie"));var q=class q{get(t){throw new Error('Must implement a "GET" method')}set(t,r){throw new Error('Must implement a "SET" method')}delete(t){throw new Error('Must implement a "DELETE" method')}};o(q,"DefaultStrategy");var M=q,V=class V extends M{constructor(){super(),this.strategy=localStorage}get(t){return this.strategy.getItem(t)}set(t,r){this.strategy.setItem(t,r)}delete(t){this.strategy.removeItem(t)}};o(V,"LocalStorageStrategy");var L=V,$=class $ extends M{constructor(){super(),this.strategy=ie.default}get(t){return this.strategy.get(t)}set(t,r){this.strategy.set(t,r)}delete(t){this.strategy.remove(t)}};o($,"CookieStrategy");var W=$,y=Symbol("storage-handler"),C=Symbol("prop-session"),v=Symbol("prop-refresh"),Q=class Q{constructor(t){this[C]=t.sessionStorageProp,this[v]=t.refreshStorageProp,t.storageType==="cookie"?this[y]=new W:this[y]=new L}getTokens(){return{refreshToken:this[y].get(this[v]),sessionToken:this[y].get(this[C])}}setTokens(t){this[y].set(this[v],t.refreshToken),this[y].set(this[C],t.sessionToken)}clear(){this[y].delete(this[v]),this[y].delete(this[C])}hasChangedSession({sessionToken:t}){let{sessionToken:r}=this.getTokens();return t!==r}};o(Q,"StorageClass");var T=Q;var ae=require("graphql-ws"),ce=require("relay-runtime");function Te(e,t,r){if(e.usePersistedQueries){if(!t.id)throw new Error(`[usePersistedQueries] Operation "${t.name}" has no persisted id \u2014 run relay-compiler with "persistConfig" set in relay.config.json.`);return{operationName:t.name,query:"",variables:r,extensions:{[e.persistedOperationField||"doc_id"]:t.id}}}return{operationName:t.name,query:t.text||"",variables:r}}o(Te,"getSubscribePayload");function ue(e){return()=>{let t;return(r,n)=>ce.Observable.create(i=>(t||(t=(0,ae.createClient)({url:e.socket})),t.subscribe(Te(e,r,n),{next:o(s=>i.next(s),"next"),error:o(s=>i.error(s),"error"),complete:o(()=>i.complete(),"complete")})))}}o(ue,"setupSubscription");var le=Symbol("mount-environment"),j=Symbol("handler-fetch"),B=Symbol("handler-subscription"),_=class _{constructor(t){if(this.url=t.url,this.authUrl=t.authUrl,this.socket=t.socket,this.storageType=t.storageType||"localStorage",this.cacheSize=t.cacheSize||250,this.cacheTime=t.cacheTime||H*8,this.timeout=t.timeout||H*15,this.sessionStorageProp=t.sessionStorageProp||"USER_SESSION_TOKEN",this.refreshStorageProp=t.refreshStorageProp||"USER_REFRESH_TOKEN",this.loginRoute=t.loginRoute||"/",this.useCache=t.useCache||!1,this.useDebug=t.useDebug||!1,this.useAuthorization=t.useAuthorization||!1,this.authMode=t.authMode||"bearer",this.credentials=t.credentials,this.sessionCheckUrl=t.sessionCheckUrl,this.useRetries=t.useRetries||!1,this.useSubscription=t.useSubscription||!1,this.redirectOnError=t.redirectOnError||!1,this.retryWhen=t.retryWhen||[503,504,521,522,524],this.authenticationErrors=t.authenticationErrors||[401,403],this.retries=t.retries||[f,f*2,f*3,f*5,f*8,f*13,f*21,f*34],this.partner=t.partner||void 0,this.usePersistedQueries=t.usePersistedQueries||!1,this.persistedOperationField=t.persistedOperationField||"doc_id",!this.url)throw new Error("[HTTPFetchEndpoint] You must at least set url parameter.");if(this.useAuthorization&&!this.authUrl)throw new Error('[useAuthorization] Authorization is set but no "authUrl" was provided.');if(this.authMode==="cookie"&&this.sessionCheckUrl!==!1&&!this.authUrl)throw new Error('[authMode:cookie] Cookie auth refreshes against "authUrl" \u2014 provide it or set "sessionCheckUrl: false" to disable the probe.');if(this.StorageHandler=new T(this),this.useSubscription){if(!this.socket)throw new Error("[useSubscription] If you choose to use WebSocket you must set a socket endpoint.");this[B]=ue(this)()}this[j]=se(this),this[le]()}[(j,B,le)](){let t=g.Network.create(this[j],this[B]||null),r=new g.RecordSource,n=new g.Store(r);this.Environment=new g.Environment({network:t,store:n})}};o(_,"RelayEnvironment");var x=_;var I=G(require("react"));var de=I.default.createContext(void 0);function Oe({children:e,environment:t}){return I.default.createElement(de.Provider,{value:{environment:t}},e)}o(Oe,"EnvironmentProvider");function ke(){let e=I.default.useContext(de);if(e===void 0)throw new Error("useEnvironment must be used within a EnvironmentProvider");if(e.environment===null||e.environment===void 0)throw new Error("You should provide a Relay Environment to EnvironmentProvider component");return e}o(ke,"useEnvironment");var z=require("node:crypto");var pe="useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";var Ue=128,b,E;function Me(e){if(e<0)throw new RangeError("Wrong ID size");try{!b||b.length<e?(b=Buffer.allocUnsafe(e*Ue),z.webcrypto.getRandomValues(b),E=0):E+e>b.length&&(z.webcrypto.getRandomValues(b),E=0)}catch(t){throw b=void 0,t}E+=e}o(Me,"fillPool");function he(e=21){Me(e|=0);let t="";for(let r=E-e;r<E;r++)t+=pe[b[r]&63];return t}o(he,"nanoid");var w=require("relay-runtime");function me(e){return e!==null&&typeof e=="object"}o(me,"isObject");var Ie=he();function Ae({parentId:e,itemId:t,parentFieldName:r,store:n}){let i=n.get(e),s=i.getLinkedRecords(r);i.setLinkedRecords(s.filter(a=>a.dataID!==t),r)}o(Ae,"listRecordRemoveUpdater");function De({parentId:e,item:t,type:r,parentFieldName:n,store:i}){let s=i.create(t.id,r);Object.keys(t).forEach(l=>{s.setValue(t[l],l)});let a=i.get(e),u=a.getLinkedRecords(n);a.setLinkedRecords([...u,s],n)}o(De,"listRecordAddUpdater");function fe(e,t,r,n,i=!1){if(n){let s=e.get(t),a=w.ConnectionHandler.getConnection(s,r);if(!a)return;i?w.ConnectionHandler.insertEdgeBefore(a,n):w.ConnectionHandler.insertEdgeAfter(a,n)}}o(fe,"connectionUpdater");function Ne({parentId:e,store:t,connectionName:r,item:n,customNode:i,itemType:s}){let a=i||t.create(n.id,s);!i&&Object.keys(n).forEach(l=>{a.setValue(n[l],l)});let u=t.create(`client:newEdge:${String(a.getDataID).match(/[^:]+$/)[0]}`,`${s}Edge`);u.setLinkedRecord(a,"node"),fe(t,e,r,u)}o(Ne,"optimisticConnectionUpdater");function Fe({parentId:e,connectionName:t,nodeId:r,store:n}){let i=n.get(e),s=w.ConnectionHandler.getConnection(i,t);if(!s){console.warn(`Connection ${t} not found on ${e}`);return}w.ConnectionHandler.deleteNode(s,r)}o(Fe,"connectionDeleteEdgeUpdater");function He({object:e,proxy:t}){Object.keys(e).forEach(r=>{me(e[r])||Array.isArray(e[r])||t.setValue(e[r],r)})}o(He,"copyObjScalarsToProxy");var ye=require("relay-runtime");var Le=o((e,t)=>new Promise((r,n)=>{(0,ye.commitMutation)(e,{...t,onError:n,onCompleted:r})}),"commitMutation");0&&(module.exports={ClientMutationID,CreateRelayEnvironment,EnvironmentProvider,commitMutation,connectionDeleteEdgeUpdater,connectionUpdater,copyObjScalarsToProxy,isObject,listRecordAddUpdater,listRecordRemoveUpdater,optimisticConnectionUpdater,useEnvironment});
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Public barrel for the `mutationUtils` module.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* (
|
|
6
|
-
* `@apollion-dsi/relay/mutationUtils` (granular)
|
|
7
|
-
* `@apollion-dsi/relay` (barrel
|
|
4
|
+
* Re-exports the helpers for writing Relay mutation `updater`s
|
|
5
|
+
* (lists, connections, optimistic responses). Importable via
|
|
6
|
+
* `@apollion-dsi/relay/mutationUtils` (granular) or via
|
|
7
|
+
* `@apollion-dsi/relay` (root barrel).
|
|
8
8
|
*/
|
|
9
9
|
export * from './mutationUtils';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a,b,c,d,e,f,g,h}from"../chunks/chunk-XJA2SRQY.esm.js";import"../chunks/chunk-GZONWSRB.esm.js";export{b as ClientMutationID,g as connectionDeleteEdgeUpdater,e as connectionUpdater,h as copyObjScalarsToProxy,a as isObject,d as listRecordAddUpdater,c as listRecordRemoveUpdater,f as optimisticConnectionUpdater};
|
|
@@ -1,28 +1,28 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @fileoverview
|
|
3
|
-
*
|
|
4
|
-
* `ConnectionHandler`
|
|
2
|
+
* @fileoverview Utilities for writing Relay mutation `updater`s
|
|
3
|
+
* declaratively, without having to manipulate `RecordProxy` /
|
|
4
|
+
* `ConnectionHandler` by hand in every common case.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
* -
|
|
8
|
-
* -
|
|
9
|
-
* -
|
|
10
|
-
* (
|
|
6
|
+
* Covers the most frequent scenarios:
|
|
7
|
+
* - inserting/removing items in lists (`linked records`);
|
|
8
|
+
* - inserting/removing edges in connections (Relay pagination);
|
|
9
|
+
* - copying scalar fields from a JS object to a `RecordProxy`
|
|
10
|
+
* (useful in optimistic responses).
|
|
11
11
|
*/
|
|
12
12
|
import { RecordProxy, RecordSourceSelectorProxy } from 'relay-runtime';
|
|
13
13
|
/**
|
|
14
|
-
*
|
|
15
|
-
*
|
|
14
|
+
* Checks whether a value is a non-null object (to detect scalar
|
|
15
|
+
* fields vs. linked records in `copyObjScalarsToProxy`).
|
|
16
16
|
*/
|
|
17
17
|
export declare function isObject(obj: any): boolean;
|
|
18
|
-
/**
|
|
18
|
+
/** Arguments for `listRecordRemoveUpdater`. */
|
|
19
19
|
type ListRecordRemoveUpdaterOptions = {
|
|
20
20
|
parentId: string;
|
|
21
21
|
itemId: string;
|
|
22
22
|
parentFieldName: string;
|
|
23
23
|
store: RecordSourceSelectorProxy;
|
|
24
24
|
};
|
|
25
|
-
/**
|
|
25
|
+
/** Arguments for `listRecordAddUpdater`. */
|
|
26
26
|
type ListRecordAddUpdaterOptions = {
|
|
27
27
|
parentId: string;
|
|
28
28
|
item: Record<string, any>;
|
|
@@ -30,7 +30,7 @@ type ListRecordAddUpdaterOptions = {
|
|
|
30
30
|
parentFieldName: string;
|
|
31
31
|
store: RecordSourceSelectorProxy;
|
|
32
32
|
};
|
|
33
|
-
/**
|
|
33
|
+
/** Arguments for `optimisticConnectionUpdater`. */
|
|
34
34
|
type OptimisticConnectionUpdaterOptions = {
|
|
35
35
|
parentId: string;
|
|
36
36
|
store: RecordSourceSelectorProxy;
|
|
@@ -39,95 +39,95 @@ type OptimisticConnectionUpdaterOptions = {
|
|
|
39
39
|
customNode: RecordProxy;
|
|
40
40
|
itemType: string;
|
|
41
41
|
};
|
|
42
|
-
/**
|
|
42
|
+
/** Arguments for `connectionDeleteEdgeUpdater`. */
|
|
43
43
|
type ConnectionDeleteEdgeUpdaterOptions = {
|
|
44
44
|
parentId: string;
|
|
45
45
|
connectionName: string;
|
|
46
46
|
nodeId: string;
|
|
47
47
|
store: RecordSourceSelectorProxy;
|
|
48
48
|
};
|
|
49
|
-
/**
|
|
49
|
+
/** Arguments for `copyObjScalarsToProxy`. */
|
|
50
50
|
type CopyObjScalarsToProxyOptions = {
|
|
51
51
|
object: Record<string, any>;
|
|
52
52
|
proxy: RecordProxy;
|
|
53
53
|
};
|
|
54
54
|
/**
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
* Modern.
|
|
55
|
+
* Unique identifier generated once per module load,
|
|
56
|
+
* intended for the `clientMutationId` field expected by the Relay
|
|
57
|
+
* Modern pattern.
|
|
58
58
|
*/
|
|
59
59
|
export declare const ClientMutationID: string;
|
|
60
60
|
/**
|
|
61
|
-
*
|
|
61
|
+
* Removes an item from a `linked records` list on a parent.
|
|
62
62
|
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
63
|
+
* Uses `getLinkedRecords` + `setLinkedRecords` with a `dataID` filter.
|
|
64
|
+
* For paginated connections, prefer `connectionDeleteEdgeUpdater`.
|
|
65
65
|
*
|
|
66
|
-
* @param options.parentId - DataID
|
|
67
|
-
* @param options.itemId - DataID
|
|
68
|
-
* @param options.parentFieldName -
|
|
69
|
-
* @param options.store - `RecordSourceSelectorProxy`
|
|
66
|
+
* @param options.parentId - DataID of the parent that owns the linked field.
|
|
67
|
+
* @param options.itemId - DataID of the item to remove.
|
|
68
|
+
* @param options.parentFieldName - Name of the linked field on the parent.
|
|
69
|
+
* @param options.store - `RecordSourceSelectorProxy` received in the updater.
|
|
70
70
|
*/
|
|
71
71
|
export declare function listRecordRemoveUpdater({ parentId, itemId, parentFieldName, store, }: ListRecordRemoveUpdaterOptions): void;
|
|
72
72
|
/**
|
|
73
|
-
*
|
|
73
|
+
* Adds an item to the end of a `linked records` list.
|
|
74
74
|
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
*
|
|
75
|
+
* Creates a new `RecordProxy` using `item.id` as the dataID and copies all
|
|
76
|
+
* fields from `item` to the new record (without validating types — scalars
|
|
77
|
+
* and linked refs both go through `setValue`).
|
|
78
78
|
*
|
|
79
|
-
* @param options.parentId - DataID
|
|
80
|
-
* @param options.item -
|
|
81
|
-
* @param options.type -
|
|
82
|
-
* @param options.parentFieldName -
|
|
83
|
-
* @param options.store - `RecordSourceSelectorProxy
|
|
79
|
+
* @param options.parentId - DataID of the parent.
|
|
80
|
+
* @param options.item - Object with the new record's fields (must have `id`).
|
|
81
|
+
* @param options.type - GraphQL type of the record (e.g. `'Todo'`).
|
|
82
|
+
* @param options.parentFieldName - Name of the linked field on the parent.
|
|
83
|
+
* @param options.store - The updater's `RecordSourceSelectorProxy`.
|
|
84
84
|
*/
|
|
85
85
|
export declare function listRecordAddUpdater({ parentId, item, type, parentFieldName, store, }: ListRecordAddUpdaterOptions): void;
|
|
86
86
|
/**
|
|
87
|
-
*
|
|
87
|
+
* Inserts an edge into a paginated connection (Relay Connections spec).
|
|
88
88
|
*
|
|
89
|
-
* @param store - `RecordSourceSelectorProxy
|
|
90
|
-
* @param parentId - DataID
|
|
91
|
-
* @param connectionName -
|
|
92
|
-
* @param edge -
|
|
93
|
-
* @param before -
|
|
89
|
+
* @param store - The updater's `RecordSourceSelectorProxy`.
|
|
90
|
+
* @param parentId - DataID of the parent that owns the connection.
|
|
91
|
+
* @param connectionName - Connection name in the schema (`@connection(key: ...)`).
|
|
92
|
+
* @param edge - The edge's `RecordProxy`, already created by the caller.
|
|
93
|
+
* @param before - If `true`, inserts before the first edge (default `false`).
|
|
94
94
|
*/
|
|
95
95
|
export declare function connectionUpdater(store: RecordSourceSelectorProxy, parentId: string, connectionName: string, edge: RecordProxy, before?: boolean): void;
|
|
96
96
|
/**
|
|
97
|
-
*
|
|
98
|
-
* node
|
|
99
|
-
*
|
|
97
|
+
* Variant of `connectionUpdater` used in optimistic responses: creates the
|
|
98
|
+
* node and the edge "from scratch" out of a JS object, simulating what the
|
|
99
|
+
* server would return.
|
|
100
100
|
*
|
|
101
|
-
* @param options.parentId - DataID
|
|
101
|
+
* @param options.parentId - DataID of the parent.
|
|
102
102
|
* @param options.store - `RecordSourceSelectorProxy`.
|
|
103
|
-
* @param options.connectionName -
|
|
104
|
-
* @param options.item -
|
|
105
|
-
* @param options.customNode - `RecordProxy`
|
|
106
|
-
* @param options.itemType -
|
|
107
|
-
*
|
|
103
|
+
* @param options.connectionName - Connection name.
|
|
104
|
+
* @param options.item - Object with the new node's fields (must have `id`).
|
|
105
|
+
* @param options.customNode - Pre-created `RecordProxy` (optional, avoids creating via `item`).
|
|
106
|
+
* @param options.itemType - GraphQL type of the node (e.g. `'Todo'`); the edge
|
|
107
|
+
* will be created as `<itemType>Edge`.
|
|
108
108
|
*/
|
|
109
109
|
export declare function optimisticConnectionUpdater({ parentId, store, connectionName, item, customNode, itemType, }: OptimisticConnectionUpdaterOptions): void;
|
|
110
110
|
/**
|
|
111
|
-
*
|
|
111
|
+
* Removes a node from a paginated connection by its `dataID`.
|
|
112
112
|
*
|
|
113
|
-
*
|
|
114
|
-
*
|
|
113
|
+
* Logs a `console.warn` if the connection is not found (usually
|
|
114
|
+
* means the `connectionName` is wrong).
|
|
115
115
|
*
|
|
116
|
-
* @param options.parentId - DataID
|
|
117
|
-
* @param options.connectionName -
|
|
118
|
-
* @param options.nodeId - DataID
|
|
116
|
+
* @param options.parentId - DataID of the parent.
|
|
117
|
+
* @param options.connectionName - Connection name.
|
|
118
|
+
* @param options.nodeId - DataID of the node to remove.
|
|
119
119
|
* @param options.store - `RecordSourceSelectorProxy`.
|
|
120
120
|
*/
|
|
121
121
|
export declare function connectionDeleteEdgeUpdater({ parentId, connectionName, nodeId, store, }: ConnectionDeleteEdgeUpdaterOptions): void;
|
|
122
122
|
/**
|
|
123
|
-
*
|
|
123
|
+
* Copies the scalar fields of a JS object to a `RecordProxy`.
|
|
124
124
|
*
|
|
125
|
-
*
|
|
126
|
-
* record lists) —
|
|
125
|
+
* Ignores fields that are objects or arrays (linked records / linked
|
|
126
|
+
* record lists) — those must be handled with
|
|
127
127
|
* `setLinkedRecord`/`setLinkedRecords`.
|
|
128
128
|
*
|
|
129
|
-
* @param options.object -
|
|
130
|
-
* @param options.proxy - `RecordProxy
|
|
129
|
+
* @param options.object - Source JS object.
|
|
130
|
+
* @param options.proxy - Destination `RecordProxy`.
|
|
131
131
|
*/
|
|
132
132
|
export declare function copyObjScalarsToProxy({ object, proxy }: CopyObjScalarsToProxyOptions): void;
|
|
133
133
|
export {};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Public barrel for the `relayArgsInterface` module.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* `CreateRelayEnvironment`)
|
|
4
|
+
* Re-exports the `RelayArgsInterface` type (config accepted by
|
|
5
|
+
* `CreateRelayEnvironment`) and `Sink` (the Relay Observable interface).
|
|
6
6
|
*/
|
|
7
7
|
export * from './relayArgsInterface';
|