@apollion-dsi/relay 0.29.0 → 0.31.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 CHANGED
@@ -1,52 +1,37 @@
1
1
  # @apollion-dsi/relay
2
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.
3
+ Configure Relay the Apollion way: one environment, bearer or httpOnly auth, and live-read helpers, without the boilerplate.
6
4
 
7
5
  [![npm](https://img.shields.io/npm/v/@apollion-dsi/relay.svg)](https://www.npmjs.com/package/@apollion-dsi/relay)
8
6
  [![downloads](https://img.shields.io/npm/dm/@apollion-dsi/relay.svg)](https://www.npmjs.com/package/@apollion-dsi/relay)
9
7
  [![license](https://img.shields.io/npm/l/@apollion-dsi/relay.svg)](https://www.npmjs.com/package/@apollion-dsi/relay)
10
8
 
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.
9
+ - **One environment.** Network, auth, cache, and subscriptions from a single config object.
10
+ - **Bearer or httpOnly cookie.** Switch with `authMode`. The bearer header is omitted on `loginRoute` only when you pass it.
11
+ - **Partial data, on purpose.** `graphqlErrorPolicy: 'legacy'` drops it. `'payload'` lets Relay normalize `data`.
12
+ - **`@live` and `@client_polling`.** Resolver state, or a query refetch on the compiled interval. Not a server live protocol.
13
+ - **Persisted queries.** The server receives a build-time hash, not GraphQL text.
14
+ - **Typed.** Relay ships its types. Do not add `@types/react-relay` or `@types/relay-runtime`.
20
15
 
21
16
  ## Installation
22
17
 
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:
18
+ React is the only peer. `react-relay`, `relay-runtime`, `graphql`, `graphql-ws`, `js-cookie`, and `nanoid` ship here. Add `relay-compiler` to generate artifacts. `relay-test-utils` is your test dependency, not a runtime dependency of this package.
26
19
 
27
20
  ```bash
28
21
  yarn add @apollion-dsi/relay react
29
22
  ```
30
23
 
31
- > To generate Relay artifacts, also add `relay-compiler` as a dev dependency and
32
- > a `relay.config.js`.
33
-
34
24
  ## Documentation
35
25
 
36
- - **Docs & API reference:** <https://www.apollion.com.br>
26
+ - **Docs:** <https://www.apollion.com.br>
37
27
  - **Changelog:** <https://www.apollion.com.br/changelog>
38
28
 
39
29
  ## Quick start
40
30
 
41
- Create the Environment and provide it to your tree with `EnvironmentProvider`
42
- — the single Relay provider, backing both the DS `useEnvironment()` hook and
43
- every `react-relay` store hook (`useLazyLoadQuery`, `usePreloadedQuery`,
44
- `useFragment`, `useSubscription`). Do not also mount `react-relay`'s
45
- `RelayEnvironmentProvider` yourself — `EnvironmentProvider` already does:
31
+ `EnvironmentProvider` is the only provider. It backs `useEnvironment()` and the `react-relay` hooks. Do not also mount `RelayEnvironmentProvider`.
46
32
 
47
33
  ```tsx
48
- import { CreateRelayEnvironment, EnvironmentProvider } from '@apollion-dsi/relay';
49
- import { App } from './app';
34
+ import { CreateRelayEnvironment, EnvironmentProvider, commitMutation } from '@apollion-dsi/relay';
50
35
 
51
36
  const { Environment } = new CreateRelayEnvironment({
52
37
  url: 'https://api.example.com/graphql',
@@ -55,94 +40,31 @@ const { Environment } = new CreateRelayEnvironment({
55
40
  <EnvironmentProvider environment={Environment}>
56
41
  <App />
57
42
  </EnvironmentProvider>;
43
+
44
+ await commitMutation(Environment, { mutation, variables: { input } });
58
45
  ```
59
46
 
60
- ## Authentication: Bearer vs. httpOnly cookie
47
+ ## Authentication
61
48
 
62
- The Environment supports two auth models via `authMode`.
49
+ `'bearer'` (default) sends `Authorization: Bearer <token>` on GraphQL and on `${authUrl}user/me`. Passing `loginRoute` strips that header on that path only. The default `'/'` does not strip it on the home page.
63
50
 
64
- ### `authMode: 'bearer'` (default)
51
+ `'cookie'` does not read the token or set `Authorization`. `credentials: 'include'` sends the httpOnly cookie, including the socket handshake. An auth error `POST`s `authUrl`. The token is never in the URL. `sessionCheckUrl: false` skips the probe.
65
52
 
66
- Reads the `sessionToken` from storage (`localStorage` or a JS-readable cookie)
67
- and injects `Authorization: Bearer <token>` into every request; session
68
- verification uses the `${authUrl}user/me` probe.
53
+ ## Errors, subscriptions, and live data
69
54
 
70
- ```ts
71
- new CreateRelayEnvironment({
72
- url: 'https://api.example.com/graphql/',
73
- authUrl: 'https://api.example.com/auth/',
74
- useAuthorization: true,
75
- storageType: 'cookie', // JS-readable cookie, or 'localStorage'
76
- });
77
- ```
55
+ `graphqlErrorPolicy` defaults to `'legacy'`: any GraphQL `errors` array probes the session and is `sink.error`, so partial `data` is dropped. `'payload'` calls `sink.next` when the body has `data`. Storage is cleared only when an error `status_code` is in `authenticationErrors`. A transport `TypeError` does not clear storage.
78
56
 
79
- ### `authMode: 'cookie'` (httpOnly session — recommended for SPAs)
80
-
81
- The session token lives in an **httpOnly + SameSite** cookie, invisible to JS
82
- and immune to XSS. The Environment never reads the token or sets
83
- `Authorization` — `credentials: 'include'` makes the browser attach the cookie
84
- automatically. On an auth error (e.g. 401), a refresh `POST` is fired to
85
- `authUrl` with credentials, without probing `user/me`.
86
-
87
- ```ts
88
- new CreateRelayEnvironment({
89
- url: 'https://api.example.com/graphql/',
90
- authUrl: 'https://api.example.com/auth/refresh/',
91
- authMode: 'cookie',
92
- redirectOnError: true,
93
- loginRoute: '/login',
94
- });
95
- ```
57
+ Subscriptions use `graphql-ws`. When `useAuthorization` is on and `authMode` is not `'cookie'`, `connectionParams` sends `{ Authorization: 'Bearer <token>' }` on every connect, including reconnect. The client is disposed when the last subscriber leaves.
96
58
 
97
- | Option | Default | What it does |
98
- | ----------------- | ---------------------------------- | ----------------------------------------------------------------------------------------- |
99
- | `authMode` | `'bearer'` | `'bearer'` (token + header) or `'cookie'` (httpOnly). |
100
- | `credentials` | cookie→`'include'`; bearer→omitted | `RequestCredentials` forwarded to the GraphQL and refresh fetches. Works in both modes. |
101
- | `sessionCheckUrl` | mode-dependent | Overrides the probe URL; `false` disables it (auth error → direct logout, no extra call). |
102
-
103
- ## Persisted queries
104
-
105
- With `usePersistedQueries: true`, every operation ships as a **build-time
106
- hash** instead of GraphQL text. The server keeps the matching query map and
107
- executes only hashes it knows — a tampered client query is refused, and the
108
- server can cache aggressively by hash.
109
-
110
- 1. Enable `persistConfig` in your `relay.config.json` so `relay-compiler`
111
- writes the query map and stamps each artifact's `id`:
112
-
113
- ```json
114
- {
115
- "src": "./src",
116
- "schema": "./schema.graphql",
117
- "language": "typescript",
118
- "persistConfig": { "file": "./persisted/queryMap.json", "algorithm": "MD5" }
119
- }
120
- ```
121
-
122
- 2. Ship `queryMap.json` to your GraphQL server as the allowlist.
123
-
124
- 3. Turn the flag on:
59
+ `@live` is a resolver docblock, not a transport. `liveState(read, subscribe)` notifies only when `Object.is` changes. `batchLiveStateUpdates(environment, fn)` batches those notifications. `subscriptionLiveState({ environment, subscription, variables })` returns `suspenseSentinel()` until the first payload, then batches, and disposes when the last listener leaves. `LiveState` and `suspenseSentinel` are re-exported. The compiler config stays in your app. A normalized payload still needs a global `id`.
125
60
 
126
- ```ts
127
- new CreateRelayEnvironment({
128
- url: 'https://api.example.com/graphql/',
129
- usePersistedQueries: true,
130
- });
131
- ```
61
+ `@client_polling(interval: Int!)` is a query directive in your schema. The compiler writes `metadata.live.polling_interval` in milliseconds. This package polls that interval and sets `force` on those ticks. If `cacheConfig.poll` is already set, it does not poll again. A GraphQL `@live` that only sets `metadata.live.config_id` is not a push channel.
132
62
 
133
- The request body becomes `{ name, doc_id, variables }` — no `query` key.
134
- Uploads carry the hash inside the multipart `operations` field, and
135
- subscriptions send it in `payload.extensions.doc_id` over `graphql-ws`.
63
+ ## Requests
136
64
 
137
- | Option | Default | What it does |
138
- | ------------------------- | ---------- | ------------------------------------------------------------------------------ |
139
- | `usePersistedQueries` | `false` | Sends only the persisted hash; the GraphQL text never leaves the build. |
140
- | `persistedOperationField` | `'doc_id'` | Renames the hash field to whatever your server's allowlist middleware expects. |
65
+ `usePersistedQueries` sends `{ name, doc_id, variables }` once `persistConfig` is on (`persistedOperationField` renames the hash). Multipart `operations` carry that hash plus `name` and `operationName`. Subscriptions send the hash in `payload.extensions`. Refuse an unknown hash with **200 and `{ errors }`**.
141
66
 
142
- > **Server contract:** resolve the hash against the query map; refuse raw text
143
- > and unknown hashes replying `200` + `{ "errors": [...] }` with
144
- > `Content-Type: application/json` — a `4xx` is treated as a transport failure
145
- > by the client's retry layer instead of surfacing the GraphQL error.
67
+ A Relay `UploadableMap` (`{ [key]: File | Blob }`) maps to `variables.<key>`. `{ files, path(i) }` still works. `fetch-multipart-graphql` reads `@defer` / `@stream`; it is not the upload implementation. Unsubscribing a query aborts the fetch. `useRetries` does not retry mutations. `QueryResponseCache` stores a body only when it has `data` and no `errors`. `redirectUser` picks `?` or `&` from the destination, encodes the return path, and does nothing without a DOM. `createClientMutationID()` is a new id per call; `ClientMutationID` is once per load.
146
68
 
147
69
  ## License
148
70
 
@@ -0,0 +1 @@
1
+ import{a as d}from"./chunk-GZONWSRB.esm.js";import{nanoid as y}from"nanoid";import{ConnectionHandler as p}from"relay-runtime";function g(e){return e!==null&&typeof e=="object"}d(g,"isObject");function l(){return y()}d(l,"createClientMutationID");var P=l();function S({parentId:e,itemId:t,parentFieldName:o,store:r}){let i=r.get(e),n=i.getLinkedRecords(o);n&&i.setLinkedRecords(n.filter(c=>c.getDataID()!==t),o)}d(S,"listRecordRemoveUpdater");function C({parentId:e,item:t,type:o,parentFieldName:r,store:i}){let n=i.create(t.id,o);Object.keys(t).forEach(s=>{g(t[s])||n.setValue(t[s],s)});let c=i.get(e),a=c.getLinkedRecords(r);c.setLinkedRecords([...a,n],r)}d(C,"listRecordAddUpdater");function u(e,t,o,r,i=!1){if(r){let n=e.get(t),c=p.getConnection(n,o);if(!c)return;i?p.insertEdgeBefore(c,r):p.insertEdgeAfter(c,r)}}d(u,"connectionUpdater");function U({parentId:e,store:t,connectionName:o,item:r,customNode:i,itemType:n}){let c=i||t.create(r.id,n);!i&&Object.keys(r).forEach(s=>{g(r[s])||c.setValue(r[s],s)});let a=t.create(`client:newEdge:${c.getDataID()}`,`${n}Edge`);a.setLinkedRecord(c,"node"),u(t,e,o,a)}d(U,"optimisticConnectionUpdater");function m({parentId:e,connectionName:t,nodeId:o,store:r}){let i=r.get(e),n=p.getConnection(i,t);if(!n){console.warn(`Connection ${t} not found on ${e}`);return}p.deleteNode(n,o)}d(m,"connectionDeleteEdgeUpdater");function E({object:e,proxy:t}){Object.keys(e).forEach(o=>{g(e[o])||Array.isArray(e[o])||t.setValue(e[o],o)})}d(E,"copyObjScalarsToProxy");export{g as a,l as b,P as c,S as d,C as e,u as f,U as g,m as h,E as i};
@@ -0,0 +1 @@
1
+ import{a as o}from"./chunk-GZONWSRB.esm.js";import e from"react";import{RelayEnvironmentProvider as v}from"react-relay";var t=e.createContext(void 0);function u({children:n,environment:r}){let i=e.useMemo(()=>({environment:r}),[r]);return e.createElement(t.Provider,{value:i},e.createElement(v,{environment:r},n))}o(u,"EnvironmentProvider");function E(){let n=e.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}o(E,"useEnvironment");export{u as a,E as b};
@@ -0,0 +1 @@
1
+ import{a as o}from"./chunk-GZONWSRB.esm.js";import{commitMutation as r}from"relay-runtime";var s=o((m,i)=>new Promise((e,n)=>{r(m,{...i,onError:n,onCompleted:o((a,t)=>t!=null&&t.length?n(t):e(a),"onCompleted")})}),"commitMutation");export{s as a};
@@ -0,0 +1 @@
1
+ import{a as e}from"./chunk-GZONWSRB.esm.js";import{requestSubscription as d,suspenseSentinel as u}from"relay-runtime";function l(i,r){let t=i();return{read:e(()=>(t=i(),t),"read"),subscribe:e(o=>r(()=>{let n=i();Object.is(n,t)||(t=n,o())}),"subscribe")}}e(l,"liveState");function v(i,r){let t=i.getStore();if(typeof t.batchLiveStateUpdates=="function"){t.batchLiveStateUpdates(r);return}r()}e(v,"batchLiveStateUpdates");function b({environment:i,subscription:r,variables:t}){let o,n=!1,s=new Set,a=null,c=e(()=>{v(i,()=>{s.forEach(p=>p())})},"publish");return{read:e(()=>n?o:u(),"read"),subscribe:e(p=>(s.add(p),s.size===1&&(a=d(i,{subscription:r,variables:t,onNext:e(S=>{o=S,n=!0,c()},"onNext")})),()=>{s.delete(p),s.size===0&&(a==null||a.dispose(),a=null)}),"subscribe")}}e(b,"subscriptionLiveState");export{u as a,l as b,v as c,b as d};
@@ -0,0 +1 @@
1
+ import{a as i}from"./chunk-GZONWSRB.esm.js";import{Environment as me,Network as be,RecordSource as ye,Store as fe}from"relay-runtime";import{Observable as le,QueryResponseCache as ue}from"relay-runtime";var F=!!(typeof window!="undefined"&&window.document&&window.document.createElement),E={canUseDOM:F,canUseWorkers:typeof Worker!="undefined",canUseEventListeners:F&&!!(window.addEventListener||window.attachEvent),canUseViewport:F&&!!window.screen,isInWorker:!F};function G(t){return async e=>{let s=t.timeout,a=t.retries,o=0,l=(e==null?void 0:e.retry)!==!1;return new Promise((p,h)=>{var T,A;let u=!1,n,d,m=i(c=>{u||(u=!0,clearTimeout(n),h(c))},"fail"),b=i(c=>{u||(u=!0,clearTimeout(n),p(c))},"succeed"),y=i(()=>{let c=new Error("The operation was aborted.");return c.name="AbortError",c},"abortError");if((T=e==null?void 0:e.signal)!=null&&T.aborted){h(y());return}let w=i(()=>{d==null||d.abort(),m(y())},"onCallerAbort");(A=e==null?void 0:e.signal)==null||A.addEventListener("abort",w);let r={};r.sendTimedRequest=()=>{o++;let c=!0;d=new AbortController;let M=setTimeout(()=>{if(c=!1,d.abort(),r.shouldRetry(o))t.useDebug&&console.log("fetchWithRetries: HTTP timeout, retrying."),r.retryRequest();else{let f=new Error(`fetchWithRetries(): Failed to get response from server, tried ${o} times.`);f.name="TimeOutError",m(f)}},s),{signal:I,retry:D,...P}=e!=null?e:{};fetch(t.url,{...P,signal:d.signal}).then(async f=>{if(clearTimeout(M),c)if(f.status>=200&&f.status<300)b(f);else if(r.shouldRetry(o)&&t.retryWhen.includes(f.status))t.useDebug&&console.log("fetchWithRetries: HTTP error, retrying..."),r.retryRequest();else{let K=new Error(`fetchWithRetries(): Still no successful response after ${o} retries, giving up.`);K.response=f,m(K)}}).catch(f=>{clearTimeout(M),f.name!=="AbortError"&&m(f)})},r.retryRequest=()=>{let c=a[o-1];n=setTimeout(r.sendTimedRequest,c)},r.shouldRetry=c=>E.canUseDOM&&t.useRetries&&l&&c<=a.length,r.sendTimedRequest()})}}i(G,"fetchWithRetries");import{PatchResolver as ne}from"fetch-multipart-graphql";var N=i(t=>t.operationKind==="mutation","isMutation"),C=i(t=>t.operationKind==="query","isQuery"),X=i(t=>!!(t&&t.force),"forceFetch");var O=i(()=>E.canUseDOM?window.location.pathname:"","getBrowserLocation"),S=i((t,e,s)=>{if(!E.canUseDOM)return;let a=e;if(t!==e){let o=e.includes("?")?"&":"?";a=`${e}${o}redirect=${encodeURIComponent(t)}`}(s==null?void 0:s.loginRoute)===e&&t===e&&(a=e),window.location.href=a},"redirectUser");function Y(t){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 t.id}i(Y,"getPersistedOperationId");function ie(t,e,s,a){let o=new FormData,l=a!=null&&a.usePersistedQueries?{[a.persistedOperationField||"doc_id"]:Y(t),variables:e,operationName:t.name}:{query:t.text,variables:e,operationName:t.name};o.append("operations",JSON.stringify({...l,name:t.name}));let p={},h=s.files,u=s.path;if(Array.isArray(h)&&typeof u=="function")for(let n=0;n<h.length;n++)o.append(`${n}`,h[n]),p[`${n}`]=[u(n)];else{let n=0;Object.keys(s).forEach(d=>{let m=s[d];o.append(`${n}`,m),p[`${n}`]=[`variables.${d}`],n+=1})}return o.append("map",JSON.stringify(p)),o}i(ie,"getRequestBodyWithUploadables");function ae(t,e,s){return s!=null&&s.usePersistedQueries?JSON.stringify({name:t.name,[s.persistedOperationField||"doc_id"]:Y(t),variables:e}):JSON.stringify({name:t.name,query:t.text,variables:e})}i(ae,"getRequestBodyWithoutUplodables");function Z(t,e,s,a){return s?ie(t,e,s,a):ae(t,e,a)}i(Z,"getRequestBody");var W=i(t=>{if(t.credentials)return t.credentials;if(t.authMode==="cookie")return"include"},"resolveCredentials"),ee=i((t,e)=>{var a;let s=new Headers;if(e?s.append("Accept","*/*"):(s.append("Accept","application/json"),s.append("Content-type","application/json")),t.useAuthorization&&t.authMode!=="cookie"){let{sessionToken:o}=t.StorageHandler.getTokens(),l=(a=t.suppressAuthOnLoginRoute)!=null?a:t.loginRoute!=null&&t.loginRoute!=="/";o&&!(l&&O()===t.loginRoute)&&s.append("Authorization",`Bearer ${o}`)}return t.partner&&s.append("X-Partner",t.partner),s},"getHeaders"),te=i((t,e,s,a)=>{if(t.status<300&&t.headers&&t.headers.get("Content-Type")&&t.headers.get("Content-Type").indexOf("multipart/mixed")>=0){let o=t.body.getReader(),l=new TextDecoder,p=new ne({onResponse:i(u=>e.next(u),"onResponse")}),h=i(async()=>{var m,b;if(a!=null&&a.aborted||e.closed){await((m=o.cancel)==null?void 0:m.call(o));return}let{value:u,done:n}=await o.read();if(n){e.complete();return}let d;try{d=l.decode(u,{stream:!0}),p.handleChunk(d)}catch(y){let r=y instanceof Error?y:new Error(String(y));r.response=t,r.statusCode=t.status,r.bodyText=d,e.error(r),await((b=o.cancel)==null?void 0:b.call(o));return}await h()},"readNext");return h().catch(u=>{a!=null&&a.aborted||e.closed||e.error(u instanceof Error?u:new Error(String(u)))})}return t.headers&&t.headers.get("Content-Type")&&t.headers.get("Content-Type").indexOf("application/json")>=0?t.json().then(o=>s(o)).catch(o=>{e.closed||e.error(o instanceof Error?o:new Error(String(o)))}):t.text().then(o=>{e.next([o]),e.complete()})},"handleData"),R=1e3,z=R*60;var re=i(t=>{let e=new ue({ttl:t.cacheTime,size:t.cacheSize}),s=G(t);async function a(){if(t.sessionCheckUrl===!1)return!1;let l=W(t);try{if(t.authMode==="cookie"){let d=t.sessionCheckUrl||t.authUrl;return(await fetch(d,{method:"POST",credentials:l||"include"})).status===200}let{sessionToken:p}=t.StorageHandler.getTokens(),h=t.sessionCheckUrl||`${t.authUrl}user/me`,u={"Content-Type":"application/json"};return p&&(u.Authorization=`Bearer ${p}`),(await fetch(h,{headers:u,...l?{credentials:l}:{}})).status===200}catch(p){return console.warn(`[Auth] ${p.message}`),!1}}i(a,"checkSession");async function o(l,p,h,u,n,d){let m=t.graphqlErrorPolicy==="payload";try{let b=l.id||("cacheID"in l?l.cacheID:null)||String(l.text);if(t.useCache&&C(l)&&!X(h)){let r=e.get(b,p);if(r){n.next(r),n.complete();return}}t.useCache&&N(l)&&e.clear();let y=W(t),w=await s({method:"POST",headers:ee(t,u),body:Z(l,p,u,t),...y?{credentials:y}:{},signal:d,retry:C(l)});if(d.aborted||n.closed)return;await te(w,n,async r=>{if(t.useCache&&C(l)&&(r!=null&&r.data)&&!r.errors&&e.set(b,p,r),n.closed)return;let A=(Array.isArray(r==null?void 0:r.errors)?r.errors.map(c=>c==null?void 0:c.status_code).filter(c=>typeof c=="number"):[]).some(c=>t.authenticationErrors.includes(c));if(m){A&&t.sessionCheckUrl!==!1&&!await a()&&!n.closed&&(t.StorageHandler.clear(),S(O(),t.loginRoute,t)),r!=null&&r.data?n.next(r):r!=null&&r.errors?n.error(r.errors):n.error(r),n.closed||n.complete();return}if(N(l)&&r.errors&&n.error(r.errors),r.errors){let c=t.sessionCheckUrl!==!1,M=c?await a():!0;if(c&&!M&&(t.StorageHandler.clear(),S("/",t.loginRoute,t)),c&&t.redirectOnError){let I=[];Array.isArray(r.errors)&&(I=r.errors.map(({status_code:P})=>P));let D=O();I.some(P=>t.authenticationErrors.includes(P))&&D!==t.loginRoute&&(t.StorageHandler.clear(),S(D,t.loginRoute,t))}n.error(r.errors)}else r.data?n.next(r):n.error(r);n.complete()})}catch(b){if(d.aborted||(b==null?void 0:b.name)==="AbortError")return;if(m){n.error(b);return}let y=t.sessionCheckUrl!==!1;if(y&&E.canUseDOM&&!["AbortError","TimeOutError"].includes(b.name)&&t.StorageHandler.clear(),y&&t.redirectOnError){let r=O();r!==t.loginRoute&&S(r,t.loginRoute,t)}let w=y?await a():!0;y&&!w&&(t.StorageHandler.clear(),S("/",t.loginRoute,t)),n.error(b)}}return i(o,"fetchFn"),(l,p,h,u)=>{var y;let n=(y=l.metadata)==null?void 0:y.live,d=n==null?void 0:n.polling_interval,m=C(l)&&(h==null?void 0:h.poll)==null&&typeof d=="number"&&d>0?d:void 0,b=le.create(w=>{let r=new AbortController,T=m!=null?{...h,force:!0}:h;return o(l,p,T,u,w,r.signal),()=>r.abort()});return m!=null?b.poll(m):b}},"createFetchFunction");import ce from"js-cookie";var L=class L{get(e){throw new Error('Must implement a "GET" method')}set(e,s){throw new Error('Must implement a "SET" method')}delete(e){throw new Error('Must implement a "DELETE" method')}};i(L,"DefaultStrategy");var H=L,Q=class Q extends H{constructor(){super(),this.strategy=localStorage}get(e){return this.strategy.getItem(e)}set(e,s){this.strategy.setItem(e,s)}delete(e){this.strategy.removeItem(e)}};i(Q,"LocalStorageStrategy");var $=Q,_=class _ extends H{constructor(){super(),this.strategy=ce}get(e){return this.strategy.get(e)}set(e,s){this.strategy.set(e,s)}delete(e){this.strategy.remove(e)}};i(_,"CookieStrategy");var q=_,g=Symbol("storage-handler"),k=Symbol("prop-session"),v=Symbol("prop-refresh"),V=class V{constructor(e){this[k]=e.sessionStorageProp,this[v]=e.refreshStorageProp,e.storageType==="cookie"?this[g]=new q:this[g]=new $}getTokens(){return{refreshToken:this[g].get(this[v]),sessionToken:this[g].get(this[k])}}setTokens(e){this[g].set(this[v],e.refreshToken),this[g].set(this[k],e.sessionToken)}clear(){this[g].delete(this[v]),this[g].delete(this[k])}hasChangedSession({sessionToken:e}){let{sessionToken:s}=this.getTokens();return e!==s}};i(V,"StorageClass");var x=V;import{createClient as de}from"graphql-ws";import{Observable as pe}from"relay-runtime";function he(t,e,s){if(t.usePersistedQueries){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{operationName:e.name,query:"",variables:s,extensions:{[t.persistedOperationField||"doc_id"]:e.id}}}return{operationName:e.name,query:e.text||"",variables:s}}i(he,"getSubscribePayload");function se(t){return()=>{let e,s=0,a=i(()=>{var l;let o=(l=t.StorageHandler)==null?void 0:l.getTokens().sessionToken;return o?{Authorization:`Bearer ${o}`}:{}},"connectionParams");return(o,l)=>pe.create(p=>{e||(e=de({url:t.socket,...t.useAuthorization&&t.authMode!=="cookie"?{connectionParams:a}:{}})),s+=1;let h=e.subscribe(he(t,o,l),{next:i(u=>p.next(u),"next"),error:i(u=>p.error(u),"error"),complete:i(()=>p.complete(),"complete")});return()=>{typeof h=="function"&&h(),s-=1,s<=0&&e&&(e.dispose(),e=void 0,s=0)}})}}i(se,"setupSubscription");var oe=Symbol("mount-environment"),B=Symbol("handler-fetch"),j=Symbol("handler-subscription"),J=class J{constructor(e){if(this.url=e.url,this.authUrl=e.authUrl,this.socket=e.socket,this.storageType=e.storageType||"localStorage",this.cacheSize=e.cacheSize||250,this.cacheTime=e.cacheTime||z*8,this.timeout=e.timeout||z*15,this.sessionStorageProp=e.sessionStorageProp||"USER_SESSION_TOKEN",this.refreshStorageProp=e.refreshStorageProp||"USER_REFRESH_TOKEN",this.loginRoute=e.loginRoute||"/",this.suppressAuthOnLoginRoute=e.loginRoute!=null,this.graphqlErrorPolicy=e.graphqlErrorPolicy||"legacy",this.useCache=e.useCache||!1,this.useDebug=e.useDebug||!1,this.useAuthorization=e.useAuthorization||!1,this.authMode=e.authMode||"bearer",this.credentials=e.credentials,this.sessionCheckUrl=e.sessionCheckUrl,this.useRetries=e.useRetries||!1,this.useSubscription=e.useSubscription||!1,this.redirectOnError=e.redirectOnError||!1,this.retryWhen=e.retryWhen||[503,504,521,522,524],this.authenticationErrors=e.authenticationErrors||[401,403],this.retries=e.retries||[R,R*2,R*3,R*5,R*8,R*13,R*21,R*34],this.partner=e.partner||void 0,this.usePersistedQueries=e.usePersistedQueries||!1,this.persistedOperationField=e.persistedOperationField||"doc_id",this.initialRecords=e.initialRecords,this.store=e.store,this.missingFieldHandlers=e.missingFieldHandlers,!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[j]=se(this)()}this[B]=re(this),this[oe]()}[(B,j,oe)](){let e=be.create(this[B],this[j]||null),s=new ye(this.initialRecords),a=new fe(s,this.store);this.Environment=new me({network:e,store:a,missingFieldHandlers:this.missingFieldHandlers})}};i(J,"RelayEnvironment");var U=J;export{U as a};
@@ -1 +1 @@
1
- import{a}from"../chunks/chunk-RMYDTZUF.esm.js";import"../chunks/chunk-GZONWSRB.esm.js";export{a as commitMutation};
1
+ import{a}from"../chunks/chunk-LAI2FBXL.esm.js";import"../chunks/chunk-GZONWSRB.esm.js";export{a as commitMutation};
package/lib/index.d.ts CHANGED
@@ -16,3 +16,5 @@ export * from './useEnvironment';
16
16
  export * from './relayArgsInterface';
17
17
  export * from './mutationUtils';
18
18
  export * from './commitMutation';
19
+ export { batchLiveStateUpdates, liveState, subscriptionLiveState, suspenseSentinel } from './liveState';
20
+ export type { LiveState, SubscriptionLiveStateArgs } from './liveState';
package/lib/index.esm.js CHANGED
@@ -1 +1 @@
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-CHTVEJCU.esm.js";import{a as e,b as t}from"./chunks/chunk-EATF764J.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};
1
+ import{a as p}from"./chunks/chunk-LAI2FBXL.esm.js";import{a as t,b as r,c as o,d as i}from"./chunks/chunk-OASJA5CE.esm.js";import{a as n,b as s,c as S,d as f,e as v,f as x,g as l,h as L,i as b}from"./chunks/chunk-I6VTFRC5.esm.js";import"./chunks/chunk-FYOI5Q5V.esm.js";import{a as e}from"./chunks/chunk-VZGQENYM.esm.js";import{a,b as m}from"./chunks/chunk-KUSP42LB.esm.js";import"./chunks/chunk-GZONWSRB.esm.js";export{S as ClientMutationID,e as CreateRelayEnvironment,a as EnvironmentProvider,o as batchLiveStateUpdates,p as commitMutation,L as connectionDeleteEdgeUpdater,x as connectionUpdater,b as copyObjScalarsToProxy,s as createClientMutationID,n as isObject,v as listRecordAddUpdater,f as listRecordRemoveUpdater,r as liveState,l as optimisticConnectionUpdater,i as subscriptionLiveState,t as suspenseSentinel,m as useEnvironment};
package/lib/index.js CHANGED
@@ -1 +1 @@
1
- var ge=Object.create;var S=Object.defineProperty;var be=Object.getOwnPropertyDescriptor;var Ee=Object.getOwnPropertyNames;var xe=Object.getPrototypeOf,we=Object.prototype.hasOwnProperty;var o=(e,t)=>S(e,"name",{value:t,configurable:!0});var Se=(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 Ee(t))!we.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)),Pe=e=>Y(S({},"__esModule",{value:!0}),e);var qe={};Se(qe,{ClientMutationID:()=>Ae,CreateRelayEnvironment:()=>E,EnvironmentProvider:()=>ke,commitMutation:()=>We,connectionDeleteEdgeUpdater:()=>He,connectionUpdater:()=>ye,copyObjScalarsToProxy:()=>Le,isObject:()=>fe,listRecordAddUpdater:()=>Ne,listRecordRemoveUpdater:()=>De,optimisticConnectionUpdater:()=>Fe,useEnvironment:()=>Ue});module.exports=Pe(qe);var R=require("relay-runtime");var I=require("relay-runtime");var k=!!(typeof window!="undefined"&&window.document&&window.document.createElement),b={canUseDOM:k,canUseWorkers:typeof Worker!="undefined",canUseEventListeners:k&&!!(window.addEventListener||window.attachEvent),canUseViewport:k&&!!window.screen,isInWorker:!k};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=>b.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"),ve=o(()=>b.canUseDOM?window.location.search.startsWith("?")?"&":"?":"","getParamsDelimiter"),U=o(()=>b.canUseDOM?window.location.pathname:"","getBrowserLocation"),P=o((e,t,r)=>{let n=e;(e!==t||r.loginRoute!==t)&&(n=`${t}${ve()}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 Te(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(Te,"getRequestBodyWithoutUplodables");function re(e,t,r,n){return r?Ce(e,t,r,n):Te(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&&U()!==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 I.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=U();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(b.canUseDOM&&!["AbortError","TimeOutError"].includes(h.name)&&e.StorageHandler.clear(),e.redirectOnError){let d=U();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)=>I.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"),v=Symbol("prop-session"),C=Symbol("prop-refresh"),Q=class Q{constructor(t){this[v]=t.sessionStorageProp,this[C]=t.refreshStorageProp,t.storageType==="cookie"?this[y]=new W:this[y]=new L}getTokens(){return{refreshToken:this[y].get(this[C]),sessionToken:this[y].get(this[v])}}setTokens(t){this[y].set(this[C],t.refreshToken),this[y].set(this[v],t.sessionToken)}clear(){this[y].delete(this[C]),this[y].delete(this[v])}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 Oe(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(Oe,"getSubscribePayload");function ue(e){return()=>{let t;return(r,n)=>ce.Observable.create(i=>(t||(t=(0,ae.createClient)({url:e.socket})),t.subscribe(Oe(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.initialRecords=t.initialRecords,!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=R.Network.create(this[j],this[B]||null),r=new R.RecordSource(this.initialRecords),n=new R.Store(r);this.Environment=new R.Environment({network:t,store:n})}};o(_,"RelayEnvironment");var E=_;var O=G(require("react")),de=require("react-relay");var pe=O.default.createContext(void 0);function ke({children:e,environment:t}){return O.default.createElement(pe.Provider,{value:{environment:t}},O.default.createElement(de.RelayEnvironmentProvider,{environment:t},e))}o(ke,"EnvironmentProvider");function Ue(){let e=O.default.useContext(pe);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(Ue,"useEnvironment");var z=require("node:crypto");var he="useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";var Ie=128,g,x;function Me(e){if(e<0)throw new RangeError("Wrong ID size");try{!g||g.length<e?(g=Buffer.allocUnsafe(e*Ie),z.webcrypto.getRandomValues(g),x=0):x+e>g.length&&(z.webcrypto.getRandomValues(g),x=0)}catch(t){throw g=void 0,t}x+=e}o(Me,"fillPool");function me(e=21){Me(e|=0);let t="";for(let r=x-e;r<x;r++)t+=he[g[r]&63];return t}o(me,"nanoid");var w=require("relay-runtime");function fe(e){return e!==null&&typeof e=="object"}o(fe,"isObject");var Ae=me();function De({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(De,"listRecordRemoveUpdater");function Ne({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(Ne,"listRecordAddUpdater");function ye(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(ye,"connectionUpdater");function Fe({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"),ye(t,e,r,u)}o(Fe,"optimisticConnectionUpdater");function He({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(He,"connectionDeleteEdgeUpdater");function Le({object:e,proxy:t}){Object.keys(e).forEach(r=>{fe(e[r])||Array.isArray(e[r])||t.setValue(e[r],r)})}o(Le,"copyObjScalarsToProxy");var Re=require("relay-runtime");var We=o((e,t)=>new Promise((r,n)=>{(0,Re.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 ke=Object.create;var L=Object.defineProperty;var Le=Object.getOwnPropertyDescriptor;var Me=Object.getOwnPropertyNames;var Ie=Object.getPrototypeOf,De=Object.prototype.hasOwnProperty;var n=(e,t)=>L(e,"name",{value:t,configurable:!0});var He=(e,t)=>{for(var r in t)L(e,r,{get:t[r],enumerable:!0})},ue=(e,t,r,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of Me(t))!De.call(e,o)&&o!==r&&L(e,o,{get:()=>t[o],enumerable:!(s=Le(t,o))||s.enumerable});return e};var ce=(e,t,r)=>(r=e!=null?ke(Ie(e)):{},ue(t||!e||!e.__esModule?L(r,"default",{value:e,enumerable:!0}):r,e)),Fe=e=>ue(L({},"__esModule",{value:!0}),e);var Xe={};He(Xe,{ClientMutationID:()=>je,CreateRelayEnvironment:()=>w,EnvironmentProvider:()=>Ve,batchLiveStateUpdates:()=>_,commitMutation:()=>Ye,connectionDeleteEdgeUpdater:()=>Ke,connectionUpdater:()=>Ue,copyObjScalarsToProxy:()=>Ge,createClientMutationID:()=>Oe,isObject:()=>Q,listRecordAddUpdater:()=>Be,listRecordRemoveUpdater:()=>ze,liveState:()=>ie,optimisticConnectionUpdater:()=>Je,subscriptionLiveState:()=>ae,suspenseSentinel:()=>P.suspenseSentinel,useEnvironment:()=>qe});module.exports=Fe(Xe);var v=require("relay-runtime");var V=require("relay-runtime");var $=!!(typeof window!="undefined"&&window.document&&window.document.createElement),x={canUseDOM:$,canUseWorkers:typeof Worker!="undefined",canUseEventListeners:$&&!!(window.addEventListener||window.attachEvent),canUseViewport:$&&!!window.screen,isInWorker:!$};function de(e){return async t=>{let r=e.timeout,s=e.retries,o=0,i=(t==null?void 0:t.retry)!==!1;return new Promise((u,d)=>{var A,N;let c=!1,l,h,m=n(p=>{c||(c=!0,clearTimeout(l),d(p))},"fail"),f=n(p=>{c||(c=!0,clearTimeout(l),u(p))},"succeed"),y=n(()=>{let p=new Error("The operation was aborted.");return p.name="AbortError",p},"abortError");if((A=t==null?void 0:t.signal)!=null&&A.aborted){d(y());return}let S=n(()=>{h==null||h.abort(),m(y())},"onCallerAbort");(N=t==null?void 0:t.signal)==null||N.addEventListener("abort",S);let a={};a.sendTimedRequest=()=>{o++;let p=!0;h=new AbortController;let W=setTimeout(()=>{if(p=!1,h.abort(),a.shouldRetry(o))e.useDebug&&console.log("fetchWithRetries: HTTP timeout, retrying."),a.retryRequest();else{let b=new Error(`fetchWithRetries(): Failed to get response from server, tried ${o} times.`);b.name="TimeOutError",m(b)}},r),{signal:j,retry:z,...k}=t!=null?t:{};fetch(e.url,{...k,signal:h.signal}).then(async b=>{if(clearTimeout(W),p)if(b.status>=200&&b.status<300)f(b);else if(a.shouldRetry(o)&&e.retryWhen.includes(b.status))e.useDebug&&console.log("fetchWithRetries: HTTP error, retrying..."),a.retryRequest();else{let le=new Error(`fetchWithRetries(): Still no successful response after ${o} retries, giving up.`);le.response=b,m(le)}}).catch(b=>{clearTimeout(W),b.name!=="AbortError"&&m(b)})},a.retryRequest=()=>{let p=s[o-1];l=setTimeout(a.sendTimedRequest,p)},a.shouldRetry=p=>x.canUseDOM&&e.useRetries&&i&&p<=s.length,a.sendTimedRequest()})}}n(de,"fetchWithRetries");var pe=require("fetch-multipart-graphql");var B=n(e=>e.operationKind==="mutation","isMutation"),M=n(e=>e.operationKind==="query","isQuery"),he=n(e=>!!(e&&e.force),"forceFetch");var I=n(()=>x.canUseDOM?window.location.pathname:"","getBrowserLocation"),T=n((e,t,r)=>{if(!x.canUseDOM)return;let s=t;if(e!==t){let o=t.includes("?")?"&":"?";s=`${t}${o}redirect=${encodeURIComponent(e)}`}(r==null?void 0:r.loginRoute)===t&&e===t&&(s=t),window.location.href=s},"redirectUser");function me(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}n(me,"getPersistedOperationId");function Ne(e,t,r,s){let o=new FormData,i=s!=null&&s.usePersistedQueries?{[s.persistedOperationField||"doc_id"]:me(e),variables:t,operationName:e.name}:{query:e.text,variables:t,operationName:e.name};o.append("operations",JSON.stringify({...i,name:e.name}));let u={},d=r.files,c=r.path;if(Array.isArray(d)&&typeof c=="function")for(let l=0;l<d.length;l++)o.append(`${l}`,d[l]),u[`${l}`]=[c(l)];else{let l=0;Object.keys(r).forEach(h=>{let m=r[h];o.append(`${l}`,m),u[`${l}`]=[`variables.${h}`],l+=1})}return o.append("map",JSON.stringify(u)),o}n(Ne,"getRequestBodyWithUploadables");function We(e,t,r){return r!=null&&r.usePersistedQueries?JSON.stringify({name:e.name,[r.persistedOperationField||"doc_id"]:me(e),variables:t}):JSON.stringify({name:e.name,query:e.text,variables:t})}n(We,"getRequestBodyWithoutUplodables");function fe(e,t,r,s){return r?Ne(e,t,r,s):We(e,t,s)}n(fe,"getRequestBody");var J=n(e=>{if(e.credentials)return e.credentials;if(e.authMode==="cookie")return"include"},"resolveCredentials"),ye=n((e,t)=>{var s;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(),i=(s=e.suppressAuthOnLoginRoute)!=null?s:e.loginRoute!=null&&e.loginRoute!=="/";o&&!(i&&I()===e.loginRoute)&&r.append("Authorization",`Bearer ${o}`)}return e.partner&&r.append("X-Partner",e.partner),r},"getHeaders"),be=n((e,t,r,s)=>{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(),i=new TextDecoder,u=new pe.PatchResolver({onResponse:n(c=>t.next(c),"onResponse")}),d=n(async()=>{var m,f;if(s!=null&&s.aborted||t.closed){await((m=o.cancel)==null?void 0:m.call(o));return}let{value:c,done:l}=await o.read();if(l){t.complete();return}let h;try{h=i.decode(c,{stream:!0}),u.handleChunk(h)}catch(y){let a=y instanceof Error?y:new Error(String(y));a.response=e,a.statusCode=e.status,a.bodyText=h,t.error(a),await((f=o.cancel)==null?void 0:f.call(o));return}await d()},"readNext");return d().catch(c=>{s!=null&&s.aborted||t.closed||t.error(c instanceof Error?c:new Error(String(c)))})}return e.headers&&e.headers.get("Content-Type")&&e.headers.get("Content-Type").indexOf("application/json")>=0?e.json().then(o=>r(o)).catch(o=>{t.closed||t.error(o instanceof Error?o:new Error(String(o)))}):e.text().then(o=>{t.next([o]),t.complete()})},"handleData"),R=1e3,K=R*60;var Re=n(e=>{let t=new V.QueryResponseCache({ttl:e.cacheTime,size:e.cacheSize}),r=de(e);async function s(){if(e.sessionCheckUrl===!1)return!1;let i=J(e);try{if(e.authMode==="cookie"){let h=e.sessionCheckUrl||e.authUrl;return(await fetch(h,{method:"POST",credentials:i||"include"})).status===200}let{sessionToken:u}=e.StorageHandler.getTokens(),d=e.sessionCheckUrl||`${e.authUrl}user/me`,c={"Content-Type":"application/json"};return u&&(c.Authorization=`Bearer ${u}`),(await fetch(d,{headers:c,...i?{credentials:i}:{}})).status===200}catch(u){return console.warn(`[Auth] ${u.message}`),!1}}n(s,"checkSession");async function o(i,u,d,c,l,h){let m=e.graphqlErrorPolicy==="payload";try{let f=i.id||("cacheID"in i?i.cacheID:null)||String(i.text);if(e.useCache&&M(i)&&!he(d)){let a=t.get(f,u);if(a){l.next(a),l.complete();return}}e.useCache&&B(i)&&t.clear();let y=J(e),S=await r({method:"POST",headers:ye(e,c),body:fe(i,u,c,e),...y?{credentials:y}:{},signal:h,retry:M(i)});if(h.aborted||l.closed)return;await be(S,l,async a=>{if(e.useCache&&M(i)&&(a!=null&&a.data)&&!a.errors&&t.set(f,u,a),l.closed)return;let N=(Array.isArray(a==null?void 0:a.errors)?a.errors.map(p=>p==null?void 0:p.status_code).filter(p=>typeof p=="number"):[]).some(p=>e.authenticationErrors.includes(p));if(m){N&&e.sessionCheckUrl!==!1&&!await s()&&!l.closed&&(e.StorageHandler.clear(),T(I(),e.loginRoute,e)),a!=null&&a.data?l.next(a):a!=null&&a.errors?l.error(a.errors):l.error(a),l.closed||l.complete();return}if(B(i)&&a.errors&&l.error(a.errors),a.errors){let p=e.sessionCheckUrl!==!1,W=p?await s():!0;if(p&&!W&&(e.StorageHandler.clear(),T("/",e.loginRoute,e)),p&&e.redirectOnError){let j=[];Array.isArray(a.errors)&&(j=a.errors.map(({status_code:k})=>k));let z=I();j.some(k=>e.authenticationErrors.includes(k))&&z!==e.loginRoute&&(e.StorageHandler.clear(),T(z,e.loginRoute,e))}l.error(a.errors)}else a.data?l.next(a):l.error(a);l.complete()})}catch(f){if(h.aborted||(f==null?void 0:f.name)==="AbortError")return;if(m){l.error(f);return}let y=e.sessionCheckUrl!==!1;if(y&&x.canUseDOM&&!["AbortError","TimeOutError"].includes(f.name)&&e.StorageHandler.clear(),y&&e.redirectOnError){let a=I();a!==e.loginRoute&&T(a,e.loginRoute,e)}let S=y?await s():!0;y&&!S&&(e.StorageHandler.clear(),T("/",e.loginRoute,e)),l.error(f)}}return n(o,"fetchFn"),(i,u,d,c)=>{var y;let l=(y=i.metadata)==null?void 0:y.live,h=l==null?void 0:l.polling_interval,m=M(i)&&(d==null?void 0:d.poll)==null&&typeof h=="number"&&h>0?h:void 0,f=V.Observable.create(S=>{let a=new AbortController,A=m!=null?{...d,force:!0}:d;return o(i,u,A,c,S,a.signal),()=>a.abort()});return m!=null?f.poll(m):f}},"createFetchFunction");var ge=ce(require("js-cookie"));var X=class X{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')}};n(X,"DefaultStrategy");var q=X,Z=class Z extends q{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)}};n(Z,"LocalStorageStrategy");var G=Z,ee=class ee extends q{constructor(){super(),this.strategy=ge.default}get(t){return this.strategy.get(t)}set(t,r){this.strategy.set(t,r)}delete(t){this.strategy.remove(t)}};n(ee,"CookieStrategy");var Y=ee,g=Symbol("storage-handler"),D=Symbol("prop-session"),H=Symbol("prop-refresh"),te=class te{constructor(t){this[D]=t.sessionStorageProp,this[H]=t.refreshStorageProp,t.storageType==="cookie"?this[g]=new Y:this[g]=new G}getTokens(){return{refreshToken:this[g].get(this[H]),sessionToken:this[g].get(this[D])}}setTokens(t){this[g].set(this[H],t.refreshToken),this[g].set(this[D],t.sessionToken)}clear(){this[g].delete(this[H]),this[g].delete(this[D])}hasChangedSession({sessionToken:t}){let{sessionToken:r}=this.getTokens();return t!==r}};n(te,"StorageClass");var F=te;var Se=require("graphql-ws"),ve=require("relay-runtime");function $e(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}}n($e,"getSubscribePayload");function Ee(e){return()=>{let t,r=0,s=n(()=>{var i;let o=(i=e.StorageHandler)==null?void 0:i.getTokens().sessionToken;return o?{Authorization:`Bearer ${o}`}:{}},"connectionParams");return(o,i)=>ve.Observable.create(u=>{t||(t=(0,Se.createClient)({url:e.socket,...e.useAuthorization&&e.authMode!=="cookie"?{connectionParams:s}:{}})),r+=1;let d=t.subscribe($e(e,o,i),{next:n(c=>u.next(c),"next"),error:n(c=>u.error(c),"error"),complete:n(()=>u.complete(),"complete")});return()=>{typeof d=="function"&&d(),r-=1,r<=0&&t&&(t.dispose(),t=void 0,r=0)}})}}n(Ee,"setupSubscription");var xe=Symbol("mount-environment"),re=Symbol("handler-fetch"),oe=Symbol("handler-subscription"),ne=class ne{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||K*8,this.timeout=t.timeout||K*15,this.sessionStorageProp=t.sessionStorageProp||"USER_SESSION_TOKEN",this.refreshStorageProp=t.refreshStorageProp||"USER_REFRESH_TOKEN",this.loginRoute=t.loginRoute||"/",this.suppressAuthOnLoginRoute=t.loginRoute!=null,this.graphqlErrorPolicy=t.graphqlErrorPolicy||"legacy",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||[R,R*2,R*3,R*5,R*8,R*13,R*21,R*34],this.partner=t.partner||void 0,this.usePersistedQueries=t.usePersistedQueries||!1,this.persistedOperationField=t.persistedOperationField||"doc_id",this.initialRecords=t.initialRecords,this.store=t.store,this.missingFieldHandlers=t.missingFieldHandlers,!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 F(this),this.useSubscription){if(!this.socket)throw new Error("[useSubscription] If you choose to use WebSocket you must set a socket endpoint.");this[oe]=Ee(this)()}this[re]=Re(this),this[xe]()}[(re,oe,xe)](){let t=v.Network.create(this[re],this[oe]||null),r=new v.RecordSource(this.initialRecords),s=new v.Store(r,this.store);this.Environment=new v.Environment({network:t,store:s,missingFieldHandlers:this.missingFieldHandlers})}};n(ne,"RelayEnvironment");var w=ne;var C=ce(require("react")),we=require("react-relay");var Pe=C.default.createContext(void 0);function Ve({children:e,environment:t}){let r=C.default.useMemo(()=>({environment:t}),[t]);return C.default.createElement(Pe.Provider,{value:r},C.default.createElement(we.RelayEnvironmentProvider,{environment:t},e))}n(Ve,"EnvironmentProvider");function qe(){let e=C.default.useContext(Pe);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}n(qe,"useEnvironment");var se=require("node:crypto");var Te="useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";var Qe=128,E,O;function _e(e){if(e<0)throw new RangeError("Wrong ID size");try{!E||E.length<e?(E=Buffer.allocUnsafe(e*Qe),se.webcrypto.getRandomValues(E),O=0):O+e>E.length&&(se.webcrypto.getRandomValues(E),O=0)}catch(t){throw E=void 0,t}O+=e}n(_e,"fillPool");function Ce(e=21){_e(e|=0);let t="";for(let r=O-e;r<O;r++)t+=Te[E[r]&63];return t}n(Ce,"nanoid");var U=require("relay-runtime");function Q(e){return e!==null&&typeof e=="object"}n(Q,"isObject");function Oe(){return Ce()}n(Oe,"createClientMutationID");var je=Oe();function ze({parentId:e,itemId:t,parentFieldName:r,store:s}){let o=s.get(e),i=o.getLinkedRecords(r);i&&o.setLinkedRecords(i.filter(u=>u.getDataID()!==t),r)}n(ze,"listRecordRemoveUpdater");function Be({parentId:e,item:t,type:r,parentFieldName:s,store:o}){let i=o.create(t.id,r);Object.keys(t).forEach(c=>{Q(t[c])||i.setValue(t[c],c)});let u=o.get(e),d=u.getLinkedRecords(s);u.setLinkedRecords([...d,i],s)}n(Be,"listRecordAddUpdater");function Ue(e,t,r,s,o=!1){if(s){let i=e.get(t),u=U.ConnectionHandler.getConnection(i,r);if(!u)return;o?U.ConnectionHandler.insertEdgeBefore(u,s):U.ConnectionHandler.insertEdgeAfter(u,s)}}n(Ue,"connectionUpdater");function Je({parentId:e,store:t,connectionName:r,item:s,customNode:o,itemType:i}){let u=o||t.create(s.id,i);!o&&Object.keys(s).forEach(c=>{Q(s[c])||u.setValue(s[c],c)});let d=t.create(`client:newEdge:${u.getDataID()}`,`${i}Edge`);d.setLinkedRecord(u,"node"),Ue(t,e,r,d)}n(Je,"optimisticConnectionUpdater");function Ke({parentId:e,connectionName:t,nodeId:r,store:s}){let o=s.get(e),i=U.ConnectionHandler.getConnection(o,t);if(!i){console.warn(`Connection ${t} not found on ${e}`);return}U.ConnectionHandler.deleteNode(i,r)}n(Ke,"connectionDeleteEdgeUpdater");function Ge({object:e,proxy:t}){Object.keys(e).forEach(r=>{Q(e[r])||Array.isArray(e[r])||t.setValue(e[r],r)})}n(Ge,"copyObjScalarsToProxy");var Ae=require("relay-runtime");var Ye=n((e,t)=>new Promise((r,s)=>{(0,Ae.commitMutation)(e,{...t,onError:s,onCompleted:n((o,i)=>i!=null&&i.length?s(i):r(o),"onCompleted")})}),"commitMutation");var P=require("relay-runtime");function ie(e,t){let r=e();return{read:n(()=>(r=e(),r),"read"),subscribe:n(s=>t(()=>{let o=e();Object.is(o,r)||(r=o,s())}),"subscribe")}}n(ie,"liveState");function _(e,t){let r=e.getStore();if(typeof r.batchLiveStateUpdates=="function"){r.batchLiveStateUpdates(t);return}t()}n(_,"batchLiveStateUpdates");function ae({environment:e,subscription:t,variables:r}){let s,o=!1,i=new Set,u=null,d=n(()=>{_(e,()=>{i.forEach(c=>c())})},"publish");return{read:n(()=>o?s:(0,P.suspenseSentinel)(),"read"),subscribe:n(c=>(i.add(c),i.size===1&&(u=(0,P.requestSubscription)(e,{subscription:t,variables:r,onNext:n(l=>{s=l,o=!0,d()},"onNext")})),()=>{i.delete(c),i.size===0&&(u==null||u.dispose(),u=null)}),"subscribe")}}n(ae,"subscriptionLiveState");0&&(module.exports={ClientMutationID,CreateRelayEnvironment,EnvironmentProvider,batchLiveStateUpdates,commitMutation,connectionDeleteEdgeUpdater,connectionUpdater,copyObjScalarsToProxy,createClientMutationID,isObject,listRecordAddUpdater,listRecordRemoveUpdater,liveState,optimisticConnectionUpdater,subscriptionLiveState,suspenseSentinel,useEnvironment});
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Public barrel for `@apollion-dsi/relay/liveState`.
3
+ */
4
+ export { batchLiveStateUpdates, liveState, subscriptionLiveState, suspenseSentinel } from './liveState';
5
+ export type { LiveState, SubscriptionLiveStateArgs } from './liveState';
@@ -0,0 +1 @@
1
+ import{a,b,c,d}from"../chunks/chunk-OASJA5CE.esm.js";import"../chunks/chunk-GZONWSRB.esm.js";export{c as batchLiveStateUpdates,b as liveState,d as subscriptionLiveState,a as suspenseSentinel};
@@ -0,0 +1,32 @@
1
+ /**
2
+ * @fileoverview Client `@live` helpers. Relay already runs a resolver that
3
+ * returns `LiveState`. These functions build that object and bridge a
4
+ * GraphQL subscription into one, so a consumer does not hand-roll the
5
+ * notify/batch ceremony.
6
+ */
7
+ import { Environment, GraphQLTaggedNode, LiveState, suspenseSentinel, Variables } from 'relay-runtime';
8
+ /**
9
+ * Builds a `LiveState`. `read` is called for the current value. `subscribe`
10
+ * is the source's listener and must return an unsubscribe. Relay is notified
11
+ * only when the value changed (`Object.is`).
12
+ */
13
+ export declare function liveState<T>(read: () => T, subscribe: (notify: () => void) => () => void): LiveState<T>;
14
+ /**
15
+ * Runs `fn` inside the store's `batchLiveStateUpdates`, so many `@live`
16
+ * resolvers notified by one change recompute once.
17
+ */
18
+ export declare function batchLiveStateUpdates(environment: Environment, fn: () => void): void;
19
+ export type SubscriptionLiveStateArgs = {
20
+ environment: Environment;
21
+ subscription: GraphQLTaggedNode;
22
+ variables: Variables;
23
+ };
24
+ /**
25
+ * `LiveState` fed by one GraphQL subscription. `read()` returns
26
+ * `suspenseSentinel()` until the first payload. Further payloads notify
27
+ * every subscriber inside `batchLiveStateUpdates`. The socket for this
28
+ * operation closes when the last subscriber leaves.
29
+ */
30
+ export declare function subscriptionLiveState<T>({ environment, subscription, variables, }: SubscriptionLiveStateArgs): LiveState<T>;
31
+ export { suspenseSentinel };
32
+ export type { LiveState };
@@ -1 +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
+ import{a,b,c,d,e,f,g,h,i}from"../chunks/chunk-I6VTFRC5.esm.js";import"../chunks/chunk-GZONWSRB.esm.js";export{c as ClientMutationID,h as connectionDeleteEdgeUpdater,f as connectionUpdater,i as copyObjScalarsToProxy,b as createClientMutationID,a as isObject,e as listRecordAddUpdater,d as listRecordRemoveUpdater,g as optimisticConnectionUpdater};
@@ -52,15 +52,19 @@ type CopyObjScalarsToProxyOptions = {
52
52
  proxy: RecordProxy;
53
53
  };
54
54
  /**
55
- * Unique identifier generated once per module load,
56
- * intended for the `clientMutationId` field expected by the Relay
57
- * Modern pattern.
55
+ * Fresh id for one mutation. Servers that treat `clientMutationId` as an
56
+ * idempotency key must not see the same value on two mutations.
57
+ */
58
+ export declare function createClientMutationID(): string;
59
+ /**
60
+ * Identifier generated once per module load. Prefer `createClientMutationID`
61
+ * for each mutation. Kept so existing call sites keep compiling.
58
62
  */
59
63
  export declare const ClientMutationID: string;
60
64
  /**
61
65
  * Removes an item from a `linked records` list on a parent.
62
66
  *
63
- * Uses `getLinkedRecords` + `setLinkedRecords` with a `dataID` filter.
67
+ * Uses `getLinkedRecords` + `setLinkedRecords` with a `getDataID()` filter.
64
68
  * For paginated connections, prefer `connectionDeleteEdgeUpdater`.
65
69
  *
66
70
  * @param options.parentId - DataID of the parent that owns the linked field.
@@ -72,9 +76,8 @@ export declare function listRecordRemoveUpdater({ parentId, itemId, parentFieldN
72
76
  /**
73
77
  * Adds an item to the end of a `linked records` list.
74
78
  *
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`).
79
+ * Creates a new `RecordProxy` using `item.id` as the dataID and copies
80
+ * scalar fields. Nested objects are skipped (`setValue` rejects them).
78
81
  *
79
82
  * @param options.parentId - DataID of the parent.
80
83
  * @param options.item - Object with the new record's fields (must have `id`).
@@ -6,7 +6,7 @@
6
6
  * `CreateRelayEnvironment` — any change here is part of the package's
7
7
  * public API.
8
8
  */
9
- import type { RecordSource } from 'relay-runtime';
9
+ import type { MissingFieldHandler, RecordSource } from 'relay-runtime';
10
10
  /**
11
11
  * Seed records for the Relay store, keyed by `DataID` — the exact shape a
12
12
  * `RecordSource` is constructed from (also what `RecordSource.toJSON()`
@@ -16,6 +16,18 @@ import type { RecordSource } from 'relay-runtime';
16
16
  * @see {@link RelayArgsInterface.initialRecords}
17
17
  */
18
18
  export type RelayInitialRecords = NonNullable<ConstructorParameters<typeof RecordSource>[0]>;
19
+ /**
20
+ * Options forwarded to Relay's `Store` constructor. Omitted fields keep
21
+ * Relay's own defaults.
22
+ */
23
+ export type RelayStoreOptions = {
24
+ /** How many queries stay in the release buffer before GC. Relay's default is 10. */
25
+ gcReleaseBufferSize?: number | null;
26
+ /** Milliseconds before a cached query is stale. */
27
+ queryCacheExpirationTime?: number | null;
28
+ /** Schedules a GC step. Relay's default runs it immediately. */
29
+ gcScheduler?: ((callback: () => void) => void) | null;
30
+ };
19
31
  /**
20
32
  * Relay `Observable` sink. Implemented by the Relay runtime and
21
33
  * passed to the `Observable.create` callback. The fetch/subscription
@@ -241,6 +253,20 @@ export interface RelayArgsInterface {
241
253
  * @defaultValue `'doc_id'`
242
254
  */
243
255
  persistedOperationField?: string;
256
+ /**
257
+ * How a GraphQL `errors` array is delivered to Relay.
258
+ *
259
+ * - `'legacy'` (default): any `errors` array probes the session and is
260
+ * pushed with `sink.error`, so partial `data` is dropped. This is the
261
+ * behaviour existing consumers already run.
262
+ * - `'payload'`: when the body has `data`, it is pushed with `sink.next`
263
+ * so Relay can normalize the partial payload. The session is probed
264
+ * only when an error carries a `status_code` in `authenticationErrors`.
265
+ * A transport failure does not clear storage.
266
+ *
267
+ * @defaultValue `'legacy'`
268
+ */
269
+ graphqlErrorPolicy?: 'legacy' | 'payload';
244
270
  /**
245
271
  * Records used to **seed the Relay store** at environment creation.
246
272
  *
@@ -276,4 +302,13 @@ export interface RelayArgsInterface {
276
302
  * @defaultValue undefined (empty store)
277
303
  */
278
304
  initialRecords?: RelayInitialRecords;
305
+ /**
306
+ * Store GC and staleness. Omitted means `new Store(source)` with Relay's defaults.
307
+ */
308
+ store?: RelayStoreOptions;
309
+ /**
310
+ * Handlers Relay calls when a field is missing from the store, such as
311
+ * `node(id:)` served from the cache.
312
+ */
313
+ missingFieldHandlers?: ReadonlyArray<MissingFieldHandler>;
279
314
  }
@@ -22,6 +22,13 @@ export type InitWithRetries = {
22
22
  headers?: HeadersInit;
23
23
  method?: string;
24
24
  mode?: RequestMode;
25
+ /** Caller abort. Distinct from the per-attempt timeout. */
26
+ signal?: AbortSignal;
27
+ /**
28
+ * When `false`, a failed attempt is not retried. Queries retry; mutations
29
+ * do not. Omitted means retry (the historical default of this helper).
30
+ */
31
+ retry?: boolean;
25
32
  };
26
33
  /**
27
34
  * Creates a `fetch` function configured with timeout and retries.
@@ -1 +1 @@
1
- import{a}from"../chunks/chunk-CHTVEJCU.esm.js";import"../chunks/chunk-GZONWSRB.esm.js";export{a as CreateRelayEnvironment,a as default};
1
+ import{a}from"../chunks/chunk-VZGQENYM.esm.js";import"../chunks/chunk-GZONWSRB.esm.js";export{a as CreateRelayEnvironment,a as default};
@@ -1,5 +1,6 @@
1
+ import type { MissingFieldHandler } from 'relay-runtime';
1
2
  import { Environment } from 'relay-runtime';
2
- import { RelayArgsInterface, RelayInitialRecords } from '../relayArgsInterface';
3
+ import { RelayArgsInterface, RelayInitialRecords, RelayStoreOptions } from '../relayArgsInterface';
3
4
  declare const kMountEnvironment: unique symbol;
4
5
  declare const kFeetchHandler: unique symbol;
5
6
  declare const kSubscriptionHandler: unique symbol;
@@ -131,6 +132,20 @@ export default class RelayEnvironment implements RelayArgsInterface {
131
132
  persistedOperationField?: string;
132
133
  /** Records used to seed the Relay store at creation (app-owned state). */
133
134
  initialRecords?: RelayInitialRecords;
135
+ /** Forwarded as the second argument of `new Store`. */
136
+ store?: RelayStoreOptions;
137
+ /** Forwarded to `new Environment`. */
138
+ missingFieldHandlers?: ReadonlyArray<MissingFieldHandler>;
139
+ /**
140
+ * `'legacy'` drops partial GraphQL payloads. `'payload'` forwards them.
141
+ * @defaultValue `'legacy'`
142
+ */
143
+ graphqlErrorPolicy: 'legacy' | 'payload';
144
+ /**
145
+ * True only when the caller passed `loginRoute`. The `'/'` default must
146
+ * not strip `Authorization` on the home page.
147
+ */
148
+ suppressAuthOnLoginRoute: boolean;
134
149
  /**
135
150
  * Fetch function assembled for use by Relay's `Network`. Internal.
136
151
  */
@@ -98,7 +98,7 @@ export declare const getHeaders: (args: any, uploadables?: UploadableMap) => Hea
98
98
  * Copied from the `fetch-multipart-graphql` library with adaptations for the
99
99
  * Relay `Sink`.
100
100
  */
101
- export declare const handleData: (response: Response, sink: Sink, callback: (data: any) => void) => void;
101
+ export declare const handleData: (response: Response, sink: Sink, callback: (data: any) => void | Promise<void>, signal?: AbortSignal) => Promise<void>;
102
102
  /** Time constant: 1 second in milliseconds. */
103
103
  export declare const ONE_SECOND = 1000;
104
104
  /** Time constant: 1 minute in milliseconds. */
@@ -13,6 +13,13 @@ interface SubscriptionSettings {
13
13
  socket?: string;
14
14
  usePersistedQueries?: boolean;
15
15
  persistedOperationField?: string;
16
+ useAuthorization?: boolean;
17
+ authMode?: 'bearer' | 'cookie';
18
+ StorageHandler?: {
19
+ getTokens: () => {
20
+ sessionToken?: string;
21
+ };
22
+ };
16
23
  }
17
24
  /**
18
25
  * Builds the subscription function for Relay's `Network.create`.
@@ -1 +1 @@
1
- import{a,b}from"../chunks/chunk-EATF764J.esm.js";import"../chunks/chunk-GZONWSRB.esm.js";export{a as EnvironmentProvider,b as useEnvironment};
1
+ import{a,b}from"../chunks/chunk-KUSP42LB.esm.js";import"../chunks/chunk-GZONWSRB.esm.js";export{a as EnvironmentProvider,b as useEnvironment};
@@ -1,12 +1,11 @@
1
1
  import React from 'react';
2
2
  import { Environment } from 'relay-runtime';
3
- import { MockEnvironment } from 'relay-test-utils';
4
3
  /**
5
4
  * Internal Context state: contains only the Relay `Environment`
6
5
  * (real, or mocked in tests).
7
6
  */
8
7
  type StateType = {
9
- environment: Environment | MockEnvironment;
8
+ environment: Environment;
10
9
  };
11
10
  /**
12
11
  * Props for `EnvironmentProvider`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@apollion-dsi/relay",
3
- "version": "0.29.0",
3
+ "version": "0.31.0",
4
4
  "description": "Frontend services regarding Relay Environment",
5
5
  "main": "lib/index.js",
6
6
  "module": "lib/index.esm.js",
@@ -31,19 +31,26 @@
31
31
  "types": "./lib/commitMutation/index.d.ts",
32
32
  "import": "./lib/commitMutation/index.esm.js"
33
33
  },
34
+ "./liveState": {
35
+ "types": "./lib/liveState/index.d.ts",
36
+ "import": "./lib/liveState/index.esm.js"
37
+ },
34
38
  "./package.json": "./package.json"
35
39
  },
36
40
  "files": [
37
41
  "lib/**/*"
38
42
  ],
39
43
  "license": "MIT",
44
+ "engines": {
45
+ "node": ">=22"
46
+ },
40
47
  "scripts": {
41
48
  "audit-dependencies": "yarn npm audit --severity moderate --no-deprecations",
42
49
  "coverage": "jest --coverage",
43
- "lint": "eslint src --quiet",
50
+ "lint": "eslint src --quiet --cache --cache-strategy content --cache-location node_modules/.cache/eslint/",
44
51
  "lint:full": "eslint src",
45
52
  "lint:fix": "eslint src --fix",
46
- "check-types": "tsc --noEmit",
53
+ "check-types": "tsc --noEmit --incremental --tsBuildInfoFile node_modules/.cache/tsc/check-types.tsbuildinfo",
47
54
  "prettier": "prettier --check **/*.{ts,tsx} --ignore-path .gitignore --no-error-on-unmatched-pattern",
48
55
  "format": "yarn prettier --write",
49
56
  "validate": "./scripts/validate.sh",
@@ -63,11 +70,10 @@
63
70
  "js-cookie": "3.0.7",
64
71
  "nanoid": "5.1.16",
65
72
  "react-relay": "^21.0.0",
66
- "relay-runtime": "^21.0.0",
67
- "relay-test-utils": "^21.0.0"
73
+ "relay-runtime": "^21.0.0"
68
74
  },
69
75
  "devDependencies": {
70
- "@apollion-dsi/eslint-config": "0.10.0",
76
+ "@apollion-dsi/eslint-config": "0.11.0",
71
77
  "@babel/core": "7.29.0",
72
78
  "@babel/plugin-transform-class-properties": "7.27.1",
73
79
  "@babel/plugin-transform-runtime": "7.29.0",
@@ -81,9 +87,6 @@
81
87
  "@types/js-cookie": "3.0.6",
82
88
  "@types/lodash": "4.17.24",
83
89
  "@types/react": "19.2.14",
84
- "@types/react-relay": "18.2.1",
85
- "@types/relay-runtime": "20.1.1",
86
- "@types/relay-test-utils": "19.0.0",
87
90
  "babel-jest": "30.4.1",
88
91
  "babel-plugin-relay": "21.0.1",
89
92
  "esbuild": "0.28.0",
@@ -99,6 +102,7 @@
99
102
  "react": "19.2.6",
100
103
  "react-dom": "19.2.6",
101
104
  "relay-compiler": "21.0.1",
105
+ "relay-test-utils": "^21.0.0",
102
106
  "typescript": "6.0.3"
103
107
  }
104
108
  }
@@ -1 +0,0 @@
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,i=e.retries,a=0,o=0;return new Promise((u,l)=>{let c={};c.sendTimedRequest=()=>{a++,o=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=i[a-1],p=o+n;setTimeout(c.sendTimedRequest,p-Date.now())},c.shouldRetry=n=>f.canUseDOM&&e.useRetries&&n<=i.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 i=e;(e!==t||r.loginRoute!==t)&&(i=`${t}${Y()}redirect=${e}`),window.location.href=i},"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,i){let a=new FormData,o=i!=null&&i.usePersistedQueries?{[i.persistedOperationField||"doc_id"]:L(e),variables:t,operationName:e.name}:{query:e.text,variables:t,operationName:e.name};a.append("operations",JSON.stringify(o));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,i){return r?Z(e,t,r,i):ee(e,t,i)}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:i}=e.StorageHandler.getTokens();i&&C()!==e.loginRoute&&r.append("Authorization",`Bearer ${i}`)}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 i=e.body.getReader(),a=new TextDecoder,o=new X({onResponse:s(u=>t.next(u),"onResponse")});i.read().then(s(function u({value:l,done:c}){if(c)t.complete();else{let n;try{n=a.decode(l),o.handleChunk(n)}catch(p){let m=p;m.response=e,m.statusCode=e.status,m.bodyText=n,t.error(m)}i.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(i=>{t.next([i]),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 i(){if(e.sessionCheckUrl===!1)return!1;let o=U(e);try{if(e.authMode==="cookie"){let n=e.sessionCheckUrl||e.authUrl;return(await fetch(n,{method:"POST",credentials:o||"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},...o?{credentials:o}:{}})).status===200}catch(u){return console.warn(`[Auth] ${u.message}`),!1}}s(i,"checkSession");async function a(o,u,l,c,n){try{let p=o.id||("cacheID"in o?o.cacheID:null)||String(o.text);if(e.useCache&&O(o)&&!V(l)){let d=t.get(p,u);if(d){n.next(d),n.complete();return}}e.useCache&&x(o)&&t.clear();let m=U(e),h=await r({method:"POST",headers:_(e,c),body:B(o,u,c,e),...m?{credentials:m}:{}});j(h,n,async d=>{if(e.useCache&&O(o)&&t.set(p,u,d),!n.closed){if(x(o)&&d.errors&&n.error(d.errors),d.errors){if(await i()||(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 i()||(e.StorageHandler.clear(),R("/",e.loginRoute,e)),n.error(p)}}return s(a,"fetchFn"),(o,u,l,c)=>te.create(n=>{a(o,u,l,c,n)})},"createFetchFunction");import se from"js-cookie";var M=class M{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(M,"DefaultStrategy");var k=M,A=class A 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(A,"LocalStorageStrategy");var D=A,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 I=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 I: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 ie}from"graphql-ws";import{Observable as oe}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,i)=>oe.create(a=>(t||(t=ie({url:e.socket})),t.subscribe(ne(e,r,i),{next:s(o=>a.next(o),"next"),error:s(o=>a.error(o),"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.initialRecords=t.initialRecords,!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(this.initialRecords),i=new ce(r);this.Environment=new ae({network:t,store:i})}};s(W,"RelayEnvironment");var T=W;export{T as a};
@@ -1 +0,0 @@
1
- import{a as r}from"./chunk-GZONWSRB.esm.js";import e from"react";import{RelayEnvironmentProvider as i}from"react-relay";var t=e.createContext(void 0);function d({children:n,environment:o}){return e.createElement(t.Provider,{value:{environment:o}},e.createElement(i,{environment:o},n))}r(d,"EnvironmentProvider");function E(){let n=e.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}r(E,"useEnvironment");export{d as a,E as b};
@@ -1 +0,0 @@
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};
@@ -1 +0,0 @@
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};