@sanity/sdk 0.0.0-alpha.21 → 0.0.0-alpha.23
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/dist/index.d.ts +428 -325
- package/dist/index.js +1618 -1553
- package/dist/index.js.map +1 -1
- package/package.json +6 -7
- package/src/_exports/index.ts +31 -30
- package/src/auth/authStore.test.ts +149 -104
- package/src/auth/authStore.ts +51 -100
- package/src/auth/handleAuthCallback.test.ts +67 -34
- package/src/auth/handleAuthCallback.ts +8 -7
- package/src/auth/logout.test.ts +61 -29
- package/src/auth/logout.ts +26 -28
- package/src/auth/refreshStampedToken.test.ts +9 -9
- package/src/auth/refreshStampedToken.ts +62 -56
- package/src/auth/subscribeToStateAndFetchCurrentUser.test.ts +5 -5
- package/src/auth/subscribeToStateAndFetchCurrentUser.ts +45 -47
- package/src/auth/subscribeToStorageEventsAndSetToken.test.ts +4 -5
- package/src/auth/subscribeToStorageEventsAndSetToken.ts +22 -24
- package/src/client/clientStore.test.ts +131 -67
- package/src/client/clientStore.ts +117 -116
- package/src/comlink/controller/actions/destroyController.test.ts +38 -13
- package/src/comlink/controller/actions/destroyController.ts +11 -15
- package/src/comlink/controller/actions/getOrCreateChannel.test.ts +56 -27
- package/src/comlink/controller/actions/getOrCreateChannel.ts +37 -35
- package/src/comlink/controller/actions/getOrCreateController.test.ts +27 -16
- package/src/comlink/controller/actions/getOrCreateController.ts +23 -22
- package/src/comlink/controller/actions/releaseChannel.test.ts +37 -13
- package/src/comlink/controller/actions/releaseChannel.ts +22 -21
- package/src/comlink/controller/comlinkControllerStore.test.ts +65 -36
- package/src/comlink/controller/comlinkControllerStore.ts +44 -5
- package/src/comlink/node/actions/getOrCreateNode.test.ts +31 -15
- package/src/comlink/node/actions/getOrCreateNode.ts +30 -29
- package/src/comlink/node/actions/releaseNode.test.ts +75 -55
- package/src/comlink/node/actions/releaseNode.ts +19 -21
- package/src/comlink/node/comlinkNodeStore.test.ts +6 -11
- package/src/comlink/node/comlinkNodeStore.ts +22 -5
- package/src/config/authConfig.ts +79 -0
- package/src/config/sanityConfig.ts +48 -0
- package/src/datasets/datasets.test.ts +2 -2
- package/src/datasets/datasets.ts +18 -5
- package/src/document/actions.test.ts +22 -10
- package/src/document/actions.ts +44 -56
- package/src/document/applyDocumentActions.test.ts +96 -36
- package/src/document/applyDocumentActions.ts +140 -99
- package/src/document/documentStore.test.ts +103 -155
- package/src/document/documentStore.ts +247 -237
- package/src/document/listen.ts +56 -55
- package/src/document/patchOperations.ts +0 -43
- package/src/document/permissions.test.ts +25 -12
- package/src/document/permissions.ts +11 -4
- package/src/document/processActions.test.ts +41 -8
- package/src/document/reducers.test.ts +87 -16
- package/src/document/reducers.ts +2 -2
- package/src/document/sharedListener.test.ts +34 -16
- package/src/document/sharedListener.ts +33 -11
- package/src/preview/getPreviewState.test.ts +40 -39
- package/src/preview/getPreviewState.ts +68 -56
- package/src/preview/previewConstants.ts +43 -0
- package/src/preview/previewQuery.test.ts +1 -1
- package/src/preview/previewQuery.ts +4 -5
- package/src/preview/previewStore.test.ts +13 -58
- package/src/preview/previewStore.ts +7 -21
- package/src/preview/resolvePreview.test.ts +33 -104
- package/src/preview/resolvePreview.ts +11 -21
- package/src/preview/subscribeToStateAndFetchBatches.test.ts +96 -97
- package/src/preview/subscribeToStateAndFetchBatches.ts +85 -81
- package/src/preview/util.ts +1 -0
- package/src/project/project.test.ts +3 -3
- package/src/project/project.ts +28 -5
- package/src/projection/getProjectionState.test.ts +69 -49
- package/src/projection/getProjectionState.ts +42 -50
- package/src/projection/projectionQuery.ts +1 -1
- package/src/projection/projectionStore.test.ts +13 -51
- package/src/projection/projectionStore.ts +6 -18
- package/src/projection/resolveProjection.test.ts +32 -127
- package/src/projection/resolveProjection.ts +15 -28
- package/src/projection/subscribeToStateAndFetchBatches.test.ts +105 -90
- package/src/projection/subscribeToStateAndFetchBatches.ts +94 -81
- package/src/projection/util.ts +2 -0
- package/src/projects/projects.test.ts +13 -4
- package/src/projects/projects.ts +6 -1
- package/src/query/queryStore.test.ts +10 -47
- package/src/query/queryStore.ts +151 -133
- package/src/query/queryStoreConstants.ts +2 -0
- package/src/store/createActionBinder.test.ts +153 -0
- package/src/store/createActionBinder.ts +176 -0
- package/src/store/createSanityInstance.test.ts +84 -0
- package/src/store/createSanityInstance.ts +124 -0
- package/src/store/createStateSourceAction.test.ts +196 -0
- package/src/store/createStateSourceAction.ts +260 -0
- package/src/store/createStoreInstance.test.ts +81 -0
- package/src/store/createStoreInstance.ts +80 -0
- package/src/store/createStoreState.test.ts +85 -0
- package/src/store/createStoreState.ts +92 -0
- package/src/store/defineStore.test.ts +18 -0
- package/src/store/defineStore.ts +81 -0
- package/src/users/reducers.test.ts +318 -0
- package/src/users/reducers.ts +88 -0
- package/src/users/types.ts +46 -4
- package/src/users/usersConstants.ts +4 -0
- package/src/users/usersStore.test.ts +350 -223
- package/src/users/usersStore.ts +285 -149
- package/src/utils/createFetcherStore.test.ts +6 -7
- package/src/utils/createFetcherStore.ts +150 -153
- package/src/{common/util.test.ts → utils/hashString.test.ts} +1 -1
- package/src/auth/fetchLoginUrls.test.ts +0 -163
- package/src/auth/fetchLoginUrls.ts +0 -74
- package/src/common/createLiveEventSubscriber.test.ts +0 -121
- package/src/common/createLiveEventSubscriber.ts +0 -55
- package/src/common/types.ts +0 -4
- package/src/instance/identity.test.ts +0 -46
- package/src/instance/identity.ts +0 -29
- package/src/instance/sanityInstance.test.ts +0 -77
- package/src/instance/sanityInstance.ts +0 -57
- package/src/instance/types.ts +0 -37
- package/src/preview/getPreviewProjection.ts +0 -45
- package/src/resources/README.md +0 -370
- package/src/resources/createAction.test.ts +0 -101
- package/src/resources/createAction.ts +0 -44
- package/src/resources/createResource.test.ts +0 -112
- package/src/resources/createResource.ts +0 -102
- package/src/resources/createStateSourceAction.test.ts +0 -114
- package/src/resources/createStateSourceAction.ts +0 -83
- package/src/resources/createStore.test.ts +0 -67
- package/src/resources/createStore.ts +0 -46
- package/src/store/createStore.test.ts +0 -108
- package/src/store/createStore.ts +0 -106
- /package/src/{common/util.ts → utils/hashString.ts} +0 -0
package/dist/index.js
CHANGED
|
@@ -1,17 +1,63 @@
|
|
|
1
1
|
import { createClient } from "@sanity/client";
|
|
2
|
-
import { Observable, share, map, distinctUntilChanged, skip, filter, switchMap, interval, takeWhile, fromEvent, EMPTY, defer, firstValueFrom, from, asapScheduler, concatMap, of, withLatestFrom, concat, timer, throwError, first as first$1, partition, merge, shareReplay,
|
|
2
|
+
import { Observable, share, map, distinctUntilChanged, skip, filter, switchMap, interval, takeWhile, fromEvent, EMPTY, defer, firstValueFrom, from, asapScheduler, concatMap, of, withLatestFrom, concat, timer, throwError, first as first$1, Subject, takeUntil, partition, merge, shareReplay, tap as tap$1, catchError as catchError$1, startWith as startWith$1, pairwise as pairwise$1, groupBy as groupBy$1, mergeMap as mergeMap$1, throttle, race, NEVER, combineLatest, debounceTime } from "rxjs";
|
|
3
3
|
import { devtools } from "zustand/middleware";
|
|
4
|
-
import { createStore
|
|
5
|
-
import {
|
|
6
|
-
import { isEqual, omit, isObject, noop } from "lodash-es";
|
|
4
|
+
import { createStore } from "zustand/vanilla";
|
|
5
|
+
import { pick, isEqual, omit, isObject } from "lodash-es";
|
|
7
6
|
import { createController, createNode } from "@sanity/comlink";
|
|
8
7
|
import { first, switchMap as switchMap$1, groupBy, mergeMap, startWith, pairwise, filter as filter$1, map as map$1, delay, tap, catchError, scan } from "rxjs/operators";
|
|
9
8
|
import { SanityEncoder } from "@sanity/mutate";
|
|
10
9
|
import { getPublishedId as getPublishedId$1 } from "@sanity/client/csm";
|
|
10
|
+
import { createSelector } from "reselect";
|
|
11
11
|
import { applyPatches, parsePatch, makePatches, stringifyPatches } from "@sanity/diff-match-patch";
|
|
12
12
|
import { isKeySegment, isKeyedObject } from "@sanity/types";
|
|
13
13
|
import { createDocumentLoaderFromClient } from "@sanity/mutate/_unstable_store";
|
|
14
14
|
var AuthStateType = /* @__PURE__ */ ((AuthStateType2) => (AuthStateType2.LOGGED_IN = "logged-in", AuthStateType2.LOGGING_IN = "logging-in", AuthStateType2.ERROR = "error", AuthStateType2.LOGGED_OUT = "logged-out", AuthStateType2))(AuthStateType || {});
|
|
15
|
+
function getPublishedId(id) {
|
|
16
|
+
const draftsPrefix = "drafts.";
|
|
17
|
+
return id.startsWith(draftsPrefix) ? id.slice(draftsPrefix.length) : id;
|
|
18
|
+
}
|
|
19
|
+
function getDraftId(id) {
|
|
20
|
+
const draftsPrefix = "drafts.";
|
|
21
|
+
return id.startsWith(draftsPrefix) ? id : `${draftsPrefix}${id}`;
|
|
22
|
+
}
|
|
23
|
+
function insecureRandomId() {
|
|
24
|
+
return Array.from({ length: 16 }, () => Math.floor(Math.random() * 16).toString(16)).join("");
|
|
25
|
+
}
|
|
26
|
+
function createSanityInstance(config = {}) {
|
|
27
|
+
const instanceId = crypto.randomUUID(), disposeListeners = /* @__PURE__ */ new Map(), disposed = { current: !1 }, instance = {
|
|
28
|
+
instanceId,
|
|
29
|
+
config,
|
|
30
|
+
isDisposed: () => disposed.current,
|
|
31
|
+
dispose: () => {
|
|
32
|
+
disposed.current || (disposed.current = !0, disposeListeners.forEach((listener) => listener()), disposeListeners.clear());
|
|
33
|
+
},
|
|
34
|
+
onDispose: (cb) => {
|
|
35
|
+
const listenerId = insecureRandomId();
|
|
36
|
+
return disposeListeners.set(listenerId, cb), () => {
|
|
37
|
+
disposeListeners.delete(listenerId);
|
|
38
|
+
};
|
|
39
|
+
},
|
|
40
|
+
getParent: () => {
|
|
41
|
+
},
|
|
42
|
+
createChild: (next) => Object.assign(
|
|
43
|
+
createSanityInstance({
|
|
44
|
+
...config,
|
|
45
|
+
...next,
|
|
46
|
+
...config.auth === next.auth ? config.auth : config.auth && next.auth && { auth: { ...config.auth, ...next.auth } }
|
|
47
|
+
}),
|
|
48
|
+
{ getParent: () => instance }
|
|
49
|
+
),
|
|
50
|
+
match: (targetConfig) => {
|
|
51
|
+
if (Object.entries(pick(targetConfig, "auth", "projectId", "dataset")).every(
|
|
52
|
+
([key, value]) => config[key] === value
|
|
53
|
+
))
|
|
54
|
+
return instance;
|
|
55
|
+
const parent = instance.getParent();
|
|
56
|
+
if (parent) return parent.match(targetConfig);
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
return instance;
|
|
60
|
+
}
|
|
15
61
|
function getEnv(key) {
|
|
16
62
|
if (typeof import.meta < "u" && import.meta.env)
|
|
17
63
|
return import.meta.env[key];
|
|
@@ -20,68 +66,78 @@ function getEnv(key) {
|
|
|
20
66
|
if (typeof window < "u" && window.ENV)
|
|
21
67
|
return window.ENV?.[key];
|
|
22
68
|
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
const store = createStore$1()(devtools(() => initialState, devToolsOptions));
|
|
69
|
+
function createStoreState(initialState, devToolsOptions) {
|
|
70
|
+
const store = createStore()(devtools(() => initialState, devToolsOptions));
|
|
26
71
|
return {
|
|
27
72
|
get: store.getState,
|
|
28
73
|
set: (actionKey, updatedState) => {
|
|
29
|
-
store.getState()
|
|
74
|
+
const currentState = store.getState(), nextState = typeof updatedState == "function" ? updatedState(currentState) : updatedState;
|
|
75
|
+
currentState !== nextState && store.setState(nextState, !1, actionKey);
|
|
30
76
|
},
|
|
31
77
|
observable: new Observable((observer) => {
|
|
32
78
|
const emit = () => observer.next(store.getState());
|
|
33
|
-
|
|
79
|
+
emit();
|
|
80
|
+
const unsubscribe = store.subscribe(emit);
|
|
81
|
+
return () => unsubscribe();
|
|
34
82
|
})
|
|
35
83
|
};
|
|
36
84
|
}
|
|
37
|
-
function
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}), dispose =
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
const initializedResources = resourceCache.get(instance.identity), cached = initializedResources.get(fullName);
|
|
49
|
-
if (cached) return cached;
|
|
50
|
-
const result = initializeResource(instance, resource);
|
|
51
|
-
return initializedResources.set(fullName, result), result;
|
|
52
|
-
}
|
|
53
|
-
function disposeResources(identity) {
|
|
54
|
-
const resources = resourceCache.get(identity);
|
|
55
|
-
if (resources)
|
|
56
|
-
for (const resource of resources.values())
|
|
57
|
-
resource.dispose();
|
|
58
|
-
}
|
|
59
|
-
function createAction(resource, actionDefinition) {
|
|
60
|
-
return (dependencies, ...args) => {
|
|
61
|
-
const instance = "state" in dependencies ? dependencies.instance : dependencies, { state } = "state" in dependencies ? dependencies : getOrCreateResource(dependencies, resource), actionContext = { instance, state };
|
|
62
|
-
return actionDefinition(actionContext).bind(actionContext)(...args);
|
|
85
|
+
function createStoreInstance(instance, { name, getInitialState, initialize }) {
|
|
86
|
+
const state = createStoreState(getInitialState(instance), {
|
|
87
|
+
enabled: !!getEnv("DEV"),
|
|
88
|
+
name: `${name}-${instance.config.projectId}.${instance.config.dataset}`
|
|
89
|
+
}), dispose = initialize?.({ state, instance }), disposed = { current: !1 };
|
|
90
|
+
return {
|
|
91
|
+
state,
|
|
92
|
+
dispose: () => {
|
|
93
|
+
disposed.current || (disposed.current = !0, dispose?.());
|
|
94
|
+
},
|
|
95
|
+
isDisposed: () => disposed.current
|
|
63
96
|
};
|
|
64
97
|
}
|
|
65
|
-
function
|
|
66
|
-
|
|
98
|
+
function createActionBinder(keyFn) {
|
|
99
|
+
const instanceRegistry = /* @__PURE__ */ new Map(), storeRegistry = /* @__PURE__ */ new Map();
|
|
100
|
+
return function(storeDefinition, action) {
|
|
101
|
+
return function(instance, ...params) {
|
|
102
|
+
const keySuffix = keyFn(instance.config), compositeKey = storeDefinition.name + (keySuffix ? `:${keySuffix}` : "");
|
|
103
|
+
let instances = instanceRegistry.get(compositeKey);
|
|
104
|
+
instances || (instances = /* @__PURE__ */ new Set(), instanceRegistry.set(compositeKey, instances)), instances.has(instance.instanceId) || (instances.add(instance.instanceId), instance.onDispose(() => {
|
|
105
|
+
instances.delete(instance.instanceId), instances.size === 0 && (storeRegistry.get(compositeKey)?.dispose(), storeRegistry.delete(compositeKey), instanceRegistry.delete(compositeKey));
|
|
106
|
+
}));
|
|
107
|
+
let storeInstance = storeRegistry.get(compositeKey);
|
|
108
|
+
return storeInstance || (storeInstance = createStoreInstance(instance, storeDefinition), storeRegistry.set(compositeKey, storeInstance)), action({ instance, state: storeInstance.state }, ...params);
|
|
109
|
+
};
|
|
110
|
+
};
|
|
67
111
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
112
|
+
const bindActionByDataset = createActionBinder(({ projectId, dataset }) => {
|
|
113
|
+
if (!projectId || !dataset)
|
|
114
|
+
throw new Error("This API requires a project ID and dataset configured.");
|
|
115
|
+
return `${projectId}.${dataset}`;
|
|
116
|
+
}), bindActionGlobally = createActionBinder(() => "global");
|
|
117
|
+
function createStateSourceAction(options) {
|
|
118
|
+
const selector = typeof options == "function" ? options : options.selector, subscribeHandler = options && "onSubscribe" in options ? options.onSubscribe : void 0, isEqual2 = options && "isEqual" in options ? options.isEqual ?? Object.is : Object.is, selectorContextCache = /* @__PURE__ */ new WeakMap();
|
|
119
|
+
function stateSourceAction(context, ...params) {
|
|
120
|
+
const { state, instance } = context, getCurrent = () => {
|
|
121
|
+
const currentState = state.get();
|
|
122
|
+
if (typeof currentState != "object" || currentState === null)
|
|
123
|
+
throw new Error(
|
|
124
|
+
`Expected store state to be an object but got "${typeof currentState}" instead`
|
|
125
|
+
);
|
|
126
|
+
let instanceCache = selectorContextCache.get(currentState);
|
|
127
|
+
instanceCache || (instanceCache = /* @__PURE__ */ new WeakMap(), selectorContextCache.set(currentState, instanceCache));
|
|
128
|
+
let selectorContext = instanceCache.get(instance);
|
|
129
|
+
return selectorContext || (selectorContext = { state: currentState, instance }, instanceCache.set(instance, selectorContext)), selector(selectorContext, ...params);
|
|
130
|
+
}, subscribe = (onStoreChanged) => {
|
|
131
|
+
const cleanup = subscribeHandler?.(context, ...params), subscription = state.observable.pipe(
|
|
132
|
+
// Derive value from current state
|
|
73
133
|
map(getCurrent),
|
|
134
|
+
// Filter unchanged values using custom equality check
|
|
74
135
|
distinctUntilChanged(isEqual2),
|
|
75
|
-
//
|
|
76
|
-
// value changes. `distinctUntilChanged` will always emit the first
|
|
77
|
-
// the first value so we skip this emission
|
|
136
|
+
// Skip initial emission since we only want changes
|
|
78
137
|
skip(1)
|
|
79
138
|
).subscribe({
|
|
80
139
|
next: () => onStoreChanged?.(),
|
|
81
|
-
//
|
|
82
|
-
// invoke onStoreChanged on error as well. this will cause the
|
|
83
|
-
// observable code path below to emit an error because the selector
|
|
84
|
-
// will throw and that will be used to emit an .error on the observer
|
|
140
|
+
// Propagate selector errors to both subscription types
|
|
85
141
|
error: () => onStoreChanged?.()
|
|
86
142
|
});
|
|
87
143
|
return () => {
|
|
@@ -102,96 +158,91 @@ function createStateSourceAction(resource, options) {
|
|
|
102
158
|
subscribe,
|
|
103
159
|
observable
|
|
104
160
|
};
|
|
105
|
-
});
|
|
106
|
-
}
|
|
107
|
-
const DEFAULT_BASE = "http://localhost", AUTH_CODE_PARAM = "sid", DEFAULT_API_VERSION$1 = "2021-06-07", REQUEST_TAG_PREFIX = "sanity.sdk.auth", refreshStampedToken = createInternalAction(
|
|
108
|
-
({ state }) => {
|
|
109
|
-
const { clientFactory, apiHost, storageArea, storageKey } = state.get().options, refreshToken$ = state.observable.pipe(
|
|
110
|
-
map(({ authState }) => authState),
|
|
111
|
-
filter(
|
|
112
|
-
(authState) => authState.type === AuthStateType.LOGGED_IN
|
|
113
|
-
),
|
|
114
|
-
distinctUntilChanged(),
|
|
115
|
-
filter((authState) => authState.token.includes("-st")),
|
|
116
|
-
// Ensure we only try to refresh stamped tokens
|
|
117
|
-
switchMap(
|
|
118
|
-
(authState) => interval(10 * 60 * 1e3).pipe(
|
|
119
|
-
takeWhile(() => state.get().authState.type === AuthStateType.LOGGED_IN),
|
|
120
|
-
map(() => authState.token),
|
|
121
|
-
distinctUntilChanged(),
|
|
122
|
-
map(
|
|
123
|
-
(token) => clientFactory({
|
|
124
|
-
apiVersion: DEFAULT_API_VERSION$1,
|
|
125
|
-
requestTagPrefix: "sdk.token-refresh",
|
|
126
|
-
useProjectHostname: !1,
|
|
127
|
-
token,
|
|
128
|
-
ignoreBrowserTokenWarning: !0,
|
|
129
|
-
...apiHost && { apiHost }
|
|
130
|
-
})
|
|
131
|
-
),
|
|
132
|
-
switchMap(
|
|
133
|
-
(client) => client.observable.request({
|
|
134
|
-
uri: "auth/refresh-token",
|
|
135
|
-
method: "POST",
|
|
136
|
-
body: {
|
|
137
|
-
token: authState.token
|
|
138
|
-
}
|
|
139
|
-
})
|
|
140
|
-
)
|
|
141
|
-
)
|
|
142
|
-
)
|
|
143
|
-
);
|
|
144
|
-
return function() {
|
|
145
|
-
return refreshToken$.subscribe({
|
|
146
|
-
next: (response) => {
|
|
147
|
-
state.set("setRefreshStampedToken", (prev) => ({
|
|
148
|
-
authState: prev.authState.type === AuthStateType.LOGGED_IN ? { ...prev.authState, token: response.token } : prev.authState
|
|
149
|
-
})), storageArea?.setItem(storageKey, JSON.stringify({ token: response.token }));
|
|
150
|
-
},
|
|
151
|
-
error: (error) => {
|
|
152
|
-
state.set("setRefreshStampedTokenError", { authState: { type: AuthStateType.ERROR, error } });
|
|
153
|
-
}
|
|
154
|
-
});
|
|
155
|
-
};
|
|
156
161
|
}
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
)
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
162
|
+
return stateSourceAction;
|
|
163
|
+
}
|
|
164
|
+
const DEFAULT_BASE = "http://localhost", AUTH_CODE_PARAM = "sid", DEFAULT_API_VERSION$1 = "2021-06-07", REQUEST_TAG_PREFIX = "sanity.sdk.auth", refreshStampedToken = ({ state }) => {
|
|
165
|
+
const { clientFactory, apiHost, storageArea, storageKey } = state.get().options, refreshInterval = 12 * 60 * 60 * 1e3;
|
|
166
|
+
return state.observable.pipe(
|
|
167
|
+
map(({ authState }) => authState),
|
|
168
|
+
filter(
|
|
169
|
+
(authState) => authState.type === AuthStateType.LOGGED_IN
|
|
170
|
+
),
|
|
171
|
+
distinctUntilChanged(),
|
|
172
|
+
filter((authState) => authState.token.includes("-st")),
|
|
173
|
+
// Ensure we only try to refresh stamped tokens
|
|
174
|
+
switchMap(
|
|
175
|
+
(authState) => interval(refreshInterval).pipe(
|
|
176
|
+
takeWhile(() => state.get().authState.type === AuthStateType.LOGGED_IN),
|
|
177
|
+
map(() => authState.token),
|
|
178
|
+
distinctUntilChanged(),
|
|
179
|
+
map(
|
|
180
|
+
(token) => clientFactory({
|
|
181
|
+
apiVersion: DEFAULT_API_VERSION$1,
|
|
182
|
+
requestTagPrefix: "sdk.token-refresh",
|
|
183
|
+
useProjectHostname: !1,
|
|
184
|
+
token,
|
|
185
|
+
ignoreBrowserTokenWarning: !0,
|
|
186
|
+
...apiHost && { apiHost }
|
|
187
|
+
})
|
|
188
|
+
),
|
|
189
|
+
switchMap(
|
|
190
|
+
(client) => client.observable.request({
|
|
191
|
+
uri: "auth/refresh-token",
|
|
192
|
+
method: "POST",
|
|
193
|
+
body: {
|
|
194
|
+
token: authState.token
|
|
195
|
+
}
|
|
196
|
+
})
|
|
197
|
+
)
|
|
179
198
|
)
|
|
180
|
-
)
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
);
|
|
199
|
+
)
|
|
200
|
+
).subscribe({
|
|
201
|
+
next: (response) => {
|
|
202
|
+
state.set("setRefreshStampedToken", (prev) => ({
|
|
203
|
+
authState: prev.authState.type === AuthStateType.LOGGED_IN ? { ...prev.authState, token: response.token } : prev.authState
|
|
204
|
+
})), storageArea?.setItem(storageKey, JSON.stringify({ token: response.token }));
|
|
205
|
+
},
|
|
206
|
+
error: (error) => {
|
|
207
|
+
state.set("setRefreshStampedTokenError", { authState: { type: AuthStateType.ERROR, error } });
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
}, subscribeToStateAndFetchCurrentUser = ({
|
|
211
|
+
state
|
|
212
|
+
}) => {
|
|
213
|
+
const { clientFactory, apiHost } = state.get().options;
|
|
214
|
+
return state.observable.pipe(
|
|
215
|
+
map(({ authState }) => authState),
|
|
216
|
+
filter(
|
|
217
|
+
(authState) => authState.type === AuthStateType.LOGGED_IN && !authState.currentUser
|
|
218
|
+
),
|
|
219
|
+
map((authState) => authState.token),
|
|
220
|
+
distinctUntilChanged()
|
|
221
|
+
).pipe(
|
|
222
|
+
map(
|
|
223
|
+
(token) => clientFactory({
|
|
224
|
+
apiVersion: DEFAULT_API_VERSION$1,
|
|
225
|
+
requestTagPrefix: REQUEST_TAG_PREFIX,
|
|
226
|
+
token,
|
|
227
|
+
ignoreBrowserTokenWarning: !0,
|
|
228
|
+
useProjectHostname: !1,
|
|
229
|
+
...apiHost && { apiHost }
|
|
230
|
+
})
|
|
231
|
+
),
|
|
232
|
+
switchMap(
|
|
233
|
+
(client) => client.observable.request({ uri: "/users/me", method: "GET" })
|
|
234
|
+
)
|
|
235
|
+
).subscribe({
|
|
236
|
+
next: (currentUser) => {
|
|
237
|
+
state.set("setCurrentUser", (prev) => ({
|
|
238
|
+
authState: prev.authState.type === AuthStateType.LOGGED_IN ? { ...prev.authState, currentUser } : prev.authState
|
|
239
|
+
}));
|
|
240
|
+
},
|
|
241
|
+
error: (error) => {
|
|
242
|
+
state.set("setError", { authState: { type: AuthStateType.ERROR, error } });
|
|
243
|
+
}
|
|
244
|
+
});
|
|
245
|
+
};
|
|
195
246
|
function getAuthCode(callbackUrl, locationHref) {
|
|
196
247
|
const loc = new URL(locationHref, DEFAULT_BASE), callbackLocation = callbackUrl ? new URL(callbackUrl, DEFAULT_BASE) : void 0, callbackLocationMatches = callbackLocation ? loc.pathname.toLowerCase().startsWith(callbackLocation.pathname.toLowerCase()) : !0, authCode = new URLSearchParams(loc.hash.slice(1)).get(AUTH_CODE_PARAM) || new URLSearchParams(loc.search).get(AUTH_CODE_PARAM);
|
|
197
248
|
return authCode && callbackLocationMatches ? authCode : null;
|
|
@@ -226,24 +277,22 @@ function getDefaultLocation() {
|
|
|
226
277
|
return DEFAULT_BASE;
|
|
227
278
|
}
|
|
228
279
|
}
|
|
229
|
-
const subscribeToStorageEventsAndSetToken =
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
)
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
}
|
|
246
|
-
);
|
|
280
|
+
const subscribeToStorageEventsAndSetToken = ({
|
|
281
|
+
state
|
|
282
|
+
}) => {
|
|
283
|
+
const { storageArea, storageKey } = state.get().options;
|
|
284
|
+
return defer(getStorageEvents).pipe(
|
|
285
|
+
filter(
|
|
286
|
+
(e3) => e3.storageArea === storageArea && e3.key === storageKey
|
|
287
|
+
),
|
|
288
|
+
map(() => getTokenFromStorage(storageArea, storageKey)),
|
|
289
|
+
distinctUntilChanged()
|
|
290
|
+
).subscribe((token) => {
|
|
291
|
+
state.set("updateTokenFromStorageEvent", {
|
|
292
|
+
authState: token ? { type: AuthStateType.LOGGED_IN, token, currentUser: null } : { type: AuthStateType.LOGGED_OUT, isDestroyingSession: !1 }
|
|
293
|
+
});
|
|
294
|
+
});
|
|
295
|
+
};
|
|
247
296
|
let tokenRefresherRunning = !1;
|
|
248
297
|
const authStore = {
|
|
249
298
|
name: "Auth",
|
|
@@ -257,12 +306,20 @@ const authStore = {
|
|
|
257
306
|
initialLocationHref = getDefaultLocation(),
|
|
258
307
|
storageArea = getDefaultStorage()
|
|
259
308
|
} = instance.config.auth ?? {}, storageKey = "__sanity_auth_token";
|
|
309
|
+
let loginDomain = "https://www.sanity.io";
|
|
310
|
+
try {
|
|
311
|
+
apiHost && new URL(apiHost).hostname.endsWith(".sanity.work") && (loginDomain = "https://www.sanity.work");
|
|
312
|
+
} catch {
|
|
313
|
+
}
|
|
314
|
+
const loginUrl = new URL("/login", loginDomain);
|
|
315
|
+
loginUrl.searchParams.set("origin", initialLocationHref), loginUrl.searchParams.set("type", "stampedToken"), loginUrl.searchParams.set("withSid", "true");
|
|
260
316
|
let authState;
|
|
261
317
|
const token = getTokenFromStorage(storageArea, storageKey);
|
|
262
318
|
return providedToken ? authState = { type: AuthStateType.LOGGED_IN, token: providedToken, currentUser: null } : getAuthCode(callbackUrl, initialLocationHref) ? authState = { type: AuthStateType.LOGGING_IN, isExchangingToken: !1 } : token ? authState = { type: AuthStateType.LOGGED_IN, token, currentUser: null } : authState = { type: AuthStateType.LOGGED_OUT, isDestroyingSession: !1 }, {
|
|
263
319
|
authState,
|
|
264
320
|
options: {
|
|
265
321
|
apiHost,
|
|
322
|
+
loginUrl: loginUrl.toString(),
|
|
266
323
|
callbackUrl,
|
|
267
324
|
customProviders,
|
|
268
325
|
providedToken,
|
|
@@ -273,61 +330,36 @@ const authStore = {
|
|
|
273
330
|
}
|
|
274
331
|
};
|
|
275
332
|
},
|
|
276
|
-
initialize() {
|
|
277
|
-
const
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
return tokenRefresherRunning || (tokenRefresherRunning = !0, refreshStampedTokenSubscription = refreshStampedToken(this)), () => {
|
|
282
|
-
stateSubscription.unsubscribe(), storageEventsSubscription?.unsubscribe(), refreshStampedTokenSubscription?.unsubscribe();
|
|
333
|
+
initialize(context) {
|
|
334
|
+
const subscriptions = [];
|
|
335
|
+
return subscriptions.push(subscribeToStateAndFetchCurrentUser(context)), context.state.get().options?.storageArea && subscriptions.push(subscribeToStorageEventsAndSetToken(context)), tokenRefresherRunning || (tokenRefresherRunning = !0, subscriptions.push(refreshStampedToken(context))), () => {
|
|
336
|
+
for (const subscription of subscriptions)
|
|
337
|
+
subscription.unsubscribe();
|
|
283
338
|
};
|
|
284
339
|
}
|
|
285
|
-
}, getCurrentUserState =
|
|
340
|
+
}, getCurrentUserState = bindActionGlobally(
|
|
286
341
|
authStore,
|
|
287
|
-
(
|
|
288
|
-
)
|
|
342
|
+
createStateSourceAction(
|
|
343
|
+
({ state: { authState } }) => authState.type === AuthStateType.LOGGED_IN ? authState.currentUser : null
|
|
344
|
+
)
|
|
345
|
+
), getTokenState = bindActionGlobally(
|
|
289
346
|
authStore,
|
|
290
|
-
(
|
|
291
|
-
)
|
|
347
|
+
createStateSourceAction(
|
|
348
|
+
({ state: { authState } }) => authState.type === AuthStateType.LOGGED_IN ? authState.token : null
|
|
349
|
+
)
|
|
350
|
+
), getLoginUrlState = bindActionGlobally(
|
|
292
351
|
authStore,
|
|
293
|
-
({
|
|
294
|
-
), getAuthState =
|
|
352
|
+
createStateSourceAction(({ state: { options } }) => options.loginUrl)
|
|
353
|
+
), getAuthState = bindActionGlobally(
|
|
295
354
|
authStore,
|
|
296
|
-
({
|
|
297
|
-
),
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
return async function() {
|
|
305
|
-
const cachedProviders = state.get().providers;
|
|
306
|
-
if (cachedProviders) return cachedProviders;
|
|
307
|
-
const { providers: defaultProviders } = await client.request({
|
|
308
|
-
uri: "/auth/providers",
|
|
309
|
-
tag: "fetch-providers"
|
|
310
|
-
});
|
|
311
|
-
let providers;
|
|
312
|
-
if (typeof customProviders == "function")
|
|
313
|
-
providers = await customProviders(defaultProviders);
|
|
314
|
-
else if (!customProviders?.length)
|
|
315
|
-
providers = defaultProviders;
|
|
316
|
-
else {
|
|
317
|
-
const customProviderUrls = new Set(customProviders.map((p2) => p2.url));
|
|
318
|
-
providers = defaultProviders.filter((official) => !customProviderUrls.has(official.url)).concat(customProviders);
|
|
319
|
-
}
|
|
320
|
-
const configuredProviders = providers.map((provider) => {
|
|
321
|
-
const url = new URL(provider.url), origin = new URL(
|
|
322
|
-
callbackUrl ? new URL(callbackUrl, new URL(getDefaultLocation()).origin).toString() : getDefaultLocation()
|
|
323
|
-
), hashParams = new URLSearchParams(origin.hash.slice(1));
|
|
324
|
-
return hashParams.delete("sid"), origin.hash = hashParams.toString(), origin.searchParams.delete("sid"), origin.searchParams.delete("url"), origin.searchParams.delete("error"), url.searchParams.set("origin", origin.toString()), url.searchParams.set("withSid", "true"), url.searchParams.set("type", "stampedToken"), { ...provider, url: url.toString() };
|
|
325
|
-
});
|
|
326
|
-
return state.set("fetchedLoginUrls", { providers: configuredProviders }), configuredProviders;
|
|
327
|
-
};
|
|
328
|
-
}), handleAuthCallback = createAction(authStore, ({ state }) => {
|
|
329
|
-
const { providedToken, callbackUrl, clientFactory, apiHost, storageArea, storageKey } = state.get().options;
|
|
330
|
-
return async function(locationHref = getDefaultLocation()) {
|
|
355
|
+
createStateSourceAction(({ state: { authState } }) => authState)
|
|
356
|
+
), getDashboardOrganizationId = bindActionGlobally(
|
|
357
|
+
authStore,
|
|
358
|
+
createStateSourceAction(({ state: { dashboardContext } }) => dashboardContext?.orgId)
|
|
359
|
+
), handleAuthCallback = bindActionGlobally(
|
|
360
|
+
authStore,
|
|
361
|
+
async ({ state }, locationHref = getDefaultLocation()) => {
|
|
362
|
+
const { providedToken, callbackUrl, clientFactory, apiHost, storageArea, storageKey } = state.get().options;
|
|
331
363
|
if (providedToken) return !1;
|
|
332
364
|
const { authState } = state.get();
|
|
333
365
|
if (authState.type === AuthStateType.LOGGING_IN && authState.isExchangingToken) return !1;
|
|
@@ -364,116 +396,484 @@ const authStore = {
|
|
|
364
396
|
} catch (error) {
|
|
365
397
|
return state.set("exchangeSessionForTokenError", { authState: { type: AuthStateType.ERROR, error } }), !1;
|
|
366
398
|
}
|
|
367
|
-
}
|
|
368
|
-
|
|
399
|
+
}
|
|
400
|
+
), logout = bindActionGlobally(authStore, async ({ state }) => {
|
|
369
401
|
const { clientFactory, apiHost, providedToken, storageArea, storageKey } = state.get().options;
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
}), storageArea?.removeItem(storageKey);
|
|
389
|
-
}
|
|
390
|
-
};
|
|
391
|
-
});
|
|
392
|
-
function getResourceId(documentResourceId) {
|
|
393
|
-
if (documentResourceId)
|
|
394
|
-
return documentResourceId.split(":")[1];
|
|
395
|
-
}
|
|
396
|
-
function parseBracketContent(content) {
|
|
397
|
-
const rangeMatch = content.match(/^(\d*):(\d*)$/);
|
|
398
|
-
if (rangeMatch) {
|
|
399
|
-
const startStr = rangeMatch[1], endStr = rangeMatch[2], start = startStr === "" ? "" : parseInt(startStr, 10), end = endStr === "" ? "" : parseInt(endStr, 10);
|
|
400
|
-
return [start, end];
|
|
402
|
+
if (providedToken) return;
|
|
403
|
+
const { authState } = state.get();
|
|
404
|
+
if (authState.type === AuthStateType.LOGGED_OUT && authState.isDestroyingSession) return;
|
|
405
|
+
const token = authState.type === AuthStateType.LOGGED_IN && authState.token;
|
|
406
|
+
try {
|
|
407
|
+
token && (state.set("loggingOut", {
|
|
408
|
+
authState: { type: AuthStateType.LOGGED_OUT, isDestroyingSession: !0 }
|
|
409
|
+
}), await clientFactory({
|
|
410
|
+
token,
|
|
411
|
+
requestTagPrefix: REQUEST_TAG_PREFIX,
|
|
412
|
+
apiVersion: DEFAULT_API_VERSION$1,
|
|
413
|
+
...apiHost && { apiHost },
|
|
414
|
+
useProjectHostname: !1
|
|
415
|
+
}).request({ uri: "/auth/logout", method: "POST" }));
|
|
416
|
+
} finally {
|
|
417
|
+
state.set("logoutSuccess", {
|
|
418
|
+
authState: { type: AuthStateType.LOGGED_OUT, isDestroyingSession: !1 }
|
|
419
|
+
}), storageArea?.removeItem(storageKey);
|
|
401
420
|
}
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
421
|
+
}), DEFAULT_API_VERSION = "2024-11-12", DEFAULT_REQUEST_TAG_PREFIX = "sanity.sdk", allowedKeys = Object.keys({
|
|
422
|
+
apiHost: null,
|
|
423
|
+
useCdn: null,
|
|
424
|
+
token: null,
|
|
425
|
+
perspective: null,
|
|
426
|
+
proxy: null,
|
|
427
|
+
withCredentials: null,
|
|
428
|
+
timeout: null,
|
|
429
|
+
maxRetries: null,
|
|
430
|
+
dataset: null,
|
|
431
|
+
projectId: null,
|
|
432
|
+
scope: null,
|
|
433
|
+
apiVersion: null,
|
|
434
|
+
requestTagPrefix: null,
|
|
435
|
+
useProjectHostname: null
|
|
436
|
+
}), DEFAULT_CLIENT_CONFIG = {
|
|
437
|
+
apiVersion: DEFAULT_API_VERSION,
|
|
438
|
+
useCdn: !1,
|
|
439
|
+
ignoreBrowserTokenWarning: !0,
|
|
440
|
+
allowReconfigure: !1,
|
|
441
|
+
requestTagPrefix: DEFAULT_REQUEST_TAG_PREFIX
|
|
442
|
+
}, clientStore = {
|
|
443
|
+
name: "clientStore",
|
|
444
|
+
getInitialState: (instance) => ({
|
|
445
|
+
clients: {},
|
|
446
|
+
token: getTokenState(instance).getCurrent()
|
|
447
|
+
}),
|
|
448
|
+
initialize(context) {
|
|
449
|
+
const subscription = listenToToken(context);
|
|
450
|
+
return () => subscription.unsubscribe();
|
|
415
451
|
}
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
452
|
+
}, listenToToken = ({ instance, state }) => getTokenState(instance).observable.subscribe((token) => {
|
|
453
|
+
state.set("setTokenAndResetClients", { token, clients: {} });
|
|
454
|
+
}), getClientConfigKey = (options) => JSON.stringify(pick(options, ...allowedKeys)), getClient = bindActionGlobally(
|
|
455
|
+
clientStore,
|
|
456
|
+
({ state, instance }, options) => {
|
|
457
|
+
const disallowedKeys = Object.keys(options).filter((key2) => !allowedKeys.includes(key2));
|
|
458
|
+
if (disallowedKeys.length > 0) {
|
|
459
|
+
const listFormatter = new Intl.ListFormat("en", { style: "long", type: "conjunction" });
|
|
460
|
+
throw new Error(
|
|
461
|
+
`The client options provided contains unsupported properties: ${listFormatter.format(disallowedKeys)}. Allowed keys are: ${listFormatter.format(allowedKeys)}.`
|
|
462
|
+
);
|
|
422
463
|
}
|
|
423
|
-
const
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
464
|
+
const { token, clients } = state.get(), projectId = options.projectId ?? instance.config.projectId, dataset = options.dataset ?? instance.config.dataset, apiHost = options.apiHost ?? instance.config.auth?.apiHost, effectiveOptions = {
|
|
465
|
+
...DEFAULT_CLIENT_CONFIG,
|
|
466
|
+
...(options.scope === "global" || !projectId) && { useProjectHostname: !1 },
|
|
467
|
+
...token && { token },
|
|
468
|
+
...options,
|
|
469
|
+
...projectId && { projectId },
|
|
470
|
+
...dataset && { dataset },
|
|
471
|
+
...apiHost && { apiHost }
|
|
472
|
+
}, key = getClientConfigKey(effectiveOptions);
|
|
473
|
+
if (clients[key]) return clients[key];
|
|
474
|
+
const client = createClient(effectiveOptions);
|
|
475
|
+
return state.set("addClient", (prev) => ({ clients: { ...prev.clients, [key]: client } })), client;
|
|
430
476
|
}
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
477
|
+
), getClientState = bindActionGlobally(
|
|
478
|
+
clientStore,
|
|
479
|
+
createStateSourceAction(({ instance }, options) => getClient(instance, options))
|
|
480
|
+
), destroyController$1 = ({ state }) => {
|
|
481
|
+
const { controller } = state.get();
|
|
482
|
+
controller && (controller.destroy(), state.set("destroyController", {
|
|
483
|
+
controller: null,
|
|
484
|
+
channels: /* @__PURE__ */ new Map()
|
|
485
|
+
}));
|
|
486
|
+
}, getOrCreateChannel$1 = ({ state }, options) => {
|
|
487
|
+
const controller = state.get().controller;
|
|
488
|
+
if (!controller)
|
|
489
|
+
throw new Error("Controller must be initialized before using or creating channels");
|
|
490
|
+
const channels = state.get().channels, existing = channels.get(options.name);
|
|
491
|
+
if (existing) {
|
|
492
|
+
if (!isEqual(existing.options, options))
|
|
493
|
+
throw new Error(`Channel "${options.name}" already exists with different options`);
|
|
494
|
+
return state.set("incrementChannelRefCount", {
|
|
495
|
+
channels: new Map(channels).set(options.name, {
|
|
496
|
+
...existing,
|
|
497
|
+
refCount: existing.refCount + 1
|
|
498
|
+
})
|
|
499
|
+
}), existing.channel.start(), existing.channel;
|
|
439
500
|
}
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
501
|
+
const channel = controller.createChannel(options);
|
|
502
|
+
return channel.start(), state.set("createChannel", {
|
|
503
|
+
channels: new Map(channels).set(options.name, {
|
|
504
|
+
channel,
|
|
505
|
+
options,
|
|
506
|
+
refCount: 1
|
|
507
|
+
})
|
|
508
|
+
}), channel;
|
|
509
|
+
}, getOrCreateController$1 = ({ state, instance }, targetOrigin) => {
|
|
510
|
+
const { controller, controllerOrigin } = state.get();
|
|
511
|
+
if (controller && controllerOrigin === targetOrigin)
|
|
512
|
+
return controller;
|
|
513
|
+
controller && destroyController$1({ state });
|
|
514
|
+
const newController = createController({ targetOrigin });
|
|
515
|
+
return state.set("initializeController", {
|
|
516
|
+
controllerOrigin: targetOrigin,
|
|
517
|
+
controller: newController
|
|
518
|
+
}), newController;
|
|
519
|
+
}, releaseChannel$1 = ({ state }, name) => {
|
|
520
|
+
const channels = state.get().channels, channelEntry = channels.get(name);
|
|
521
|
+
if (channelEntry) {
|
|
522
|
+
const newRefCount = channelEntry.refCount === 0 ? 0 : channelEntry.refCount - 1;
|
|
523
|
+
newRefCount === 0 ? (channelEntry.channel.stop(), channels.delete(name), state.set("releaseChannel", { channels: new Map(channels) })) : state.set("releaseChannel", {
|
|
524
|
+
channels: new Map(channels).set(name, {
|
|
525
|
+
...channelEntry,
|
|
526
|
+
refCount: newRefCount
|
|
527
|
+
})
|
|
528
|
+
});
|
|
455
529
|
}
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
const nextValue = value[head];
|
|
468
|
-
return matchRecursive(nextValue, rest, [...currentPath, head]);
|
|
469
|
-
}
|
|
470
|
-
return [];
|
|
530
|
+
}, comlinkControllerStore = {
|
|
531
|
+
name: "connectionStore",
|
|
532
|
+
getInitialState: () => ({
|
|
533
|
+
controller: null,
|
|
534
|
+
controllerOrigin: null,
|
|
535
|
+
channels: /* @__PURE__ */ new Map()
|
|
536
|
+
}),
|
|
537
|
+
initialize({ instance }) {
|
|
538
|
+
return () => {
|
|
539
|
+
destroyController(instance);
|
|
540
|
+
};
|
|
471
541
|
}
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
542
|
+
}, destroyController = bindActionGlobally(
|
|
543
|
+
comlinkControllerStore,
|
|
544
|
+
destroyController$1
|
|
545
|
+
), getOrCreateChannel = bindActionGlobally(
|
|
546
|
+
comlinkControllerStore,
|
|
547
|
+
getOrCreateChannel$1
|
|
548
|
+
), getOrCreateController = bindActionGlobally(
|
|
549
|
+
comlinkControllerStore,
|
|
550
|
+
getOrCreateController$1
|
|
551
|
+
), releaseChannel = bindActionGlobally(comlinkControllerStore, releaseChannel$1), getOrCreateNode$1 = ({ state }, options) => {
|
|
552
|
+
const nodes = state.get().nodes, existing = nodes.get(options.name);
|
|
553
|
+
if (existing) {
|
|
554
|
+
if (!isEqual(existing.options, options))
|
|
555
|
+
throw new Error(`Node "${options.name}" already exists with different options`);
|
|
556
|
+
return state.set("incrementNodeRefCount", {
|
|
557
|
+
nodes: new Map(nodes).set(options.name, {
|
|
558
|
+
...existing,
|
|
559
|
+
refCount: existing.refCount + 1
|
|
560
|
+
})
|
|
561
|
+
}), existing.node.start(), existing.node;
|
|
562
|
+
}
|
|
563
|
+
const node = createNode(options);
|
|
564
|
+
return node.start(), nodes.set(options.name, { node, options, refCount: 1 }), state.set("createNode", { nodes }), node;
|
|
565
|
+
}, releaseNode$1 = ({ state }, name) => {
|
|
566
|
+
const nodes = state.get().nodes, nodeEntry = nodes.get(name);
|
|
567
|
+
if (nodeEntry) {
|
|
568
|
+
const newRefCount = nodeEntry.refCount === 0 ? 0 : nodeEntry.refCount - 1;
|
|
569
|
+
newRefCount === 0 ? (nodeEntry.node.stop(), nodes.delete(name), state.set("releaseNode", { nodes: new Map(nodes) })) : state.set("releaseNode", {
|
|
570
|
+
nodes: new Map(nodes).set(name, {
|
|
571
|
+
...nodeEntry,
|
|
572
|
+
refCount: newRefCount
|
|
573
|
+
})
|
|
574
|
+
});
|
|
575
|
+
}
|
|
576
|
+
}, comlinkNodeStore = {
|
|
577
|
+
name: "nodeStore",
|
|
578
|
+
getInitialState: () => ({
|
|
579
|
+
nodes: /* @__PURE__ */ new Map()
|
|
580
|
+
}),
|
|
581
|
+
initialize({ state }) {
|
|
582
|
+
return () => {
|
|
583
|
+
state.get().nodes.forEach(({ node }) => {
|
|
584
|
+
node.stop();
|
|
585
|
+
});
|
|
586
|
+
};
|
|
587
|
+
}
|
|
588
|
+
}, releaseNode = bindActionGlobally(comlinkNodeStore, releaseNode$1), getOrCreateNode = bindActionGlobally(comlinkNodeStore, getOrCreateNode$1);
|
|
589
|
+
function createFetcherStore({
|
|
590
|
+
name,
|
|
591
|
+
fetcher: getObservable,
|
|
592
|
+
getKey,
|
|
593
|
+
fetchThrottleInternal = 1e3,
|
|
594
|
+
stateExpirationDelay = 5e3
|
|
595
|
+
}) {
|
|
596
|
+
const store = {
|
|
597
|
+
name,
|
|
598
|
+
getInitialState: () => ({
|
|
599
|
+
stateByParams: {}
|
|
600
|
+
}),
|
|
601
|
+
initialize: (context) => {
|
|
602
|
+
const subscription = subscribeToSubscriptionsAndFetch(context);
|
|
603
|
+
return () => subscription.unsubscribe();
|
|
604
|
+
}
|
|
605
|
+
}, subscribeToSubscriptionsAndFetch = ({
|
|
606
|
+
state
|
|
607
|
+
}) => state.observable.pipe(
|
|
608
|
+
// Map the state to an array of [serialized, entry] pairs.
|
|
609
|
+
switchMap$1((s2) => {
|
|
610
|
+
const entries = Object.entries(s2.stateByParams);
|
|
611
|
+
return entries.length > 0 ? from(entries) : EMPTY;
|
|
612
|
+
}),
|
|
613
|
+
// Group by the serialized key.
|
|
614
|
+
groupBy(([key]) => key),
|
|
615
|
+
mergeMap(
|
|
616
|
+
(group$) => group$.pipe(
|
|
617
|
+
// Emit an initial value for pairwise comparisons.
|
|
618
|
+
startWith([group$.key, void 0]),
|
|
619
|
+
pairwise(),
|
|
620
|
+
// Trigger only when the subscriptions array grows.
|
|
621
|
+
filter$1(([[, prevEntry], [, currEntry]]) => {
|
|
622
|
+
const prevSubs = prevEntry?.subscriptions ?? [];
|
|
623
|
+
return (currEntry?.subscriptions ?? []).length > prevSubs.length;
|
|
624
|
+
}),
|
|
625
|
+
map$1(([, [, currEntry]]) => currEntry),
|
|
626
|
+
// Only trigger if we haven't fetched recently.
|
|
627
|
+
filter$1((entry) => {
|
|
628
|
+
const lastFetch = entry?.lastFetchInitiatedAt;
|
|
629
|
+
return lastFetch ? Date.now() - new Date(lastFetch).getTime() >= fetchThrottleInternal : !0;
|
|
630
|
+
}),
|
|
631
|
+
switchMap$1((entry) => entry ? (state.set("setLastFetchInitiatedAt", (prev) => ({
|
|
632
|
+
stateByParams: {
|
|
633
|
+
...prev.stateByParams,
|
|
634
|
+
[entry.key]: {
|
|
635
|
+
...entry,
|
|
636
|
+
...prev.stateByParams[entry.key],
|
|
637
|
+
lastFetchInitiatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
})), getObservable(entry.instance)(...entry.params).pipe(
|
|
641
|
+
// the `createStateSourceAction` util requires the update
|
|
642
|
+
// to
|
|
643
|
+
delay(0, asapScheduler),
|
|
644
|
+
tap(
|
|
645
|
+
(data) => state.set("setData", (prev) => ({
|
|
646
|
+
stateByParams: {
|
|
647
|
+
...prev.stateByParams,
|
|
648
|
+
[entry.key]: {
|
|
649
|
+
...omit(entry, "error"),
|
|
650
|
+
...omit(prev.stateByParams[entry.key], "error"),
|
|
651
|
+
data
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
}))
|
|
655
|
+
),
|
|
656
|
+
catchError((error) => (state.set("setError", (prev) => ({
|
|
657
|
+
stateByParams: {
|
|
658
|
+
...prev.stateByParams,
|
|
659
|
+
[entry.key]: {
|
|
660
|
+
...entry,
|
|
661
|
+
...prev.stateByParams[entry.key],
|
|
662
|
+
error
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
})), EMPTY))
|
|
666
|
+
)) : EMPTY)
|
|
667
|
+
)
|
|
668
|
+
)
|
|
669
|
+
).subscribe({
|
|
670
|
+
error: (error) => state.set("setError", { error })
|
|
671
|
+
}), getState = bindActionGlobally(
|
|
672
|
+
store,
|
|
673
|
+
createStateSourceAction({
|
|
674
|
+
selector: ({
|
|
675
|
+
instance,
|
|
676
|
+
state: { stateByParams, error }
|
|
677
|
+
}, ...params) => {
|
|
678
|
+
if (error) throw error;
|
|
679
|
+
const key = getKey(instance, ...params), entry = stateByParams[key];
|
|
680
|
+
if (entry?.error) throw entry.error;
|
|
681
|
+
return entry?.data;
|
|
682
|
+
},
|
|
683
|
+
onSubscribe: ({ instance, state }, ...params) => {
|
|
684
|
+
const subscriptionId = insecureRandomId(), key = getKey(instance, ...params);
|
|
685
|
+
return state.set("addSubscription", (prev) => ({
|
|
686
|
+
stateByParams: {
|
|
687
|
+
...prev.stateByParams,
|
|
688
|
+
[key]: {
|
|
689
|
+
...prev.stateByParams[key],
|
|
690
|
+
instance,
|
|
691
|
+
key,
|
|
692
|
+
params: prev.stateByParams[key]?.params || params,
|
|
693
|
+
subscriptions: [...prev.stateByParams[key]?.subscriptions || [], subscriptionId]
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
})), () => {
|
|
697
|
+
setTimeout(() => {
|
|
698
|
+
state.set("removeSubscription", (prev) => {
|
|
699
|
+
const entry = prev.stateByParams[key];
|
|
700
|
+
if (!entry) return prev;
|
|
701
|
+
const newSubs = (entry.subscriptions || []).filter((id) => id !== subscriptionId);
|
|
702
|
+
return newSubs.length === 0 ? { stateByParams: omit(prev.stateByParams, key) } : {
|
|
703
|
+
stateByParams: {
|
|
704
|
+
...prev.stateByParams,
|
|
705
|
+
[key]: {
|
|
706
|
+
...entry,
|
|
707
|
+
subscriptions: newSubs
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
};
|
|
711
|
+
});
|
|
712
|
+
}, stateExpirationDelay);
|
|
713
|
+
};
|
|
714
|
+
}
|
|
715
|
+
})
|
|
716
|
+
), resolveState = bindActionGlobally(
|
|
717
|
+
store,
|
|
718
|
+
({ instance }, ...params) => firstValueFrom(getState(instance, ...params).observable.pipe(first((i2) => i2 !== void 0)))
|
|
719
|
+
);
|
|
720
|
+
return { getState, resolveState };
|
|
721
|
+
}
|
|
722
|
+
const API_VERSION$5 = "v2025-02-19", datasets = createFetcherStore({
|
|
723
|
+
name: "Datasets",
|
|
724
|
+
getKey: (instance, options) => {
|
|
725
|
+
const projectId = options?.projectId ?? instance.config.projectId;
|
|
726
|
+
if (!projectId)
|
|
727
|
+
throw new Error("A projectId is required to use the project API.");
|
|
728
|
+
return projectId;
|
|
729
|
+
},
|
|
730
|
+
fetcher: (instance) => (options) => getClientState(instance, {
|
|
731
|
+
apiVersion: API_VERSION$5,
|
|
732
|
+
// non-null assertion is fine because we check above
|
|
733
|
+
projectId: options?.projectId ?? instance.config.projectId,
|
|
734
|
+
useProjectHostname: !0
|
|
735
|
+
}).observable.pipe(switchMap((client) => client.observable.datasets.list()))
|
|
736
|
+
}), getDatasetsState = datasets.getState, resolveDatasets = datasets.resolveState, isSanityMutatePatch = (value) => !(typeof value != "object" || !value || !("type" in value) || typeof value.type != "string" || value.type !== "patch" || !("id" in value) || typeof value.id != "string" || !("patches" in value) || !Array.isArray(value.patches));
|
|
737
|
+
function createDocument(doc) {
|
|
738
|
+
return {
|
|
739
|
+
type: "document.create",
|
|
740
|
+
...doc,
|
|
741
|
+
...doc.documentId && { documentId: getPublishedId(doc.documentId) }
|
|
742
|
+
};
|
|
743
|
+
}
|
|
744
|
+
function deleteDocument(doc) {
|
|
745
|
+
return {
|
|
746
|
+
type: "document.delete",
|
|
747
|
+
...doc,
|
|
748
|
+
documentId: getPublishedId(doc.documentId)
|
|
749
|
+
};
|
|
750
|
+
}
|
|
751
|
+
function convertSanityMutatePatch(sanityPatchMutation) {
|
|
752
|
+
return SanityEncoder.encode(sanityPatchMutation).map((i2) => {
|
|
753
|
+
const copy = { ...i2.patch };
|
|
754
|
+
return "id" in copy && delete copy.id, copy;
|
|
755
|
+
});
|
|
756
|
+
}
|
|
757
|
+
function editDocument(doc, patches) {
|
|
758
|
+
if (isSanityMutatePatch(patches)) {
|
|
759
|
+
const converted = convertSanityMutatePatch(patches) ?? [];
|
|
760
|
+
return {
|
|
761
|
+
...doc,
|
|
762
|
+
type: "document.edit",
|
|
763
|
+
documentId: getPublishedId(doc.documentId),
|
|
764
|
+
patches: converted
|
|
765
|
+
};
|
|
766
|
+
}
|
|
767
|
+
return {
|
|
768
|
+
...doc,
|
|
769
|
+
type: "document.edit",
|
|
770
|
+
documentId: getPublishedId(doc.documentId),
|
|
771
|
+
...patches && { patches: Array.isArray(patches) ? patches : [patches] }
|
|
772
|
+
};
|
|
773
|
+
}
|
|
774
|
+
function publishDocument(doc) {
|
|
775
|
+
return {
|
|
776
|
+
type: "document.publish",
|
|
777
|
+
...doc,
|
|
778
|
+
documentId: getPublishedId(doc.documentId)
|
|
779
|
+
};
|
|
780
|
+
}
|
|
781
|
+
function unpublishDocument(doc) {
|
|
782
|
+
return {
|
|
783
|
+
type: "document.unpublish",
|
|
784
|
+
...doc,
|
|
785
|
+
documentId: getPublishedId(doc.documentId)
|
|
786
|
+
};
|
|
787
|
+
}
|
|
788
|
+
function discardDocument(doc) {
|
|
789
|
+
return {
|
|
790
|
+
type: "document.discard",
|
|
791
|
+
...doc,
|
|
792
|
+
documentId: getPublishedId(doc.documentId)
|
|
793
|
+
};
|
|
794
|
+
}
|
|
795
|
+
const DOCUMENT_STATE_CLEAR_DELAY = 1e3, INITIAL_OUTGOING_THROTTLE_TIME = 1e3, API_VERSION$4 = "vX";
|
|
796
|
+
function parseBracketContent(content) {
|
|
797
|
+
const rangeMatch = content.match(/^(\d*):(\d*)$/);
|
|
798
|
+
if (rangeMatch) {
|
|
799
|
+
const startStr = rangeMatch[1], endStr = rangeMatch[2], start = startStr === "" ? "" : parseInt(startStr, 10), end = endStr === "" ? "" : parseInt(endStr, 10);
|
|
800
|
+
return [start, end];
|
|
801
|
+
}
|
|
802
|
+
const keyedMatch = content.match(/^_key==["'](.+)["']$/);
|
|
803
|
+
if (keyedMatch)
|
|
804
|
+
return { _key: keyedMatch[1] };
|
|
805
|
+
const index = parseInt(content, 10);
|
|
806
|
+
if (!isNaN(index))
|
|
807
|
+
return index;
|
|
808
|
+
throw new Error(`Invalid bracket content: \u201C[${content}]\u201D`);
|
|
809
|
+
}
|
|
810
|
+
function parseSegment(segment) {
|
|
811
|
+
const segments = [];
|
|
812
|
+
let idx = 0;
|
|
813
|
+
function pushIfNotEmpty(text) {
|
|
814
|
+
text && segments.push(text);
|
|
815
|
+
}
|
|
816
|
+
for (; idx < segment.length; ) {
|
|
817
|
+
const openIndex = segment.indexOf("[", idx);
|
|
818
|
+
if (openIndex === -1) {
|
|
819
|
+
const remaining = segment.slice(idx);
|
|
820
|
+
pushIfNotEmpty(remaining);
|
|
821
|
+
break;
|
|
822
|
+
}
|
|
823
|
+
const before = segment.slice(idx, openIndex);
|
|
824
|
+
pushIfNotEmpty(before);
|
|
825
|
+
const closeIndex = segment.indexOf("]", openIndex);
|
|
826
|
+
if (closeIndex === -1)
|
|
827
|
+
throw new Error(`Unmatched "[" in segment: "${segment}"`);
|
|
828
|
+
const bracketContent = segment.slice(openIndex + 1, closeIndex);
|
|
829
|
+
segments.push(parseBracketContent(bracketContent)), idx = closeIndex + 1;
|
|
830
|
+
}
|
|
831
|
+
return segments;
|
|
832
|
+
}
|
|
833
|
+
function parsePath(path) {
|
|
834
|
+
const result = [];
|
|
835
|
+
let buffer = "", bracketDepth = 0;
|
|
836
|
+
for (let i2 = 0; i2 < path.length; i2++) {
|
|
837
|
+
const ch = path[i2];
|
|
838
|
+
ch === "[" ? (bracketDepth++, buffer += ch) : ch === "]" ? (bracketDepth--, buffer += ch) : ch === "." && bracketDepth === 0 ? buffer && (result.push(...parseSegment(buffer)), buffer = "") : buffer += ch;
|
|
839
|
+
}
|
|
840
|
+
return buffer && result.push(...parseSegment(buffer)), result;
|
|
841
|
+
}
|
|
842
|
+
function stringifyPath(path) {
|
|
843
|
+
let result = "";
|
|
844
|
+
for (let i2 = 0; i2 < path.length; i2++) {
|
|
845
|
+
const segment = path[i2];
|
|
846
|
+
if (typeof segment == "string")
|
|
847
|
+
result && (result += "."), result += segment;
|
|
848
|
+
else if (typeof segment == "number")
|
|
849
|
+
result += `[${segment}]`;
|
|
850
|
+
else if (Array.isArray(segment)) {
|
|
851
|
+
const [start, end] = segment, startStr = start === "" ? "" : String(start), endStr = end === "" ? "" : String(end);
|
|
852
|
+
result += `[${startStr}:${endStr}]`;
|
|
853
|
+
} else
|
|
854
|
+
result += `[_key=="${segment._key}"]`;
|
|
855
|
+
}
|
|
856
|
+
return result;
|
|
857
|
+
}
|
|
858
|
+
function jsonMatch(input, pathExpression) {
|
|
859
|
+
return matchRecursive(input, parsePath(pathExpression), []);
|
|
860
|
+
}
|
|
861
|
+
function matchRecursive(value, path, currentPath) {
|
|
862
|
+
if (path.length === 0)
|
|
863
|
+
return [{ value, path: currentPath }];
|
|
864
|
+
const [head, ...rest] = path;
|
|
865
|
+
if (typeof head == "string") {
|
|
866
|
+
if (value && typeof value == "object" && !Array.isArray(value)) {
|
|
867
|
+
const nextValue = value[head];
|
|
868
|
+
return matchRecursive(nextValue, rest, [...currentPath, head]);
|
|
869
|
+
}
|
|
870
|
+
return [];
|
|
871
|
+
}
|
|
872
|
+
if (typeof head == "number") {
|
|
873
|
+
if (Array.isArray(value)) {
|
|
874
|
+
const nextValue = value.at(head);
|
|
875
|
+
return matchRecursive(nextValue, rest, [...currentPath, head]);
|
|
876
|
+
}
|
|
477
877
|
return [];
|
|
478
878
|
}
|
|
479
879
|
if (Array.isArray(head)) {
|
|
@@ -607,475 +1007,105 @@ function inc(input, pathExpressionValues) {
|
|
|
607
1007
|
}
|
|
608
1008
|
function dec(input, pathExpressionValues) {
|
|
609
1009
|
const result = inc(
|
|
610
|
-
input,
|
|
611
|
-
Object.fromEntries(
|
|
612
|
-
Object.entries(pathExpressionValues).filter(([, value]) => typeof value == "number").map(([key, value]) => [key, -value])
|
|
613
|
-
)
|
|
614
|
-
);
|
|
615
|
-
return ensureArrayKeysDeep(result);
|
|
616
|
-
}
|
|
617
|
-
function diffMatchPatch(input, pathExpressionValues) {
|
|
618
|
-
const result = Object.entries(pathExpressionValues).flatMap(([pathExpression, dmp]) => jsonMatch(input, pathExpression).map((m2) => ({ ...m2, dmp }))).filter((i2) => i2.value !== void 0).map(({ path, value, dmp }) => {
|
|
619
|
-
if (typeof value != "string")
|
|
620
|
-
throw new Error(
|
|
621
|
-
`Can't diff-match-patch \`${JSON.stringify(value)}\` at path \`${stringifyPath(path)}\`, because it is not a string`
|
|
622
|
-
);
|
|
623
|
-
const [nextValue] = applyPatches(parsePatch(dmp), value);
|
|
624
|
-
return { path, value: nextValue };
|
|
625
|
-
}).reduce((acc, { path, value }) => setDeep(acc, path, value), input);
|
|
626
|
-
return ensureArrayKeysDeep(result);
|
|
627
|
-
}
|
|
628
|
-
function ifRevisionID(input, revisionId) {
|
|
629
|
-
const inputRev = typeof input == "object" && input && "_rev" in input && typeof input._rev == "string" ? input._rev : void 0;
|
|
630
|
-
if (typeof inputRev != "string")
|
|
631
|
-
throw new Error("Patch specified `ifRevisionID` but could not find document's revision ID.");
|
|
632
|
-
if (revisionId !== inputRev)
|
|
633
|
-
throw new Error(
|
|
634
|
-
`Patch's \`ifRevisionID\` \`${revisionId}\` does not match document's revision ID \`${inputRev}\``
|
|
635
|
-
);
|
|
636
|
-
return input;
|
|
637
|
-
}
|
|
638
|
-
function isNonNullable(t2) {
|
|
639
|
-
return t2 != null;
|
|
640
|
-
}
|
|
641
|
-
const indexCache = /* @__PURE__ */ new WeakMap();
|
|
642
|
-
function getIndexForKey(input, key) {
|
|
643
|
-
if (!Array.isArray(input)) return;
|
|
644
|
-
const cached = indexCache.get(input);
|
|
645
|
-
if (cached) return cached[key];
|
|
646
|
-
const lookup = input.reduce((acc, next, index) => (typeof next?._key == "string" && (acc[next._key] = index), acc), {});
|
|
647
|
-
return indexCache.set(input, lookup), lookup[key];
|
|
648
|
-
}
|
|
649
|
-
function getDeep(input, path) {
|
|
650
|
-
const [currentSegment, ...restOfPath] = path;
|
|
651
|
-
if (currentSegment === void 0) return input;
|
|
652
|
-
if (typeof input != "object" || input === null) return;
|
|
653
|
-
let key;
|
|
654
|
-
if (isKeySegment(currentSegment) ? key = getIndexForKey(input, currentSegment._key) : (typeof currentSegment == "string" || typeof currentSegment == "number") && (key = currentSegment), key === void 0) return;
|
|
655
|
-
const nestedInput = typeof key == "number" && Array.isArray(input) ? input.at(key) : input[key];
|
|
656
|
-
return getDeep(nestedInput, restOfPath);
|
|
657
|
-
}
|
|
658
|
-
function setDeep(input, path, value) {
|
|
659
|
-
const [currentSegment, ...restOfPath] = path;
|
|
660
|
-
if (currentSegment === void 0) return value;
|
|
661
|
-
if (typeof input != "object" || input === null) {
|
|
662
|
-
if (typeof currentSegment == "string")
|
|
663
|
-
return { [currentSegment]: setDeep(null, restOfPath, value) };
|
|
664
|
-
let index;
|
|
665
|
-
if (isKeySegment(currentSegment))
|
|
666
|
-
index = 0;
|
|
667
|
-
else if (typeof currentSegment == "number" && currentSegment >= 0)
|
|
668
|
-
index = currentSegment;
|
|
669
|
-
else
|
|
670
|
-
return input;
|
|
671
|
-
return [
|
|
672
|
-
// fill until index
|
|
673
|
-
...Array.from({ length: index }).fill(null),
|
|
674
|
-
// then set deep here
|
|
675
|
-
setDeep(null, restOfPath, value)
|
|
676
|
-
];
|
|
677
|
-
}
|
|
678
|
-
if (Array.isArray(input)) {
|
|
679
|
-
let index;
|
|
680
|
-
return isKeySegment(currentSegment) ? index = getIndexForKey(input, currentSegment._key) : typeof currentSegment == "number" && (index = currentSegment < 0 ? input.length + currentSegment : currentSegment), index === void 0 ? input : index in input ? input.map(
|
|
681
|
-
(nestedInput, i2) => i2 === index ? setDeep(nestedInput, restOfPath, value) : nestedInput
|
|
682
|
-
) : [
|
|
683
|
-
...input,
|
|
684
|
-
...Array.from({ length: index - input.length }).fill(null),
|
|
685
|
-
setDeep(null, restOfPath, value)
|
|
686
|
-
];
|
|
687
|
-
}
|
|
688
|
-
return typeof currentSegment == "object" ? input : currentSegment in input ? Object.fromEntries(
|
|
689
|
-
Object.entries(input).map(
|
|
690
|
-
([key, nestedInput]) => key === currentSegment ? [key, setDeep(nestedInput, restOfPath, value)] : [key, nestedInput]
|
|
691
|
-
)
|
|
692
|
-
) : { ...input, [currentSegment]: setDeep(null, restOfPath, value) };
|
|
693
|
-
}
|
|
694
|
-
function unsetDeep(input, path) {
|
|
695
|
-
const [currentSegment, ...restOfPath] = path;
|
|
696
|
-
if (currentSegment === void 0 || typeof input != "object" || input === null) return input;
|
|
697
|
-
let _segment;
|
|
698
|
-
if (isKeySegment(currentSegment) ? _segment = getIndexForKey(input, currentSegment._key) : (typeof currentSegment == "string" || typeof currentSegment == "number") && (_segment = currentSegment), _segment === void 0) return input;
|
|
699
|
-
let segment = _segment;
|
|
700
|
-
return typeof segment == "number" && Array.isArray(input) && (segment = segment < 0 ? input.length + segment : segment), segment in input ? restOfPath.length ? Array.isArray(input) ? input.map(
|
|
701
|
-
(nestedInput, index) => index === segment ? unsetDeep(nestedInput, restOfPath) : nestedInput
|
|
702
|
-
) : Object.fromEntries(
|
|
703
|
-
Object.entries(input).map(
|
|
704
|
-
([key, value]) => key === segment ? [key, unsetDeep(value, restOfPath)] : [key, value]
|
|
705
|
-
)
|
|
706
|
-
) : Array.isArray(input) ? input.filter((_nestedInput, index) => index !== segment) : Object.fromEntries(Object.entries(input).filter(([key]) => key !== segment.toString())) : input;
|
|
707
|
-
}
|
|
708
|
-
const DEFAULT_API_VERSION = "2024-11-12", DEFAULT_REQUEST_TAG_PREFIX = "sanity.sdk", clientStore = {
|
|
709
|
-
name: "clientStore",
|
|
710
|
-
getInitialState: (instance) => {
|
|
711
|
-
const { identity, config } = instance, defaultClient = createClient({
|
|
712
|
-
projectId: identity.projectId,
|
|
713
|
-
dataset: identity.dataset,
|
|
714
|
-
token: config?.auth?.token,
|
|
715
|
-
useCdn: !1,
|
|
716
|
-
apiVersion: DEFAULT_API_VERSION,
|
|
717
|
-
requestTagPrefix: DEFAULT_REQUEST_TAG_PREFIX,
|
|
718
|
-
...config?.auth?.apiHost ? { apiHost: config.auth.apiHost } : {}
|
|
719
|
-
}), defaultGlobalClient = createClient({
|
|
720
|
-
token: config?.auth?.token,
|
|
721
|
-
useCdn: !1,
|
|
722
|
-
apiVersion: "vX",
|
|
723
|
-
// Many global APIs are only available under this version, we may need to support other versions in the future
|
|
724
|
-
useProjectHostname: !1,
|
|
725
|
-
requestTagPrefix: DEFAULT_REQUEST_TAG_PREFIX,
|
|
726
|
-
...config?.auth?.apiHost ? { apiHost: config.auth.apiHost } : {}
|
|
727
|
-
});
|
|
728
|
-
return {
|
|
729
|
-
defaultClient,
|
|
730
|
-
defaultGlobalClient
|
|
731
|
-
};
|
|
732
|
-
},
|
|
733
|
-
initialize() {
|
|
734
|
-
const authEventSubscription = subscribeToAuthEvents(this);
|
|
735
|
-
return () => {
|
|
736
|
-
authEventSubscription.unsubscribe();
|
|
737
|
-
};
|
|
738
|
-
}
|
|
739
|
-
}, receiveToken = (prev, token) => {
|
|
740
|
-
const newDefaultClient = prev.defaultClient.withConfig({
|
|
741
|
-
token
|
|
742
|
-
}), newGlobalClient = prev.defaultGlobalClient.withConfig({
|
|
743
|
-
token
|
|
744
|
-
});
|
|
745
|
-
return {
|
|
746
|
-
defaultClient: newDefaultClient,
|
|
747
|
-
defaultGlobalClient: newGlobalClient
|
|
748
|
-
};
|
|
749
|
-
}, subscribeToAuthEvents = createInternalAction(
|
|
750
|
-
({ instance, state }) => () => getTokenState(instance).observable.subscribe((newToken) => {
|
|
751
|
-
state.set("receiveToken", (prev) => receiveToken(prev, newToken ?? void 0));
|
|
752
|
-
})
|
|
753
|
-
), optionsCache = /* @__PURE__ */ new WeakMap(), defaultClientSelector = (state, options) => options?.scope === "global" ? state.defaultGlobalClient : state.defaultClient, memoizedOptionsSelector = createSelector(
|
|
754
|
-
[defaultClientSelector, (_state, options) => options],
|
|
755
|
-
(client, options) => {
|
|
756
|
-
let nestedCache = optionsCache.get(client);
|
|
757
|
-
nestedCache || (nestedCache = /* @__PURE__ */ new Map(), optionsCache.set(client, nestedCache));
|
|
758
|
-
const key = JSON.stringify(options);
|
|
759
|
-
return nestedCache.get(key) || (nestedCache.set(key, options), options);
|
|
760
|
-
}
|
|
761
|
-
), clientSelector = createSelector(
|
|
762
|
-
[defaultClientSelector, memoizedOptionsSelector],
|
|
763
|
-
(client, options) => client.withConfig(options)
|
|
764
|
-
), getClient = createAction(
|
|
765
|
-
clientStore,
|
|
766
|
-
({ state }) => (options) => clientSelector(state.get(), options)
|
|
767
|
-
), getClientState = createStateSourceAction(clientStore, clientSelector), comlinkControllerStore = {
|
|
768
|
-
name: "connectionStore",
|
|
769
|
-
getInitialState: () => ({
|
|
770
|
-
controller: null,
|
|
771
|
-
controllerOrigin: null,
|
|
772
|
-
channels: /* @__PURE__ */ new Map()
|
|
773
|
-
}),
|
|
774
|
-
initialize() {
|
|
775
|
-
return () => {
|
|
776
|
-
destroyController(this);
|
|
777
|
-
};
|
|
778
|
-
}
|
|
779
|
-
}, destroyController = createInternalAction(
|
|
780
|
-
({ state }) => () => {
|
|
781
|
-
const { controller } = state.get();
|
|
782
|
-
controller && (controller.destroy(), state.set("destroyController", {
|
|
783
|
-
controller: null,
|
|
784
|
-
channels: /* @__PURE__ */ new Map()
|
|
785
|
-
}));
|
|
786
|
-
}
|
|
787
|
-
), getOrCreateChannel = createAction(comlinkControllerStore, ({ state }) => (options) => {
|
|
788
|
-
const controller = state.get().controller;
|
|
789
|
-
if (!controller)
|
|
790
|
-
throw new Error("Controller must be initialized before using or creating channels");
|
|
791
|
-
const channels = state.get().channels, existing = channels.get(options.name);
|
|
792
|
-
if (existing) {
|
|
793
|
-
if (!isEqual(existing.options, options))
|
|
794
|
-
throw new Error(`Channel "${options.name}" already exists with different options`);
|
|
795
|
-
return state.set("incrementChannelRefCount", {
|
|
796
|
-
channels: new Map(channels).set(options.name, {
|
|
797
|
-
...existing,
|
|
798
|
-
refCount: existing.refCount + 1
|
|
799
|
-
})
|
|
800
|
-
}), existing.channel.start(), existing.channel;
|
|
801
|
-
}
|
|
802
|
-
const channel = controller.createChannel(options);
|
|
803
|
-
return channel.start(), state.set("createChannel", {
|
|
804
|
-
channels: new Map(channels).set(options.name, {
|
|
805
|
-
channel,
|
|
806
|
-
options,
|
|
807
|
-
refCount: 1
|
|
808
|
-
})
|
|
809
|
-
}), channel;
|
|
810
|
-
}), getOrCreateController = createAction(comlinkControllerStore, ({ state, instance }) => (targetOrigin) => {
|
|
811
|
-
const { controller, controllerOrigin } = state.get();
|
|
812
|
-
if (controller && controllerOrigin === targetOrigin)
|
|
813
|
-
return controller;
|
|
814
|
-
controller && destroyController({ state, instance });
|
|
815
|
-
const newController = createController({ targetOrigin });
|
|
816
|
-
return state.set("initializeController", {
|
|
817
|
-
controllerOrigin: targetOrigin,
|
|
818
|
-
controller: newController
|
|
819
|
-
}), newController;
|
|
820
|
-
}), releaseChannel = createAction(comlinkControllerStore, ({ state }) => (name) => {
|
|
821
|
-
const channels = state.get().channels, channelEntry = channels.get(name);
|
|
822
|
-
if (channelEntry) {
|
|
823
|
-
const newRefCount = channelEntry.refCount === 0 ? 0 : channelEntry.refCount - 1;
|
|
824
|
-
newRefCount === 0 ? (channelEntry.channel.stop(), channels.delete(name), state.set("releaseChannel", { channels: new Map(channels) })) : state.set("releaseChannel", {
|
|
825
|
-
channels: new Map(channels).set(name, {
|
|
826
|
-
...channelEntry,
|
|
827
|
-
refCount: newRefCount
|
|
828
|
-
})
|
|
829
|
-
});
|
|
830
|
-
}
|
|
831
|
-
}), comlinkNodeStore = {
|
|
832
|
-
name: "nodeStore",
|
|
833
|
-
getInitialState: () => ({
|
|
834
|
-
nodes: /* @__PURE__ */ new Map()
|
|
835
|
-
}),
|
|
836
|
-
initialize() {
|
|
837
|
-
return () => {
|
|
838
|
-
this.state.get().nodes.forEach(({ node }) => {
|
|
839
|
-
node.stop();
|
|
840
|
-
});
|
|
841
|
-
};
|
|
842
|
-
}
|
|
843
|
-
}, getOrCreateNode = createAction(comlinkNodeStore, ({ state }) => (options) => {
|
|
844
|
-
const nodes = state.get().nodes, existing = nodes.get(options.name);
|
|
845
|
-
if (existing) {
|
|
846
|
-
if (!isEqual(existing.options, options))
|
|
847
|
-
throw new Error(`Node "${options.name}" already exists with different options`);
|
|
848
|
-
return state.set("incrementNodeRefCount", {
|
|
849
|
-
nodes: new Map(nodes).set(options.name, {
|
|
850
|
-
...existing,
|
|
851
|
-
refCount: existing.refCount + 1
|
|
852
|
-
})
|
|
853
|
-
}), existing.node.start(), existing.node;
|
|
854
|
-
}
|
|
855
|
-
const node = createNode(options);
|
|
856
|
-
return node.start(), nodes.set(options.name, { node, options, refCount: 1 }), state.set("createNode", { nodes }), node;
|
|
857
|
-
}), releaseNode = createAction(comlinkNodeStore, ({ state }) => (name) => {
|
|
858
|
-
const nodes = state.get().nodes, nodeEntry = nodes.get(name);
|
|
859
|
-
if (nodeEntry) {
|
|
860
|
-
const newRefCount = nodeEntry.refCount === 0 ? 0 : nodeEntry.refCount - 1;
|
|
861
|
-
newRefCount === 0 ? (nodeEntry.node.stop(), nodes.delete(name), state.set("releaseNode", { nodes: new Map(nodes) })) : state.set("releaseNode", {
|
|
862
|
-
nodes: new Map(nodes).set(name, {
|
|
863
|
-
...nodeEntry,
|
|
864
|
-
refCount: newRefCount
|
|
865
|
-
})
|
|
866
|
-
});
|
|
867
|
-
}
|
|
868
|
-
});
|
|
869
|
-
function getPublishedId(id) {
|
|
870
|
-
const draftsPrefix = "drafts.";
|
|
871
|
-
return id.startsWith(draftsPrefix) ? id.slice(draftsPrefix.length) : id;
|
|
872
|
-
}
|
|
873
|
-
function getDraftId(id) {
|
|
874
|
-
const draftsPrefix = "drafts.";
|
|
875
|
-
return id.startsWith(draftsPrefix) ? id : `${draftsPrefix}${id}`;
|
|
876
|
-
}
|
|
877
|
-
function insecureRandomId() {
|
|
878
|
-
return Array.from({ length: 16 }, () => Math.floor(Math.random() * 16).toString(16)).join("");
|
|
879
|
-
}
|
|
880
|
-
function createFetcherStore({
|
|
881
|
-
name,
|
|
882
|
-
fetcher: getObservable,
|
|
883
|
-
getKey,
|
|
884
|
-
fetchThrottleInternal = 1e3,
|
|
885
|
-
stateExpirationDelay = 5e3
|
|
886
|
-
}) {
|
|
887
|
-
const store = {
|
|
888
|
-
name,
|
|
889
|
-
getInitialState: () => ({
|
|
890
|
-
stateByParams: {}
|
|
891
|
-
}),
|
|
892
|
-
initialize() {
|
|
893
|
-
const subscription = subscribeToSubscriptionsAndFetch(this);
|
|
894
|
-
return () => subscription.unsubscribe();
|
|
895
|
-
}
|
|
896
|
-
}, subscribeToSubscriptionsAndFetch = createInternalAction(
|
|
897
|
-
({ instance, state }) => function() {
|
|
898
|
-
const factoryFn = getObservable(instance);
|
|
899
|
-
return state.observable.pipe(
|
|
900
|
-
// Map the state to an array of [serialized, entry] pairs.
|
|
901
|
-
switchMap$1((s2) => {
|
|
902
|
-
const entries = Object.entries(s2.stateByParams);
|
|
903
|
-
return entries.length > 0 ? from(entries) : EMPTY;
|
|
904
|
-
}),
|
|
905
|
-
// Group by the serialized key.
|
|
906
|
-
groupBy(([key]) => key),
|
|
907
|
-
mergeMap(
|
|
908
|
-
(group$) => group$.pipe(
|
|
909
|
-
// Emit an initial value for pairwise comparisons.
|
|
910
|
-
startWith([
|
|
911
|
-
group$.key,
|
|
912
|
-
void 0
|
|
913
|
-
]),
|
|
914
|
-
pairwise(),
|
|
915
|
-
// Trigger only when the subscriptions array grows.
|
|
916
|
-
filter$1(([[, prevEntry], [, currEntry]]) => {
|
|
917
|
-
const prevSubs = prevEntry?.subscriptions ?? [];
|
|
918
|
-
return (currEntry?.subscriptions ?? []).length > prevSubs.length;
|
|
919
|
-
}),
|
|
920
|
-
map$1(([, [, currEntry]]) => currEntry),
|
|
921
|
-
// Only trigger if we haven't fetched recently.
|
|
922
|
-
filter$1((entry) => {
|
|
923
|
-
const lastFetch = entry?.lastFetchInitiatedAt;
|
|
924
|
-
return lastFetch ? Date.now() - new Date(lastFetch).getTime() >= fetchThrottleInternal : !0;
|
|
925
|
-
}),
|
|
926
|
-
switchMap$1((entry) => entry ? (state.set(
|
|
927
|
-
"setLastFetchInitiatedAt",
|
|
928
|
-
(prev) => ({
|
|
929
|
-
stateByParams: {
|
|
930
|
-
...prev.stateByParams,
|
|
931
|
-
[entry.key]: {
|
|
932
|
-
...entry,
|
|
933
|
-
...prev.stateByParams[entry.key],
|
|
934
|
-
lastFetchInitiatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
935
|
-
}
|
|
936
|
-
}
|
|
937
|
-
})
|
|
938
|
-
), factoryFn(...entry.params).pipe(
|
|
939
|
-
// the `createStateSourceAction` util requires the update
|
|
940
|
-
// to
|
|
941
|
-
delay(0, asapScheduler),
|
|
942
|
-
tap(
|
|
943
|
-
(data) => state.set("setData", (prev) => ({
|
|
944
|
-
stateByParams: {
|
|
945
|
-
...prev.stateByParams,
|
|
946
|
-
[entry.key]: {
|
|
947
|
-
...omit(entry, "error"),
|
|
948
|
-
...omit(prev.stateByParams[entry.key], "error"),
|
|
949
|
-
data
|
|
950
|
-
}
|
|
951
|
-
}
|
|
952
|
-
}))
|
|
953
|
-
),
|
|
954
|
-
catchError((error) => (state.set("setError", (prev) => ({
|
|
955
|
-
stateByParams: {
|
|
956
|
-
...prev.stateByParams,
|
|
957
|
-
[entry.key]: {
|
|
958
|
-
...entry,
|
|
959
|
-
...prev.stateByParams[entry.key],
|
|
960
|
-
error
|
|
961
|
-
}
|
|
962
|
-
}
|
|
963
|
-
})), EMPTY))
|
|
964
|
-
)) : EMPTY)
|
|
965
|
-
)
|
|
966
|
-
)
|
|
967
|
-
).subscribe({
|
|
968
|
-
error: (error) => state.set("setError", { error })
|
|
969
|
-
});
|
|
970
|
-
}
|
|
971
|
-
), getState2 = createStateSourceAction(store, {
|
|
972
|
-
selector: ({ stateByParams, error }, ...params) => {
|
|
973
|
-
if (error) throw error;
|
|
974
|
-
const key = getKey(...params), entry = stateByParams[key];
|
|
975
|
-
if (entry?.error) throw entry.error;
|
|
976
|
-
return entry?.data;
|
|
977
|
-
},
|
|
978
|
-
onSubscribe: ({ state }, ...params) => {
|
|
979
|
-
const subscriptionId = insecureRandomId(), key = getKey(...params);
|
|
980
|
-
return state.set("addSubscription", (prev) => ({
|
|
981
|
-
stateByParams: {
|
|
982
|
-
...prev.stateByParams,
|
|
983
|
-
[key]: {
|
|
984
|
-
...prev.stateByParams[key],
|
|
985
|
-
key,
|
|
986
|
-
params: prev.stateByParams[key]?.params || params,
|
|
987
|
-
subscriptions: [...prev.stateByParams[key]?.subscriptions || [], subscriptionId]
|
|
988
|
-
}
|
|
989
|
-
}
|
|
990
|
-
})), () => {
|
|
991
|
-
setTimeout(() => {
|
|
992
|
-
state.set("removeSubscription", (prev) => {
|
|
993
|
-
const entry = prev.stateByParams[key];
|
|
994
|
-
if (!entry) return prev;
|
|
995
|
-
const newSubs = (entry.subscriptions || []).filter((id) => id !== subscriptionId);
|
|
996
|
-
return newSubs.length === 0 ? { stateByParams: omit(prev.stateByParams, key) } : {
|
|
997
|
-
stateByParams: {
|
|
998
|
-
...prev.stateByParams,
|
|
999
|
-
[key]: {
|
|
1000
|
-
...entry,
|
|
1001
|
-
subscriptions: newSubs
|
|
1002
|
-
}
|
|
1003
|
-
}
|
|
1004
|
-
};
|
|
1005
|
-
});
|
|
1006
|
-
}, stateExpirationDelay);
|
|
1007
|
-
};
|
|
1008
|
-
}
|
|
1009
|
-
}), resolveState = createAction(store, () => function(...params) {
|
|
1010
|
-
return firstValueFrom(
|
|
1011
|
-
getState2(this, ...params).observable.pipe(first((i2) => i2 !== void 0))
|
|
1012
|
-
);
|
|
1013
|
-
});
|
|
1014
|
-
return { getState: getState2, resolveState };
|
|
1010
|
+
input,
|
|
1011
|
+
Object.fromEntries(
|
|
1012
|
+
Object.entries(pathExpressionValues).filter(([, value]) => typeof value == "number").map(([key, value]) => [key, -value])
|
|
1013
|
+
)
|
|
1014
|
+
);
|
|
1015
|
+
return ensureArrayKeysDeep(result);
|
|
1015
1016
|
}
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
...doc._id && { documentId: doc._id },
|
|
1027
|
-
documentType: doc._type,
|
|
1028
|
-
...doc.resourceId && { resourceId: doc.resourceId }
|
|
1029
|
-
};
|
|
1017
|
+
function diffMatchPatch(input, pathExpressionValues) {
|
|
1018
|
+
const result = Object.entries(pathExpressionValues).flatMap(([pathExpression, dmp]) => jsonMatch(input, pathExpression).map((m2) => ({ ...m2, dmp }))).filter((i2) => i2.value !== void 0).map(({ path, value, dmp }) => {
|
|
1019
|
+
if (typeof value != "string")
|
|
1020
|
+
throw new Error(
|
|
1021
|
+
`Can't diff-match-patch \`${JSON.stringify(value)}\` at path \`${stringifyPath(path)}\`, because it is not a string`
|
|
1022
|
+
);
|
|
1023
|
+
const [nextValue] = applyPatches(parsePatch(dmp), value);
|
|
1024
|
+
return { path, value: nextValue };
|
|
1025
|
+
}).reduce((acc, { path, value }) => setDeep(acc, path, value), input);
|
|
1026
|
+
return ensureArrayKeysDeep(result);
|
|
1030
1027
|
}
|
|
1031
|
-
function
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1028
|
+
function ifRevisionID(input, revisionId) {
|
|
1029
|
+
const inputRev = typeof input == "object" && input && "_rev" in input && typeof input._rev == "string" ? input._rev : void 0;
|
|
1030
|
+
if (typeof inputRev != "string")
|
|
1031
|
+
throw new Error("Patch specified `ifRevisionID` but could not find document's revision ID.");
|
|
1032
|
+
if (revisionId !== inputRev)
|
|
1033
|
+
throw new Error(
|
|
1034
|
+
`Patch's \`ifRevisionID\` \`${revisionId}\` does not match document's revision ID \`${inputRev}\``
|
|
1035
|
+
);
|
|
1036
|
+
return input;
|
|
1037
1037
|
}
|
|
1038
|
-
function
|
|
1039
|
-
|
|
1040
|
-
return {
|
|
1041
|
-
documentId: sanityPatchMutation.id,
|
|
1042
|
-
type: "document.edit",
|
|
1043
|
-
patches: encoded.map((i2) => {
|
|
1044
|
-
const copy = { ...i2.patch };
|
|
1045
|
-
return "id" in copy && delete copy.id, copy;
|
|
1046
|
-
})
|
|
1047
|
-
};
|
|
1038
|
+
function isNonNullable(t2) {
|
|
1039
|
+
return t2 != null;
|
|
1048
1040
|
}
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1041
|
+
const indexCache = /* @__PURE__ */ new WeakMap();
|
|
1042
|
+
function getIndexForKey(input, key) {
|
|
1043
|
+
if (!Array.isArray(input)) return;
|
|
1044
|
+
const cached = indexCache.get(input);
|
|
1045
|
+
if (cached) return cached[key];
|
|
1046
|
+
const lookup = input.reduce((acc, next, index) => (typeof next?._key == "string" && (acc[next._key] = index), acc), {});
|
|
1047
|
+
return indexCache.set(input, lookup), lookup[key];
|
|
1056
1048
|
}
|
|
1057
|
-
function
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1049
|
+
function getDeep(input, path) {
|
|
1050
|
+
const [currentSegment, ...restOfPath] = path;
|
|
1051
|
+
if (currentSegment === void 0) return input;
|
|
1052
|
+
if (typeof input != "object" || input === null) return;
|
|
1053
|
+
let key;
|
|
1054
|
+
if (isKeySegment(currentSegment) ? key = getIndexForKey(input, currentSegment._key) : (typeof currentSegment == "string" || typeof currentSegment == "number") && (key = currentSegment), key === void 0) return;
|
|
1055
|
+
const nestedInput = typeof key == "number" && Array.isArray(input) ? input.at(key) : input[key];
|
|
1056
|
+
return getDeep(nestedInput, restOfPath);
|
|
1063
1057
|
}
|
|
1064
|
-
function
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1058
|
+
function setDeep(input, path, value) {
|
|
1059
|
+
const [currentSegment, ...restOfPath] = path;
|
|
1060
|
+
if (currentSegment === void 0) return value;
|
|
1061
|
+
if (typeof input != "object" || input === null) {
|
|
1062
|
+
if (typeof currentSegment == "string")
|
|
1063
|
+
return { [currentSegment]: setDeep(null, restOfPath, value) };
|
|
1064
|
+
let index;
|
|
1065
|
+
if (isKeySegment(currentSegment))
|
|
1066
|
+
index = 0;
|
|
1067
|
+
else if (typeof currentSegment == "number" && currentSegment >= 0)
|
|
1068
|
+
index = currentSegment;
|
|
1069
|
+
else
|
|
1070
|
+
return input;
|
|
1071
|
+
return [
|
|
1072
|
+
// fill until index
|
|
1073
|
+
...Array.from({ length: index }).fill(null),
|
|
1074
|
+
// then set deep here
|
|
1075
|
+
setDeep(null, restOfPath, value)
|
|
1076
|
+
];
|
|
1077
|
+
}
|
|
1078
|
+
if (Array.isArray(input)) {
|
|
1079
|
+
let index;
|
|
1080
|
+
return isKeySegment(currentSegment) ? index = getIndexForKey(input, currentSegment._key) : typeof currentSegment == "number" && (index = currentSegment < 0 ? input.length + currentSegment : currentSegment), index === void 0 ? input : index in input ? input.map(
|
|
1081
|
+
(nestedInput, i2) => i2 === index ? setDeep(nestedInput, restOfPath, value) : nestedInput
|
|
1082
|
+
) : [
|
|
1083
|
+
...input,
|
|
1084
|
+
...Array.from({ length: index - input.length }).fill(null),
|
|
1085
|
+
setDeep(null, restOfPath, value)
|
|
1086
|
+
];
|
|
1087
|
+
}
|
|
1088
|
+
return typeof currentSegment == "object" ? input : currentSegment in input ? Object.fromEntries(
|
|
1089
|
+
Object.entries(input).map(
|
|
1090
|
+
([key, nestedInput]) => key === currentSegment ? [key, setDeep(nestedInput, restOfPath, value)] : [key, nestedInput]
|
|
1091
|
+
)
|
|
1092
|
+
) : { ...input, [currentSegment]: setDeep(null, restOfPath, value) };
|
|
1070
1093
|
}
|
|
1071
|
-
function
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1094
|
+
function unsetDeep(input, path) {
|
|
1095
|
+
const [currentSegment, ...restOfPath] = path;
|
|
1096
|
+
if (currentSegment === void 0 || typeof input != "object" || input === null) return input;
|
|
1097
|
+
let _segment;
|
|
1098
|
+
if (isKeySegment(currentSegment) ? _segment = getIndexForKey(input, currentSegment._key) : (typeof currentSegment == "string" || typeof currentSegment == "number") && (_segment = currentSegment), _segment === void 0) return input;
|
|
1099
|
+
let segment = _segment;
|
|
1100
|
+
return typeof segment == "number" && Array.isArray(input) && (segment = segment < 0 ? input.length + segment : segment), segment in input ? restOfPath.length ? Array.isArray(input) ? input.map(
|
|
1101
|
+
(nestedInput, index) => index === segment ? unsetDeep(nestedInput, restOfPath) : nestedInput
|
|
1102
|
+
) : Object.fromEntries(
|
|
1103
|
+
Object.entries(input).map(
|
|
1104
|
+
([key, value]) => key === segment ? [key, unsetDeep(value, restOfPath)] : [key, value]
|
|
1105
|
+
)
|
|
1106
|
+
) : Array.isArray(input) ? input.filter((_nestedInput, index) => index !== segment) : Object.fromEntries(Object.entries(input).filter(([key]) => key !== segment.toString())) : input;
|
|
1077
1107
|
}
|
|
1078
|
-
const
|
|
1108
|
+
const patchOperations = {
|
|
1079
1109
|
ifRevisionID,
|
|
1080
1110
|
set,
|
|
1081
1111
|
setIfMissing,
|
|
@@ -1284,50 +1314,48 @@ function sortListenerEvents(options) {
|
|
|
1284
1314
|
mergeMap((state) => of(...state.emitEvents))
|
|
1285
1315
|
);
|
|
1286
1316
|
}
|
|
1287
|
-
const listen =
|
|
1317
|
+
const listen = ({ state }, documentId) => {
|
|
1288
1318
|
const { sharedListener, fetchDocument } = state.get();
|
|
1289
|
-
return
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
if (next.type === "sync")
|
|
1304
|
-
return {
|
|
1305
|
-
type: "sync",
|
|
1306
|
-
documentId,
|
|
1307
|
-
document: next.document,
|
|
1308
|
-
revision: next.document?._rev,
|
|
1309
|
-
timestamp: next.document?._updatedAt ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
1310
|
-
};
|
|
1311
|
-
const [document] = Object.values(
|
|
1312
|
-
processMutations({
|
|
1313
|
-
documents: { [documentId]: documentState.remote },
|
|
1314
|
-
mutations: next.mutations,
|
|
1315
|
-
transactionId: next.transactionId,
|
|
1316
|
-
timestamp: next.timestamp
|
|
1317
|
-
})
|
|
1318
|
-
), { previousRev, transactionId, timestamp } = next;
|
|
1319
|
+
return sharedListener.events.pipe(
|
|
1320
|
+
concatMap((e3) => e3.type === "welcome" ? fetchDocument(documentId).pipe(
|
|
1321
|
+
map((document) => ({ type: "sync", document }))
|
|
1322
|
+
) : e3.type === "mutation" && e3.documentId === documentId ? of(e3) : EMPTY),
|
|
1323
|
+
sortListenerEvents(),
|
|
1324
|
+
withLatestFrom(
|
|
1325
|
+
state.observable.pipe(
|
|
1326
|
+
map((s2) => s2.documentStates[documentId]),
|
|
1327
|
+
filter(Boolean),
|
|
1328
|
+
distinctUntilChanged()
|
|
1329
|
+
)
|
|
1330
|
+
),
|
|
1331
|
+
map(([next, documentState]) => {
|
|
1332
|
+
if (next.type === "sync")
|
|
1319
1333
|
return {
|
|
1320
|
-
type: "
|
|
1334
|
+
type: "sync",
|
|
1321
1335
|
documentId,
|
|
1322
|
-
document: document
|
|
1323
|
-
revision:
|
|
1324
|
-
timestamp
|
|
1325
|
-
...previousRev && { previousRev }
|
|
1336
|
+
document: next.document,
|
|
1337
|
+
revision: next.document?._rev,
|
|
1338
|
+
timestamp: next.document?._updatedAt ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
1326
1339
|
};
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1340
|
+
const [document] = Object.values(
|
|
1341
|
+
processMutations({
|
|
1342
|
+
documents: { [documentId]: documentState.remote },
|
|
1343
|
+
mutations: next.mutations,
|
|
1344
|
+
transactionId: next.transactionId,
|
|
1345
|
+
timestamp: next.timestamp
|
|
1346
|
+
})
|
|
1347
|
+
), { previousRev, transactionId, timestamp } = next;
|
|
1348
|
+
return {
|
|
1349
|
+
type: "mutation",
|
|
1350
|
+
documentId,
|
|
1351
|
+
document: document ?? null,
|
|
1352
|
+
revision: transactionId,
|
|
1353
|
+
timestamp,
|
|
1354
|
+
...previousRev && { previousRev }
|
|
1355
|
+
};
|
|
1356
|
+
})
|
|
1357
|
+
);
|
|
1358
|
+
};
|
|
1331
1359
|
class e {
|
|
1332
1360
|
pattern;
|
|
1333
1361
|
patternRe;
|
|
@@ -3189,8 +3217,8 @@ function createGrantsLookup(datasetAcl) {
|
|
|
3189
3217
|
}
|
|
3190
3218
|
const documentsCache = new MultiKeyWeakMap(), actionsCache = /* @__PURE__ */ new WeakMap(), nullReplacer = {}, documentsSelector = createSelector(
|
|
3191
3219
|
[
|
|
3192
|
-
({ documentStates }) => documentStates,
|
|
3193
|
-
(
|
|
3220
|
+
({ state: { documentStates } }) => documentStates,
|
|
3221
|
+
(_context, actions) => actions
|
|
3194
3222
|
],
|
|
3195
3223
|
(documentStates, actions) => {
|
|
3196
3224
|
const documentIds = new Set(
|
|
@@ -3225,7 +3253,11 @@ function checkGrant$1(grantExpr, document) {
|
|
|
3225
3253
|
return C(grantExpr, { params: { document } }).get();
|
|
3226
3254
|
}
|
|
3227
3255
|
const enNarrowConjunction = new Intl.ListFormat("en", { style: "narrow", type: "conjunction" }), calculatePermissions = createSelector(
|
|
3228
|
-
[
|
|
3256
|
+
[
|
|
3257
|
+
({ state: { grants } }) => grants,
|
|
3258
|
+
documentsSelector,
|
|
3259
|
+
memoizedActionsSelector
|
|
3260
|
+
],
|
|
3229
3261
|
(grants, documents, actions) => {
|
|
3230
3262
|
if (!documents || !grants || !actions) return;
|
|
3231
3263
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString(), reasons = [];
|
|
@@ -3795,7 +3827,7 @@ function removeSubscriptionIdFromDocument(prev, documentId, subscriptionId) {
|
|
|
3795
3827
|
}
|
|
3796
3828
|
} : { ...prev, documentStates: omit(prev.documentStates, documentId) } : prev;
|
|
3797
3829
|
}
|
|
3798
|
-
function manageSubscriberIds(state, documentId) {
|
|
3830
|
+
function manageSubscriberIds({ state }, documentId) {
|
|
3799
3831
|
const documentIds = Array.from(
|
|
3800
3832
|
new Set(
|
|
3801
3833
|
(Array.isArray(documentId) ? documentId : [documentId]).flatMap((id) => [
|
|
@@ -3853,9 +3885,11 @@ function getDocumentEvents(outgoing) {
|
|
|
3853
3885
|
)
|
|
3854
3886
|
);
|
|
3855
3887
|
}
|
|
3856
|
-
const API_VERSION$
|
|
3888
|
+
const API_VERSION$3 = "vX";
|
|
3857
3889
|
function createSharedListener(instance) {
|
|
3858
|
-
const events$ = getClientState(instance, {
|
|
3890
|
+
const dispose$ = new Subject(), events$ = getClientState(instance, {
|
|
3891
|
+
apiVersion: API_VERSION$3
|
|
3892
|
+
}).observable.pipe(
|
|
3859
3893
|
switchMap(
|
|
3860
3894
|
(client) => (
|
|
3861
3895
|
// TODO: it seems like the client.listen method is not emitting disconnected
|
|
@@ -3876,17 +3910,21 @@ function createSharedListener(instance) {
|
|
|
3876
3910
|
)
|
|
3877
3911
|
)
|
|
3878
3912
|
),
|
|
3913
|
+
takeUntil(dispose$),
|
|
3879
3914
|
share()
|
|
3880
3915
|
), [welcome$, mutation$] = partition(events$, (e3) => e3.type === "welcome");
|
|
3881
|
-
return
|
|
3882
|
-
|
|
3883
|
-
|
|
3884
|
-
|
|
3885
|
-
|
|
3916
|
+
return {
|
|
3917
|
+
events: merge(
|
|
3918
|
+
// we replay the welcome event because that event kicks off fetching the document
|
|
3919
|
+
welcome$.pipe(shareReplay(1)),
|
|
3920
|
+
mutation$
|
|
3921
|
+
),
|
|
3922
|
+
dispose: () => dispose$.next()
|
|
3923
|
+
};
|
|
3886
3924
|
}
|
|
3887
3925
|
function createFetchDocument(instance) {
|
|
3888
3926
|
return function(documentId) {
|
|
3889
|
-
return getClientState(instance, { apiVersion: API_VERSION$
|
|
3927
|
+
return getClientState(instance, { apiVersion: API_VERSION$3 }).observable.pipe(
|
|
3890
3928
|
switchMap((client) => createDocumentLoaderFromClient(client)(documentId)),
|
|
3891
3929
|
map((result) => {
|
|
3892
3930
|
if (!result.accessible) {
|
|
@@ -3910,329 +3948,458 @@ const documentStore = {
|
|
|
3910
3948
|
fetchDocument: createFetchDocument(instance),
|
|
3911
3949
|
events: new Subject()
|
|
3912
3950
|
}),
|
|
3913
|
-
initialize() {
|
|
3914
|
-
const
|
|
3951
|
+
initialize(context) {
|
|
3952
|
+
const { sharedListener } = context.state.get(), subscriptions = [
|
|
3953
|
+
subscribeToQueuedAndApplyNextTransaction(context),
|
|
3954
|
+
subscribeToSubscriptionsAndListenToDocuments(context),
|
|
3955
|
+
subscribeToAppliedAndSubmitNextTransaction(context),
|
|
3956
|
+
subscribeToClientAndFetchDatasetAcl(context)
|
|
3957
|
+
];
|
|
3915
3958
|
return () => {
|
|
3916
|
-
|
|
3959
|
+
sharedListener.dispose(), subscriptions.forEach((subscription) => subscription.unsubscribe());
|
|
3917
3960
|
};
|
|
3918
3961
|
}
|
|
3919
3962
|
};
|
|
3920
3963
|
function getDocumentState(...args) {
|
|
3921
3964
|
return _getDocumentState(...args);
|
|
3922
3965
|
}
|
|
3923
|
-
const _getDocumentState =
|
|
3924
|
-
|
|
3925
|
-
|
|
3926
|
-
|
|
3927
|
-
|
|
3928
|
-
|
|
3929
|
-
|
|
3930
|
-
|
|
3931
|
-
|
|
3932
|
-
}
|
|
3966
|
+
const _getDocumentState = bindActionByDataset(
|
|
3967
|
+
documentStore,
|
|
3968
|
+
createStateSourceAction({
|
|
3969
|
+
selector: ({ state: { error, documentStates } }, doc, path) => {
|
|
3970
|
+
const documentId = typeof doc == "string" ? doc : doc.documentId;
|
|
3971
|
+
if (error) throw error;
|
|
3972
|
+
const draftId = getDraftId(documentId), publishedId = getPublishedId$1(documentId), draft = documentStates[draftId]?.local, published = documentStates[publishedId]?.local, document = draft ?? published;
|
|
3973
|
+
if (document !== void 0)
|
|
3974
|
+
return path ? jsonMatch(document, path).at(0)?.value : document;
|
|
3975
|
+
},
|
|
3976
|
+
onSubscribe: (context, doc) => manageSubscriberIds(context, typeof doc == "string" ? doc : doc.documentId)
|
|
3977
|
+
})
|
|
3978
|
+
);
|
|
3933
3979
|
function resolveDocument(...args) {
|
|
3934
3980
|
return _resolveDocument(...args);
|
|
3935
3981
|
}
|
|
3936
|
-
const _resolveDocument =
|
|
3937
|
-
|
|
3938
|
-
|
|
3939
|
-
|
|
3940
|
-
|
|
3941
|
-
|
|
3942
|
-
|
|
3943
|
-
const documentId = doc._id;
|
|
3944
|
-
if (error) throw error;
|
|
3945
|
-
const draftId = getDraftId(documentId), publishedId = getPublishedId$1(documentId), draft = documents[draftId], published = documents[publishedId];
|
|
3946
|
-
if (!(draft === void 0 || published === void 0))
|
|
3947
|
-
return !queued.length && !applied.length && !outgoing;
|
|
3948
|
-
},
|
|
3949
|
-
onSubscribe: ({ state }, doc) => manageSubscriberIds(state, doc._id)
|
|
3950
|
-
}), getPermissionsState = createStateSourceAction(documentStore, {
|
|
3951
|
-
selector: calculatePermissions,
|
|
3952
|
-
onSubscribe: ({ state }, actions) => manageSubscriberIds(state, getDocumentIdsFromActions(actions))
|
|
3953
|
-
}), resolvePermissions = createAction(documentStore, () => function(actions) {
|
|
3954
|
-
return firstValueFrom(
|
|
3955
|
-
getPermissionsState(this, actions).observable.pipe(filter((i2) => i2 !== void 0))
|
|
3956
|
-
);
|
|
3957
|
-
}), subscribeDocumentEvents = createAction(documentStore, ({ state }) => {
|
|
3958
|
-
const { events } = state.get();
|
|
3959
|
-
return function(eventHandler) {
|
|
3960
|
-
const subscription = events.subscribe(eventHandler);
|
|
3961
|
-
return () => subscription.unsubscribe();
|
|
3962
|
-
};
|
|
3963
|
-
}), subscribeToQueuedAndApplyNextTransaction = createInternalAction(
|
|
3964
|
-
({ state }) => {
|
|
3965
|
-
const { events } = state.get();
|
|
3966
|
-
return function() {
|
|
3967
|
-
return state.observable.pipe(
|
|
3968
|
-
map(applyFirstQueuedTransaction),
|
|
3969
|
-
distinctUntilChanged(),
|
|
3970
|
-
tap$1((next) => state.set("applyFirstQueuedTransaction", next)),
|
|
3971
|
-
catchError$1((error, caught) => {
|
|
3972
|
-
if (error instanceof ActionError)
|
|
3973
|
-
return state.set(
|
|
3974
|
-
"removeQueuedTransaction",
|
|
3975
|
-
(prev) => removeQueuedTransaction(prev, error.transactionId)
|
|
3976
|
-
), events.next({
|
|
3977
|
-
type: "error",
|
|
3978
|
-
message: error.message,
|
|
3979
|
-
documentId: error.documentId,
|
|
3980
|
-
transactionId: error.transactionId,
|
|
3981
|
-
error
|
|
3982
|
-
}), caught;
|
|
3983
|
-
throw error;
|
|
3984
|
-
})
|
|
3985
|
-
).subscribe({ error: (error) => state.set("setError", { error }) });
|
|
3986
|
-
};
|
|
3982
|
+
const _resolveDocument = bindActionByDataset(
|
|
3983
|
+
documentStore,
|
|
3984
|
+
({ instance }, doc) => {
|
|
3985
|
+
const documentId = typeof doc == "string" ? doc : doc.documentId;
|
|
3986
|
+
return firstValueFrom(
|
|
3987
|
+
getDocumentState(instance, documentId).observable.pipe(filter((i2) => i2 !== void 0))
|
|
3988
|
+
);
|
|
3987
3989
|
}
|
|
3988
|
-
),
|
|
3989
|
-
|
|
3990
|
-
|
|
3991
|
-
|
|
3992
|
-
|
|
3993
|
-
|
|
3994
|
-
|
|
3995
|
-
|
|
3996
|
-
|
|
3997
|
-
|
|
3998
|
-
|
|
3999
|
-
|
|
4000
|
-
|
|
4001
|
-
|
|
4002
|
-
|
|
4003
|
-
|
|
4004
|
-
|
|
4005
|
-
|
|
4006
|
-
|
|
4007
|
-
|
|
4008
|
-
|
|
4009
|
-
|
|
4010
|
-
|
|
4011
|
-
|
|
4012
|
-
|
|
4013
|
-
|
|
4014
|
-
|
|
4015
|
-
|
|
4016
|
-
) : EMPTY),
|
|
4017
|
-
tap$1(({ outgoing, result }) => {
|
|
4018
|
-
state.set("cleanupOutgoingTransaction", cleanupOutgoingTransaction);
|
|
4019
|
-
for (const e3 of getDocumentEvents(outgoing)) events.next(e3);
|
|
4020
|
-
events.next({ type: "accepted", outgoing, result });
|
|
4021
|
-
})
|
|
4022
|
-
).subscribe({ error: (error) => state.set("setError", { error }) });
|
|
4023
|
-
};
|
|
3990
|
+
), getDocumentSyncStatus = bindActionByDataset(
|
|
3991
|
+
documentStore,
|
|
3992
|
+
createStateSourceAction({
|
|
3993
|
+
selector: ({ state: { error, documentStates: documents, outgoing, applied, queued } }, doc) => {
|
|
3994
|
+
const documentId = typeof doc == "string" ? doc : doc.documentId;
|
|
3995
|
+
if (error) throw error;
|
|
3996
|
+
const draftId = getDraftId(documentId), publishedId = getPublishedId$1(documentId), draft = documents[draftId], published = documents[publishedId];
|
|
3997
|
+
if (!(draft === void 0 || published === void 0))
|
|
3998
|
+
return !queued.length && !applied.length && !outgoing;
|
|
3999
|
+
},
|
|
4000
|
+
onSubscribe: (context, doc) => manageSubscriberIds(context, doc.documentId)
|
|
4001
|
+
})
|
|
4002
|
+
), getPermissionsState = bindActionByDataset(
|
|
4003
|
+
documentStore,
|
|
4004
|
+
createStateSourceAction({
|
|
4005
|
+
selector: calculatePermissions,
|
|
4006
|
+
onSubscribe: (context, actions) => manageSubscriberIds(context, getDocumentIdsFromActions(actions))
|
|
4007
|
+
})
|
|
4008
|
+
), resolvePermissions = bindActionByDataset(
|
|
4009
|
+
documentStore,
|
|
4010
|
+
({ instance }, actions) => firstValueFrom(
|
|
4011
|
+
getPermissionsState(instance, actions).observable.pipe(filter((i2) => i2 !== void 0))
|
|
4012
|
+
)
|
|
4013
|
+
), subscribeDocumentEvents = bindActionByDataset(
|
|
4014
|
+
documentStore,
|
|
4015
|
+
({ state }, eventHandler) => {
|
|
4016
|
+
const { events } = state.get(), subscription = events.subscribe(eventHandler);
|
|
4017
|
+
return () => subscription.unsubscribe();
|
|
4024
4018
|
}
|
|
4025
|
-
),
|
|
4026
|
-
|
|
4027
|
-
|
|
4028
|
-
|
|
4029
|
-
|
|
4030
|
-
|
|
4031
|
-
|
|
4032
|
-
|
|
4033
|
-
|
|
4034
|
-
|
|
4035
|
-
|
|
4036
|
-
|
|
4037
|
-
|
|
4038
|
-
|
|
4039
|
-
|
|
4040
|
-
|
|
4041
|
-
|
|
4042
|
-
|
|
4043
|
-
|
|
4044
|
-
|
|
4045
|
-
|
|
4046
|
-
|
|
4047
|
-
|
|
4048
|
-
|
|
4049
|
-
|
|
4050
|
-
|
|
4051
|
-
|
|
4052
|
-
|
|
4053
|
-
|
|
4054
|
-
|
|
4055
|
-
|
|
4056
|
-
|
|
4057
|
-
|
|
4058
|
-
|
|
4059
|
-
|
|
4060
|
-
|
|
4061
|
-
|
|
4062
|
-
|
|
4019
|
+
), subscribeToQueuedAndApplyNextTransaction = ({ state }) => {
|
|
4020
|
+
const { events } = state.get();
|
|
4021
|
+
return state.observable.pipe(
|
|
4022
|
+
map(applyFirstQueuedTransaction),
|
|
4023
|
+
distinctUntilChanged(),
|
|
4024
|
+
tap$1((next) => state.set("applyFirstQueuedTransaction", next)),
|
|
4025
|
+
catchError$1((error, caught) => {
|
|
4026
|
+
if (error instanceof ActionError)
|
|
4027
|
+
return state.set(
|
|
4028
|
+
"removeQueuedTransaction",
|
|
4029
|
+
(prev) => removeQueuedTransaction(prev, error.transactionId)
|
|
4030
|
+
), events.next({
|
|
4031
|
+
type: "error",
|
|
4032
|
+
message: error.message,
|
|
4033
|
+
documentId: error.documentId,
|
|
4034
|
+
transactionId: error.transactionId,
|
|
4035
|
+
error
|
|
4036
|
+
}), caught;
|
|
4037
|
+
throw error;
|
|
4038
|
+
})
|
|
4039
|
+
).subscribe({ error: (error) => state.set("setError", { error }) });
|
|
4040
|
+
}, subscribeToAppliedAndSubmitNextTransaction = ({
|
|
4041
|
+
state,
|
|
4042
|
+
instance
|
|
4043
|
+
}) => {
|
|
4044
|
+
const { events } = state.get();
|
|
4045
|
+
return state.observable.pipe(
|
|
4046
|
+
throttle(
|
|
4047
|
+
(s2) => (
|
|
4048
|
+
// if there is no outgoing transaction, we can throttle by the
|
|
4049
|
+
// initial outgoing throttle time…
|
|
4050
|
+
s2.outgoing ? (
|
|
4051
|
+
// …otherwise, wait until the outgoing has been cleared
|
|
4052
|
+
state.observable.pipe(first$1(({ outgoing }) => !outgoing))
|
|
4053
|
+
) : timer(INITIAL_OUTGOING_THROTTLE_TIME)
|
|
4054
|
+
),
|
|
4055
|
+
{ leading: !1, trailing: !0 }
|
|
4056
|
+
),
|
|
4057
|
+
map(transitionAppliedTransactionsToOutgoing),
|
|
4058
|
+
distinctUntilChanged((a2, b2) => a2.outgoing?.transactionId === b2.outgoing?.transactionId),
|
|
4059
|
+
tap$1((next) => state.set("transitionAppliedTransactionsToOutgoing", next)),
|
|
4060
|
+
map((s2) => s2.outgoing),
|
|
4061
|
+
distinctUntilChanged(),
|
|
4062
|
+
withLatestFrom(getClientState(instance, { apiVersion: API_VERSION$4 }).observable),
|
|
4063
|
+
concatMap(([outgoing, client]) => outgoing ? client.observable.action(outgoing.outgoingActions, {
|
|
4064
|
+
transactionId: outgoing.transactionId,
|
|
4065
|
+
skipCrossDatasetReferenceValidation: !0
|
|
4066
|
+
}).pipe(
|
|
4067
|
+
catchError$1((error) => (state.set("revertOutgoingTransaction", revertOutgoingTransaction), events.next({ type: "reverted", message: error.message, outgoing, error }), EMPTY)),
|
|
4068
|
+
map((result) => ({ result, outgoing }))
|
|
4069
|
+
) : EMPTY),
|
|
4070
|
+
tap$1(({ outgoing, result }) => {
|
|
4071
|
+
state.set("cleanupOutgoingTransaction", cleanupOutgoingTransaction);
|
|
4072
|
+
for (const e3 of getDocumentEvents(outgoing)) events.next(e3);
|
|
4073
|
+
events.next({ type: "accepted", outgoing, result });
|
|
4074
|
+
})
|
|
4075
|
+
).subscribe({ error: (error) => state.set("setError", { error }) });
|
|
4076
|
+
}, subscribeToSubscriptionsAndListenToDocuments = (context) => {
|
|
4077
|
+
const { state } = context, { events } = state.get();
|
|
4078
|
+
return state.observable.pipe(
|
|
4079
|
+
filter((s2) => !!s2.grants),
|
|
4080
|
+
map((s2) => Object.keys(s2.documentStates)),
|
|
4081
|
+
distinctUntilChanged((curr, next) => {
|
|
4082
|
+
if (curr.length !== next.length) return !1;
|
|
4083
|
+
const currSet = new Set(curr);
|
|
4084
|
+
return next.every((i2) => currSet.has(i2));
|
|
4085
|
+
}),
|
|
4086
|
+
startWith$1(/* @__PURE__ */ new Set()),
|
|
4087
|
+
pairwise$1(),
|
|
4088
|
+
switchMap((pair) => {
|
|
4089
|
+
const [curr, next] = pair.map((ids) => new Set(ids)), added = Array.from(next).filter((i2) => !curr.has(i2)), removed = Array.from(curr).filter((i2) => !next.has(i2)), changes = [
|
|
4090
|
+
...added.map((id) => ({ id, add: !0 })),
|
|
4091
|
+
...removed.map((id) => ({ id, add: !1 }))
|
|
4092
|
+
].sort((a2, b2) => {
|
|
4093
|
+
const aIsDraft = a2.id === getDraftId(a2.id), bIsDraft = b2.id === getDraftId(b2.id);
|
|
4094
|
+
return aIsDraft && bIsDraft ? a2.id.localeCompare(b2.id, "en-US") : aIsDraft ? -1 : bIsDraft ? 1 : a2.id.localeCompare(b2.id, "en-US");
|
|
4095
|
+
});
|
|
4096
|
+
return of(...changes);
|
|
4097
|
+
}),
|
|
4098
|
+
groupBy$1((i2) => i2.id),
|
|
4099
|
+
mergeMap$1(
|
|
4100
|
+
(group) => group.pipe(
|
|
4101
|
+
switchMap((e3) => e3.add ? listen(context, e3.id).pipe(
|
|
4102
|
+
catchError$1((error) => {
|
|
4103
|
+
throw error instanceof OutOfSyncError && listen(context, e3.id), error;
|
|
4104
|
+
}),
|
|
4105
|
+
tap$1(
|
|
4106
|
+
(remote) => state.set(
|
|
4107
|
+
"applyRemoteDocument",
|
|
4108
|
+
(prev) => applyRemoteDocument(prev, remote, events)
|
|
4109
|
+
)
|
|
4063
4110
|
)
|
|
4064
|
-
)
|
|
4065
|
-
)
|
|
4066
|
-
|
|
4111
|
+
) : EMPTY)
|
|
4112
|
+
)
|
|
4113
|
+
)
|
|
4114
|
+
).subscribe({ error: (error) => state.set("setError", { error }) });
|
|
4115
|
+
}, subscribeToClientAndFetchDatasetAcl = ({
|
|
4116
|
+
instance,
|
|
4117
|
+
state
|
|
4118
|
+
}) => {
|
|
4119
|
+
const { projectId, dataset } = instance.config;
|
|
4120
|
+
return getClientState(instance, { apiVersion: API_VERSION$4 }).observable.pipe(
|
|
4121
|
+
switchMap(
|
|
4122
|
+
(client) => client.observable.request({
|
|
4123
|
+
uri: `/projects/${projectId}/datasets/${dataset}/acl`,
|
|
4124
|
+
tag: "acl.get",
|
|
4125
|
+
withCredentials: !0
|
|
4126
|
+
})
|
|
4127
|
+
),
|
|
4128
|
+
tap$1((datasetAcl) => state.set("setGrants", { grants: createGrantsLookup(datasetAcl) }))
|
|
4129
|
+
).subscribe({
|
|
4130
|
+
error: (error) => state.set("setError", { error })
|
|
4131
|
+
});
|
|
4132
|
+
};
|
|
4133
|
+
function applyDocumentActions(...args) {
|
|
4134
|
+
return boundApplyDocumentActions(...args);
|
|
4135
|
+
}
|
|
4136
|
+
const boundApplyDocumentActions = bindActionByDataset(documentStore, _applyDocumentActions);
|
|
4137
|
+
async function _applyDocumentActions({ instance, state }, actionOrActions, { transactionId = crypto.randomUUID(), disableBatching } = {}) {
|
|
4138
|
+
const actions = Array.isArray(actionOrActions) ? actionOrActions : [actionOrActions];
|
|
4139
|
+
let projectId, dataset;
|
|
4140
|
+
for (const action of actions)
|
|
4141
|
+
if (action.projectId) {
|
|
4142
|
+
if (projectId || (projectId = action.projectId), action.projectId !== projectId)
|
|
4143
|
+
throw new Error(
|
|
4144
|
+
`Mismatched project IDs found in actions. All actions must belong to the same project. Found "${action.projectId}" but expected "${projectId}".`
|
|
4145
|
+
);
|
|
4146
|
+
if (action.dataset && (dataset || (dataset = action.dataset), action.dataset !== dataset))
|
|
4147
|
+
throw new Error(
|
|
4148
|
+
`Mismatched datasets found in actions. All actions must belong to the same dataset. Found "${action.dataset}" but expected "${dataset}".`
|
|
4149
|
+
);
|
|
4150
|
+
}
|
|
4151
|
+
if (projectId && projectId !== instance.config.projectId || dataset && dataset !== instance.config.dataset) {
|
|
4152
|
+
const matchedInstance = instance.match({ projectId, dataset });
|
|
4153
|
+
if (!matchedInstance)
|
|
4154
|
+
throw new Error(
|
|
4155
|
+
`Could not find a matching instance for projectId: "${projectId}" and dataset: "${dataset}"`
|
|
4156
|
+
);
|
|
4157
|
+
return boundApplyDocumentActions(matchedInstance, actionOrActions, {
|
|
4158
|
+
disableBatching,
|
|
4159
|
+
transactionId
|
|
4160
|
+
});
|
|
4067
4161
|
}
|
|
4068
|
-
),
|
|
4069
|
-
|
|
4070
|
-
|
|
4071
|
-
|
|
4072
|
-
|
|
4073
|
-
|
|
4074
|
-
|
|
4075
|
-
|
|
4076
|
-
|
|
4077
|
-
|
|
4078
|
-
|
|
4079
|
-
|
|
4080
|
-
|
|
4081
|
-
|
|
4082
|
-
|
|
4162
|
+
const { events } = state.get(), transaction = {
|
|
4163
|
+
transactionId,
|
|
4164
|
+
actions,
|
|
4165
|
+
...disableBatching && { disableBatching }
|
|
4166
|
+
}, fatalError$ = state.observable.pipe(
|
|
4167
|
+
map((s2) => s2.error),
|
|
4168
|
+
first$1(Boolean),
|
|
4169
|
+
map((error) => ({ type: "error", error }))
|
|
4170
|
+
), transactionError$ = events.pipe(
|
|
4171
|
+
filter((e3) => e3.type === "error"),
|
|
4172
|
+
first$1((e3) => e3.transactionId === transactionId)
|
|
4173
|
+
), appliedTransaction$ = state.observable.pipe(
|
|
4174
|
+
map((s2) => s2.applied),
|
|
4175
|
+
distinctUntilChanged(),
|
|
4176
|
+
map((applied) => applied.find((t2) => t2.transactionId === transactionId)),
|
|
4177
|
+
first$1(Boolean)
|
|
4178
|
+
), successfulTransaction$ = events.pipe(
|
|
4179
|
+
filter((e3) => e3.type === "accepted"),
|
|
4180
|
+
first$1((e3) => e3.outgoing.batchedTransactionIds.includes(transactionId))
|
|
4181
|
+
), rejectedTransaction$ = events.pipe(
|
|
4182
|
+
filter((e3) => e3.type === "reverted"),
|
|
4183
|
+
first$1((e3) => e3.outgoing.batchedTransactionIds.includes(transactionId))
|
|
4184
|
+
), appliedTransactionOrError = firstValueFrom(
|
|
4185
|
+
race([fatalError$, transactionError$, appliedTransaction$])
|
|
4186
|
+
), acceptedOrRejectedTransaction = firstValueFrom(
|
|
4187
|
+
race([successfulTransaction$, rejectedTransaction$, transactionError$])
|
|
4188
|
+
);
|
|
4189
|
+
state.set("queueTransaction", (prev) => queueTransaction(prev, transaction));
|
|
4190
|
+
const result = await appliedTransactionOrError;
|
|
4191
|
+
if ("type" in result && result.type === "error") throw result.error;
|
|
4192
|
+
const { working: documents, previous, previousRevs } = result, existingIds = new Set(
|
|
4193
|
+
Object.entries(previous).filter(([, value]) => !!value).map(([key]) => key)
|
|
4194
|
+
), resultingIds = new Set(
|
|
4195
|
+
Object.entries(documents).filter(([, value]) => !!value).map(([key]) => key)
|
|
4196
|
+
), allIds = /* @__PURE__ */ new Set([...existingIds, ...resultingIds]), updated = [], appeared = [], disappeared = [];
|
|
4197
|
+
for (const id of allIds)
|
|
4198
|
+
existingIds.has(id) && resultingIds.has(id) ? updated.push(id) : !existingIds.has(id) && resultingIds.has(id) ? appeared.push(id) : !resultingIds.has(id) && existingIds.has(id) && disappeared.push(id);
|
|
4199
|
+
async function submitted() {
|
|
4200
|
+
const raceResult = await acceptedOrRejectedTransaction;
|
|
4201
|
+
if (raceResult.type !== "accepted") throw raceResult.error;
|
|
4202
|
+
return raceResult.result;
|
|
4203
|
+
}
|
|
4204
|
+
return {
|
|
4205
|
+
transactionId,
|
|
4206
|
+
documents,
|
|
4207
|
+
previous,
|
|
4208
|
+
previousRevs,
|
|
4209
|
+
appeared,
|
|
4210
|
+
updated,
|
|
4211
|
+
disappeared,
|
|
4212
|
+
submitted
|
|
4213
|
+
};
|
|
4214
|
+
}
|
|
4215
|
+
const QUERY_STATE_CLEAR_DELAY = 1e3, QUERY_STORE_API_VERSION = "vX", setQueryError = (key, error) => (prev) => {
|
|
4216
|
+
const prevQuery = prev.queries[key];
|
|
4217
|
+
return prevQuery ? { ...prev, queries: { ...prev.queries, [key]: { ...prevQuery, error } } } : prev;
|
|
4218
|
+
}, setQueryData = (key, result, syncTags) => (prev) => {
|
|
4219
|
+
const prevQuery = prev.queries[key];
|
|
4220
|
+
return prevQuery ? {
|
|
4221
|
+
...prev,
|
|
4222
|
+
queries: { ...prev.queries, [key]: { ...prevQuery, result: result ?? null, syncTags } }
|
|
4223
|
+
} : prev;
|
|
4224
|
+
}, setLastLiveEventId = (key, lastLiveEventId) => (prev) => {
|
|
4225
|
+
const prevQuery = prev.queries[key];
|
|
4226
|
+
return prevQuery ? { ...prev, queries: { ...prev.queries, [key]: { ...prevQuery, lastLiveEventId } } } : prev;
|
|
4227
|
+
}, addSubscriber = (key, subscriptionId) => (prev) => {
|
|
4228
|
+
const prevQuery = prev.queries[key], subscribers = [...prevQuery?.subscribers ?? [], subscriptionId];
|
|
4229
|
+
return { ...prev, queries: { ...prev.queries, [key]: { ...prevQuery, subscribers } } };
|
|
4230
|
+
}, removeSubscriber = (key, subscriptionId) => (prev) => {
|
|
4231
|
+
const prevQuery = prev.queries[key];
|
|
4232
|
+
if (!prevQuery) return prev;
|
|
4233
|
+
const subscribers = prevQuery.subscribers.filter((id) => id !== subscriptionId);
|
|
4234
|
+
return subscribers.length ? { ...prev, queries: { ...prev.queries, [key]: { ...prevQuery, subscribers } } } : { ...prev, queries: omit(prev.queries, key) };
|
|
4235
|
+
}, cancelQuery = (key) => (prev) => {
|
|
4236
|
+
const prevQuery = prev.queries[key];
|
|
4237
|
+
return !prevQuery || prevQuery.subscribers.length ? prev : { ...prev, queries: omit(prev.queries, key) };
|
|
4238
|
+
}, initializeQuery = (key) => (prev) => prev.queries[key] ? prev : { ...prev, queries: { ...prev.queries, [key]: { subscribers: [] } } }, EMPTY_ARRAY = [], getQueryKey = (query, options = {}) => JSON.stringify({ query, options }), parseQueryKey = (key) => JSON.parse(key), queryStore = {
|
|
4239
|
+
name: "QueryStore",
|
|
4240
|
+
getInitialState: () => ({ queries: {} }),
|
|
4241
|
+
initialize(context) {
|
|
4242
|
+
const subscriptions = [
|
|
4243
|
+
listenForNewSubscribersAndFetch(context),
|
|
4244
|
+
listenToLiveClientAndSetLastLiveEventIds(context)
|
|
4245
|
+
];
|
|
4246
|
+
return () => {
|
|
4247
|
+
for (const subscription of subscriptions)
|
|
4248
|
+
subscription.unsubscribe();
|
|
4083
4249
|
};
|
|
4084
4250
|
}
|
|
4085
|
-
)
|
|
4086
|
-
|
|
4087
|
-
|
|
4251
|
+
}, errorHandler$1 = (state) => (error) => state.set("setError", { error }), listenForNewSubscribersAndFetch = ({ state, instance }) => state.observable.pipe(
|
|
4252
|
+
map((s2) => new Set(Object.keys(s2.queries))),
|
|
4253
|
+
distinctUntilChanged((curr, next) => curr.size !== next.size ? !1 : Array.from(next).every((i2) => curr.has(i2))),
|
|
4254
|
+
startWith$1(/* @__PURE__ */ new Set()),
|
|
4255
|
+
pairwise$1(),
|
|
4256
|
+
mergeMap$1(([curr, next]) => {
|
|
4257
|
+
const added = Array.from(next).filter((i2) => !curr.has(i2)), removed = Array.from(curr).filter((i2) => !next.has(i2));
|
|
4258
|
+
return [
|
|
4259
|
+
...added.map((key) => ({ key, added: !0 })),
|
|
4260
|
+
...removed.map((key) => ({ key, added: !1 }))
|
|
4261
|
+
];
|
|
4262
|
+
}),
|
|
4263
|
+
groupBy$1((i2) => i2.key),
|
|
4264
|
+
mergeMap$1(
|
|
4265
|
+
(group$) => group$.pipe(
|
|
4266
|
+
switchMap((e3) => {
|
|
4267
|
+
if (!e3.added) return EMPTY;
|
|
4268
|
+
const lastLiveEventId$ = state.observable.pipe(
|
|
4269
|
+
map((s2) => s2.queries[group$.key]?.lastLiveEventId),
|
|
4270
|
+
distinctUntilChanged()
|
|
4271
|
+
), { query, options: { params, projectId, dataset, tag, ...options } = {} } = parseQueryKey(group$.key), client$ = getClientState(instance, {
|
|
4272
|
+
apiVersion: QUERY_STORE_API_VERSION,
|
|
4273
|
+
projectId,
|
|
4274
|
+
dataset
|
|
4275
|
+
}).observable;
|
|
4276
|
+
return combineLatest([lastLiveEventId$, client$]).pipe(
|
|
4277
|
+
switchMap(
|
|
4278
|
+
([lastLiveEventId, client]) => client.observable.fetch(query, params, {
|
|
4279
|
+
...options,
|
|
4280
|
+
filterResponse: !1,
|
|
4281
|
+
returnQuery: !1,
|
|
4282
|
+
lastLiveEventId,
|
|
4283
|
+
tag
|
|
4284
|
+
})
|
|
4285
|
+
)
|
|
4286
|
+
);
|
|
4287
|
+
}),
|
|
4288
|
+
catchError$1((error) => (state.set("setQueryError", setQueryError(group$.key, error)), EMPTY)),
|
|
4289
|
+
tap$1(({ result, syncTags }) => {
|
|
4290
|
+
state.set("setQueryData", setQueryData(group$.key, result, syncTags));
|
|
4291
|
+
})
|
|
4292
|
+
)
|
|
4293
|
+
)
|
|
4294
|
+
).subscribe({ error: errorHandler$1(state) }), listenToLiveClientAndSetLastLiveEventIds = ({
|
|
4295
|
+
state,
|
|
4296
|
+
instance
|
|
4297
|
+
}) => {
|
|
4298
|
+
const liveMessages$ = getClientState(instance, {
|
|
4299
|
+
apiVersion: QUERY_STORE_API_VERSION
|
|
4300
|
+
}).observable.pipe(
|
|
4301
|
+
switchMap(
|
|
4302
|
+
(client) => client.live.events({ includeDrafts: !!client.config().token, tag: "query-store" })
|
|
4303
|
+
),
|
|
4304
|
+
share(),
|
|
4305
|
+
filter((e3) => e3.type === "message")
|
|
4306
|
+
);
|
|
4307
|
+
return state.observable.pipe(
|
|
4308
|
+
mergeMap$1((s2) => Object.entries(s2.queries)),
|
|
4309
|
+
groupBy$1(([key]) => key),
|
|
4310
|
+
mergeMap$1((group$) => {
|
|
4311
|
+
const syncTags$ = group$.pipe(
|
|
4312
|
+
map(([, queryState]) => queryState),
|
|
4313
|
+
map((i2) => i2?.syncTags ?? EMPTY_ARRAY),
|
|
4314
|
+
distinctUntilChanged()
|
|
4315
|
+
);
|
|
4316
|
+
return combineLatest([liveMessages$, syncTags$]).pipe(
|
|
4317
|
+
filter(([message, syncTags]) => message.tags.some((tag) => syncTags.includes(tag))),
|
|
4318
|
+
tap$1(([message]) => {
|
|
4319
|
+
state.set("setLastLiveEventId", setLastLiveEventId(group$.key, message.id));
|
|
4320
|
+
})
|
|
4321
|
+
);
|
|
4322
|
+
})
|
|
4323
|
+
).subscribe({ error: errorHandler$1(state) });
|
|
4324
|
+
};
|
|
4325
|
+
function getQueryState(...args) {
|
|
4326
|
+
return _getQueryState(...args);
|
|
4088
4327
|
}
|
|
4089
|
-
const
|
|
4090
|
-
|
|
4091
|
-
|
|
4092
|
-
|
|
4093
|
-
|
|
4094
|
-
|
|
4095
|
-
|
|
4096
|
-
|
|
4097
|
-
|
|
4098
|
-
|
|
4099
|
-
|
|
4100
|
-
|
|
4101
|
-
|
|
4102
|
-
|
|
4103
|
-
|
|
4104
|
-
|
|
4105
|
-
|
|
4106
|
-
map((applied) => applied.find((t2) => t2.transactionId === transactionId)),
|
|
4107
|
-
first$1(Boolean)
|
|
4108
|
-
), successfulTransaction$ = events.pipe(
|
|
4109
|
-
filter((e3) => e3.type === "accepted"),
|
|
4110
|
-
first$1((e3) => e3.outgoing.batchedTransactionIds.includes(transactionId))
|
|
4111
|
-
), rejectedTransaction$ = events.pipe(
|
|
4112
|
-
filter((e3) => e3.type === "reverted"),
|
|
4113
|
-
first$1((e3) => e3.outgoing.batchedTransactionIds.includes(transactionId))
|
|
4114
|
-
), appliedTransactionOrError = firstValueFrom(
|
|
4115
|
-
race([fatalError$, transactionError$, appliedTransaction$])
|
|
4116
|
-
), acceptedOrRejectedTransaction = firstValueFrom(
|
|
4117
|
-
race([successfulTransaction$, rejectedTransaction$, transactionError$])
|
|
4118
|
-
);
|
|
4119
|
-
state.set("queueTransaction", (prev) => queueTransaction(prev, transaction));
|
|
4120
|
-
const result = await appliedTransactionOrError;
|
|
4121
|
-
if ("type" in result && result.type === "error") throw result.error;
|
|
4122
|
-
const { working: documents, previous, previousRevs } = result, existingIds = new Set(
|
|
4123
|
-
Object.entries(previous).filter(([, value]) => !!value).map(([key]) => key)
|
|
4124
|
-
), resultingIds = new Set(
|
|
4125
|
-
Object.entries(documents).filter(([, value]) => !!value).map(([key]) => key)
|
|
4126
|
-
), allIds = /* @__PURE__ */ new Set([...existingIds, ...resultingIds]), updated = [], appeared = [], disappeared = [];
|
|
4127
|
-
for (const id of allIds)
|
|
4128
|
-
existingIds.has(id) && resultingIds.has(id) ? updated.push(id) : !existingIds.has(id) && resultingIds.has(id) ? appeared.push(id) : !resultingIds.has(id) && existingIds.has(id) && disappeared.push(id);
|
|
4129
|
-
async function submitted() {
|
|
4130
|
-
const raceResult = await acceptedOrRejectedTransaction;
|
|
4131
|
-
if (raceResult.type !== "accepted") throw raceResult.error;
|
|
4132
|
-
return raceResult.result;
|
|
4328
|
+
const _getQueryState = bindActionByDataset(
|
|
4329
|
+
queryStore,
|
|
4330
|
+
createStateSourceAction({
|
|
4331
|
+
selector: ({ state }, query, options) => {
|
|
4332
|
+
if (state.error) throw state.error;
|
|
4333
|
+
const key = getQueryKey(query, options), queryState = state.queries[key];
|
|
4334
|
+
if (queryState?.error) throw queryState.error;
|
|
4335
|
+
return queryState?.result;
|
|
4336
|
+
},
|
|
4337
|
+
onSubscribe: ({ state }, query, options) => {
|
|
4338
|
+
const subscriptionId = insecureRandomId(), key = getQueryKey(query, options);
|
|
4339
|
+
return state.set("addSubscriber", addSubscriber(key, subscriptionId)), () => {
|
|
4340
|
+
setTimeout(
|
|
4341
|
+
() => state.set("removeSubscriber", removeSubscriber(key, subscriptionId)),
|
|
4342
|
+
QUERY_STATE_CLEAR_DELAY
|
|
4343
|
+
);
|
|
4344
|
+
};
|
|
4133
4345
|
}
|
|
4134
|
-
|
|
4135
|
-
|
|
4136
|
-
|
|
4137
|
-
|
|
4138
|
-
previousRevs,
|
|
4139
|
-
appeared,
|
|
4140
|
-
updated,
|
|
4141
|
-
disappeared,
|
|
4142
|
-
submitted
|
|
4143
|
-
};
|
|
4144
|
-
};
|
|
4145
|
-
});
|
|
4146
|
-
function getSdkIdentity({
|
|
4147
|
-
projectId,
|
|
4148
|
-
dataset
|
|
4149
|
-
}) {
|
|
4150
|
-
const id = generateId();
|
|
4151
|
-
return Object.freeze({
|
|
4152
|
-
id,
|
|
4153
|
-
projectId,
|
|
4154
|
-
dataset,
|
|
4155
|
-
resourceId: `${projectId}.${dataset}`
|
|
4156
|
-
});
|
|
4157
|
-
}
|
|
4158
|
-
function generateId() {
|
|
4159
|
-
return Array.from(
|
|
4160
|
-
{ length: 8 },
|
|
4161
|
-
() => Math.floor(Math.random() * 16).toString(16).padStart(2, "0")
|
|
4162
|
-
).join("");
|
|
4163
|
-
}
|
|
4164
|
-
function createSanityInstance({
|
|
4165
|
-
projectId = "",
|
|
4166
|
-
dataset = "",
|
|
4167
|
-
...config
|
|
4168
|
-
}) {
|
|
4169
|
-
const identity = getSdkIdentity({ projectId, dataset });
|
|
4170
|
-
return {
|
|
4171
|
-
identity,
|
|
4172
|
-
config,
|
|
4173
|
-
dispose: () => disposeResources(identity)
|
|
4174
|
-
};
|
|
4346
|
+
})
|
|
4347
|
+
);
|
|
4348
|
+
function resolveQuery(...args) {
|
|
4349
|
+
return _resolveQuery(...args);
|
|
4175
4350
|
}
|
|
4176
|
-
|
|
4177
|
-
|
|
4178
|
-
|
|
4179
|
-
|
|
4180
|
-
|
|
4351
|
+
const _resolveQuery = bindActionByDataset(
|
|
4352
|
+
queryStore,
|
|
4353
|
+
({ state, instance }, query, { signal, ...options } = {}) => {
|
|
4354
|
+
const { getCurrent } = getQueryState(instance, query, options), key = getQueryKey(query, options), aborted$ = signal ? new Observable((observer) => {
|
|
4355
|
+
const cleanup = () => {
|
|
4356
|
+
signal.removeEventListener("abort", listener);
|
|
4357
|
+
}, listener = () => {
|
|
4358
|
+
observer.error(new DOMException("The operation was aborted.", "AbortError")), observer.complete(), cleanup();
|
|
4359
|
+
};
|
|
4360
|
+
return signal.addEventListener("abort", listener), cleanup;
|
|
4361
|
+
}).pipe(
|
|
4362
|
+
catchError$1((error) => {
|
|
4363
|
+
throw error instanceof Error && error.name === "AbortError" && state.set("cancelQuery", cancelQuery(key)), error;
|
|
4364
|
+
})
|
|
4365
|
+
) : NEVER;
|
|
4366
|
+
state.set("initializeQuery", initializeQuery(key));
|
|
4367
|
+
const resolved$ = state.observable.pipe(
|
|
4368
|
+
map(getCurrent),
|
|
4369
|
+
first$1((i2) => i2 !== void 0)
|
|
4181
4370
|
);
|
|
4182
|
-
return
|
|
4183
|
-
|
|
4184
|
-
|
|
4185
|
-
(client) => client.live.events({ includeDrafts: !!client.config().token, tag }).pipe(filter((e3) => e3.type === "message"))
|
|
4186
|
-
)
|
|
4187
|
-
);
|
|
4188
|
-
return combineLatest([messageEvents$, syncTags$]).subscribe({
|
|
4189
|
-
next: ([event, currentSyncTags]) => {
|
|
4190
|
-
for (const eventTag of event.tags)
|
|
4191
|
-
if (currentSyncTags[eventTag]) {
|
|
4192
|
-
state.set("setLastLiveEventId", (prevState) => ({
|
|
4193
|
-
...prevState,
|
|
4194
|
-
lastLiveEventId: event.id
|
|
4195
|
-
}));
|
|
4196
|
-
return;
|
|
4197
|
-
}
|
|
4198
|
-
}
|
|
4199
|
-
});
|
|
4200
|
-
};
|
|
4201
|
-
});
|
|
4202
|
-
}
|
|
4371
|
+
return firstValueFrom(race([resolved$, aborted$]));
|
|
4372
|
+
}
|
|
4373
|
+
);
|
|
4203
4374
|
function hashString(str) {
|
|
4204
4375
|
let hash = 0;
|
|
4205
4376
|
for (let i2 = 0; i2 < str.length; i2++)
|
|
4206
4377
|
hash = (hash * 31 + str.charCodeAt(i2)) % 2147483647;
|
|
4207
4378
|
return Math.abs(hash).toString(16).padStart(8, "0");
|
|
4208
4379
|
}
|
|
4209
|
-
const TITLE_CANDIDATES = ["title", "name", "label", "heading", "header", "caption"], SUBTITLE_CANDIDATES = ["description", "subtitle", ...TITLE_CANDIDATES]
|
|
4210
|
-
|
|
4211
|
-
|
|
4212
|
-
|
|
4213
|
-
"titleCandidates": {
|
|
4214
|
-
${TITLE_CANDIDATES.map((field) => `"${field}": ${field}`).join(`,
|
|
4380
|
+
const TITLE_CANDIDATES = ["title", "name", "label", "heading", "header", "caption"], SUBTITLE_CANDIDATES = ["description", "subtitle", ...TITLE_CANDIDATES], PREVIEW_PROJECTION = `{
|
|
4381
|
+
// Get all potential title fields
|
|
4382
|
+
"titleCandidates": {
|
|
4383
|
+
${TITLE_CANDIDATES.map((field) => `"${field}": ${field}`).join(`,
|
|
4215
4384
|
`)}
|
|
4216
|
-
|
|
4217
|
-
|
|
4218
|
-
|
|
4219
|
-
|
|
4385
|
+
},
|
|
4386
|
+
// Get all potential subtitle fields
|
|
4387
|
+
"subtitleCandidates": {
|
|
4388
|
+
${SUBTITLE_CANDIDATES.map((field) => `"${field}": ${field}`).join(`,
|
|
4220
4389
|
`)}
|
|
4221
|
-
|
|
4222
|
-
|
|
4223
|
-
|
|
4224
|
-
|
|
4225
|
-
|
|
4226
|
-
|
|
4227
|
-
|
|
4228
|
-
|
|
4229
|
-
|
|
4230
|
-
|
|
4231
|
-
|
|
4232
|
-
|
|
4233
|
-
|
|
4234
|
-
}
|
|
4235
|
-
const PREVIEW_TAG = "preview", STABLE_EMPTY_PREVIEW = { data: null, isPending: !1 }, STABLE_ERROR_PREVIEW = {
|
|
4390
|
+
},
|
|
4391
|
+
"media": coalesce(
|
|
4392
|
+
select(
|
|
4393
|
+
defined(asset) => {"type": "image-asset", "_ref": asset._ref},
|
|
4394
|
+
defined(image.asset) => {"type": "image-asset", "_ref": image.asset._ref},
|
|
4395
|
+
defined(mainImage.asset) => {"type": "image-asset", "_ref": mainImage.asset._ref},
|
|
4396
|
+
null
|
|
4397
|
+
)
|
|
4398
|
+
),
|
|
4399
|
+
_type,
|
|
4400
|
+
_id,
|
|
4401
|
+
_updatedAt
|
|
4402
|
+
}`, PREVIEW_TAG = "preview", PREVIEW_PERSPECTIVE = "drafts", STABLE_EMPTY_PREVIEW = { data: null, isPending: !1 }, STABLE_ERROR_PREVIEW = {
|
|
4236
4403
|
data: {
|
|
4237
4404
|
title: "Preview Error",
|
|
4238
4405
|
...!!getEnv("DEV") && { subtitle: "Check the console for more details" }
|
|
@@ -4296,104 +4463,92 @@ function processPreviewQuery({
|
|
|
4296
4463
|
);
|
|
4297
4464
|
}
|
|
4298
4465
|
function createPreviewQuery(documentIds) {
|
|
4299
|
-
const allIds = Array.from(documentIds).flatMap((id) => [getPublishedId(id), getDraftId(id)]),
|
|
4466
|
+
const allIds = Array.from(documentIds).flatMap((id) => [getPublishedId(id), getDraftId(id)]), queryHash = hashString(PREVIEW_PROJECTION);
|
|
4300
4467
|
return {
|
|
4301
|
-
query: `*[_id in $__ids_${queryHash}]${
|
|
4468
|
+
query: `*[_id in $__ids_${queryHash}]${PREVIEW_PROJECTION}`,
|
|
4302
4469
|
params: {
|
|
4303
4470
|
[`__ids_${queryHash}`]: allIds
|
|
4304
4471
|
}
|
|
4305
4472
|
};
|
|
4306
4473
|
}
|
|
4307
|
-
const BATCH_DEBOUNCE_TIME$1 = 50, subscribeToStateAndFetchBatches$1 =
|
|
4308
|
-
|
|
4309
|
-
|
|
4310
|
-
|
|
4311
|
-
|
|
4312
|
-
|
|
4313
|
-
|
|
4314
|
-
|
|
4315
|
-
|
|
4316
|
-
|
|
4317
|
-
|
|
4318
|
-
|
|
4319
|
-
)
|
|
4320
|
-
|
|
4321
|
-
|
|
4322
|
-
|
|
4323
|
-
|
|
4324
|
-
|
|
4325
|
-
|
|
4326
|
-
|
|
4327
|
-
|
|
4328
|
-
|
|
4329
|
-
|
|
4330
|
-
|
|
4331
|
-
|
|
4332
|
-
|
|
4333
|
-
|
|
4334
|
-
|
|
4335
|
-
|
|
4336
|
-
|
|
4337
|
-
|
|
4338
|
-
|
|
4339
|
-
|
|
4340
|
-
return client.observable.fetch(query, params, {
|
|
4341
|
-
filterResponse: !1,
|
|
4342
|
-
returnQuery: !1,
|
|
4343
|
-
perspective: "drafts",
|
|
4474
|
+
const BATCH_DEBOUNCE_TIME$1 = 50, isSetEqual$1 = (a2, b2) => a2.size === b2.size && Array.from(a2).every((i2) => b2.has(i2)), subscribeToStateAndFetchBatches$1 = ({
|
|
4475
|
+
state,
|
|
4476
|
+
instance
|
|
4477
|
+
}) => state.observable.pipe(
|
|
4478
|
+
map(({ subscriptions }) => new Set(Object.keys(subscriptions))),
|
|
4479
|
+
distinctUntilChanged(isSetEqual$1),
|
|
4480
|
+
debounceTime(BATCH_DEBOUNCE_TIME$1),
|
|
4481
|
+
startWith$1(/* @__PURE__ */ new Set()),
|
|
4482
|
+
pairwise$1(),
|
|
4483
|
+
tap$1(([prevIds, currIds]) => {
|
|
4484
|
+
const newIds = [...currIds].filter((element) => !prevIds.has(element));
|
|
4485
|
+
state.set("updatingPending", (prev) => {
|
|
4486
|
+
const pendingValues = newIds.reduce((acc, id) => {
|
|
4487
|
+
const prevValue = prev.values[id], value = prevValue?.data ? prevValue.data : null;
|
|
4488
|
+
return acc[id] = { data: value, isPending: !0 }, acc;
|
|
4489
|
+
}, {});
|
|
4490
|
+
return { values: { ...prev.values, ...pendingValues } };
|
|
4491
|
+
});
|
|
4492
|
+
}),
|
|
4493
|
+
map(([, ids]) => ids),
|
|
4494
|
+
distinctUntilChanged(isSetEqual$1)
|
|
4495
|
+
).pipe(
|
|
4496
|
+
switchMap((ids) => {
|
|
4497
|
+
if (!ids.size) return EMPTY;
|
|
4498
|
+
const { query, params } = createPreviewQuery(ids), controller = new AbortController();
|
|
4499
|
+
return new Observable((observer) => {
|
|
4500
|
+
const { getCurrent, observable } = getQueryState(instance, query, {
|
|
4501
|
+
params,
|
|
4502
|
+
tag: PREVIEW_TAG,
|
|
4503
|
+
perspective: PREVIEW_PERSPECTIVE
|
|
4504
|
+
}), subscription = defer(() => getCurrent() === void 0 ? from(
|
|
4505
|
+
resolveQuery(instance, query, {
|
|
4506
|
+
params,
|
|
4344
4507
|
tag: PREVIEW_TAG,
|
|
4345
|
-
|
|
4346
|
-
|
|
4347
|
-
}),
|
|
4348
|
-
map(({ ids, result, syncTags }) => ({
|
|
4349
|
-
syncTags,
|
|
4350
|
-
values: processPreviewQuery({
|
|
4351
|
-
projectId: instance.identity.projectId,
|
|
4352
|
-
dataset: instance.identity.dataset,
|
|
4353
|
-
ids,
|
|
4354
|
-
results: result
|
|
4508
|
+
perspective: PREVIEW_PERSPECTIVE,
|
|
4509
|
+
signal: controller.signal
|
|
4355
4510
|
})
|
|
4356
|
-
|
|
4357
|
-
|
|
4358
|
-
|
|
4359
|
-
|
|
4360
|
-
|
|
4361
|
-
|
|
4362
|
-
|
|
4363
|
-
|
|
4364
|
-
|
|
4511
|
+
).pipe(switchMap(() => observable)) : observable).pipe(filter((result) => result !== void 0)).subscribe(observer);
|
|
4512
|
+
return () => {
|
|
4513
|
+
controller.signal.aborted || controller.abort(), subscription.unsubscribe();
|
|
4514
|
+
};
|
|
4515
|
+
}).pipe(map((data) => ({ data, ids })));
|
|
4516
|
+
}),
|
|
4517
|
+
map(({ ids, data }) => ({
|
|
4518
|
+
values: processPreviewQuery({
|
|
4519
|
+
projectId: instance.config.projectId,
|
|
4520
|
+
dataset: instance.config.dataset,
|
|
4521
|
+
ids,
|
|
4522
|
+
results: data
|
|
4523
|
+
})
|
|
4524
|
+
}))
|
|
4525
|
+
).subscribe({
|
|
4526
|
+
next: ({ values }) => {
|
|
4527
|
+
state.set("updateResult", (prev) => ({ values: { ...prev.values, ...values } }));
|
|
4365
4528
|
}
|
|
4366
|
-
), previewStore = {
|
|
4529
|
+
}), previewStore = {
|
|
4367
4530
|
name: "Preview",
|
|
4368
4531
|
getInitialState() {
|
|
4369
4532
|
return {
|
|
4370
|
-
documentTypes: {},
|
|
4371
|
-
lastLiveEventId: null,
|
|
4372
4533
|
subscriptions: {},
|
|
4373
|
-
syncTags: {},
|
|
4374
4534
|
values: {}
|
|
4375
4535
|
};
|
|
4376
4536
|
},
|
|
4377
|
-
initialize() {
|
|
4378
|
-
const
|
|
4379
|
-
return () =>
|
|
4380
|
-
stateSubscriptionForBatches.unsubscribe(), liveSubscription.unsubscribe();
|
|
4381
|
-
};
|
|
4537
|
+
initialize: (context) => {
|
|
4538
|
+
const subscription = subscribeToStateAndFetchBatches$1(context);
|
|
4539
|
+
return () => subscription.unsubscribe;
|
|
4382
4540
|
}
|
|
4383
|
-
}
|
|
4541
|
+
};
|
|
4542
|
+
function getPreviewState(...args) {
|
|
4543
|
+
return _getPreviewState(...args);
|
|
4544
|
+
}
|
|
4545
|
+
const _getPreviewState = bindActionByDataset(
|
|
4384
4546
|
previewStore,
|
|
4385
|
-
(
|
|
4386
|
-
|
|
4387
|
-
|
|
4388
|
-
|
|
4389
|
-
|
|
4390
|
-
subscribe: (subscriber) => {
|
|
4391
|
-
const subscriptionId = insecureRandomId();
|
|
4392
|
-
state.set("addSubscription", (prev) => ({
|
|
4393
|
-
documentTypes: {
|
|
4394
|
-
...prev.documentTypes,
|
|
4395
|
-
[documentId]: documentType
|
|
4396
|
-
},
|
|
4547
|
+
createStateSourceAction({
|
|
4548
|
+
selector: ({ state }, docHandle) => state.values[docHandle.documentId] ?? STABLE_EMPTY_PREVIEW,
|
|
4549
|
+
onSubscribe: ({ state }, docHandle) => {
|
|
4550
|
+
const subscriptionId = insecureRandomId(), documentId = getPublishedId(docHandle.documentId);
|
|
4551
|
+
return state.set("addSubscription", (prev) => ({
|
|
4397
4552
|
subscriptions: {
|
|
4398
4553
|
...prev.subscriptions,
|
|
4399
4554
|
[documentId]: {
|
|
@@ -4401,10 +4556,8 @@ const BATCH_DEBOUNCE_TIME$1 = 50, subscribeToStateAndFetchBatches$1 = createInte
|
|
|
4401
4556
|
[subscriptionId]: !0
|
|
4402
4557
|
}
|
|
4403
4558
|
}
|
|
4404
|
-
}))
|
|
4405
|
-
|
|
4406
|
-
return () => {
|
|
4407
|
-
unsubscribe(), state.set("removeSubscription", (prev) => {
|
|
4559
|
+
})), () => {
|
|
4560
|
+
state.set("removeSubscription", (prev) => {
|
|
4408
4561
|
const documentSubscriptions = omit(prev.subscriptions[documentId], subscriptionId), hasSubscribers = !!Object.keys(documentSubscriptions).length, prevValue = prev.values[documentId], previewValue = prevValue?.data ? prevValue.data : null;
|
|
4409
4562
|
return {
|
|
4410
4563
|
subscriptions: hasSubscribers ? { ...prev.subscriptions, [documentId]: documentSubscriptions } : omit(prev.subscriptions, documentId),
|
|
@@ -4413,22 +4566,34 @@ const BATCH_DEBOUNCE_TIME$1 = 50, subscribeToStateAndFetchBatches$1 = createInte
|
|
|
4413
4566
|
});
|
|
4414
4567
|
};
|
|
4415
4568
|
}
|
|
4416
|
-
}
|
|
4417
|
-
|
|
4418
|
-
|
|
4419
|
-
|
|
4420
|
-
|
|
4421
|
-
const current = getCurrent();
|
|
4422
|
-
current?.data && (resolve(current), unsubscribe());
|
|
4423
|
-
});
|
|
4424
|
-
});
|
|
4425
|
-
}), project = createFetcherStore({
|
|
4569
|
+
})
|
|
4570
|
+
), resolvePreview = bindActionByDataset(
|
|
4571
|
+
previewStore,
|
|
4572
|
+
({ instance }, docHandle) => firstValueFrom(getPreviewState(instance, docHandle).observable.pipe(filter((i2) => !!i2.data)))
|
|
4573
|
+
), API_VERSION$2 = "v2025-02-19", project = createFetcherStore({
|
|
4426
4574
|
name: "Project",
|
|
4427
|
-
getKey: (
|
|
4428
|
-
|
|
4429
|
-
|
|
4430
|
-
|
|
4431
|
-
|
|
4575
|
+
getKey: (instance, options) => {
|
|
4576
|
+
const projectId = options?.projectId ?? instance.config.projectId;
|
|
4577
|
+
if (!projectId)
|
|
4578
|
+
throw new Error("A projectId is required to use the project API.");
|
|
4579
|
+
return projectId;
|
|
4580
|
+
},
|
|
4581
|
+
fetcher: (instance) => (options = {}) => {
|
|
4582
|
+
const projectId = options.projectId ?? instance.config.projectId;
|
|
4583
|
+
return getClientState(instance, {
|
|
4584
|
+
apiVersion: API_VERSION$2,
|
|
4585
|
+
scope: "global",
|
|
4586
|
+
projectId
|
|
4587
|
+
}).observable.pipe(
|
|
4588
|
+
switchMap(
|
|
4589
|
+
(client) => client.observable.projects.getById(
|
|
4590
|
+
// non-null assertion is fine with the above throwing
|
|
4591
|
+
projectId ?? instance.config.projectId
|
|
4592
|
+
)
|
|
4593
|
+
)
|
|
4594
|
+
);
|
|
4595
|
+
}
|
|
4596
|
+
}), getProjectState = project.getState, resolveProject = project.resolveState, PROJECTION_TAG = "sdk.projection", PROJECTION_PERSPECTIVE = "drafts", PROJECTION_STATE_CLEAR_DELAY = 1e3, STABLE_EMPTY_PROJECTION = {
|
|
4432
4597
|
data: null,
|
|
4433
4598
|
isPending: !1
|
|
4434
4599
|
};
|
|
@@ -4474,99 +4639,92 @@ function processProjectionQuery({ ids, results }) {
|
|
|
4474
4639
|
})
|
|
4475
4640
|
);
|
|
4476
4641
|
}
|
|
4477
|
-
const BATCH_DEBOUNCE_TIME = 50, subscribeToStateAndFetchBatches =
|
|
4478
|
-
|
|
4479
|
-
|
|
4480
|
-
|
|
4481
|
-
|
|
4482
|
-
|
|
4483
|
-
|
|
4484
|
-
|
|
4485
|
-
|
|
4486
|
-
|
|
4487
|
-
),
|
|
4488
|
-
|
|
4489
|
-
|
|
4490
|
-
|
|
4491
|
-
)
|
|
4492
|
-
|
|
4493
|
-
|
|
4494
|
-
|
|
4495
|
-
|
|
4496
|
-
|
|
4497
|
-
|
|
4498
|
-
|
|
4499
|
-
|
|
4500
|
-
|
|
4501
|
-
|
|
4502
|
-
|
|
4503
|
-
|
|
4504
|
-
|
|
4505
|
-
|
|
4506
|
-
|
|
4507
|
-
|
|
4508
|
-
|
|
4509
|
-
|
|
4510
|
-
|
|
4511
|
-
const { query, params } = createProjectionQuery(ids, documentProjections);
|
|
4512
|
-
return client.observable.fetch(query, params, {
|
|
4513
|
-
filterResponse: !1,
|
|
4514
|
-
returnQuery: !1,
|
|
4515
|
-
perspective: "drafts",
|
|
4642
|
+
const BATCH_DEBOUNCE_TIME = 50, isSetEqual = (a2, b2) => a2.size === b2.size && Array.from(a2).every((i2) => b2.has(i2)), subscribeToStateAndFetchBatches = ({
|
|
4643
|
+
state,
|
|
4644
|
+
instance
|
|
4645
|
+
}) => {
|
|
4646
|
+
const documentProjections$ = state.observable.pipe(
|
|
4647
|
+
map((i2) => i2.documentProjections),
|
|
4648
|
+
distinctUntilChanged()
|
|
4649
|
+
), newSubscriberIds$ = state.observable.pipe(
|
|
4650
|
+
map(({ subscriptions }) => new Set(Object.keys(subscriptions))),
|
|
4651
|
+
distinctUntilChanged(isSetEqual),
|
|
4652
|
+
debounceTime(BATCH_DEBOUNCE_TIME),
|
|
4653
|
+
startWith$1(/* @__PURE__ */ new Set()),
|
|
4654
|
+
pairwise$1(),
|
|
4655
|
+
tap$1(([prevIds, currIds]) => {
|
|
4656
|
+
const newIds = [...currIds].filter((element) => !prevIds.has(element));
|
|
4657
|
+
state.set("updatingPending", (prev) => {
|
|
4658
|
+
const pendingValues = newIds.reduce((acc, id) => {
|
|
4659
|
+
const prevValue = prev.values[id], value = prevValue?.data ? prevValue.data : null;
|
|
4660
|
+
return acc[id] = { data: value, isPending: !0 }, acc;
|
|
4661
|
+
}, {});
|
|
4662
|
+
return { values: { ...prev.values, ...pendingValues } };
|
|
4663
|
+
});
|
|
4664
|
+
}),
|
|
4665
|
+
map(([, ids]) => ids),
|
|
4666
|
+
distinctUntilChanged(isSetEqual)
|
|
4667
|
+
);
|
|
4668
|
+
return combineLatest([newSubscriberIds$, documentProjections$]).pipe(
|
|
4669
|
+
distinctUntilChanged(isEqual),
|
|
4670
|
+
switchMap(([ids, documentProjections]) => {
|
|
4671
|
+
if (!ids.size) return EMPTY;
|
|
4672
|
+
const { query, params } = createProjectionQuery(ids, documentProjections), controller = new AbortController();
|
|
4673
|
+
return new Observable((observer) => {
|
|
4674
|
+
const { getCurrent, observable } = getQueryState(instance, query, {
|
|
4675
|
+
params,
|
|
4516
4676
|
tag: PROJECTION_TAG,
|
|
4517
|
-
|
|
4518
|
-
})
|
|
4519
|
-
|
|
4520
|
-
|
|
4521
|
-
|
|
4522
|
-
|
|
4523
|
-
|
|
4524
|
-
|
|
4525
|
-
|
|
4526
|
-
|
|
4527
|
-
|
|
4528
|
-
|
|
4529
|
-
|
|
4530
|
-
|
|
4531
|
-
|
|
4532
|
-
|
|
4533
|
-
|
|
4534
|
-
|
|
4535
|
-
|
|
4536
|
-
)
|
|
4677
|
+
perspective: PROJECTION_PERSPECTIVE
|
|
4678
|
+
}), subscription = defer(() => getCurrent() === void 0 ? from(
|
|
4679
|
+
resolveQuery(instance, query, {
|
|
4680
|
+
params,
|
|
4681
|
+
tag: PROJECTION_TAG,
|
|
4682
|
+
perspective: PROJECTION_PERSPECTIVE,
|
|
4683
|
+
signal: controller.signal
|
|
4684
|
+
})
|
|
4685
|
+
).pipe(switchMap(() => observable)) : observable).pipe(filter((result) => result !== void 0)).subscribe(observer);
|
|
4686
|
+
return () => {
|
|
4687
|
+
controller.signal.aborted || controller.abort(), subscription.unsubscribe();
|
|
4688
|
+
};
|
|
4689
|
+
}).pipe(map((data) => ({ data, ids })));
|
|
4690
|
+
}),
|
|
4691
|
+
map(({ ids, data }) => ({
|
|
4692
|
+
values: processProjectionQuery({
|
|
4693
|
+
ids,
|
|
4694
|
+
results: data
|
|
4695
|
+
})
|
|
4696
|
+
}))
|
|
4697
|
+
).subscribe({
|
|
4698
|
+
next: ({ values }) => {
|
|
4699
|
+
state.set("updateResult", (prev) => ({
|
|
4700
|
+
values: { ...prev.values, ...values }
|
|
4701
|
+
}));
|
|
4702
|
+
}
|
|
4703
|
+
});
|
|
4704
|
+
}, projectionStore = {
|
|
4537
4705
|
name: "Projection",
|
|
4538
4706
|
getInitialState() {
|
|
4539
4707
|
return {
|
|
4540
4708
|
values: {},
|
|
4541
4709
|
documentProjections: {},
|
|
4542
|
-
subscriptions: {}
|
|
4543
|
-
syncTags: {},
|
|
4544
|
-
lastLiveEventId: null
|
|
4710
|
+
subscriptions: {}
|
|
4545
4711
|
};
|
|
4546
4712
|
},
|
|
4547
|
-
initialize() {
|
|
4548
|
-
const
|
|
4549
|
-
return () =>
|
|
4550
|
-
liveSubscription.unsubscribe(), batchSubscription.unsubscribe();
|
|
4551
|
-
};
|
|
4713
|
+
initialize(context) {
|
|
4714
|
+
const batchSubscription = subscribeToStateAndFetchBatches(context);
|
|
4715
|
+
return () => batchSubscription.unsubscribe();
|
|
4552
4716
|
}
|
|
4553
|
-
}
|
|
4554
|
-
projectionStore,
|
|
4555
|
-
(state, { document }) => state.values[document._id] ?? STABLE_EMPTY_PROJECTION
|
|
4556
|
-
);
|
|
4717
|
+
};
|
|
4557
4718
|
function getProjectionState(...args) {
|
|
4558
4719
|
return _getProjectionState(...args);
|
|
4559
4720
|
}
|
|
4560
|
-
const _getProjectionState =
|
|
4561
|
-
|
|
4562
|
-
|
|
4563
|
-
})
|
|
4564
|
-
|
|
4565
|
-
|
|
4566
|
-
|
|
4567
|
-
subscribe: (subscriber) => {
|
|
4568
|
-
const subscriptionId = insecureRandomId();
|
|
4569
|
-
state.set("addSubscription", (prev) => ({
|
|
4721
|
+
const _getProjectionState = bindActionByDataset(
|
|
4722
|
+
projectionStore,
|
|
4723
|
+
createStateSourceAction({
|
|
4724
|
+
selector: ({ state }, options) => state.values[options.documentId] ?? STABLE_EMPTY_PROJECTION,
|
|
4725
|
+
onSubscribe: ({ state }, { projection, ...docHandle }) => {
|
|
4726
|
+
const subscriptionId = insecureRandomId(), documentId = getPublishedId(docHandle.documentId);
|
|
4727
|
+
return state.set("addSubscription", (prev) => ({
|
|
4570
4728
|
documentProjections: {
|
|
4571
4729
|
...prev.documentProjections,
|
|
4572
4730
|
[documentId]: validateProjection(projection)
|
|
@@ -4578,275 +4736,180 @@ const _getProjectionState = createAction(projectionStore, ({ state }) => functio
|
|
|
4578
4736
|
[subscriptionId]: !0
|
|
4579
4737
|
}
|
|
4580
4738
|
}
|
|
4581
|
-
}))
|
|
4582
|
-
|
|
4583
|
-
|
|
4584
|
-
|
|
4585
|
-
|
|
4586
|
-
|
|
4587
|
-
|
|
4588
|
-
|
|
4589
|
-
};
|
|
4590
|
-
});
|
|
4739
|
+
})), () => {
|
|
4740
|
+
setTimeout(() => {
|
|
4741
|
+
state.set("removeSubscription", (prev) => {
|
|
4742
|
+
const documentSubscriptions = omit(prev.subscriptions[documentId], subscriptionId), hasSubscribers = !!Object.keys(documentSubscriptions).length, prevValue = prev.values[documentId], projectionValue = prevValue?.data ? prevValue.data : null;
|
|
4743
|
+
return {
|
|
4744
|
+
subscriptions: hasSubscribers ? { ...prev.subscriptions, [documentId]: documentSubscriptions } : omit(prev.subscriptions, documentId),
|
|
4745
|
+
values: hasSubscribers ? prev.values : { ...prev.values, [documentId]: { data: projectionValue, isPending: !1 } }
|
|
4746
|
+
};
|
|
4747
|
+
});
|
|
4748
|
+
}, PROJECTION_STATE_CLEAR_DELAY);
|
|
4591
4749
|
};
|
|
4592
4750
|
}
|
|
4593
|
-
}
|
|
4594
|
-
|
|
4595
|
-
|
|
4596
|
-
|
|
4597
|
-
|
|
4598
|
-
|
|
4599
|
-
|
|
4600
|
-
|
|
4601
|
-
|
|
4602
|
-
}), projects = createFetcherStore({
|
|
4751
|
+
})
|
|
4752
|
+
), resolveProjection = bindActionByDataset(
|
|
4753
|
+
projectionStore,
|
|
4754
|
+
({ instance }, { projection, ...docHandle }) => firstValueFrom(
|
|
4755
|
+
getProjectionState(instance, { ...docHandle, projection }).observable.pipe(
|
|
4756
|
+
filter((i2) => !!i2.data)
|
|
4757
|
+
)
|
|
4758
|
+
)
|
|
4759
|
+
), API_VERSION$1 = "v2025-02-19", projects = createFetcherStore({
|
|
4603
4760
|
name: "Projects",
|
|
4604
4761
|
getKey: () => "projects",
|
|
4605
|
-
fetcher: (instance) => () => getClientState(instance, {
|
|
4762
|
+
fetcher: (instance) => () => getClientState(instance, {
|
|
4763
|
+
apiVersion: API_VERSION$1,
|
|
4764
|
+
scope: "global"
|
|
4765
|
+
}).observable.pipe(
|
|
4606
4766
|
switchMap((client) => client.observable.projects.list({ includeMembers: !1 }))
|
|
4607
4767
|
)
|
|
4608
|
-
}), getProjectsState = projects.getState, resolveProjects = projects.resolveState,
|
|
4609
|
-
|
|
4610
|
-
|
|
4611
|
-
|
|
4612
|
-
|
|
4613
|
-
|
|
4614
|
-
|
|
4615
|
-
|
|
4616
|
-
|
|
4617
|
-
|
|
4618
|
-
|
|
4619
|
-
|
|
4620
|
-
|
|
4621
|
-
|
|
4622
|
-
|
|
4623
|
-
|
|
4624
|
-
const
|
|
4625
|
-
|
|
4626
|
-
|
|
4627
|
-
|
|
4628
|
-
|
|
4629
|
-
|
|
4630
|
-
|
|
4631
|
-
|
|
4632
|
-
|
|
4633
|
-
|
|
4634
|
-
|
|
4635
|
-
|
|
4636
|
-
|
|
4637
|
-
|
|
4638
|
-
|
|
4639
|
-
|
|
4640
|
-
|
|
4641
|
-
subscription.unsubscribe();
|
|
4642
|
-
};
|
|
4643
|
-
}
|
|
4644
|
-
}, errorHandler = createInternalAction(({ state }) => function() {
|
|
4645
|
-
return (error) => state.set("setError", { error });
|
|
4646
|
-
}), listenForNewSubscribersAndFetch = createInternalAction(
|
|
4647
|
-
({ state, instance }) => function() {
|
|
4648
|
-
return state.observable.pipe(
|
|
4649
|
-
map((s2) => new Set(Object.keys(s2.queries))),
|
|
4650
|
-
distinctUntilChanged((curr, next) => curr.size !== next.size ? !1 : Array.from(next).every((i2) => curr.has(i2))),
|
|
4651
|
-
startWith$1(/* @__PURE__ */ new Set()),
|
|
4652
|
-
pairwise$1(),
|
|
4653
|
-
mergeMap$1(([curr, next]) => {
|
|
4654
|
-
const added = Array.from(next).filter((i2) => !curr.has(i2)), removed = Array.from(curr).filter((i2) => !next.has(i2));
|
|
4655
|
-
return [
|
|
4656
|
-
...added.map((key) => ({ key, added: !0 })),
|
|
4657
|
-
...removed.map((key) => ({ key, added: !1 }))
|
|
4658
|
-
];
|
|
4659
|
-
}),
|
|
4660
|
-
groupBy$1((i2) => i2.key),
|
|
4661
|
-
mergeMap$1(
|
|
4662
|
-
(group$) => group$.pipe(
|
|
4663
|
-
switchMap((e3) => {
|
|
4664
|
-
if (!e3.added) return EMPTY;
|
|
4665
|
-
const lastLiveEventId$ = state.observable.pipe(
|
|
4666
|
-
map((s2) => s2.queries[group$.key]?.lastLiveEventId),
|
|
4667
|
-
distinctUntilChanged()
|
|
4668
|
-
), { query, options: { params, scope, ...options } = {} } = parseQueryKey(group$.key), client$ = getClientState(instance, { apiVersion: "vX", scope }).observable;
|
|
4669
|
-
return combineLatest([lastLiveEventId$, client$]).pipe(
|
|
4670
|
-
switchMap(
|
|
4671
|
-
([lastLiveEventId, client]) => client.observable.fetch(query, params, {
|
|
4672
|
-
...options,
|
|
4673
|
-
filterResponse: !1,
|
|
4674
|
-
returnQuery: !1,
|
|
4675
|
-
lastLiveEventId
|
|
4676
|
-
})
|
|
4677
|
-
)
|
|
4678
|
-
);
|
|
4679
|
-
}),
|
|
4680
|
-
catchError$1((error) => (state.set("setQueryError", setQueryError(group$.key, error)), EMPTY)),
|
|
4681
|
-
tap$1(({ result, syncTags }) => {
|
|
4682
|
-
state.set("setQueryData", setQueryData(group$.key, result, syncTags));
|
|
4683
|
-
})
|
|
4684
|
-
)
|
|
4685
|
-
)
|
|
4686
|
-
).subscribe({ error: errorHandler(this) });
|
|
4768
|
+
}), getProjectsState = projects.getState, resolveProjects = projects.resolveState, API_VERSION = "vX", USERS_STATE_CLEAR_DELAY = 5e3, DEFAULT_USERS_BATCH_SIZE = 100, getUsersKey = (instance, {
|
|
4769
|
+
resourceType,
|
|
4770
|
+
organizationId,
|
|
4771
|
+
batchSize = DEFAULT_USERS_BATCH_SIZE,
|
|
4772
|
+
projectId = instance.config.projectId
|
|
4773
|
+
} = {}) => JSON.stringify({ resourceType, organizationId, batchSize, projectId }), parseUsersKey = (key) => JSON.parse(key), addSubscription = (subscriptionId, key) => (prev) => {
|
|
4774
|
+
const group = prev.users[key], subscriptions = [...group?.subscriptions ?? [], subscriptionId];
|
|
4775
|
+
return { ...prev, users: { ...prev.users, [key]: { ...group, subscriptions } } };
|
|
4776
|
+
}, removeSubscription = (subscriptionId, key) => (prev) => {
|
|
4777
|
+
const group = prev.users[key];
|
|
4778
|
+
if (!group) return prev;
|
|
4779
|
+
const subscriptions = group.subscriptions.filter((id) => id !== subscriptionId);
|
|
4780
|
+
return subscriptions.length ? { ...prev, users: { ...prev.users, [key]: { ...group, subscriptions } } } : { ...prev, users: omit(prev.users, key) };
|
|
4781
|
+
}, setUsersData = (key, { data, nextCursor, totalCount }) => (prev) => {
|
|
4782
|
+
const group = prev.users[key];
|
|
4783
|
+
if (!group) return prev;
|
|
4784
|
+
const users = [...group.users ?? [], ...data];
|
|
4785
|
+
return { ...prev, users: { ...prev.users, [key]: { ...group, users, totalCount, nextCursor } } };
|
|
4786
|
+
}, updateLastLoadMoreRequest = (timestamp, key) => (prev) => {
|
|
4787
|
+
const group = prev.users[key];
|
|
4788
|
+
return group ? { ...prev, users: { ...prev.users, [key]: { ...group, lastLoadMoreRequest: timestamp } } } : prev;
|
|
4789
|
+
}, setUsersError = (key, error) => (prev) => {
|
|
4790
|
+
const group = prev.users[key];
|
|
4791
|
+
return group ? { ...prev, users: { ...prev.users, [key]: { ...group, error } } } : prev;
|
|
4792
|
+
}, cancelRequest = (key) => (prev) => {
|
|
4793
|
+
const group = prev.users[key];
|
|
4794
|
+
return !group || group.subscriptions.length ? prev : { ...prev, users: omit(prev.users, key) };
|
|
4795
|
+
}, initializeRequest = (key) => (prev) => prev.users[key] ? prev : { ...prev, users: { ...prev.users, [key]: { subscriptions: [] } } }, usersStore = {
|
|
4796
|
+
name: "UsersStore",
|
|
4797
|
+
getInitialState: () => ({ users: {} }),
|
|
4798
|
+
initialize: (context) => {
|
|
4799
|
+
const subscription = listenForLoadMoreAndFetch(context);
|
|
4800
|
+
return () => subscription.unsubscribe();
|
|
4687
4801
|
}
|
|
4688
|
-
),
|
|
4689
|
-
(
|
|
4690
|
-
|
|
4691
|
-
|
|
4692
|
-
|
|
4693
|
-
|
|
4694
|
-
|
|
4695
|
-
|
|
4696
|
-
|
|
4697
|
-
|
|
4698
|
-
|
|
4699
|
-
|
|
4700
|
-
|
|
4701
|
-
|
|
4702
|
-
|
|
4703
|
-
|
|
4802
|
+
}, errorHandler = (state) => (error) => state.set("setError", { error }), listenForLoadMoreAndFetch = ({ state, instance }) => state.observable.pipe(
|
|
4803
|
+
map((s2) => new Set(Object.keys(s2.users))),
|
|
4804
|
+
distinctUntilChanged((curr, next) => curr.size !== next.size ? !1 : Array.from(next).every((i2) => curr.has(i2))),
|
|
4805
|
+
startWith$1(/* @__PURE__ */ new Set()),
|
|
4806
|
+
pairwise$1(),
|
|
4807
|
+
mergeMap$1(([curr, next]) => {
|
|
4808
|
+
const added = Array.from(next).filter((i2) => !curr.has(i2)), removed = Array.from(curr).filter((i2) => !next.has(i2));
|
|
4809
|
+
return [
|
|
4810
|
+
...added.map((key) => ({ key, added: !0 })),
|
|
4811
|
+
...removed.map((key) => ({ key, added: !1 }))
|
|
4812
|
+
];
|
|
4813
|
+
}),
|
|
4814
|
+
groupBy$1((i2) => i2.key),
|
|
4815
|
+
mergeMap$1(
|
|
4816
|
+
(group$) => group$.pipe(
|
|
4817
|
+
switchMap((e3) => {
|
|
4818
|
+
if (!e3.added) return EMPTY;
|
|
4819
|
+
const { batchSize, ...options } = parseUsersKey(group$.key), projectId = options.projectId ?? instance.config.projectId, resourceType = options.resourceType ?? (options.organizationId ? "organization" : projectId ? "project" : "organization"), organizationId$ = options.organizationId ? of(options.organizationId) : getDashboardOrganizationId(instance).observable.pipe(
|
|
4820
|
+
filter((i2) => typeof i2 == "string")
|
|
4821
|
+
), resource$ = resourceType === "project" ? projectId ? of({ type: "project", id: projectId }) : throwError(() => new Error("Project ID required for this API.")) : organizationId$.pipe(map((id) => ({ type: "organization", id }))), client$ = getClientState(instance, {
|
|
4822
|
+
scope: "global",
|
|
4823
|
+
apiVersion: API_VERSION
|
|
4824
|
+
}).observable, loadMore$ = state.observable.pipe(
|
|
4825
|
+
map((s2) => s2.users[group$.key]?.lastLoadMoreRequest),
|
|
4704
4826
|
distinctUntilChanged()
|
|
4827
|
+
), cursor$ = state.observable.pipe(
|
|
4828
|
+
map((s2) => s2.users[group$.key]?.nextCursor),
|
|
4829
|
+
distinctUntilChanged(),
|
|
4830
|
+
filter((cursor) => cursor !== null)
|
|
4705
4831
|
);
|
|
4706
|
-
return combineLatest([
|
|
4707
|
-
|
|
4708
|
-
|
|
4709
|
-
|
|
4710
|
-
|
|
4832
|
+
return combineLatest([resource$, client$, loadMore$]).pipe(
|
|
4833
|
+
withLatestFrom(cursor$),
|
|
4834
|
+
switchMap(
|
|
4835
|
+
([[resource, client], cursor]) => client.observable.request({
|
|
4836
|
+
method: "GET",
|
|
4837
|
+
uri: `access/${resource.type}/${resource.id}/users`,
|
|
4838
|
+
query: cursor ? { nextCursor: cursor, limit: batchSize.toString() } : { limit: batchSize.toString() }
|
|
4839
|
+
})
|
|
4840
|
+
),
|
|
4841
|
+
catchError$1((error) => (state.set("setUsersError", setUsersError(group$.key, error)), EMPTY)),
|
|
4842
|
+
tap$1((response) => state.set("setUsersData", setUsersData(group$.key, response)))
|
|
4711
4843
|
);
|
|
4712
4844
|
})
|
|
4713
|
-
)
|
|
4714
|
-
|
|
4715
|
-
)
|
|
4716
|
-
|
|
4717
|
-
|
|
4718
|
-
|
|
4719
|
-
|
|
4720
|
-
|
|
4721
|
-
|
|
4722
|
-
|
|
4723
|
-
|
|
4724
|
-
|
|
4725
|
-
|
|
4726
|
-
|
|
4727
|
-
|
|
4728
|
-
|
|
4729
|
-
|
|
4730
|
-
|
|
4731
|
-
|
|
4732
|
-
);
|
|
4733
|
-
|
|
4734
|
-
|
|
4735
|
-
|
|
4736
|
-
|
|
4737
|
-
|
|
4738
|
-
}
|
|
4739
|
-
const _resolveQuery = createAction(queryStore, ({ state }) => function(query, { signal, ...options } = {}) {
|
|
4740
|
-
const { getCurrent } = getQueryState(this, query, options), key = getQueryKey(query, options), aborted$ = signal ? new Observable((observer) => {
|
|
4741
|
-
const cleanup = () => {
|
|
4742
|
-
signal.removeEventListener("abort", listener);
|
|
4743
|
-
}, listener = () => {
|
|
4744
|
-
observer.error(new DOMException("The operation was aborted.", "AbortError")), observer.complete(), cleanup();
|
|
4745
|
-
};
|
|
4746
|
-
return signal.addEventListener("abort", listener), cleanup;
|
|
4747
|
-
}).pipe(
|
|
4748
|
-
catchError$1((error) => {
|
|
4749
|
-
throw error instanceof Error && error.name === "AbortError" && state.set("cancelQuery", cancelQuery(key)), error;
|
|
4750
|
-
})
|
|
4751
|
-
) : NEVER;
|
|
4752
|
-
state.set("initializeQuery", initializeQuery(key));
|
|
4753
|
-
const resolved$ = state.observable.pipe(
|
|
4754
|
-
map(getCurrent),
|
|
4755
|
-
first$1((i2) => i2 !== void 0)
|
|
4756
|
-
);
|
|
4757
|
-
return firstValueFrom(race([resolved$, aborted$]));
|
|
4758
|
-
});
|
|
4759
|
-
function createStore(resource, actions) {
|
|
4760
|
-
return function(dependencies) {
|
|
4761
|
-
const instance = "instance" in dependencies ? dependencies.instance : dependencies, { state, dispose } = "state" in dependencies ? { state: dependencies.state, dispose: noop } : initializeResource(instance, resource), boundActions = Object.entries(actions).reduce((acc, [key, action]) => (acc[key] = action.bind(null, { state, instance }), acc), {});
|
|
4762
|
-
return { dispose, ...boundActions };
|
|
4763
|
-
};
|
|
4764
|
-
}
|
|
4765
|
-
const API_VERSION = "vX", usersStore = {
|
|
4766
|
-
name: "users",
|
|
4767
|
-
getInitialState: () => ({
|
|
4768
|
-
users: [],
|
|
4769
|
-
totalCount: 0,
|
|
4770
|
-
nextCursor: null,
|
|
4771
|
-
hasMore: !1,
|
|
4772
|
-
initialFetchCompleted: !1,
|
|
4773
|
-
options: {
|
|
4774
|
-
resourceType: "",
|
|
4775
|
-
resourceId: "",
|
|
4776
|
-
limit: 100
|
|
4845
|
+
)
|
|
4846
|
+
)
|
|
4847
|
+
).subscribe({ error: errorHandler(state) }), getUsersState = bindActionGlobally(
|
|
4848
|
+
usersStore,
|
|
4849
|
+
createStateSourceAction({
|
|
4850
|
+
selector: createSelector(
|
|
4851
|
+
[
|
|
4852
|
+
({ instance, state }, options) => state.error ?? state.users[getUsersKey(instance, options)]?.error,
|
|
4853
|
+
({ instance, state }, options) => state.users[getUsersKey(instance, options)]?.users,
|
|
4854
|
+
({ instance, state }, options) => state.users[getUsersKey(instance, options)]?.totalCount,
|
|
4855
|
+
({ instance, state }, options) => state.users[getUsersKey(instance, options)]?.nextCursor
|
|
4856
|
+
],
|
|
4857
|
+
(error, data, totalCount, nextCursor) => {
|
|
4858
|
+
if (error) throw error;
|
|
4859
|
+
if (!(data === void 0 || totalCount === void 0 || nextCursor === void 0))
|
|
4860
|
+
return { data, totalCount, hasMore: nextCursor !== null };
|
|
4861
|
+
}
|
|
4862
|
+
),
|
|
4863
|
+
onSubscribe: ({ instance, state }, options) => {
|
|
4864
|
+
const subscriptionId = insecureRandomId(), key = getUsersKey(instance, options);
|
|
4865
|
+
return state.set("addSubscription", addSubscription(subscriptionId, key)), () => {
|
|
4866
|
+
setTimeout(
|
|
4867
|
+
() => state.set("removeSubscription", removeSubscription(subscriptionId, key)),
|
|
4868
|
+
USERS_STATE_CLEAR_DELAY
|
|
4869
|
+
);
|
|
4870
|
+
};
|
|
4777
4871
|
}
|
|
4778
|
-
})
|
|
4779
|
-
|
|
4780
|
-
|
|
4781
|
-
|
|
4872
|
+
})
|
|
4873
|
+
), resolveUsers = bindActionGlobally(
|
|
4874
|
+
usersStore,
|
|
4875
|
+
async ({ state, instance }, { signal, ...options }) => {
|
|
4876
|
+
const key = getUsersKey(instance, options), { getCurrent } = getUsersState(instance, options), aborted$ = signal ? new Observable((observer) => {
|
|
4877
|
+
const cleanup = () => {
|
|
4878
|
+
signal.removeEventListener("abort", listener);
|
|
4879
|
+
}, listener = () => {
|
|
4880
|
+
observer.error(new DOMException("The operation was aborted.", "AbortError")), observer.complete(), cleanup();
|
|
4881
|
+
};
|
|
4882
|
+
return signal.addEventListener("abort", listener), cleanup;
|
|
4883
|
+
}).pipe(
|
|
4884
|
+
catchError$1((error) => {
|
|
4885
|
+
throw error instanceof Error && error.name === "AbortError" && state.set("cancelRequest", cancelRequest(key)), error;
|
|
4886
|
+
})
|
|
4887
|
+
) : NEVER;
|
|
4888
|
+
state.set("initializeRequest", initializeRequest(key));
|
|
4889
|
+
const resolved$ = state.observable.pipe(
|
|
4890
|
+
map(getCurrent),
|
|
4891
|
+
first$1((i2) => i2 !== void 0)
|
|
4892
|
+
);
|
|
4893
|
+
return firstValueFrom(race([resolved$, aborted$]));
|
|
4782
4894
|
}
|
|
4783
|
-
|
|
4895
|
+
), loadMoreUsers = bindActionGlobally(
|
|
4784
4896
|
usersStore,
|
|
4785
|
-
|
|
4786
|
-
|
|
4787
|
-
|
|
4788
|
-
(
|
|
4789
|
-
|
|
4790
|
-
(
|
|
4791
|
-
|
|
4792
|
-
(
|
|
4793
|
-
|
|
4794
|
-
|
|
4795
|
-
|
|
4796
|
-
|
|
4797
|
-
|
|
4798
|
-
|
|
4799
|
-
|
|
4800
|
-
|
|
4801
|
-
})
|
|
4802
|
-
)
|
|
4803
|
-
), fetchUsers = (instance, params) => {
|
|
4804
|
-
const { resourceType, resourceId, nextCursor, limit = 100 } = params;
|
|
4805
|
-
return getClient(instance, { scope: "global", apiVersion: API_VERSION }).request({
|
|
4806
|
-
method: "GET",
|
|
4807
|
-
uri: `access/${resourceType}/${resourceId}/users`,
|
|
4808
|
-
query: nextCursor ? { nextCursor, limit: limit.toString() } : { limit: limit.toString() },
|
|
4809
|
-
tag: "users"
|
|
4810
|
-
});
|
|
4811
|
-
}, loadMore = createAction(usersStore, ({ state, instance }) => async function() {
|
|
4812
|
-
const { users, nextCursor, options } = state.get(), { resourceType, resourceId, limit } = options;
|
|
4813
|
-
if (!resourceType || !resourceId)
|
|
4814
|
-
throw new Error("Resource type and ID are required to load more users");
|
|
4815
|
-
const response = await fetchUsers(instance, { resourceType, resourceId, nextCursor, limit }), allUsers = [...users, ...response.data], hasMore = allUsers.length < response.totalCount;
|
|
4816
|
-
state.set("loadMore", {
|
|
4817
|
-
users: allUsers,
|
|
4818
|
-
totalCount: response.totalCount,
|
|
4819
|
-
nextCursor: response.nextCursor,
|
|
4820
|
-
hasMore
|
|
4821
|
-
});
|
|
4822
|
-
}), resolveUsers = createAction(usersStore, ({ state, instance }) => async function() {
|
|
4823
|
-
const { options } = state.get(), { resourceType, resourceId, limit } = options;
|
|
4824
|
-
if (!resourceType || !resourceId)
|
|
4825
|
-
throw new Error("Resource type and ID are required to resolve users");
|
|
4826
|
-
const response = await fetchUsers(instance, { resourceType, resourceId, limit }), hasMore = response.data.length < response.totalCount;
|
|
4827
|
-
return state.set("resolveUsers", {
|
|
4828
|
-
users: response.data,
|
|
4829
|
-
totalCount: response.totalCount,
|
|
4830
|
-
nextCursor: response.nextCursor,
|
|
4831
|
-
hasMore,
|
|
4832
|
-
initialFetchCompleted: !0
|
|
4833
|
-
}), response;
|
|
4834
|
-
}), setOptions = createAction(usersStore, ({ state }) => function(options) {
|
|
4835
|
-
state.set("options", {
|
|
4836
|
-
...state.get(),
|
|
4837
|
-
options: {
|
|
4838
|
-
...state.get().options,
|
|
4839
|
-
resourceType: options.resourceType,
|
|
4840
|
-
resourceId: options.resourceId
|
|
4841
|
-
}
|
|
4842
|
-
});
|
|
4843
|
-
}), createUsersStore = createStore(usersStore, {
|
|
4844
|
-
getState,
|
|
4845
|
-
loadMore,
|
|
4846
|
-
resolveUsers,
|
|
4847
|
-
setOptions
|
|
4848
|
-
});
|
|
4849
|
-
var version = "0.0.0-alpha.21";
|
|
4897
|
+
async ({ state, instance }, options) => {
|
|
4898
|
+
const key = getUsersKey(instance, options), users = getUsersState(instance, options), usersState = users.getCurrent();
|
|
4899
|
+
if (!usersState)
|
|
4900
|
+
throw new Error("Users not loaded for specified resource. Please call resolveUsers first.");
|
|
4901
|
+
if (!usersState.hasMore)
|
|
4902
|
+
throw new Error("No more users available to load for this resource.");
|
|
4903
|
+
const promise = firstValueFrom(
|
|
4904
|
+
users.observable.pipe(
|
|
4905
|
+
filter((i2) => i2 !== void 0),
|
|
4906
|
+
skip(1)
|
|
4907
|
+
)
|
|
4908
|
+
), timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
4909
|
+
return state.set("updateLastLoadMoreRequest", updateLastLoadMoreRequest(timestamp, key)), await promise;
|
|
4910
|
+
}
|
|
4911
|
+
);
|
|
4912
|
+
var version = "0.0.0-alpha.23";
|
|
4850
4913
|
const CORE_SDK_VERSION = getEnv("PKG_VERSION") || `${version}-development`;
|
|
4851
4914
|
export {
|
|
4852
4915
|
AuthStateType,
|
|
@@ -4854,12 +4917,10 @@ export {
|
|
|
4854
4917
|
applyDocumentActions,
|
|
4855
4918
|
createDocument,
|
|
4856
4919
|
createSanityInstance,
|
|
4857
|
-
createUsersStore,
|
|
4858
4920
|
deleteDocument,
|
|
4859
4921
|
destroyController,
|
|
4860
4922
|
discardDocument,
|
|
4861
4923
|
editDocument,
|
|
4862
|
-
fetchLoginUrls,
|
|
4863
4924
|
getAuthState,
|
|
4864
4925
|
getClient,
|
|
4865
4926
|
getClientState,
|
|
@@ -4868,7 +4929,7 @@ export {
|
|
|
4868
4929
|
getDatasetsState,
|
|
4869
4930
|
getDocumentState,
|
|
4870
4931
|
getDocumentSyncStatus,
|
|
4871
|
-
|
|
4932
|
+
getLoginUrlState,
|
|
4872
4933
|
getOrCreateChannel,
|
|
4873
4934
|
getOrCreateController,
|
|
4874
4935
|
getOrCreateNode,
|
|
@@ -4879,12 +4940,15 @@ export {
|
|
|
4879
4940
|
getProjectsState,
|
|
4880
4941
|
getQueryKey,
|
|
4881
4942
|
getQueryState,
|
|
4882
|
-
getResourceId,
|
|
4883
4943
|
getTokenState,
|
|
4944
|
+
getUsersKey,
|
|
4945
|
+
getUsersState,
|
|
4884
4946
|
handleAuthCallback,
|
|
4885
4947
|
jsonMatch,
|
|
4948
|
+
loadMoreUsers,
|
|
4886
4949
|
logout,
|
|
4887
4950
|
parseQueryKey,
|
|
4951
|
+
parseUsersKey,
|
|
4888
4952
|
publishDocument,
|
|
4889
4953
|
releaseChannel,
|
|
4890
4954
|
releaseNode,
|
|
@@ -4896,6 +4960,7 @@ export {
|
|
|
4896
4960
|
resolveProjection,
|
|
4897
4961
|
resolveProjects,
|
|
4898
4962
|
resolveQuery,
|
|
4963
|
+
resolveUsers,
|
|
4899
4964
|
subscribeDocumentEvents,
|
|
4900
4965
|
unpublishDocument
|
|
4901
4966
|
};
|